In order to support encryption of connections you need to supply Prosody with a certificate and a key file in the standard PEM format. If you run other encrypted services such as a HTTPS website or mail server then you may have these already and can simply direct Prosody to use them. Otherwise you will need to obtain some.

Which domain?

Sometimes there is confusion about which domain to get a certificate for, if your service uses SRV records to delegate XMPP services to a second domain (e.g. xmpp.example.com).

The answer is simple - your certificate simply needs to match whatever you have in your VirtualHost and Component definitions (e.g. example.com and conference.example.com), as these are the services you need to authenticate as. When you use the prosodyctl cert commands (see below), the correct entries are always included.

Obtaining a certificate

You essentially have two options. You can get a certificate from a recognised certificate authority (recommended), or you can create your own self-signed certificate.

Using a certificate authority

Any recognised certificate authority can provide certificates for you. Most charge for this, but the free Let's Encrypt certificates are also suitable for securing an XMPP service.

Many CAs will ask you to send them a certificate signing request (CSR). As of Prosody 0.9, Prosody can generate one for you based on any host in your config. Simply run:

  prosodyctl cert request example.com

Creating self-signed certificates

Many people choose to use a self-signed certificate, though in general practice it often results in reduced security. A self-signed certificate can be made in a few moments quite easily, but will not automatically allow your users or other servers to securely identify you.

Prosody 0.9+ makes it easy to produce a certificate from a host in your config file. Simply run:

  prosodyctl cert generate example.com

For older versions (e.g. 0.8), you can run openssl manually like so:

 openssl req -new -x509 -days 365 -nodes -out "prosody.crt" -newkey rsa:2048 -keyout "prosody.key"

You can replace 'prosody' in the filename with e.g. your domain name for identification.

Enter the information openssl asks for, it will be encoded in the certificate, and what you enter isn't too important, except ensure that when it asks for the "Common Name (eg, YOUR name)" you must enter the domain of your Prosody server (that is, whatever you defined with VirtualHost in the Prosody config file).

Installing the certificate

Prosody needs both the certificate and key file. Copy the files to somewhere Prosody can find them. Make sure that they are both readable to Prosody, and ensure that the key is kept private from anyone else. Under the host you generated the certificate for, put:

ssl = {
  key = "/path/to/prosody.key";
  certificate = "/path/to/prosody.crt";

Restart Prosody, or reload the config file and mod_tls to apply the change.

Note: If you received your certificate from a certificate authority, many require you to include an 'intermediate' certificate as well as yours. Simply add it into your certificate file, at the end. See certificate chains for more info.


From 0.10 (not released yet as of this writing) prosodyctl gains the ability to import and activate certificates in one command:

prosodyctl --root cert import HOSTNAME /path/to/certificates/host.crt

Certificates and their keys are copied to /etc/prosody/certs (can be changed with the certificates option) and then it signals Prosody to reload itself. --root lets prosodyctl write to paths that may not be writable by the prosody user, as is common with /etc/prosody. Multiple hostnames and paths can be given, as long as the hostnames are given before the paths.

This command can be put in cron or passed as a callback to automated certificate renewal programs such as certbot or other Let's Encrypt clients.


Certificate chains

Many certificate authorities1) provide you with an intermediate certificate which your server must supply to clients in addition to your own certificate so that they can verify it successfully.

The certbot (formerly "official") Let's Encrypt client includes the certificate and intermediate in the fullchain.pem file, so you should configure Prosody to use this as certificate.

ssl = {
  certificate = "/etc/letsencrypt/live/example.com/fullchain.pem"; -- Note: Only readable by root by default
  key = "/etc/letsencrypt/live/example.com/privkey.pem";

Your CA should tell you if you need an intermediate certificate, and either send it to you or tell you where to download it from. Once you have it, you can simply add it to the end of your existing certificate file. The order is important, your own certificate must be at the top.

On the command-line, this is an easy way to append the intermediate (ICA) certificate to yours:

cat /path/to/ica.crt >> /path/to/prosody.crt

If you get them the wrong way round you might see this error when connecting with your client:

  info    Client disconnected: no shared cipher

Note: This error can also happen for other reasons, for example if your key file does not match your certificate, or the format of your certificate/key file is incorrect (they need to be in the standard PEM format).

Specify trusted certificate store

Most systems have a place to store all the certificates from CAs that they trust. By default Prosody uses the operating system's trusted certificate store (generally /etc/ssl/certs on Linux), but you can specify a different path with the capath option:

ssl = {
  -- (other SSL options here) --
  capath = "/usr/mycertstore";


Some SSL keys are protected with passphrases. If this is the case for your file then you can specify a 'password' field in the Prosody ssl config. For example:

    ssl = {
        key = "/path/to/key.key";
        certificate = "/path/to/certificate.crt";
        password = "youllneverguess";

However note that including your password in plain text in a config file can compromise your key if you're not careful and the passphrase is the only security measure. Always check that the permissions on both Prosody's config and the key itself are secure against untrusted users.

Should you want to remove the passphrase from a key entirely, you can run:

 cp server.key server.key.orig
 openssl rsa -in server.key.orig -out server.key

Again, be sure to check permissions!


Prosody's certificates and keys must be readable by the user that Prosody runs as. For security reasons it is recommended to make sure that no other user (except root) can read the key file.

These examples assume that Prosody is running as the prosody user (the default in most packages).

  sudo chmod 600 /path/to/certificate.key
  sudo chown prosody:prosody /path/to/certificate.key

Prosody should also be able to read the parent directories of the file.

To test that only Prosody can read the file:

  sudo -u prosody cat /path/to/certificate.key # Should succeed
  sudo -u nobody cat /path/to/certificate.key # Should fail

Server-to-server encryption issues

Openfire has a bug that causes the following errors in Prosody's logs:

  ssl handshake failed
  ssl handshake error: wrong version number

If you need to communicate with Openfire servers the only way currently is to disable server-to-server encryption. Apart from disabling encryption entirely, you can use a module to disable encryption for selected domains only - see mod_s2s_never_encrypt_blacklist.

1) including the popular StartCom/StartSSL CA
doc/certificates.txt · Last modified: 2017/07/01 18:49 by Kim Alvefur