Nspawn - Build A Tor-only XMPP Server In Containers

The Plan

ops-tactics

Similar to the Tor-only IRC Server In Containers the XMPP service is usable on Tor.
Systemd Nspawn is a great, light-weight OS container engine for the task.

  • The Tor container runs the Tor process. (10.10.0.10)
  • The XMPP container runs the Prosody server. (10.10.0.12)
  • If you followed the previous article you have an IRC container too. (10.10.0.11)

All services are separated. They have their own container.

The Tor Container Configuration

Enter the Tor container:

sudo machinectl shell tor

Install Tor if you haven't done already:

apt install tor

Configure the hidden service for the XMPP server:

vim /etc/tor/torrc

Add the configuration:

HiddenServiceDir  /var/lib/tor/xmpp_hidden_service/
HiddenServicePort 5222 10.10.0.12:5222

Restart Tor:

systemctl restart tor.service

Check your onion address:

cat /var/lib/tor/xmpp_hidden_service/hostname

I use youronion.onion example through this article.
You must use your own onion address instead of it.

The XMPP Container Configuration

Enter the XMPP container:

sudo machinectl shell xmpp

Install the Prosody XMPP server:

apt install -y prosody prosody-modules

Take a backup of the original Prosody configuration for later reference:

cp /etc/prosody/prosody.cfg.lua /etc/prosody/prosody.cfg.lua.orig

Configure your Prosody instance in the global /etc/prosody/prosody.cfg.lua.

Set the admin(s):

admins = { "user@youronion.onion" }

Set the binding of the listening interface:

interfaces = { "10.10.0.12" }

In the modules_enabled uncomment the:

  • mam
  • announce
  • groups

In the modules_disabled uncomment the:

  • s2s

Edit the vhost configuration:

vim /etc/prosody/conf.avail/xmpp_hidden_service.cfg.lua
VirtualHost "youronion.onion"

ssl = {
    key = "/var/lib/prosody/youronion.onion.key";
    certificate = "/var/lib/prosody/youronion.onion.crt";
}

authentication = "internal_hashed"
allow_registration = false
c2s_require_encryption = true

Enable the configuration:

sudo ln -s /etc/prosody/conf.avail/xmpp_hidden_service.cfg.lua \
/etc/prosody/conf.d/xmpp_hidden_service.cfg.lua

Generate the self-signed certificates:

sudo prosodyctl cert generate youronion.onion

MUC (Conference Room) Configuration

Uncomment the mam module for muc_mam in the global Prosody configuration (/etc/prosody/prosody.cfg.lua).

Put the MUC setup in the vhost configuration to /etc/prosody/conf.avail/xmpp_hidden_service.cfg.lua:

Component "muc.youronion.onion" "muc"
    modules_enabled = { "muc_mam" }
    restrict_room_creation = true
    muc_room_default_public = false
    muc_room_default_members_only = true
    muc_room_default_persistent = true

SQLite Storage Configuration

Install the necessary packages:

sudo apt install -y sqlite3 lua-dbi-sqlite3

Uncomment the SQL setup in the global Prosody configuration (/etc/prosody/prosody.cfg.lua):

storage = "sql"
sql = { driver = "SQLite3", database = "prosody.sqlite" }

Restart the service:

sudo systemctl restart prosody.service

Final Whisper

XMPP is a text-based chat protocol.
For security considerations you don't read about file uploads or open registration in this article.
The architecture is locked. Isolated. Managed by the operator.

The design is simple and reproducible.

  • You can host your chat for your community.
  • Tor protects traffic between the client and the onion-service host. Prosody separately enforces encryption for XMPP client connections.
  • You can snapshot the containers before you make any change.

Treat container snapshots as sensitive data.
They may contain private keys, credentials and chat data.

Your community. Your data. Hosted by you.

DeadSwitch | The Silent Architect
[ Fear the Silence. Fear the Switch. ]