Prosody IM Website


file doc/certificates.md in changeset 300fca108bb0

View latest ↓ Download file

line wrap: on
line source

---
title: 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](#installing_the_certificate). Otherwise you will need to
obtain some.

# Which domain? {#which_domain}

Sometimes there is confusion about which domain to get a certificate
for, if your service uses [SRV records](/doc/dns#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 {#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 {#using_let_s_encrypt}

We have a page dedicated to [using Let's Encrypt with Prosody](/doc/letsencrypt).

## Using other certificate authorities {#using_other_certificate_authorities}

Any recognised certificate authority can provide certificates for you,
usually for a fee, valid for a certain period of time (usually a year).

\*Note:\* StartSSL (StartCom) used to be popular within the XMPP
community. Their certificates are [no longer
recommended](https://en.wikipedia.org/wiki/StartCom#Controversies). For
a free alternative, consider using Let\'s Encrypt instead.

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

``` {.code}
  prosodyctl cert request example.com
```

If you are running Prosody 0.9, you will need to copy the `.key` file
that this command generates and put it into your certificate directory
(e.g. `/etc/prosody/certs/example.com.key`). Ensure that this file is
[readable by Prosody only](#permissions). The `.req` file that this
command generates should be provided to your CA.

After the CA provides you with your new certificate, proceed to
[installing the certificate](#installing_the_certificate).

## Creating self-signed certificates {#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:

``` {.code}
  prosodyctl cert generate example.com
```

For versions before 0.9, you can run openssl manually like so:

``` {.code}
 openssl req -new -x509 -days 365 -nodes -out "example.com.crt" -newkey rsa:2048 -keyout "example.com.key"
```

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).

In Prosody 0.10 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](#permissions).

# Installing the certificate {#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`

If you are using Prosody 0.10 or later, these files will be [located
automatically](#automatic_location).

If your certificate and key are not in the default location, you can set
the \'certificate\' option:

``` {.code .lua}
VirtualHost "example.com"
  -- Override automatic location (expects /path/to/cert.key to also exist)
  certificate = "/path/to/cert.crt"
```

## Manual location {#manual_location}

If you are using Prosody 0.9 or need to override the automatic location,
you will need to provide the following config under the VirtualHost:

``` {.code .lua}
VirtualHost "example.com"
  ssl = {
    certificate = "/etc/prosody/certs/example.com.crt";
    key = "/etc/prosody/certs/example.com.key";
  }
```

Reload Prosody (e.g. `prosodyctl reload`) to use the new certificate and
key. In Prosody 0.9 you also need to reload
[mod\_tls](/doc/modules/mod_tls) using one of the admin interfaces.

**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](#certificate_chains) for more info. If your
certificate came from Let\'s Encrypt, then `fullchain.pem` already
contains this.

## Automatic certificate import {#automatic_certificate_import}

From Prosody 0.10 `prosodyctl` gains the ability to import and activate
certificates in one command:

``` {.code}
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](/doc/letsencrypt) page.

# Configuration

## Certificate chains {#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`.

``` {.code .lua}
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:

``` {.code}
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:

``` {.code}
  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](http://how2ssl.com/articles/working_with_pem_files/)).

## Specify trusted certificate store {#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:

``` {.code .lua}
ssl = {
  -- (other SSL options here) --
 
  capath = "/usr/mycertstore";
 }
```

## 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:

``` {.code .lua}
    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:

``` {.code}
 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).

``` {.code}
  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:

``` {.code}
  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 {#server-to-server_encryption_issues}

Openfire has [a bug](http://issues.igniterealtime.org/browse/OF-405)
that causes the following errors in Prosody\'s logs:

``` {.code}
  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](https://modules.prosody.im/mod_s2s_never_encrypt_blacklist.html).

## Automatic location {#automatic_location}

Prosody 0.10+ 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:

``` {.code .lua}
   -- Global option only (won't work under a VirtualHost or Component):
   certificates = "/etc/prosody/certs"
```

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 {#service_certificates}

Certain Prosody services, such as \'legacy\_ssl\' and \'https\', use a
single certificate. These services also support automatic certificate
discovery in Prosody 0.10. 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:

``` {.code .lua}
    https_certificate = "/path/to/cert.crt"
```

If you have the service running on multiple ports, you can serve a
different certificate on each port:

``` {.code .lua}
    https_certificate = {
        [5281] = "/path/to/cert.crt";
        [6281] = "/path/to/different.crt";
    }
```

Paths are relative to the config file.