Certificates
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.
Tip: Prosody comes with a tool to perform basic sanity checks. To check if your certificate configuration looks correct, run:
prosodyctl check certs
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
If you do not currently have certificates, you have several options:
- Use a recognised certificate authority (recommended):
- Let's Encrypt, a free automatic certificate authority
- Other certificate authorities
- Create a self-signed certificate
Using Let’s Encrypt
We have a page dedicated to using Let’s Encrypt with Prosody.
Creating self-signed certificates
Instead of using a certificate authority, you can create a "self-signed" certificate instead. These are quick and easy to create, but they will show security warnings in clients, and some clients or other servers may refuse to connect to your server entirely.
Prosody makes it easy to produce a self-signed certificate from a host in your config file. Simply run:
prosodyctl cert generate example.com
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).
The generated certificate can be used immediately after running
prosodyctl reload
, if you have not changed the certificate
path in the config file.
In earlier versions of Prosody, you will need to copy the generated
.key and .crt file to an appropriate place
(e.g. /etc/prosody/certs
) and set the appropriate permissions.
Installing the certificate
Prosody needs both the certificate and key file. We recommend copying these to the 'certs' subdirectory in the config directory.
For example, if your config file is in
/etc/prosody/prosody.cfg.lua
:
- Certificate:
/etc/prosody/certs/example.com.crt
- Key:
/etc/prosody/certs/example.com.key
These files are located automatically.
If your certificate and key are not in the default location, you can set the 'certificate' option:
"example.com"
VirtualHost -- Override automatic location (expects /path/to/cert.key to also exist)
= "/path/to/cert.crt" certificate
Manual location
If you need to override the automatic location, you will need to provide the following config under the VirtualHost:
"example.com"
VirtualHost = {
ssl = "/etc/prosody/certs/example.com.crt";
certificate = "/etc/prosody/certs/example.com.key";
key }
Reload Prosody (e.g. prosodyctl reload
) to use the new
certificate and key.
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. If your certificate came from Let's Encrypt, then
fullchain.pem
already contains this.
Automatic certificate import
prosodyctl
has the ability to import and activate
certificates in one command:
prosodyctl --root cert import HOSTNAME /path/to/certificates
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. For more information on
using Prosody with these, see our Let's
Encrypt page.
Configuration
Certificate chains
Many certificate authorities 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 = "/etc/letsencrypt/live/example.com/fullchain.pem"; -- Note: Only readable by root by default
certificate = "/etc/letsencrypt/live/example.com/privkey.pem";
key }
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) --
= "/usr/mycertstore";
capath }
Passphrases
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 = "/path/to/key.key";
key = "/path/to/certificate.crt";
certificate = "youllneverguess";
password }
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!
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 640 /path/to/certificate.key
sudo chown root: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
Automatic location
Prosody will automatically search for a certificate and key for each host, unless a path is manually specified in the config file.
By default the directory that Prosody searches is the 'certs' subdirectory in the same location as the config file. You can override this with the global 'certificates' option:
-- Global option only (won't work under a VirtualHost or Component):
= "/etc/prosody/certs" certificates
Within this directory, these are the locations that Prosody will search:
Certificate file | Key file |
HOSTNAME.crt |
HOSTNAME.key |
HOSTNAME/fullchain.pem |
HOSTNAME/privkey.pem |
Service certificates
Certain Prosody services, such as 'legacy_ssl' and 'https', use a
single certificate. These services also support automatic certificate
discovery. The same search list is used, but instead of the hostname,
the name 'SERVICE' is used. For example, https.crt
and
https.key
.
Alternatively the location can be manually overridden using the corresponding option in the global section of the config file:
= "/path/to/cert.crt" https_certificate
If you have the service running on multiple ports, you can serve a different certificate on each port:
= {
https_certificate [5281] = "/path/to/cert.crt";
[6281] = "/path/to/different.crt";
}
Paths are relative to the config file.