OpenWrt-based XMPP server

This document describes how to build an OpenWrt-based XMPP server. We build on top of OpenWrt because of the distribution’s simplicity and small size. Here we assume that the server will run within the confines of a Xen hypervisor.

Establish the VM

Perform the following steps on the Xen Dom0 host to establish the VM which will host the XMPP server:

  1. Obtain the x86_64 OpenWrt image at https://downloads.lede-project.org/releases/17.01.1/targets/x86/64/lede-17.01.1-x86-64-combined-ext4.img.gz.
  2. Uncompress the image and place it at /var/lib/xen/images/prosody-lede-17.01.1-x86-64-combined-ext4.img on the Xen Dom0 host.
  3. Write the following at /etc/xen/vm-prosody.cfg on the Xen Dom0 host (replace XX:XX:XX:XX:XX:XX):
name    = "prosody"
memory  =  1024
vcpus   =  1
builder = "hvm"
vif     = [ "model=e1000,script=vif-bridge,bridge=xenbr0,mac=XX:XX:XX:XX:XX:XX" ]
disk    = [ "tap2:tapdisk:aio:/var/lib/xen/images/prosody-lede-17.01.1-x86-64-combined-ext4.img,xvda,w" ]
serial  = "pty"

Software installation

Perform the following steps on the VM:

  1. Set the root password: passwd.
  2. Remove unnecessary packages:
opkg remove \
        dnsmasq \
        kmod-ppp \
        kmod-pppoe \
        kmod-pppox \
        kmod-r8169 \
        logd \
        luci-app-firewall \
        luci-lib-ip \
        luci-lib-jsonc \
        luci-lib-nixio \
        luci-proto-ipv6 \
        luci-proto-ppp \
        luci-theme-bootstrap \
        luci-mod-admin-full \
        luci-base \
        luci \
        mtd \
        odhcpd-ipv6only \
        ppp \
        ppp-mod-pppoe \
        r8169-firmware \
        uhttpd-mod-ubus \
        uhttpd
  1. Configure networking by writing /etc/config/network:
config interface loopback
        option ifname lo
        option proto static
        option ipaddr 127.0.0.1
        option netmask 255.0.0.0

config interface lan
        option ifname eth0
        option proto dhcp
  1. Install the necessary software:
opkg update
opkg install \
        freifunk-watchdog \
        prosody \
        zoneinfo-core \
        zoneinfo-northamerica
  1. Install a public SSH key at /etc/dropbear/authorized_keys.

Configuring the Prosody chat server

  1. /etc/prosody/certs/example.com.cert: Concatenate your certificate, the immediate certificate, and the root certificate to produce etc/prosody/certs/example.com.cert.

  2. /etc/prosody/certs/example.com.key: Place your private key in etc/prosody/certs/example.com.key.

  3. /etc/prosody/prosody.cfg.lua (replace example.com):

admins = { }

modules_enabled = {
        "roster";
        "saslauth";
        "tls";
        "dialback";
        "disco";
        "private";
        "vcard";
        "legacyauth";
        "version";
        "uptime";
        "time";
        "ping";
        "pep";
        "register";
        "posix";
};

allow_registration = false;

pidfile = "/var/run/prosody/prosody.pid";
        
ssl = { 
        key = "/etc/prosody/certs/example.com.key";
        certificate = "/etc/prosody/certs/example.com.cert";
        c2s_require_encryption = true;
        s2s_require_encryption = true;
}

log = {
        { levels = { "error" }; to = "syslog";  };
        { levels = { "error" }; to = "file"; 
                filename = "/var/log/prosody/prosody.err";  };
        { levels = { min = "info" }; to = "file"; 
                filename = "/var/log/prosody/prosody.log";  };
}

VirtualHost "example.com"
        enabled = true
  1. Set the ownership of Prosody’s sensitive files using chown prosody /etc/prosody/certs/*, and set the permissions on these files with chmod 600 /etc/prosody/certs/*.
  2. For each prosody user, prosodyctl register USERNAME example.com PASSWORD, replacing USERNAME, PASSWORD, and example.com. (Use LDAP?)

Configure the host firewall

  1. /etc/config/firewall:
config defaults
        option drop_invalid 1
        option input ACCEPT
        option output ACCEPT
        option forward ACCEPT

config zone
        option name lan
        option network lan
        option input DROP
        option output ACCEPT
        option forward DROP

# Allow Jabber client-to-server connections from LAN.
config rule
        option target ACCEPT
        option src lan
        option proto tcp
        option dest_port 5222

# Allow Jabber server-to-server connections from LAN.
config rule
        option target ACCEPT
        option src lan
        option proto tcp
        option dest_port 5269

Configure basic system settings

  1. /etc/config/system:
config system
        option hostname prosody.flyn.org
        option timezone EST5EDT,M3.2.0,M11.1.0

config timeserver ntp
        list server     0.openwrt.pool.ntp.org
        list server     1.openwrt.pool.ntp.org
        list server     2.openwrt.pool.ntp.org
        list server     3.openwrt.pool.ntp.org
        option enabled 1
        option enable_server 0
  1. /etc/config/freifunk-watchdog:
config process
        option process dropbear 
        option initscript /etc/init.d/dropbear
  1. /etc/config/dropbear:
config dropbear
        option PasswordAuth 'off'
        option RootPasswordAuth 'off'
        option Port         '22'