Use Existing TLS certificate with Traefik 2

In my previous articles, I used Traefik 2 to get free SSL certificate from Let’s Encrypt and BuyPass. Although these DV certificates are good enough for most users, some users especially enterprise users may prefer using their own certificates. In this article I will show you how you can use SSL certificate from other CAs.

From official website, it seems that we only need to reference certificate and key files in dynamic configuration.

1
2
3
4
5
6
7
8
# Dynamic configuration

tls:
certificates:
- certFile: /path/to/domain.cert
keyFile: /path/to/domain.key
- certFile: /path/to/other-domain.cert
keyFile: /path/to/other-domain.key

Not surprisingly, it is more complicated than that. Here are the changes you need to make.

Modify docker compose file

First of all, I put my certificate and private key in ~/data/ssl/ folder. Then I mounted this folder into traefik container by adding a volume label as below.

1
2
3
4
5
6
7
8
9
10
11
12
13
...
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
# Add folder with dynamic configuration yml
- ./data/configurations:/configurations
# Add SSL certificate to traefik container
- ./data/ssl:/ssl
networks:
- proxy
labels:
...

Modify static configuration file

Next, we need to change our static configuration file ~/data/traefik.yml. As I am using entry point redirects and default router configuration, I need to change tls configuration. I commented out the previous tls configure and added tls: {}[1]. Please note, if you choose to use your own SSL, you need to provide certificates for all services under Traefik. You won’t be able to use Let’s Encrypt or Buypass for some services and use your own certificate for the other services. (Maybe you can, I just couldn’t figure out how to do it… Please let me know if you find a way.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
https:
address: :443
http:
middlewares:
- secureHeaders@file
tls: {}
# tls:
# certResolver: buypass

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

Modify dynamic configuration file.

Lastly it is time to modify the dynamic configuration file ~/data/configurations/dynamic.yml. As I mounted my ~/data/ssl/ as /ssl/ inside traefik container, we should reference our certificate and key files under /ssl/. If we did not mount this folder, traefik won’t be able to use the files on your server directly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
user-auth:
basicAuth:
users:
- "admin:$apr1$tm53ra6x$FntXd6jcvxYM/YH0P2hcc1"

tls:
certificates:
- certFile: /ssl/server.pem
keyFile: /ssl/private.key
options:
default:
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
minVersion: VersionTLS12
...

If you know SSL, you would know that trust chain is one of the most important thing of SSL. If we are installing our certificate on Apache server, we need to define CertificateChainFile on the virtual host file. Traefik is taking the same approach as Nginx, which you put your server and all chain certificates on the same x509 format file.

1
2
3
4
5
6
-----BEGIN CERTIFICATE-----
Server cert
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
Intermediate cert
-----END CERTIFICATE-----

After that, you can run your services with your own TLS certificates.

By the way, I started to make some videos and posted on Bilibili and YouTube. Reading a long article can be very painful nowadays, all these concepts and information can be very confusing as well. The purpose of making videos is to allow people to follow my procedures exactly and help them to have at least one working example to follow along.

Anyway, thanks for reading. I hope you find this article useful. See you next time.


  1. Official documentation here https://docs.traefik.io/routing/routers/#tls ↩︎