Traefik 2 Request Multiple Domain and Wildcard SSL Certificates

In my previous article, I briefly mentioned we can modify static configuration to request wildcard and multiple domains SSL certificates. I will focus on how we can request such certificates in this article.

All supported providers for dnsChallenge are listed on official website. If your DNS provider is listed, you can follow containeroo’s article (They used Cloudflare as an example) to request wildcard certificate. I will use acme-dnsas the provider in this article to help people that are not familiar with API or their DNS providers are not listed on official documentation to get wildcard certificates.

Configurations

Multiple Domain SSL

This is pretty straight forward. You just need to change your static configurationas below and make sure the main domain and SANs listed are pointing to the same server where Traefik is used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
websecure:
address: ":443"
http:
middlewares:
- secureHeaders@file
tls:
certResolver: letsencrypt
domains:
- main: yourdomain
sans:
- "test1.yourdomainn"
- "test2.yourdomainn"
- "test3.yourdomainn"

Wildcard SSL

The official documentation says we need two environment variables foracme-dns. The first one is ACME_DNS_API_BASE url which is the URL of acme-dns server. The other one ACME_DNS_STORAGE_PATHis the location of a file containing acme-dns variables. I will be using acme-dnsofficial url to demonstrate how this works.

acmd-dns environment file

I created an empty file acme-dns and put it under ~/data/. On official website, it says we can use {acme-dns-url}/registerendpoint to get the necessary variables. Instead of using cURL and put them in the acmd-dns file manually, I will be using Traefik to get these variables and save it to our file automatically.

Static Configuration

I use root domain as the common name and wildcard domain as a SAN in my configuration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: https
websecure:
address: ":443"
http:
middlewares:
- secureHeaders@file
tls:
certResolver: le-dns
domains:
- main: yourdomain
sans:
- "*.yourdomain"

I also create a newcertResolverfor DNS validation. Comparing to the http validation, we need to declare we will be using dnsChallenge and acme-dns as provider.

1
2
3
4
5
6
7
le-dns:
acme:
email: admin@yourdomain
storage: acme.json
keyType: EC384
dnsChallenge:
provider: acme-dns

Full configuration as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
api:
dashboard: true

entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
websecure:
address: ":443"
http:
middlewares:
- secureHeaders@file
tls:
certResolver: le-dns
domains:
- main: yourdomain
sans:
- "*.yourdomainn"

providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /configurations/dynamic.yml

certificatesResolvers:
letsencrypt:
acme:
email: admin@yourdomain
storage: acme.json
keyType: EC384
httpChallenge:
entryPoint: http

buypass:
acme:
email: admin@yourdomain
storage: acme.json
caServer: https://api.buypass.com/acme/directory
keyType: EC256
httpChallenge:
entryPoint: http

le-dns:
acme:
email: admin@yourdomain
storage: acme.json
keyType: EC384
dnsChallenge:
provider: acme-dns

Docker Compose file

We need to include these two Environment variables on our docker-compose.yml file. In my configuration, I mount acmd-dns files to Traefik container.

Full Configuration below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
version: '3.3'

services:
traefik:
image: traefik:latest
container_name: traefik
restart: always
security_opt:
- no-new-privileges:true
ports:
- 80:80
- 443:443
environment:
- ACME_DNS_API_BASE=https://auth.acme-dns.io
- ACME_DNS_STORAGE_PATH=/acme-dns
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./data/acme.json:/acme.json
- ./data/acme-dns:/acme-dns
# Add folder with dynamic configuration yml
- ./data/configurations:/configurations
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.traefik-secure.entrypoints=websecure"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain`)"
- "traefik.http.routers.traefik-secure.middlewares=user-auth@file"
- "traefik.http.routers.traefik-secure.service=api@internal"

networks:
proxy:
external: true

Set up DNS

Getting acme-dns info

After we’ve complete modifying our two files, let’s run docker-compose up to fetch the variables fromacme-dns server. 5 seconds later we can press CTRL+C to terminal the process and open acme-dnsfile. We should see something similar listed:

1
2
3
4
5
6
7
8
9
{
"yourdomain": {
"FullDomain": "c9877300-2abb-40c6-87e6-321adcd1f625.auth.acme-dns.io",
"SubDomain": "c9877300-2abb-40c6-87e6-321adcd1f625",
"Username": "9b9fc655-c708-4c20-b37e-1da72851c538",
"Password": "MPhWzI2ZwgeZKyGK3cYPLICfXlNbmF5tFutacpFF"
}
}

Create DNS CNAME Record

Log in to your DNS management page and create a DNS CNAME record_acme-challenge.yourdomainpoints to c9877300-2abb-40c6-87e6-321adcd1f625.auth.acme-dns.io

If you can see below CNAME record with dig, it means the DNS record is propagated and we are ready to request our wildcard certificate.

1
_acme-challenge.yourdomain. 21599 IN	CNAME	c9877300-2abb-40c6-87e6-321adcd1f625.auth.acme-dns.io

Request Cert

Run docker-compose up -done more time, Traefik should get this wildcard certificate successfully.

For everyday user, the default http is good enough. If you need a wildcard or multiple domain SSLs, I hope this article can be of any help.

Thanks for reading.