Introduction
This procedure describes how Alexis Huxley set up a XMPP server.
Prologue
- Note that, because this procedure starts with setting up a proper certificate and that requires authentication, DNS may need to be modified before the XMPP server itself is installed. This means there is noticable service downtime.
- Set some environment variables used in the rest of this procedure:
FQDN=<fqdn-of-server-as-seen-from-internet> # e.g. FQDN=jabber.pasta.freemyip.com
Let’s Encrypt certificate
- Ensure that the front-end webserver to does not forward requests that it receives over https to the mail server (it is not needed).
- Ensure that the front-end webserver forwards requests that it receives over http to the mail server, with a configuration something like this:
<VirtualHost *:80> ServerName jabber.pasta.freemyip.com ServerAdmin webmaster@dont-use-this-address CustomLog /var/log/apache2/jabber.pasta.freemyip.com/jabber.pasta.freemyip.com-access.log combined2 ErrorLog /var/log/apache2/jabber.pasta.freemyip.com/jabber.pasta.freemyip.com-error.log LogLevel warn ServerSignature Off <Location /> ProxyPass http://jabber.pasta.net/ ProxyPassReverse http://jabber.pasta.net/ </Location> </VirtualHost>
- On the DNS server, update the CNAME record for ‘jabber.pasta.freemyip.com’ to point to the new XMPP server.
- On the firewall/router make an adjustments to where incoming traffic on ports 5222 and 5269 is sent.
- On the XMPP server install and run certbot as follows:
apt -y install certbot certbot certonly --standalone -d $FQDN
(The option
--standalone
will – whenever requesting/renewing a certificate – start a standalone internal webserver to allow letsencrypt.org authenticate the renewal request; /etc/cron.d/certbot will respect this option when it is used to initially request the certificate.) - Locate the certificate and key generated by certbot:
find /etc/letsencrypt/live/ -name fullchain.pem -o -name privkey.pem
Prosody
- Run:
apt -y install prosody systemctl stop prosody
- Edit /etc/prosody/prosody.cfg.lua and make the following global config changes:
---------- Server-wide settings ---------- ... interfaces = { "*" } -- don't listen on IPv6 ...
- Create a minimal new virtual host by editing /etc/prosody/conf.avail/$FQDN.cfg.lua to contain only:
VirtualHost "FQDN" ssl = { key = "/etc/letsencrypt/live/FQDN/privkey.pem"; certificate = "/etc/letsencrypt/live/FQDN/fullchain.pem"; } allow_registration = true;
and then replacing all the placeholders by running:
sed -i "s/FQDN/$FQDN/g" /etc/prosody/conf.avail/$FQDN.cfg.lua
- Symlink the new config into place and remove the old config:
ln -sr /etc/prosody/conf.avail/$FQDN.cfg.lua /etc/prosody/conf.d rm /etc/prosody/conf.d/localhost.cfg.lua
- Create a script to instruct prosody to reload its configuration when the Let’s Encrypt certificate gets renewed:
{ echo '#!/bin/sh' echo 'cp /etc/letsencrypt/live/FQDN/fullchain.pem /etc/prosody/certs/FQDN.fullchain.pem' echo 'cp /etc/letsencrypt/live/FQDN/privkey.pem /etc/prosody/certs/FQDN.privkey.pem' echo 'chown prosody:prosody /etc/prosody/certs/FQDN.fullchain.pem' echo 'chown prosody:prosody /etc/prosody/certs/FQDN.privkey.pem' echo 'systemctl reload prosody' } > /etc/letsencrypt/renewal-hooks/deploy/prosody sed -i "s/FQDN/$FQDN/g" /etc/letsencrypt/renewal-hooks/deploy/prosody chmod 755 /etc/letsencrypt/renewal-hooks/deploy/prosody
(I tried to configure prosody to use the Let’s Encrypt certificate in situ and for the hook to just run
prosodyctl reload
, but prosody does not run as root and therefore lacks access rights, so the above hook is better. In an older version of the this procedure, I usedprosodyctl --root cert import
, but the method above has the advantage of transparency.) - If migrating to a new server then copy over account information, which is stored in /var/lib/prosody/{accounts,roster,vcard}, remembering to set the owner & group correctly.
- Restart the service by running:
service prosody restart
- As an experiment, to improve file transfer time, I edited /etc/prosody/prosody.cfg.lua and commented out the following lines:
modules_enabled = { ... -- "limits"; ... } -- limits = { -- ... -- }
- To test:
- In pidgin go to Tools–>Certificates and select the appropriate certificate and click ‘Get Info’.
- Verify the ‘Activation date’ matches the time at which the above certbot command was run.