Adjusted documentation for service name and Traefik certificate issuance (#1918)

Co-authored-by: Casper <casperklein@users.noreply.github.com>
This commit is contained in:
Georg Lauterbach 2021-04-18 15:21:08 +02:00 committed by GitHub
parent 81a05ad432
commit 8313d9753b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 64 deletions

View file

@ -26,7 +26,7 @@ To enable Let's Encrypt on your mail server, you have to:
```yaml ```yaml
services: services:
mail: mailserver:
hostname: mail hostname: mail
domainname: myserver.tld domainname: myserver.tld
fqdn: mail.myserver.tld fqdn: mail.myserver.tld
@ -193,25 +193,25 @@ The second part of the setup is the actual mail container. So, in another folder
```yaml ```yaml
version: '2' version: '2'
services: services:
mail: mailserver:
image: mailserver/docker-mailserver:latest image: mailserver/docker-mailserver:latest
hostname: ${HOSTNAME} hostname: ${HOSTNAME}
domainname: ${DOMAINNAME} domainname: ${DOMAINNAME}
container_name: ${CONTAINER_NAME} container_name: ${CONTAINER_NAME}
ports: ports:
- "25:25" - "25:25"
- "143:143" - "143:143"
- "465:465" - "465:465"
- "587:587" - "587:587"
- "993:993" - "993:993"
volumes: volumes:
- ./mail:/var/mail - ./mail:/var/mail
- ./mail-state:/var/mail-state - ./mail-state:/var/mail-state
- ./config/:/tmp/docker-mailserver/ - ./config/:/tmp/docker-mailserver/
- /mnt/data/nginx/certs/:/etc/letsencrypt/live/:ro - /mnt/data/nginx/certs/:/etc/letsencrypt/live/:ro
cap_add: cap_add:
- NET_ADMIN - NET_ADMIN
- SYS_PTRACE - SYS_PTRACE
restart: always restart: always
cert-companion: cert-companion:
@ -363,73 +363,64 @@ no peer certificate available
No client certificate CA names sent No client certificate CA names sent
``` ```
## Traefik ## Traefik v2
[Traefik](https://github.com/containous/traefik) is an open-source Edge Router which handles ACME protocol using [lego](https://github.com/go-acme/lego). [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 can request certificates for domains through the ACME protocol (see [Traefik's documentation about its ACME negotiation & storage mechanism](https://docs.traefik.io/https/acme/)). Traefik's router will take care of renewals, challenge negotiations, etc. [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. Wild card certificates issued for `*.domain.tld` are supported. You will then want to use `#!bash SSL_DOMAIN=domain.tld`. Lookup of the certificate domain happens in the following order:
### Traefik v2 1. `#!bash ${SSL_DOMAIN}`
2. `#!bash ${HOSTNAME}`
3. `#!bash ${DOMAINNAME}`
(For Traefik v1 see [next section](#traefik-v1)) 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.
Traefik's V2 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. Lookup of the certificate domain happens in the following order:
1. `$SSL_DOMAIN`
2. `$HOSTNAME`
3. `$DOMAINNAME`
This allows for support of wild card certificates: `SSL_DOMAIN=*.example.com`. Here is an example setup for [`docker-compose`](https://docs.docker.com/compose/):
???+ example "Example Code" ???+ example "Example Code"
Here is an example setup for [`docker-compose`](https://docs.docker.com/compose/):
```yaml ``` YAML
version: '3.8' version: '3.8'
services: services:
mail:
image: mailserver/docker-mailserver:stable mailserver:
image: docker.io/mailserver/docker-mailserver:latest
container_name: mailserver
hostname: mail hostname: mail
domainname: example.com domainname: domain.tld
volumes: volumes:
- /etc/ssl/acme-v2.json:/etc/letsencrypt/acme.json:ro - /traefik/acme.json:/etc/letsencrypt/acme.json:ro
environment: environment:
SSL_TYPE: letsencrypt SSL_TYPE: letsencrypt
# SSL_DOMAIN: "*.example.com" SSL_DOMAIN: mail.example.com"
# for a wildcard certificate, use
# SSL_DOMAIN: example.com
traefik: traefik:
image: traefik:v2.2 image: docker.io/traefik:v2.4.8
restart: always
ports: ports:
- "80:80" - "80:80"
- "443:443" - "443:443"
command: command:
- --providers.docker - --providers.docker
- --entrypoints.web.address=:80 - --entrypoints.http.address=:80
- --entrypoints.web.http.redirections.entryPoint.to=websecure - --entrypoints.http.http.redirections.entryPoint.to=https
- --entrypoints.web.http.redirections.entryPoint.scheme=https - --entrypoints.http.http.redirections.entryPoint.scheme=https
- --entrypoints.websecure.address=:443 - --entrypoints.https.address=:443
- --entrypoints.websecure.http.middlewares=hsts@docker - --entrypoints.https.http.tls.certResolver=letsencrypt
- --entrypoints.websecure.http.tls.certResolver=le - --certificatesresolvers.letsencrypt.acme.email=admin@domain.tld
- --certificatesresolvers.le.acme.email=admin@example.net - --certificatesresolvers.letsencrypt.acme.storage=/acme.json
- --certificatesresolvers.le.acme.storage=/acme.json - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro - /traefik/acme.json:/acme.json
- /etc/ssl/acme-v2.json:/acme.json - /var/run/docker.sock:/var/run/docker.sock:ro
whoami: whoami:
image: containous/whoami image: docker.io/traefik/whoami:latest
labels: labels:
- "traefik.http.routers.whoami.rule=Host(`mail.example.com`)" - "traefik.http.routers.whoami.rule=Host(`mail.domain.tld`)"
``` ```
This setup only comes with one caveat: The domain has to be configured on another service for traefik to actually request it from lets-encrypt (`whoami` in this case).
### Traefik v1
If you are using Traefik v1, you might want to _push_ your Traefik-managed certificates to the mailserver container, in order to reuse them. Not an easy task, but fortunately, [`youtous/mailserver-traefik`][youtous-mailtraefik] is a certificate renewal service for `docker-mailserver`.
Depending of your Traefik configuration, certificates may be stored using a file or a KV Store (consul, etcd...) Either way, certificates will be renewed by Traefik, then automatically pushed to the mailserver thanks to the `cert-renewer` service. Finally, dovecot and postfix will be restarted.
## Self-Signed Certificates ## Self-Signed Certificates
!!! warning !!! warning
@ -637,4 +628,6 @@ fi
[github-file-compose]: https://github.com/docker-mailserver/docker-mailserver/blob/master/docker-compose.yml [github-file-compose]: https://github.com/docker-mailserver/docker-mailserver/blob/master/docker-compose.yml
[github-issue-1440]: https://github.com/docker-mailserver/docker-mailserver/issues/1440 [github-issue-1440]: https://github.com/docker-mailserver/docker-mailserver/issues/1440
[hanscees-renewcerts]: https://github.com/hanscees/dockerscripts/blob/master/scripts/tomav-renew-certs [hanscees-renewcerts]: https://github.com/hanscees/dockerscripts/blob/master/scripts/tomav-renew-certs
[youtous-mailtraefik]: https://github.com/youtous/docker-mailserver-traefik
[traefik::github]: https://github.com/containous/traefik
[ietf::rfc::acme]: https://tools.ietf.org/html/rfc8555

View file

@ -799,12 +799,12 @@ function _setup_ssl
# Primary certificate to serve for TLS # Primary certificate to serve for TLS
function _set_certificate function _set_certificate
{ {
local POSTFIX_KEY_WITH_FULLCHAIN=$1 local POSTFIX_KEY_WITH_FULLCHAIN=${1}
local DOVECOT_KEY=$1 local DOVECOT_KEY=${1}
local DOVECOT_CERT=$1 local DOVECOT_CERT=${1}
# If 2nd param is provided, we've been provided separate key and cert instead of a fullkeychain # If 2nd param is provided, we've been provided separate key and cert instead of a fullkeychain
if [[ -n $2 ]] if [[ -n ${2} ]]
then then
local PRIVATE_KEY=$1 local PRIVATE_KEY=$1
local CERT_CHAIN=$2 local CERT_CHAIN=$2
@ -891,7 +891,7 @@ function _setup_ssl
;; ;;
* ) * )
_notify 'err' 'TLS_LEVEL not found [ in _setup_ssl ]' _notify 'err' "TLS_LEVEL not found [ in ${FUNCNAME[0]} ]"
;; ;;
esac esac