docs(ssl): Add an FQDN section (#2268)

* docs(ssl): Adjust heading levels for provisioning sections

- Group provisioning sections under one heading level.
- Use `attr_list` syntax for headings to make the ToC sidebar entry less verbose.

* docs(ssl): Minor fixes

Typos, formatting.

* docs(ssl): Rephrase Traefik wildcard support

Split the line out into multiple with better phrasing.

* docs(ssl): Add FQDN section

We briefly mention the same info twice on the docs page, but as it applies to all provisioners in general, it's been given it's own detailed section with examples.

Single section to inform users about an FQDN, how it's configured and understood by `docker-mailserver` for both Docker CLI and `docker-compose.yml` variations.

Adds note about wildcard support and bare domains to clear up any confusion configuring FQDN for these two.

Additional note about Certbot using symlinks for it's cert storage.

* chore: Add FQDN comment for `docker-compose.yml` example config
This commit is contained in:
Brennan Kinney 2021-10-31 00:12:39 +13:00 committed by GitHub
parent 9afaa54f5d
commit bdcfe27482
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 18 deletions

View file

@ -1,9 +1,12 @@
version: '3.8' # `version` key here is optional and no longer required in modern docker-compose versions.
# version: '3.8'
services: services:
mailserver: mailserver:
image: docker.io/mailserver/docker-mailserver:latest image: docker.io/mailserver/docker-mailserver:latest
container_name: mailserver container_name: mailserver
# If the FQDN for your mail-server is only two labels (eg: example.com),
# you can assign this entirely to `hostname` and remove `domainname`.
hostname: mail hostname: mail
domainname: example.com domainname: example.com
env_file: mailserver.env env_file: mailserver.env

View file

@ -23,21 +23,66 @@ After installation, you can test your setup with:
You could use a [wildcard certificate][wildcard-cert]. This avoids accidentally leaking information to the internet, but keep in mind the [potential security risks][security::wildcard-cert] of wildcard certs. You could use a [wildcard certificate][wildcard-cert]. This avoids accidentally leaking information to the internet, but keep in mind the [potential security risks][security::wildcard-cert] of wildcard certs.
## Let's Encrypt (Recommended) ## The FQDN
An [FQDN](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) (_Fully Qualified Domain Name_) such as `mail.example.com` is required for `docker-mailserver` to function correctly, especially for looking up the correct SSL certificate to use.
Internally, `hostname -f` will be used to retrieve the FQDN as configured in the below examples.
Wildcard certificates (eg: `*.example.com`) are supported for `SSL_TYPE=letsencrypt`. Your configured FQDN below may be `mail.example.com`, and your wildcard certificate provisioned to `/etc/letsencrypt/live/example.com` which will be checked as a fallback FQDN by `docker-mailserver`.
!!! example "Docker CLI options `--hostname` and optionally `--domainname`"
```sh
docker run --hostname mail --domainname example.com
# `--domainname` is not required:
docker run --hostname mail.example.com
```
!!! example "`docker-compose.yml` config"
```yml
services:
mailserver:
hostname: mail
domainname: example.com
# `domainname` is not required:
services:
mailserver:
hostname: mail.example.com
```
!!! example "_Bare domains_ (eg: `example.com`) should only use the hostname option"
```sh
docker run --hostname example.com
```
```yml
services:
mailserver:
hostname: example.com
```
## Provisioning methods
### Let's Encrypt (Recommended)
To enable _Let's Encrypt_ for `docker-mailserver`, you have to: To enable _Let's Encrypt_ for `docker-mailserver`, you have to:
1. Get your certificate using the _Let's Encrypt_ client [Certbot][certbot::github]. 1. Get your certificate using the _Let's Encrypt_ client [Certbot][certbot::github].
2. For your `docker-mailserver` container: 2. For your `docker-mailserver` container:
1. Add the environment variable `SSL_TYPE=letsencrypt`. - Add the environment variable `SSL_TYPE=letsencrypt`.
2. Mount [your local `letsencrypt` folder][certbot::certs-storage] as a volume to `/etc/letsencrypt`. - Mount [your local `letsencrypt` folder][certbot::certs-storage] as a volume to `/etc/letsencrypt`.
You don't have to do anything else. Enjoy! You don't have to do anything else. Enjoy!
!!! note !!! note
`/etc/letsencrypt/live` stores provisioned certificates in individual folders named by their FQDN (_Fully Qualified Domain Name_). `docker-mailserver` looks for it's certificate folder via the `hostname` command. The FQDN inside the docker container is derived from the `--hostname` and `--domainname` options. `/etc/letsencrypt/live` stores provisioned certificates in individual folders named by their FQDN.
Make sure that the entire folder is mounted to `docker-mailserver` as there are typically symlinks from `/etc/letsencrypt/live/mail.example.com` to `/etc/letsencrypt/archive`.
!!! example !!! example
@ -55,7 +100,7 @@ You don't have to do anything else. Enjoy!
- /etc/letsencrypt:/etc/letsencrypt - /etc/letsencrypt:/etc/letsencrypt
``` ```
### Example using Docker for _Let's Encrypt_ #### Example using Docker for _Let's Encrypt_ { data-toc-label='Certbot with Docker' }
- Certbot provisions certificates to `/etc/letsencrypt`. Add a volume to store these, so that they can later be accessed by `docker-mailserver` container. - Certbot provisions certificates to `/etc/letsencrypt`. Add a volume to store these, so that they can later be accessed by `docker-mailserver` container.
- You may also want to persist Certbot [logs][certbot::log-rotation], just in case you need to troubleshoot. - You may also want to persist Certbot [logs][certbot::log-rotation], just in case you need to troubleshoot.
@ -97,7 +142,7 @@ You don't have to do anything else. Enjoy!
Certbot does support [alternative certificate providers via the `--server`][certbot::custom-ca] option. In most cases you'll want to use the default _Let's Encrypt_. Certbot does support [alternative certificate providers via the `--server`][certbot::custom-ca] option. In most cases you'll want to use the default _Let's Encrypt_.
### Example using `nginx-proxy` and `acme-companion` with Docker #### Example using `nginx-proxy` and `acme-companion` with Docker { data-toc-label='nginx-proxy with Docker' }
If you are running a web server already, port 80 will be in use which Certbot requires. You could use the [Certbot `--webroot`][certbot::webroot] feature, but it is more common to leverage a _reverse proxy_ that manages the provisioning and renewal of certificates for your services automatically. If you are running a web server already, port 80 will be in use which Certbot requires. You could use the [Certbot `--webroot`][certbot::webroot] feature, but it is more common to leverage a _reverse proxy_ that manages the provisioning and renewal of certificates for your services automatically.
@ -135,7 +180,7 @@ In the following example, we show how `docker-mailserver` can be run alongside t
3. Start the rest of your web server containers as usual. 3. Start the rest of your web server containers as usual.
4. Start a _dummy container_ to provision certificatess for your FQDN (eg: `mail.example.com`). `acme-companion` will detect the container and generate a _Let's Encrypt_ certificate for your domain, which can be used by `docker-mailserver`: 4. Start a _dummy container_ to provision certificates for your FQDN (eg: `mail.example.com`). `acme-companion` will detect the container and generate a _Let's Encrypt_ certificate for your domain, which can be used by `docker-mailserver`:
```sh ```sh
docker run --detach \ docker run --detach \
@ -160,7 +205,7 @@ In the following example, we show how `docker-mailserver` can be run alongside t
6. Then from the `docker-compose.yml` project directory, run: `docker-compose up -d mailserver`. 6. Then from the `docker-compose.yml` project directory, run: `docker-compose up -d mailserver`.
### Example using `nginx-proxy` and `acme-companion` with `docker-compose` #### Example using `nginx-proxy` and `acme-companion` with `docker-compose` { data-toc-label='nginx-proxy with docker-compose' }
The following example is the [basic setup][acme-companion::basic-setup] you need for using `nginx-proxy` and `acme-companion` with `docker-mailserver` (_Referencing: [`acme-companion` documentation][acme-companion::docs]_): The following example is the [basic setup][acme-companion::basic-setup] you need for using `nginx-proxy` and `acme-companion` with `docker-mailserver` (_Referencing: [`acme-companion` documentation][acme-companion::docs]_):
@ -287,7 +332,7 @@ The following example is the [basic setup][acme-companion::basic-setup] you need
`#!bash docker exec nginx-proxy-acme /app/signal_le_service` `#!bash docker exec nginx-proxy-acme /app/signal_le_service`
### Example using _Let's Encrypt_ Certificates with a _Synology NAS_ #### Example using _Let's Encrypt_ Certificates with a _Synology NAS_ { data-toc-label='Synology NAS' }
Version 6.2 and later of the Synology NAS DSM OS now come with an interface to generate and renew letencrypt certificates. Navigation into your DSM control panel and go to Security, then click on the tab Certificate to generate and manage letsencrypt certificates. Version 6.2 and later of the Synology NAS DSM OS now come with an interface to generate and renew letencrypt certificates. Navigation into your DSM control panel and go to Security, then click on the tab Certificate to generate and manage letsencrypt certificates.
@ -308,7 +353,7 @@ environment:
DSM-generated letsencrypt certificates get auto-renewed every three months. DSM-generated letsencrypt certificates get auto-renewed every three months.
## Caddy ### Caddy
If you are using Caddy to renew your certificates, please note that only RSA certificates work. Read [#1440][github-issue-1440] for details. In short for Caddy v1 the `Caddyfile` should look something like: If you are using Caddy to renew your certificates, please note that only RSA certificates work. Read [#1440][github-issue-1440] for details. In short for Caddy v1 the `Caddyfile` should look something like:
@ -419,17 +464,21 @@ no peer certificate available
No client certificate CA names sent No client certificate CA names sent
``` ```
## Traefik v2 ### Traefik v2
[Traefik][traefik::github] is an open-source application proxy using the [ACME protocol][ietf::rfc::acme]. [Traefik][traefik::github] can request certificates for domains and subdomains, and it will take care of renewals, challenge negotiations, etc. We strongly recommend to use [Traefik][traefik::github]'s major version 2. [Traefik][traefik::github] is an open-source application proxy using the [ACME protocol][ietf::rfc::acme]. [Traefik][traefik::github] can request certificates for domains and subdomains, and it will take care of renewals, challenge negotiations, etc. We strongly recommend to use [Traefik][traefik::github]'s major version 2.
[Traefik][traefik::github]'s storage format is natively supported if the `acme.json` store is mounted into the container at `/etc/letsencrypt/acme.json`. The file is also monitored for changes and will trigger a reload of the mail services (Postfix and Dovecot). Wild card certificates issued for `*.example.com` are supported. You will then want to use `#!bash SSL_DOMAIN=example.com`. Lookup of the certificate domain happens in the following order: [Traefik][traefik::github]'s storage format is natively supported if the `acme.json` store is mounted into the container at `/etc/letsencrypt/acme.json`. The file is also monitored for changes and will trigger a reload of the mail services (Postfix and Dovecot).
Wildcard certificates are supported. If your FQDN is `mail.example.com` and your wildcard certificate is `*.example.com`, add the ENV: `#!bash SSL_DOMAIN=example.com`.
The mail-server will select it's certificate from `acme.json` checking these ENV for a matching FQDN (_in order of priority_):
1. `#!bash ${SSL_DOMAIN}` 1. `#!bash ${SSL_DOMAIN}`
2. `#!bash ${HOSTNAME}` 2. `#!bash ${HOSTNAME}`
3. `#!bash ${DOMAINNAME}` 3. `#!bash ${DOMAINNAME}`
This setup only comes with one caveat: The domain has to be configured on another service for [Traefik][traefik::github] to actually request it from Let'sEncrypt, i.e. [Traefik][traefik::github] will not issue a certificate without a service / router demanding it. This setup only comes with one caveat: The domain has to be configured on another service for [Traefik][traefik::github] to actually request it from _Let's Encrypt_, i.e. [Traefik][traefik::github] will not issue a certificate without a service / router demanding it.
???+ example "Example Code" ???+ example "Example Code"
Here is an example setup for [`docker-compose`](https://docs.docker.com/compose/): Here is an example setup for [`docker-compose`](https://docs.docker.com/compose/):
@ -476,7 +525,7 @@ This setup only comes with one caveat: The domain has to be configured on anothe
- "traefik.http.routers.whoami.rule=Host(`mail.example.com`)" - "traefik.http.routers.whoami.rule=Host(`mail.example.com`)"
``` ```
## Self-Signed Certificates ### Self-Signed Certificates
!!! warning !!! warning
@ -488,11 +537,11 @@ This feature requires you to provide the following files into your [`docker-data
- `<FQDN>-cert.pem` - `<FQDN>-cert.pem`
- `demoCA/cacert.pem` - `demoCA/cacert.pem`
Where `<FQDN>` is the [FQDN](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) assigned to `docker-mailserver` (_eg: `mail.example.com` (FQDN) => `mail` (hostname) + `example.com` (domainname)_) via `docker run` command or `docker-compose.yml` config. Where `<FQDN>` is the FQDN you've configured for your `docker-mailserver` container.
Add `SSL_TYPE=self-signed` to your `docker-mailserver` environment variables. Postfix and Dovecot will be configured to use the provided certificate (_`.pem` files above_) during container startup. Add `SSL_TYPE=self-signed` to your `docker-mailserver` environment variables. Postfix and Dovecot will be configured to use the provided certificate (_`.pem` files above_) during container startup.
### Generating a self-signed certificate #### Generating a self-signed certificate
!!! note !!! note
@ -540,7 +589,7 @@ docker run --rm -it \
smallstep/step-ca smallstep/step-ca
``` ```
## Bring Your Own Certificates ### Bring Your Own Certificates
You can also provide your own certificate files. Add these entries to your `docker-compose.yml`: You can also provide your own certificate files. Add these entries to your `docker-compose.yml`: