New doc: Request a free cert from Let's Encrypt.

This commit is contained in:
Zhang Huangbin 2018-12-11 22:44:46 +08:00
parent 42e244aa0d
commit d08dcc787d
5 changed files with 902 additions and 390 deletions

397
en_US/howto/letsencrypt.md Normal file
View File

@ -0,0 +1,397 @@
# Request a free cert from Let's Encrypt
[TOC]
iRedMail generates a self-signed SSL certificate during installation, it's
strongly recommended to use an valid ssl cert.
You can either request free cert, or buy one from ssl cert vendors. In this
tutorial, we will show you how to request a free cert for host name
`mail.mydomain.com` from __[Let's Encrypt](https://letsencrypt.org)__, and ssl
related configurations in relevant softwares running on iRedMail server.
Let's Encrypt supports wildcard host names, but it's not covered in this
tutorial, please read its [User Guide](https://certbot.eff.org/docs/using.html)
instead.
We use Let's Encrypt official tool named `certbot` to request cert, there're
some other third-party tools you can use. On OpenBSD, you can use command
`acme-client` which is in base system (check its manual page here:
[acme-client(1)](https://man.openbsd.org/acme-client). To get a list of other
tools, please visit Let's Encrypt website: [ACME Client
Implementations](https://letsencrypt.org/docs/client-options/).
## Before requesting a cert
### Which host names should be supported in the SSL cert?
You must understand which host names you need to support in the SSL cert:
1. __The full hostname of your mail server.__
Server hostname is usually used as SMTP/IMAP/POP3 server address in user's
mail client application like Outlook, Thunderbird.
You can get full hostname with command `hostname -f` on Linux, or
`hostname` on OpenBSD.
1. __The web host names you need to access via https.__
For example, `https://mydomain.com`, `https://support.mydomain.com`, then
you need to support both `mydomain.com` and `support.mydomain.com` in ssl
cert.
1. __NO__ need to support mail domain name in SSL cert, __except it's a web
host name also__.
### One cert for all host names, or one cert for each host name?
Dovecot and Nginx support reading/loading multiple ssl certs (for different
host names), but Postfix doesn't (except running multiple Postfix instances and
each instance uses one (different) ssl cert). so we recommend to use one cert
for all host names which are used by SMTP and IMAP/POP3 services.
### Make sure you have correct DNS record for the host names
The way we request free Let's Encrypt cert requires correct A type DNS record
for the host name, because Let's Encrypt organization needs to make sure that
you actually control the domain name and server. We will describe the detail
later.
To check the DNS record, you can use `dig` command like below:
```
dig +short -t a mail.mydomain.com
```
It should return the (public) IP address of your server.
## Request a free cert from Let's Encrypt
* Follow Let's Encrypt official tutorial to install required `certbot` package:
<https://certbot.eff.org>. it's used to request cert.
!!! warning
`certbot` program offers argument `--apache` and `--nginx` to modify
Apache/Nginx config files directly, they mess up iRedMail
configurations, please do not use these 2 arguments.
* Let's Encrypt has request rate limit control, you can request limited times
for same domain in one day, but the verification process doesn't have such
limit. We suggest run verification process first to make sure we fully match
its requirements.
Run command below as root user to verify the request process with
`--dry-run` argument. It will print some text on console to ask you few
simple questions, please read carefully and answer them.
```
certbot certonly --webroot --dry-run -w /var/www/html -d mail.mydomain.com
```
What's happening after you typed this command? you may ask.
!!! note "Things happening right behind the command"
1. `certbot` program creates a temporary plain text file locally under
`/var/www/html/.well-known/acme-challenge/`. We use file name
`35c9406f6b63bd18fa626e5bd9d0ea8b` for example in this tutorial
(`/var/www/html/.well-known/acme-challenge/35c9406f6b63bd18fa626e5bd9d0ea8b`).
1. `certbot` program sends the request to Let's Encrypt organization's
server, including the temporary file name.
1. Let's Encrypt organization's server will perform http request to your
server by visiting URL
`http://mail.mydomain.com/.well-known/acme-challenge/35c9406f6b63bd18fa626e5bd9d0ea8b`
to make sure the file actually exist on your server. This step is used
to verify A type DNS record of the host name and the domain name
ownership (you actually control this domain name and server).
1. `certbot` program remove temporary file locally.
1. if no error was reported by `certbot` program on console, and you run
above command without `--dry-run` argument (described later in this
tutorial), certbot will obtain ssl cert files and store them under
`/etc/letsencrypt/` directory.
For more details, please read Let's Encrypt official document: [How it
works](https://letsencrypt.org/how-it-works/).
!!! warning
We assume the web document root directory for web host name
`mail.mydomain.com` is `/var/www/html` (this is default path configured
by iRedMail). In new iRedMail releases, the path `/.well-known/` is
defined in Nginx config file `/etc/nginx/templates/misc.tmpl`, if you
have hard-coded directory for it with Nginx directive `root
/path/to/somewhere;`, you need to replace `/var/www/html` by
`/path/to/somewhere` in commands. For example:
```
certbot certonly --webroot -w /path/to/somewhere -d mail.mydomain.com
```
And sample Nginx configuration:
```
location ~ ^/.well-known/ { allow all; root /path/to/somewhere; }
```
* If everything went well and no error was reported by `certbot` program on
console, that means we fully match the requirements, and it's ok to
actually request the cert by running above command again but without
`--dry-run` argument:
```
certbot certonly --webroot -w /var/www/html -d mail.mydomain.com
```
If the command finished successfully, it will create and store cert files under
`/etc/letsencrypt/live/mail.mydomain.com/` (You may have different host name
instead of `mail.mydomain.com` in this sample path).
Created cert files:
* `cert.pem`: Server certificate.
* `chain.pem`: Additional intermediate certificate or certificates that web
browsers will need in order to validate the server certificate.
* `fullchain.pem`: All certificates, including server certificate (aka leaf
certificate or end-entity certificate). The server certificate is the first
one in this file, followed by any intermediates.
* `privkey.pem`: Private key for the certificate.
Directory `/etc/letsencrypt/live/` and `/etc/letsencrypt/archive` are owned by
root user and group, with permission 0700 (set by `certbot` program) by
default, it means other users can not access them -- including the daemon users
used to run network services like Postfix/Dovecot/OpenLDAP/MariaDB/PostgreSQL.
It's necessary to set the permission to 0644 for other applications to access them.
```
chmod 0644 /etc/letsencrypt/{live,archive}
```
## Use Let's Encrypt cert
The easiest and quickest way to use Let's Encrypt cert is creating symbol links
to the self-signed SSL cert generated by iRedMail installer, then
restart services which use the cert files.
### Create symbol links
* On RHEL/CentOS:
```
mv /etc/pki/tls/certs/iRedMail.crt{,.bak} # Backup. Rename iRedMail.crt to iRedMail.crt.bak
mv /etc/pki/tls/private/iRedMail.key{,.bak} # Backup. Rename iRedMail.key to iRedMail.key.bak
ln -s /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem /etc/pki/tls/certs/iRedMail.crt
ln -s /etc/letsencrypt/live/mail.mydomain.com/privkey.pem /etc/pki/tls/private/iRedMail.key
```
* On Debian/Ubuntu, FreeBSD and OpenBSD:
```
mv /etc/ssl/certs/iRedMail.crt{,.bak} # Backup. Rename iRedMail.crt to iRedMail.crt.bak
mv /etc/ssl/private/iRedMail.key{,.bak} # Backup. Rename iRedMail.key to iRedMail.key.bak
ln -s /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem /etc/ssl/certs/iRedMail.crt
ln -s /etc/letsencrypt/live/mail.mydomain.com/privkey.pem /etc/ssl/private/iRedMail.key
```
### Restart network services
Required services:
* Postfix
* Dovecot
* Nginx or Apache
Depends on the backend you chose during iRedMail installation, you may need to
restart:
* MySQL or MariaDB
* PostgreSQL
* OpenLDAP
## Verify the cert
* To verify ssl cert used in Postfix (SMTP server) and Dovecot, please launch a
mail client application (MUA, e.g. Outlook, Thunderbird) and create an email
account, make sure you correctly configured the MUA to connect to mail
server. If SSL cert is not valid, MUA will warn you.
* For Apache / Nginx web server, you can access your website with favourite web
browser, the browser should show you the ssl cert status. Or, use other
website to help test it, for example:
<https://www.ssllabs.com/ssltest/index.html> (input your web host name, then
submit and wait for a result).
## FAQ
### Renew the cert
Let's Encrypt cert will expire in 90 days, you must renew it before expired.
After renewed, don't forget to restart Postfix/Dovecot/Nginx/Apache to load the
new cert files.
For more details, please read Let's Encrypt official document: [Renewing certificates](https://certbot.eff.org/docs/using.html#renewing-certificates).
### How to check cert status
Run command:
```
certbot certificates
```
It will show you all existing certs and expiry date.
### How to request one cert with multiple host names
If you need to support multiple host names, you can specify multiple `-w`
and `-d` arguments like below:
```
certbot certonly \
--webroot \
--dry-run \
-w /var/www/html \
-d mail.mydomain.com \
-w /var/www/vhosts/2nd-domain.com \
-d 2nd-domain.com \
-w /var/www/vhosts/3rd-domain.com \
-d 3rd-domain.com
```
## SSL cert relevant settings in Postfix/Dovecot/Apache/Nginx
In sample settings below, file paths are for Debian/Ubuntu.
### Postfix
File `/etc/postfix/main.cf` (on Linux/OpenBSD) or `/usr/local/etc/postfix/main.cf` (on FreeBSD):
```
smtpd_tls_cert_file = /etc/ssl/certs/iRedMail.crt
smtpd_tls_key_file = /etc/ssl/private/iRedMail.key
smtpd_tls_CAfile = /etc/ssl/certs/iRedMail.crt
```
### Dovecot
File `/etc/dovecot/dovecot.conf` (on Linux/OpenBSD) or `/usr/local/etc/dovecot/dovecot.conf` (on FreeBSD):
```
ssl = required
ssl_cert = </etc/ssl/certs/iRedMail.crt
ssl_key = </etc/ssl/private/iRedMail.key
ssl_ca = </etc/ssl/certs/iRedMail.crt
```
### Apache (web server)
* On RHEL/CentOS, SSL certificate is defined in `/etc/httpd/conf.d/ssl.conf`.
* On Debian/Ubuntu, it's defined in `/etc/apache2/sites-available/default-ssl`
(or `default-ssl.conf`)
* On FreeBSD, it's defined in `/usr/local/etc/apache24/extra/httpd-ssl.conf`. Note:
if you're running different version of Apache, the path will be slightly
different (`apache24` will be `apache[_version_]`).
* On OpenBSD, if you're running OpenBSD 5.5 or earlier releases, it's defined
in `/var/www/conf/httpd.conf`. Note: OpenBSD 5.6 and later releases don't
ship Apache anymore.
Example:
```
SSLCertificateFile /etc/ssl/certs/iRedMail.crt
SSLCertificateKeyFile /etc/ssl/private/iRedMail.key
SSLCertificateChainFile /etc/ssl/certs/iRedMail.crt
```
Restarting Apache service is required.
### Nginx
File `/etc/nginx/templates/ssl.tmpl` (on Linux/OpenBSD) or `/usr/local/etc/nginx/templates/ssl.tmpl` (on FreeBSD):
```
ssl_certificate /etc/ssl/certs/iRedMail.crt;
ssl_certificate_key /etc/ssl/private/iRedMail.key;
```
### MySQL, MariaDB
> If MySQL/MariaDB is listening on localhost and not accessible from external
> network, this is OPTIONAL.
* On Red Hat and CentOS, it's defined in `/etc/my.cnf`
* On Debian and Ubuntu, it's defined in `/etc/mysql/my.cnf`.
* Since Ubuntu 15.04, it's defined in `/etc/mysql/mariadb.conf.d/mysqld.cnf`.
* On FreeBSD, it's defined in `/usr/local/etc/my.cnf`.
* On OpenBSD, it's defined in `/etc/my.cnf`.
```
[mysqld]
ssl-ca = /etc/ssl/certs/iRedMail.crt
ssl-cert = /etc/ssl/certs/iRedMail.crt
ssl-key = /etc/ssl/private/iRedMail.key
```
### OpenLDAP
> If OpenLDAP is listening on localhost and not accessible from external
> network, this is OPTIONAL.
* On Red Hat and CentOS, it's defined in `/etc/openldap/slapd.conf`.
* On Debian and Ubuntu, it's defined in `/etc/ldap/slapd.conf`.
* On FreeBSD, it's defined in `/usr/local/etc/openldap/slapd.conf`.
* On OpenBSD, it's defined in `/etc/openldap/slapd.conf`.
```
TLSCACertificateFile /etc/ssl/certs/iRedMail.crt
TLSCertificateKeyFile /etc/ssl/private/iRedMail.key
TLSCertificateFile /etc/ssl/certs/iRedMail.crt
```
### OpenBSD ldapd(8)
> If ldapd(8) is listening on localhost and not accessible from external
> network, this is OPTIONAL.
>
> For more details about ldapd config file, please check its manual page: ldapd.conf(5).
To make ldapd(8) listening on network interface for external network, please
make sure you have setting in `/etc/ldapd.conf` to listen on the interface. We
use `em0` as external network interface here for example.
```
# Listen on network interface 'em0', port 389, use STARTTLS for secure connection.
listen on em0 port 389 tls
```
If you want to use port 636 with SSL, try this:
```
# Listen on network interface 'em0', port 636, use SSL for secure connection.
listen on em0 port 636 ldaps
```
ldapd(8) will look for SSL cert and key from directory `/etc/ldap/certs/` by
default, the cert file name is `<interface_name>.crt` and `<interface_name>.key`.
In our case, it will look for `/etc/ldap/certs/em0.crt` and `/etc/ldap/certs/em0.key`.
Since iRedMail already generates a cert and key, we can use it directly. If you
have bought SSL cert/key, or requested one from LetsEncrypt, you can use them
too.
```
cd /etc/ldap/certs/
ln -s /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem em0.crt
ln -s /etc/letsencrypt/live/mail.mydomain.com/privkey.pem em0.key
```
Now restart ldapd(8) service:
```
rcctl restart ldapd
```
## See Also
* [Use a bought SSL certificate](./use.a.bought.ssl.certificate.html)

View File

@ -1,4 +1,4 @@
# Use a SSL certificate
# Use a bought SSL certificate
[TOC]
@ -12,17 +12,10 @@ providers, choose the one you prefer.
## Get a SSL certificate
### Get a free LetsEncrypt ssl cert
### Request a free cert from Let's Encrypt
["Let's Encrypt"](https://letsencrypt.org) offers free SSL certificate, please
follow its official tutorial to get one: <https://certbot.eff.org>
!!! attention
The `--apache` option of `certbot` program will modify Apache config
files, most time it messes up iRedMail configurations, so it's better
to get the cert with `certonly --webroot` option while requesting cert, then
follow tutorial below to update config files to use the cert.
We have another tutorial to show you to request a free cert from Let's Encrypt:
[Request a free cert from Let's Encrypt](./letsencrypt.html).
### Buy from a trusted SSL vendor
@ -72,8 +65,8 @@ issue an SSL certificate.
Usually, SSL provider will give you 2 files:
* cert.pem
* fullchain.pem (some SSL providers use name `server.ca-bundle`)
* `cert.pem`
* `fullchain.pem` (some SSL providers use name `server.ca-bundle`)
We need above 2 files, and `privkey.pem`. Upload them to your server, you can
store them in any directory you like, recommended directories are:
@ -84,207 +77,59 @@ store them in any directory you like, recommended directories are:
placed under `/etc/ssl/certs/`, `privkey.pem` should be `/etc/ssl/private/`.
* on OpenBSD: `/etc/ssl/`.
## Configure Postfix/Dovecot/Apache/Nginx to use bought SSL certificate
## Use the bought cert
We use CentOS for example in below tutorial, please adjust the file to correct
one on your server according to above description.
The easiest and quickest way to use the bought cert is replacing
the self-signed SSL cert generated by iRedMail installer, then
restart services which use the cert files.
### Postfix (SMTP server)
### Replace cert files
We can use `postconf` command to update SSL related settings directly:
```
postconf -e smtpd_tls_cert_file='/etc/pki/tls/certs/cert.pem'
postconf -e smtpd_tls_key_file='/etc/pki/tls/private/privkey.pem'
postconf -e smtpd_tls_CAfile='/etc/pki/tls/certs/fullchain.pem'
```
Restarting Postfix service is required.
### Dovecot (POP3/IMAP server)
SSL certificate settings are defined in Dovecot main config file,
`/etc/dovecot/dovecot.conf` (Linux/OpenBSD) or
`/usr/local/etc/dovecot/dovecot.conf` (FreeBSD):
* On RHEL/CentOS:
```
ssl = required
ssl_cert = </etc/pki/tls/certs/cert.pem
ssl_key = </etc/pki/tls/private/privkey.pem
ssl_ca = </etc/pki/tls/certs/fullchain.pem
mv /etc/pki/tls/certs/iRedMail.crt{,.bak} # Backup. Rename iRedMail.crt to iRedMail.crt.bak
mv /etc/pki/tls/private/iRedMail.key{,.bak} # Backup. Rename iRedMail.key to iRedMail.key.bak
cp fullchain.pem /etc/pki/tls/certs/iRedMail.crt
cp privkey.pem /etc/pki/tls/private/iRedMail.key
```
Restarting Dovecot service is required.
### Apache (web server)
* On RHEL/CentOS, SSL certificate is defined in `/etc/httpd/conf.d/ssl.conf`.
* On Debian/Ubuntu, it's defined in `/etc/apache2/sites-available/default-ssl`
(or `default-ssl.conf`)
* On FreeBSD, it's defined in `/usr/local/etc/apache24/extra/httpd-ssl.conf`. Note:
if you're running different version of Apache, the path will be slightly
different (`apache24` will be `apache[_version_]`).
* On OpenBSD, if you're running OpenBSD 5.5 or earlier releases, it's defined
in `/var/www/conf/httpd.conf`. Note: OpenBSD 5.6 and later releases don't
ship Apache anymore.
Example:
* On Debian/Ubuntu, FreeBSD and OpenBSD:
```
SSLCertificateFile /etc/pki/tls/certs/cert.pem
SSLCertificateKeyFile /etc/pki/tls/private/privkey.pem
SSLCertificateChainFile /etc/pki/tls/certs/fullchain.pem
mv /etc/ssl/certs/iRedMail.crt{,.bak} # Backup. Rename iRedMail.crt to iRedMail.crt.bak
mv /etc/ssl/private/iRedMail.key{,.bak} # Backup. Rename iRedMail.key to iRedMail.key.bak
cp fullchain.pem /etc/ssl/certs/iRedMail.crt
cp privkey.pem /etc/ssl/private/iRedMail.key
```
Restarting Apache service is required.
### Restart network services
### Nginx (web server)
Required services:
* On Linux and OpenBSD, it's defined in `/etc/nginx/templates/ssl.tmpl`
(or `/etc/nginx/conf.d/default.conf` on old iRedMail release)
* On FreeBSD, it's defined in `/usr/local/etc/nginx/templates/ssl.tmpl`
(or `/usr/local/etc/nginx/conf.d/default.conf` on old iRedMail release)
* Postfix
* Dovecot
* Nginx or Apache
```
ssl_certificate /etc/pki/tls/certs/cert.pem;
ssl_certificate_key /etc/pki/tls/private/privkey.pem;
```
Depends on the backend you chose during iRedMail installation, you may need to
restart:
Some browsers may complain about a certificate signed by a well-known
certificate authority, while other browsers may accept the certificate without
issues. This occurs because the issuing authority has signed the server
certificate using an intermediate certificate that is not present in the
certificate base of well-known trusted certificate authorities which is
distributed with a particular browser. In this case the authority provides a
bundle of chained certificates which should be concatenated to the signed
server certificate. The server certificate must appear before the chained
certificates in the combined file:
* MySQL or MariaDB
* PostgreSQL
* OpenLDAP
```
# cd /etc/pki/tls/certs/
# cat cert.pem fullchain.pem > server.chained.crt
```
## Verify the cert
Then update `ssl_certificate` parameter in `/etc/nginx/conf.d/default.conf`:
```
ssl_certificate /etc/pki/tls/certs/server.chained.crt;
```
* To verify ssl cert used in Postfix (SMTP server) and Dovecot, please launch a
mail client application (MUA, e.g. Outlook, Thunderbird) and create an email
account, make sure you correctly configured the MUA to connect to mail
server. If SSL cert is not valid, MUA will warn you.
* For Apache / Nginx web server, you can access your website with favourite web
browser, the browser should show you the ssl cert status. Or, use other
website to help test it, for example:
<https://www.ssllabs.com/ssltest/index.html> (input your web host name, then
submit and wait for a result).
Restarting Nginx service is required.
## See Also
### MySQL, MariaDB
> If MySQL/MariaDB is listening on localhost and not accessible from external
> network, this is OPTIONAL.
* On Red Hat and CentOS, it's defined in `/etc/my.cnf`
* On Debian and Ubuntu, it's defined in `/etc/mysql/my.cnf`.
* Since Ubuntu 15.04, it's defined in `/etc/mysql/mariadb.conf.d/mysqld.cnf`.
* On FreeBSD, it's defined in `/usr/local/etc/my.cnf`.
* On OpenBSD, it's defined in `/etc/my.cnf`.
```
[mysqld]
ssl-ca = /etc/pki/tls/certs/fullchain.pem
ssl-cert = /etc/pki/tls/certs/cert.pem
ssl-key = /etc/pki/tls/private/privkey.pem
```
### OpenLDAP
> If OpenLDAP is listening on localhost and not accessible from external
> network, this is OPTIONAL.
* On Red Hat and CentOS, it's defined in `/etc/openldap/slapd.conf`.
* On Debian and Ubuntu, it's defined in `/etc/ldap/slapd.conf`.
* On FreeBSD, it's defined in `/usr/local/etc/openldap/slapd.conf`.
* On OpenBSD, it's defined in `/etc/openldap/slapd.conf`.
```
TLSCACertificateFile /etc/pki/tls/certs/fullchain.pem
TLSCertificateFile /etc/pki/tls/certs/cert.pem
TLSCertificateKeyFile /etc/pki/tls/private/privkey.pem
```
Restarting OpenLDAP service is required.
If you want to connect with TLS (port 389) or SSL (port 636) for secure
connection from command line tools like `ldapsearch`, please update parameter
`TLS_CACERT` in OpenLDAP client config file also, otherwise you will get
error message like `Peer's Certificate issuer is not recognized`.
* On Red Hat and CentOS, it's defined in `/etc/openldap/ldap.conf`.
* On Debian and Ubuntu, it's defined in `/etc/ldap/ldap.conf`.
* On FreeBSD, it's defined in `/usr/local/etc/openldap/ldap.conf`.
* On OpenBSD, it's defined in `/etc/openldap/ldap.conf`.
```
TLS_CACERT /etc/pki/tls/certs/fullchain.pem
```
To connect with TLS, please run `ldapsearch` with argument `-Z` and use
`ldap://<your_server_name>:389` as ldap host. For example:
```
ldapsearch -x -W -Z \
-H 'ldap://mail.example.com:389' \
-D 'cn=vmail,dc=example,dc=com' \
-b 'o=domains,dc=example,dc=com' mail
```
* To connection with SSL, use `ldaps://<your_server_name>:636` as ldap host.
for example:
```
ldapsearch -x -W \
-H 'ldaps://mail.example.com:636' \
-D 'cn=vmail,dc=example,dc=com' \
-b 'o=domains,dc=example,dc=com' mail
```
### OpenBSD ldapd(8)
> If ldapd(8) is listening on localhost and not accessible from external
> network, this is OPTIONAL.
>
> For more details about ldapd config file, please check its manual page: ldapd.conf(5).
To make ldapd(8) listening on network interface for external network, please
make sure you have setting in `/etc/ldapd.conf` to listen on the interface. We
use `em0` as external network interface here for example.
```
# Listen on network interface 'em0', port 389, use STARTTLS for secure connection.
listen on em0 port 389 tls
```
If you want to use port 636 with SSL, try this:
```
# Listen on network interface 'em0', port 636, use SSL for secure connection.
listen on em0 port 636 ldaps
```
ldapd(8) will look for SSL cert and key from directory `/etc/ldap/certs/` by
default, the cert file name is `<interface_name>.crt` and `<interface_name>.key`.
In our case, it will look for `/etc/ldap/certs/em0.crt` and `/etc/ldap/certs/em0.key`.
Since iRedMail already generates a cert and key, we can use it directly. If you
have bought SSL cert/key, or requested one from LetsEncrypt, you can use them
too.
```
cd /etc/ldap/certs/
ln -s /etc/ssl/iRedMail.crt em0.crt
ln -s /etc/ssl/iRedMail.key em0.key
```
Now restart ldapd(8) service:
```
rcctl restart ldapd
```
## Reference
* [Configuring HTTPS servers](http://nginx.org/en/docs/http/configuring_https_servers.html)
* [Request a free cert from Let's Encrypt](./letsencrypt.html)

View File

@ -127,6 +127,7 @@
<li><a href="ldap.add.mail.list.html">LDAP: Add a mail list account</a></li>
<li><a href="ldap.bulk.create.mail.users.html">LDAP: Bulk create mail users</a></li>
<li><a href="ldap.user.mail.forwarding.html">LDAP: User mail forwarding</a></li>
<li><a href="letsencrypt.html">Request a free cert from Let's Encrypt</a></li>
<li><a href="mailbox.sharing.html">Mailbox sharing (Sharing IMAP folder with other users)</a></li>
<li><a href="manage.iredapd.html">Manage iRedAPD (white/blacklists, greylisting, and more)</a></li>
<li><a href="monitor.incoming.and.outgoing.mails.with.bcc.html">Monitor incoming and outgoing mails with BCC</a></li>
@ -148,7 +149,7 @@
<li><a href="sql.create.mail.user.html">SQL: Create new mail user</a></li>
<li><a href="sql.user.mail.forwarding.html">SQL: User mail forwarding</a></li>
<li><a href="store.spamassassin.bayes.in.sql.html">Store SpamAssassin bayes in SQL</a></li>
<li><a href="use.a.bought.ssl.certificate.html">Use a SSL certificate</a></li>
<li><a href="use.a.bought.ssl.certificate.html">Use a bought SSL certificate</a></li>
<li><a href="use.openldap.as.address.book.in.outlook.html">Use OpenLDAP as address book in Microsoft Outlook</a></li>
<li><a href="user.alias.address.html">Per-user alias address</a></li>
<li><a href="webmail.customization.html">Webmail customization</a></li>

403
html/letsencrypt.html Normal file
View File

@ -0,0 +1,403 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Request a free cert from Let's Encrypt</title>
<link rel="stylesheet" type="text/css" href="./css/markdown.css" />
</head>
<body>
<div id="navigation">
<a href="https://www.iredmail.org" target="_blank">
<img alt="iRedMail web site"
src="./images/logo-iredmail.png"
style="vertical-align: middle; height: 30px;"
/>&nbsp;
<span>iRedMail</span>
</a>
&nbsp;&nbsp;//&nbsp;&nbsp;<a href="./index.html">Document Index</a></div><h1 id="request-a-free-cert-from-lets-encrypt">Request a free cert from Let's Encrypt</h1>
<div class="toc">
<ul>
<li><a href="#request-a-free-cert-from-lets-encrypt">Request a free cert from Let's Encrypt</a><ul>
<li><a href="#before-requesting-a-cert">Before requesting a cert</a><ul>
<li><a href="#which-host-names-should-be-supported-in-the-ssl-cert">Which host names should be supported in the SSL cert?</a></li>
<li><a href="#one-cert-for-all-host-names-or-one-cert-for-each-host-name">One cert for all host names, or one cert for each host name?</a></li>
<li><a href="#make-sure-you-have-correct-dns-record-for-the-host-names">Make sure you have correct DNS record for the host names</a></li>
</ul>
</li>
<li><a href="#request-a-free-cert-from-lets-encrypt_1">Request a free cert from Let's Encrypt</a></li>
<li><a href="#use-lets-encrypt-cert">Use Let's Encrypt cert</a><ul>
<li><a href="#create-symbol-links">Create symbol links</a></li>
<li><a href="#restart-network-services">Restart network services</a></li>
</ul>
</li>
<li><a href="#verify-the-cert">Verify the cert</a></li>
<li><a href="#faq">FAQ</a><ul>
<li><a href="#renew-the-cert">Renew the cert</a></li>
<li><a href="#how-to-check-cert-status">How to check cert status</a></li>
<li><a href="#how-to-request-one-cert-with-multiple-host-names">How to request one cert with multiple host names</a></li>
</ul>
</li>
<li><a href="#ssl-cert-relevant-settings-in-postfixdovecotapachenginx">SSL cert relevant settings in Postfix/Dovecot/Apache/Nginx</a><ul>
<li><a href="#postfix">Postfix</a></li>
<li><a href="#dovecot">Dovecot</a></li>
<li><a href="#apache-web-server">Apache (web server)</a></li>
<li><a href="#nginx">Nginx</a></li>
<li><a href="#mysql-mariadb">MySQL, MariaDB</a></li>
<li><a href="#openldap">OpenLDAP</a></li>
<li><a href="#openbsd-ldapd8">OpenBSD ldapd(8)</a></li>
</ul>
</li>
<li><a href="#see-also">See Also</a></li>
</ul>
</li>
</ul>
</div>
<p>iRedMail generates a self-signed SSL certificate during installation, it's
strongly recommended to use an valid ssl cert.</p>
<p>You can either request free cert, or buy one from ssl cert vendors. In this
tutorial, we will show you how to request a free cert for host name
<code>mail.mydomain.com</code> from <strong><a href="https://letsencrypt.org">Let's Encrypt</a></strong>, and ssl
related configurations in relevant softwares running on iRedMail server.</p>
<p>Let's Encrypt supports wildcard host names, but it's not covered in this
tutorial, please read its <a href="https://certbot.eff.org/docs/using.html">User Guide</a>
instead.</p>
<p>We use Let's Encrypt official tool named <code>certbot</code> to request cert, there're
some other third-party tools you can use. On OpenBSD, you can use command
<code>acme-client</code> which is in base system (check its manual page here:
<a href="https://man.openbsd.org/acme-client">acme-client(1)</a>. To get a list of other
tools, please visit Let's Encrypt website: <a href="https://letsencrypt.org/docs/client-options/">ACME Client
Implementations</a>.</p>
<h2 id="before-requesting-a-cert">Before requesting a cert</h2>
<h3 id="which-host-names-should-be-supported-in-the-ssl-cert">Which host names should be supported in the SSL cert?</h3>
<p>You must understand which host names you need to support in the SSL cert:</p>
<ol>
<li>
<p><strong>The full hostname of your mail server.</strong></p>
<p>Server hostname is usually used as SMTP/IMAP/POP3 server address in user's
mail client application like Outlook, Thunderbird.</p>
<p>You can get full hostname with command <code>hostname -f</code> on Linux, or
<code>hostname</code> on OpenBSD.</p>
</li>
<li>
<p><strong>The web host names you need to access via https.</strong></p>
<p>For example, <code>https://mydomain.com</code>, <code>https://support.mydomain.com</code>, then
you need to support both <code>mydomain.com</code> and <code>support.mydomain.com</code> in ssl
cert.</p>
</li>
<li>
<p><strong>NO</strong> need to support mail domain name in SSL cert, <strong>except it's a web
host name also</strong>.</p>
</li>
</ol>
<h3 id="one-cert-for-all-host-names-or-one-cert-for-each-host-name">One cert for all host names, or one cert for each host name?</h3>
<p>Dovecot and Nginx support reading/loading multiple ssl certs (for different
host names), but Postfix doesn't (except running multiple Postfix instances and
each instance uses one (different) ssl cert). so we recommend to use one cert
for all host names which are used by SMTP and IMAP/POP3 services.</p>
<h3 id="make-sure-you-have-correct-dns-record-for-the-host-names">Make sure you have correct DNS record for the host names</h3>
<p>The way we request free Let's Encrypt cert requires correct A type DNS record
for the host name, because Let's Encrypt organization needs to make sure that
you actually control the domain name and server. We will describe the detail
later.</p>
<p>To check the DNS record, you can use <code>dig</code> command like below:</p>
<pre><code>dig +short -t a mail.mydomain.com
</code></pre>
<p>It should return the (public) IP address of your server.</p>
<h2 id="request-a-free-cert-from-lets-encrypt_1">Request a free cert from Let's Encrypt</h2>
<ul>
<li>
<p>Follow Let's Encrypt official tutorial to install required <code>certbot</code> package:
<a href="https://certbot.eff.org">https://certbot.eff.org</a>. it's used to request cert.</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p><code>certbot</code> program offers argument <code>--apache</code> and <code>--nginx</code> to modify
Apache/Nginx config files directly, they mess up iRedMail
configurations, please do not use these 2 arguments.</p>
</div>
</li>
<li>
<p>Let's Encrypt has request rate limit control, you can request limited times
for same domain in one day, but the verification process doesn't have such
limit. We suggest run verification process first to make sure we fully match
its requirements.</p>
<p>Run command below as root user to verify the request process with
<code>--dry-run</code> argument. It will print some text on console to ask you few
simple questions, please read carefully and answer them.</p>
</li>
</ul>
<pre><code>certbot certonly --webroot --dry-run -w /var/www/html -d mail.mydomain.com
</code></pre>
<p>What's happening after you typed this command? you may ask.</p>
<div class="admonition note">
<p class="admonition-title">Things happening right behind the command</p>
<ol>
<li><code>certbot</code> program creates a temporary plain text file locally under
<code>/var/www/html/.well-known/acme-challenge/</code>. We use file name
<code>35c9406f6b63bd18fa626e5bd9d0ea8b</code> for example in this tutorial
(<code>/var/www/html/.well-known/acme-challenge/35c9406f6b63bd18fa626e5bd9d0ea8b</code>).</li>
<li><code>certbot</code> program sends the request to Let's Encrypt organization's
server, including the temporary file name.</li>
<li>Let's Encrypt organization's server will perform http request to your
server by visiting URL
<code>http://mail.mydomain.com/.well-known/acme-challenge/35c9406f6b63bd18fa626e5bd9d0ea8b</code>
to make sure the file actually exist on your server. This step is used
to verify A type DNS record of the host name and the domain name
ownership (you actually control this domain name and server).</li>
<li><code>certbot</code> program remove temporary file locally.</li>
<li>if no error was reported by <code>certbot</code> program on console, and you run
above command without <code>--dry-run</code> argument (described later in this
tutorial), certbot will obtain ssl cert files and store them under
<code>/etc/letsencrypt/</code> directory.</li>
</ol>
<p>For more details, please read Let's Encrypt official document: <a href="https://letsencrypt.org/how-it-works/">How it
works</a>.</p>
</div>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>We assume the web document root directory for web host name
<code>mail.mydomain.com</code> is <code>/var/www/html</code> (this is default path configured
by iRedMail). In new iRedMail releases, the path <code>/.well-known/</code> is
defined in Nginx config file <code>/etc/nginx/templates/misc.tmpl</code>, if you
have hard-coded directory for it with Nginx directive <code>root
/path/to/somewhere;</code>, you need to replace <code>/var/www/html</code> by
<code>/path/to/somewhere</code> in commands. For example:</p>
<p><code>certbot certonly --webroot -w /path/to/somewhere -d mail.mydomain.com</code></p>
<p>And sample Nginx configuration:</p>
<p><code>location ~ ^/.well-known/ { allow all; root /path/to/somewhere; }</code></p>
</div>
<ul>
<li>If everything went well and no error was reported by <code>certbot</code> program on
console, that means we fully match the requirements, and it's ok to
actually request the cert by running above command again but without
<code>--dry-run</code> argument:</li>
</ul>
<pre><code>certbot certonly --webroot -w /var/www/html -d mail.mydomain.com
</code></pre>
<p>If the command finished successfully, it will create and store cert files under
<code>/etc/letsencrypt/live/mail.mydomain.com/</code> (You may have different host name
instead of <code>mail.mydomain.com</code> in this sample path).</p>
<p>Created cert files:</p>
<ul>
<li><code>cert.pem</code>: Server certificate.</li>
<li><code>chain.pem</code>: Additional intermediate certificate or certificates that web
browsers will need in order to validate the server certificate.</li>
<li><code>fullchain.pem</code>: All certificates, including server certificate (aka leaf
certificate or end-entity certificate). The server certificate is the first
one in this file, followed by any intermediates.</li>
<li><code>privkey.pem</code>: Private key for the certificate.</li>
</ul>
<p>Directory <code>/etc/letsencrypt/live/</code> and <code>/etc/letsencrypt/archive</code> are owned by
root user and group, with permission 0700 (set by <code>certbot</code> program) by
default, it means other users can not access them -- including the daemon users
used to run network services like Postfix/Dovecot/OpenLDAP/MariaDB/PostgreSQL.
It's necessary to set the permission to 0644 for other applications to access them.</p>
<pre><code>chmod 0644 /etc/letsencrypt/{live,archive}
</code></pre>
<h2 id="use-lets-encrypt-cert">Use Let's Encrypt cert</h2>
<p>The easiest and quickest way to use Let's Encrypt cert is creating symbol links
to the self-signed SSL cert generated by iRedMail installer, then
restart services which use the cert files.</p>
<h3 id="create-symbol-links">Create symbol links</h3>
<ul>
<li>On RHEL/CentOS:</li>
</ul>
<pre><code>mv /etc/pki/tls/certs/iRedMail.crt{,.bak} # Backup. Rename iRedMail.crt to iRedMail.crt.bak
mv /etc/pki/tls/private/iRedMail.key{,.bak} # Backup. Rename iRedMail.key to iRedMail.key.bak
ln -s /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem /etc/pki/tls/certs/iRedMail.crt
ln -s /etc/letsencrypt/live/mail.mydomain.com/privkey.pem /etc/pki/tls/private/iRedMail.key
</code></pre>
<ul>
<li>On Debian/Ubuntu, FreeBSD and OpenBSD:</li>
</ul>
<pre><code>mv /etc/ssl/certs/iRedMail.crt{,.bak} # Backup. Rename iRedMail.crt to iRedMail.crt.bak
mv /etc/ssl/private/iRedMail.key{,.bak} # Backup. Rename iRedMail.key to iRedMail.key.bak
ln -s /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem /etc/ssl/certs/iRedMail.crt
ln -s /etc/letsencrypt/live/mail.mydomain.com/privkey.pem /etc/ssl/private/iRedMail.key
</code></pre>
<h3 id="restart-network-services">Restart network services</h3>
<p>Required services:</p>
<ul>
<li>Postfix</li>
<li>Dovecot</li>
<li>Nginx or Apache</li>
</ul>
<p>Depends on the backend you chose during iRedMail installation, you may need to
restart:</p>
<ul>
<li>MySQL or MariaDB</li>
<li>PostgreSQL</li>
<li>OpenLDAP</li>
</ul>
<h2 id="verify-the-cert">Verify the cert</h2>
<ul>
<li>To verify ssl cert used in Postfix (SMTP server) and Dovecot, please launch a
mail client application (MUA, e.g. Outlook, Thunderbird) and create an email
account, make sure you correctly configured the MUA to connect to mail
server. If SSL cert is not valid, MUA will warn you.</li>
<li>For Apache / Nginx web server, you can access your website with favourite web
browser, the browser should show you the ssl cert status. Or, use other
website to help test it, for example:
<a href="https://www.ssllabs.com/ssltest/index.html">https://www.ssllabs.com/ssltest/index.html</a> (input your web host name, then
submit and wait for a result).</li>
</ul>
<h2 id="faq">FAQ</h2>
<h3 id="renew-the-cert">Renew the cert</h3>
<p>Let's Encrypt cert will expire in 90 days, you must renew it before expired.
After renewed, don't forget to restart Postfix/Dovecot/Nginx/Apache to load the
new cert files.</p>
<p>For more details, please read Let's Encrypt official document: <a href="https://certbot.eff.org/docs/using.html#renewing-certificates">Renewing certificates</a>.</p>
<h3 id="how-to-check-cert-status">How to check cert status</h3>
<p>Run command:</p>
<pre><code>certbot certificates
</code></pre>
<p>It will show you all existing certs and expiry date.</p>
<h3 id="how-to-request-one-cert-with-multiple-host-names">How to request one cert with multiple host names</h3>
<p>If you need to support multiple host names, you can specify multiple <code>-w</code>
and <code>-d</code> arguments like below:</p>
<pre><code>certbot certonly \
--webroot \
--dry-run \
-w /var/www/html \
-d mail.mydomain.com \
-w /var/www/vhosts/2nd-domain.com \
-d 2nd-domain.com \
-w /var/www/vhosts/3rd-domain.com \
-d 3rd-domain.com
</code></pre>
<h2 id="ssl-cert-relevant-settings-in-postfixdovecotapachenginx">SSL cert relevant settings in Postfix/Dovecot/Apache/Nginx</h2>
<p>In sample settings below, file paths are for Debian/Ubuntu.</p>
<h3 id="postfix">Postfix</h3>
<p>File <code>/etc/postfix/main.cf</code> (on Linux/OpenBSD) or <code>/usr/local/etc/postfix/main.cf</code> (on FreeBSD):</p>
<pre><code>smtpd_tls_cert_file = /etc/ssl/certs/iRedMail.crt
smtpd_tls_key_file = /etc/ssl/private/iRedMail.key
smtpd_tls_CAfile = /etc/ssl/certs/iRedMail.crt
</code></pre>
<h3 id="dovecot">Dovecot</h3>
<p>File <code>/etc/dovecot/dovecot.conf</code> (on Linux/OpenBSD) or <code>/usr/local/etc/dovecot/dovecot.conf</code> (on FreeBSD):</p>
<pre><code>ssl = required
ssl_cert = &lt;/etc/ssl/certs/iRedMail.crt
ssl_key = &lt;/etc/ssl/private/iRedMail.key
ssl_ca = &lt;/etc/ssl/certs/iRedMail.crt
</code></pre>
<h3 id="apache-web-server">Apache (web server)</h3>
<ul>
<li>On RHEL/CentOS, SSL certificate is defined in <code>/etc/httpd/conf.d/ssl.conf</code>.</li>
<li>On Debian/Ubuntu, it's defined in <code>/etc/apache2/sites-available/default-ssl</code>
(or <code>default-ssl.conf</code>)</li>
<li>On FreeBSD, it's defined in <code>/usr/local/etc/apache24/extra/httpd-ssl.conf</code>. Note:
if you're running different version of Apache, the path will be slightly
different (<code>apache24</code> will be <code>apache[_version_]</code>).</li>
<li>On OpenBSD, if you're running OpenBSD 5.5 or earlier releases, it's defined
in <code>/var/www/conf/httpd.conf</code>. Note: OpenBSD 5.6 and later releases don't
ship Apache anymore.</li>
</ul>
<p>Example:</p>
<pre><code>SSLCertificateFile /etc/ssl/certs/iRedMail.crt
SSLCertificateKeyFile /etc/ssl/private/iRedMail.key
SSLCertificateChainFile /etc/ssl/certs/iRedMail.crt
</code></pre>
<p>Restarting Apache service is required.</p>
<h3 id="nginx">Nginx</h3>
<p>File <code>/etc/nginx/templates/ssl.tmpl</code> (on Linux/OpenBSD) or <code>/usr/local/etc/nginx/templates/ssl.tmpl</code> (on FreeBSD):</p>
<pre><code>ssl_certificate /etc/ssl/certs/iRedMail.crt;
ssl_certificate_key /etc/ssl/private/iRedMail.key;
</code></pre>
<h3 id="mysql-mariadb">MySQL, MariaDB</h3>
<blockquote>
<p>If MySQL/MariaDB is listening on localhost and not accessible from external
network, this is OPTIONAL.</p>
</blockquote>
<ul>
<li>On Red Hat and CentOS, it's defined in <code>/etc/my.cnf</code></li>
<li>On Debian and Ubuntu, it's defined in <code>/etc/mysql/my.cnf</code>.<ul>
<li>Since Ubuntu 15.04, it's defined in <code>/etc/mysql/mariadb.conf.d/mysqld.cnf</code>.</li>
</ul>
</li>
<li>On FreeBSD, it's defined in <code>/usr/local/etc/my.cnf</code>.</li>
<li>On OpenBSD, it's defined in <code>/etc/my.cnf</code>.</li>
</ul>
<pre><code>[mysqld]
ssl-ca = /etc/ssl/certs/iRedMail.crt
ssl-cert = /etc/ssl/certs/iRedMail.crt
ssl-key = /etc/ssl/private/iRedMail.key
</code></pre>
<h3 id="openldap">OpenLDAP</h3>
<blockquote>
<p>If OpenLDAP is listening on localhost and not accessible from external
network, this is OPTIONAL.</p>
</blockquote>
<ul>
<li>On Red Hat and CentOS, it's defined in <code>/etc/openldap/slapd.conf</code>.</li>
<li>On Debian and Ubuntu, it's defined in <code>/etc/ldap/slapd.conf</code>.</li>
<li>On FreeBSD, it's defined in <code>/usr/local/etc/openldap/slapd.conf</code>.</li>
<li>On OpenBSD, it's defined in <code>/etc/openldap/slapd.conf</code>.</li>
</ul>
<pre><code>TLSCACertificateFile /etc/ssl/certs/iRedMail.crt
TLSCertificateKeyFile /etc/ssl/private/iRedMail.key
TLSCertificateFile /etc/ssl/certs/iRedMail.crt
</code></pre>
<h3 id="openbsd-ldapd8">OpenBSD ldapd(8)</h3>
<blockquote>
<p>If ldapd(8) is listening on localhost and not accessible from external
network, this is OPTIONAL.</p>
<p>For more details about ldapd config file, please check its manual page: ldapd.conf(5).</p>
</blockquote>
<p>To make ldapd(8) listening on network interface for external network, please
make sure you have setting in <code>/etc/ldapd.conf</code> to listen on the interface. We
use <code>em0</code> as external network interface here for example.</p>
<pre><code># Listen on network interface 'em0', port 389, use STARTTLS for secure connection.
listen on em0 port 389 tls
</code></pre>
<p>If you want to use port 636 with SSL, try this:</p>
<pre><code># Listen on network interface 'em0', port 636, use SSL for secure connection.
listen on em0 port 636 ldaps
</code></pre>
<p>ldapd(8) will look for SSL cert and key from directory <code>/etc/ldap/certs/</code> by
default, the cert file name is <code>&lt;interface_name&gt;.crt</code> and <code>&lt;interface_name&gt;.key</code>.
In our case, it will look for <code>/etc/ldap/certs/em0.crt</code> and <code>/etc/ldap/certs/em0.key</code>.</p>
<p>Since iRedMail already generates a cert and key, we can use it directly. If you
have bought SSL cert/key, or requested one from LetsEncrypt, you can use them
too.</p>
<pre><code>cd /etc/ldap/certs/
ln -s /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem em0.crt
ln -s /etc/letsencrypt/live/mail.mydomain.com/privkey.pem em0.key
</code></pre>
<p>Now restart ldapd(8) service:</p>
<pre><code>rcctl restart ldapd
</code></pre>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="./use.a.bought.ssl.certificate.html">Use a bought SSL certificate</a></li>
</ul><div class="footer">
<p style="text-align: center; color: grey;">All documents are available in <a href="https://bitbucket.org/zhb/iredmail-docs/src">BitBucket repository</a>, and published under <a href="http://creativecommons.org/licenses/by-nd/3.0/us/" target="_blank">Creative Commons</a> license. You can <a href="https://bitbucket.org/zhb/iredmail-docs/get/tip.tar.bz2">download the latest version</a> for offline reading. If you found something wrong, please do <a href="https://www.iredmail.org/contact.html">contact us</a> to fix it.</p>
</div>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-3293801-21"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-3293801-21');
</script>
</body></html>

View File

@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Use a SSL certificate</title>
<title>Use a bought SSL certificate</title>
<link rel="stylesheet" type="text/css" href="./css/markdown.css" />
</head>
<body>
@ -19,26 +19,22 @@
<p class="admonition-title">This tutorial is available in other languages. <a href="https://bitbucket.org/zhb/iredmail-docs/src">Help translate more</a></p>
<p><a href="./use.a.bought.ssl.certificate-zh_CN.html">简体中文</a> /</p>
</div>
<h1 id="use-a-ssl-certificate">Use a SSL certificate</h1>
<h1 id="use-a-bought-ssl-certificate">Use a bought SSL certificate</h1>
<div class="toc">
<ul>
<li><a href="#use-a-ssl-certificate">Use a SSL certificate</a><ul>
<li><a href="#use-a-bought-ssl-certificate">Use a bought SSL certificate</a><ul>
<li><a href="#get-a-ssl-certificate">Get a SSL certificate</a><ul>
<li><a href="#get-a-free-letsencrypt-ssl-cert">Get a free LetsEncrypt ssl cert</a></li>
<li><a href="#request-a-free-cert-from-lets-encrypt">Request a free cert from Let's Encrypt</a></li>
<li><a href="#buy-from-a-trusted-ssl-vendor">Buy from a trusted SSL vendor</a></li>
</ul>
</li>
<li><a href="#configure-postfixdovecotapachenginx-to-use-bought-ssl-certificate">Configure Postfix/Dovecot/Apache/Nginx to use bought SSL certificate</a><ul>
<li><a href="#postfix-smtp-server">Postfix (SMTP server)</a></li>
<li><a href="#dovecot-pop3imap-server">Dovecot (POP3/IMAP server)</a></li>
<li><a href="#apache-web-server">Apache (web server)</a></li>
<li><a href="#nginx-web-server">Nginx (web server)</a></li>
<li><a href="#mysql-mariadb">MySQL, MariaDB</a></li>
<li><a href="#openldap">OpenLDAP</a></li>
<li><a href="#openbsd-ldapd8">OpenBSD ldapd(8)</a></li>
<li><a href="#use-the-bought-cert">Use the bought cert</a><ul>
<li><a href="#replace-cert-files">Replace cert files</a></li>
<li><a href="#restart-network-services">Restart network services</a></li>
</ul>
</li>
<li><a href="#reference">Reference</a></li>
<li><a href="#verify-the-cert">Verify the cert</a></li>
<li><a href="#see-also">See Also</a></li>
</ul>
</li>
</ul>
@ -51,16 +47,9 @@ annoying message, you have to buy a SSL certificate from SSL certificate
provider. Search <code>buy ssl certificate</code> in Google will give you many SSL
providers, choose the one you prefer.</p>
<h2 id="get-a-ssl-certificate">Get a SSL certificate</h2>
<h3 id="get-a-free-letsencrypt-ssl-cert">Get a free LetsEncrypt ssl cert</h3>
<p><a href="https://letsencrypt.org">"Let's Encrypt"</a> offers free SSL certificate, please
follow its official tutorial to get one: <a href="https://certbot.eff.org">https://certbot.eff.org</a></p>
<div class="admonition attention">
<p class="admonition-title">Attention</p>
<p>The <code>--apache</code> option of <code>certbot</code> program will modify Apache config
files, most time it messes up iRedMail configurations, so it's better
to get the cert with <code>certonly --webroot</code> option while requesting cert, then
follow tutorial below to update config files to use the cert.</p>
</div>
<h3 id="request-a-free-cert-from-lets-encrypt">Request a free cert from Let's Encrypt</h3>
<p>We have another tutorial to show you to request a free cert from Let's Encrypt:
<a href="./letsencrypt.html">Request a free cert from Let's Encrypt</a>.</p>
<h3 id="buy-from-a-trusted-ssl-vendor">Buy from a trusted SSL vendor</h3>
<p>To buy ssl cert from a trusted vendor, you need to generate a new SSL
key and signing request file on your server with <code>openssl</code> command:</p>
@ -104,8 +93,8 @@ your preferred SSL privider, it will ask you to upload <code>server.csr</code> f
issue an SSL certificate.</p>
<p>Usually, SSL provider will give you 2 files:</p>
<ul>
<li>cert.pem</li>
<li>fullchain.pem (some SSL providers use name <code>server.ca-bundle</code>)</li>
<li><code>cert.pem</code></li>
<li><code>fullchain.pem</code> (some SSL providers use name <code>server.ca-bundle</code>)</li>
</ul>
<p>We need above 2 files, and <code>privkey.pem</code>. Upload them to your server, you can
store them in any directory you like, recommended directories are:</p>
@ -116,181 +105,58 @@ store them in any directory you like, recommended directories are:</p>
placed under <code>/etc/ssl/certs/</code>, <code>privkey.pem</code> should be <code>/etc/ssl/private/</code>.</li>
<li>on OpenBSD: <code>/etc/ssl/</code>.</li>
</ul>
<h2 id="configure-postfixdovecotapachenginx-to-use-bought-ssl-certificate">Configure Postfix/Dovecot/Apache/Nginx to use bought SSL certificate</h2>
<p>We use CentOS for example in below tutorial, please adjust the file to correct
one on your server according to above description.</p>
<h3 id="postfix-smtp-server">Postfix (SMTP server)</h3>
<p>We can use <code>postconf</code> command to update SSL related settings directly:</p>
<pre><code>postconf -e smtpd_tls_cert_file='/etc/pki/tls/certs/cert.pem'
postconf -e smtpd_tls_key_file='/etc/pki/tls/private/privkey.pem'
postconf -e smtpd_tls_CAfile='/etc/pki/tls/certs/fullchain.pem'
</code></pre>
<p>Restarting Postfix service is required.</p>
<h3 id="dovecot-pop3imap-server">Dovecot (POP3/IMAP server)</h3>
<p>SSL certificate settings are defined in Dovecot main config file,
<code>/etc/dovecot/dovecot.conf</code> (Linux/OpenBSD) or
<code>/usr/local/etc/dovecot/dovecot.conf</code> (FreeBSD):</p>
<pre><code>ssl = required
ssl_cert = &lt;/etc/pki/tls/certs/cert.pem
ssl_key = &lt;/etc/pki/tls/private/privkey.pem
ssl_ca = &lt;/etc/pki/tls/certs/fullchain.pem
</code></pre>
<p>Restarting Dovecot service is required.</p>
<h3 id="apache-web-server">Apache (web server)</h3>
<h2 id="use-the-bought-cert">Use the bought cert</h2>
<p>The easiest and quickest way to use the bought cert is replacing
the self-signed SSL cert generated by iRedMail installer, then
restart services which use the cert files.</p>
<h3 id="replace-cert-files">Replace cert files</h3>
<ul>
<li>On RHEL/CentOS, SSL certificate is defined in <code>/etc/httpd/conf.d/ssl.conf</code>.</li>
<li>On Debian/Ubuntu, it's defined in <code>/etc/apache2/sites-available/default-ssl</code>
(or <code>default-ssl.conf</code>)</li>
<li>On FreeBSD, it's defined in <code>/usr/local/etc/apache24/extra/httpd-ssl.conf</code>. Note:
if you're running different version of Apache, the path will be slightly
different (<code>apache24</code> will be <code>apache[_version_]</code>).</li>
<li>On OpenBSD, if you're running OpenBSD 5.5 or earlier releases, it's defined
in <code>/var/www/conf/httpd.conf</code>. Note: OpenBSD 5.6 and later releases don't
ship Apache anymore.</li>
<li>On RHEL/CentOS:</li>
</ul>
<p>Example:</p>
<pre><code>SSLCertificateFile /etc/pki/tls/certs/cert.pem
SSLCertificateKeyFile /etc/pki/tls/private/privkey.pem
SSLCertificateChainFile /etc/pki/tls/certs/fullchain.pem
</code></pre>
<p>Restarting Apache service is required.</p>
<h3 id="nginx-web-server">Nginx (web server)</h3>
<ul>
<li>On Linux and OpenBSD, it's defined in <code>/etc/nginx/templates/ssl.tmpl</code>
(or <code>/etc/nginx/conf.d/default.conf</code> on old iRedMail release)</li>
<li>On FreeBSD, it's defined in <code>/usr/local/etc/nginx/templates/ssl.tmpl</code>
(or <code>/usr/local/etc/nginx/conf.d/default.conf</code> on old iRedMail release)</li>
</ul>
<pre><code>ssl_certificate /etc/pki/tls/certs/cert.pem;
ssl_certificate_key /etc/pki/tls/private/privkey.pem;
</code></pre>
<p>Some browsers may complain about a certificate signed by a well-known
certificate authority, while other browsers may accept the certificate without
issues. This occurs because the issuing authority has signed the server
certificate using an intermediate certificate that is not present in the
certificate base of well-known trusted certificate authorities which is
distributed with a particular browser. In this case the authority provides a
bundle of chained certificates which should be concatenated to the signed
server certificate. The server certificate must appear before the chained
certificates in the combined file:</p>
<pre><code># cd /etc/pki/tls/certs/
# cat cert.pem fullchain.pem &gt; server.chained.crt
</code></pre>
<p>Then update <code>ssl_certificate</code> parameter in <code>/etc/nginx/conf.d/default.conf</code>:</p>
<pre><code> ssl_certificate /etc/pki/tls/certs/server.chained.crt;
</code></pre>
<p>Restarting Nginx service is required.</p>
<h3 id="mysql-mariadb">MySQL, MariaDB</h3>
<blockquote>
<p>If MySQL/MariaDB is listening on localhost and not accessible from external
network, this is OPTIONAL.</p>
</blockquote>
<ul>
<li>On Red Hat and CentOS, it's defined in <code>/etc/my.cnf</code></li>
<li>On Debian and Ubuntu, it's defined in <code>/etc/mysql/my.cnf</code>.<ul>
<li>Since Ubuntu 15.04, it's defined in <code>/etc/mysql/mariadb.conf.d/mysqld.cnf</code>.</li>
</ul>
</li>
<li>On FreeBSD, it's defined in <code>/usr/local/etc/my.cnf</code>.</li>
<li>On OpenBSD, it's defined in <code>/etc/my.cnf</code>.</li>
</ul>
<pre><code>[mysqld]
ssl-ca = /etc/pki/tls/certs/fullchain.pem
ssl-cert = /etc/pki/tls/certs/cert.pem
ssl-key = /etc/pki/tls/private/privkey.pem
</code></pre>
<h3 id="openldap">OpenLDAP</h3>
<blockquote>
<p>If OpenLDAP is listening on localhost and not accessible from external
network, this is OPTIONAL.</p>
</blockquote>
<ul>
<li>On Red Hat and CentOS, it's defined in <code>/etc/openldap/slapd.conf</code>.</li>
<li>On Debian and Ubuntu, it's defined in <code>/etc/ldap/slapd.conf</code>.</li>
<li>On FreeBSD, it's defined in <code>/usr/local/etc/openldap/slapd.conf</code>.</li>
<li>On OpenBSD, it's defined in <code>/etc/openldap/slapd.conf</code>.</li>
</ul>
<pre><code>TLSCACertificateFile /etc/pki/tls/certs/fullchain.pem
TLSCertificateFile /etc/pki/tls/certs/cert.pem
TLSCertificateKeyFile /etc/pki/tls/private/privkey.pem
</code></pre>
<p>Restarting OpenLDAP service is required.</p>
<p>If you want to connect with TLS (port 389) or SSL (port 636) for secure
connection from command line tools like <code>ldapsearch</code>, please update parameter
<code>TLS_CACERT</code> in OpenLDAP client config file also, otherwise you will get
error message like <code>Peer's Certificate issuer is not recognized</code>.</p>
<ul>
<li>On Red Hat and CentOS, it's defined in <code>/etc/openldap/ldap.conf</code>.</li>
<li>On Debian and Ubuntu, it's defined in <code>/etc/ldap/ldap.conf</code>.</li>
<li>On FreeBSD, it's defined in <code>/usr/local/etc/openldap/ldap.conf</code>.</li>
<li>On OpenBSD, it's defined in <code>/etc/openldap/ldap.conf</code>.</li>
</ul>
<pre><code>TLS_CACERT /etc/pki/tls/certs/fullchain.pem
</code></pre>
<p>To connect with TLS, please run <code>ldapsearch</code> with argument <code>-Z</code> and use
<code>ldap://&lt;your_server_name&gt;:389</code> as ldap host. For example:</p>
<pre><code>ldapsearch -x -W -Z \
-H 'ldap://mail.example.com:389' \
-D 'cn=vmail,dc=example,dc=com' \
-b 'o=domains,dc=example,dc=com' mail
<pre><code>mv /etc/pki/tls/certs/iRedMail.crt{,.bak} # Backup. Rename iRedMail.crt to iRedMail.crt.bak
mv /etc/pki/tls/private/iRedMail.key{,.bak} # Backup. Rename iRedMail.key to iRedMail.key.bak
cp fullchain.pem /etc/pki/tls/certs/iRedMail.crt
cp privkey.pem /etc/pki/tls/private/iRedMail.key
</code></pre>
<ul>
<li>To connection with SSL, use <code>ldaps://&lt;your_server_name&gt;:636</code> as ldap host.
for example:</li>
<li>On Debian/Ubuntu, FreeBSD and OpenBSD:</li>
</ul>
<pre><code>ldapsearch -x -W \
-H 'ldaps://mail.example.com:636' \
-D 'cn=vmail,dc=example,dc=com' \
-b 'o=domains,dc=example,dc=com' mail
<pre><code>mv /etc/ssl/certs/iRedMail.crt{,.bak} # Backup. Rename iRedMail.crt to iRedMail.crt.bak
mv /etc/ssl/private/iRedMail.key{,.bak} # Backup. Rename iRedMail.key to iRedMail.key.bak
cp fullchain.pem /etc/ssl/certs/iRedMail.crt
cp privkey.pem /etc/ssl/private/iRedMail.key
</code></pre>
<h3 id="openbsd-ldapd8">OpenBSD ldapd(8)</h3>
<blockquote>
<p>If ldapd(8) is listening on localhost and not accessible from external
network, this is OPTIONAL.</p>
<p>For more details about ldapd config file, please check its manual page: ldapd.conf(5).</p>
</blockquote>
<p>To make ldapd(8) listening on network interface for external network, please
make sure you have setting in <code>/etc/ldapd.conf</code> to listen on the interface. We
use <code>em0</code> as external network interface here for example.</p>
<pre><code># Listen on network interface 'em0', port 389, use STARTTLS for secure connection.
listen on em0 port 389 tls
</code></pre>
<p>If you want to use port 636 with SSL, try this:</p>
<pre><code># Listen on network interface 'em0', port 636, use SSL for secure connection.
listen on em0 port 636 ldaps
</code></pre>
<p>ldapd(8) will look for SSL cert and key from directory <code>/etc/ldap/certs/</code> by
default, the cert file name is <code>&lt;interface_name&gt;.crt</code> and <code>&lt;interface_name&gt;.key</code>.
In our case, it will look for <code>/etc/ldap/certs/em0.crt</code> and <code>/etc/ldap/certs/em0.key</code>.</p>
<p>Since iRedMail already generates a cert and key, we can use it directly. If you
have bought SSL cert/key, or requested one from LetsEncrypt, you can use them
too.</p>
<pre><code>cd /etc/ldap/certs/
ln -s /etc/ssl/iRedMail.crt em0.crt
ln -s /etc/ssl/iRedMail.key em0.key
</code></pre>
<p>Now restart ldapd(8) service:</p>
<pre><code>rcctl restart ldapd
</code></pre>
<h2 id="reference">Reference</h2>
<h3 id="restart-network-services">Restart network services</h3>
<p>Required services:</p>
<ul>
<li><a href="http://nginx.org/en/docs/http/configuring_https_servers.html">Configuring HTTPS servers</a></li>
<li>Postfix</li>
<li>Dovecot</li>
<li>Nginx or Apache</li>
</ul>
<p>Depends on the backend you chose during iRedMail installation, you may need to
restart:</p>
<ul>
<li>MySQL or MariaDB</li>
<li>PostgreSQL</li>
<li>OpenLDAP</li>
</ul>
<h2 id="verify-the-cert">Verify the cert</h2>
<ul>
<li>To verify ssl cert used in Postfix (SMTP server) and Dovecot, please launch a
mail client application (MUA, e.g. Outlook, Thunderbird) and create an email
account, make sure you correctly configured the MUA to connect to mail
server. If SSL cert is not valid, MUA will warn you.</li>
<li>For Apache / Nginx web server, you can access your website with favourite web
browser, the browser should show you the ssl cert status. Or, use other
website to help test it, for example:
<a href="https://www.ssllabs.com/ssltest/index.html">https://www.ssllabs.com/ssltest/index.html</a> (input your web host name, then
submit and wait for a result).</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="./letsencrypt.html">Request a free cert from Let's Encrypt</a></li>
</ul><div class="footer">
<p style="text-align: center; color: grey;">All documents are available in <a href="https://bitbucket.org/zhb/iredmail-docs/src">BitBucket repository</a>, and published under <a href="http://creativecommons.org/licenses/by-nd/3.0/us/" target="_blank">Creative Commons</a> license. You can <a href="https://bitbucket.org/zhb/iredmail-docs/get/tip.tar.bz2">download the latest version</a> for offline reading. If you found something wrong, please do <a href="https://www.iredmail.org/contact.html">contact us</a> to fix it.</p>
</div>