SSL and XMPP

Wed 22 April 2015 by Eric Richter

So we have an XMPP server, and it even communicates with others. But what happens when we get super paranoid, and want to make sure nobody can snoop on the network's traffic? The answer is SSL! Due the amount of setup for this one, I am going to pass on writing a huge wall of text as a preample this time.

Obtaining a SSL Certificate

In order to set up SSL, we need a certificate. There are two options for this: request one from a trusted Certificate Authority (CA), or create a self-signed one. Acquiring one from a CA may not be free, but are much more likely to be accepted by clients. Self-signed certs are obviously free, but are not always trusted (and rightfully so).

Certificate Authority

Prosody provides a nice fancy tool to generate a request for you, simply run:

prosodyctl cert request server.net

Otherwise, consider checking out Comodo, Symantec, GoDaddy, etc. or wait patiently for Let's Encrypt.

Self-Signing a Certificate

Prosody also provides a tool (more like a wrapper to OpenSSL), to generate certificates, run:

prosodyctl cert generate server.net

and it will handle all the messy generation details.

Using the Certificate

Now that you have the certificate, make sure you configure your server to utilize it. Add, uncomment, or modify the following to your configuration file:

ssl = {
    key = "/path/to/cert.key"
    certificate = "/path/to/cert.crt"
}

WARNING: It is a very good idea to make sure these files are NOT accessible by normal users! I recommend putting them in a directory where only the prosody user has rights to view it. Example:

$ mkdir /etc/prosody/certs
$ chown prosody:prosody /etc/prosody/certs
$ chmod 700 /etc/prosody/certs

Enabling Encryption

So we have a certificate, and the server is now aware of it. Now we need to actually utilize it! The following will be a list of options are their purpose, feel free to mix and match to meet your needs.

If you want to force your users to use encryption, add

c2s_require_encrpytion = true

This will require ALL federated servers to verify each other and use encryption.

s2s_secure_auth = true

Even if the previous is set to false, you can still specify certain servers to provide a valid certificate by added them to the following array:

s2s_secure_domains = { "xmpp.server.net" }


-- For servers with self-signed, or no cert
s2s_insecure_domains = { }

Finally, add tls to your modules_enabled array:

modules_enabled = {
    ...
    "tls",
    ...
}

Fork me on GitHub