Problem
I need to replace Cloudflare as my DNS provider. I run Mail-in-a-Box which can serve DNS and has a good API but Traefik can't directly use it.
Background
Let's Encrypt
Let's encrypt provides free TLS certificates by giving you a token and asking you to post it somewhere authoritative that they can then check to verify your identity.
The two main challenge types are http-01
(you essentially make the token available at http://<DOMAIN>/.well-known/acme-challenge/<TOKEN>
) and dns-01
(create a TXT record _acme-challenge.<DOMAIN>
with <TOKEN>
as the value). The http-01
method is preferred since it doesn't require additional administrative access but it's not feasible for sites that are internal-only.
Traefik
Traefik uses the Lego ACME library for interacting with Let's Encrypt. While Lego doesn't have a dedicated MiaB provider it does have one named exec
that can run an arbitrary executable. We can use this to call to any DNS API that's not already supported.
Mail-in-a-Box
Mail-in-a-Box is a great option for self-hosting email, calendar, and contacts functionality. It prefers to be configured as the authoritative DNS for each domain it manages since it can seamlessly handle all the DNS entries needed to run smoothly. Creating and deleting DNS entries using the API using curl
is easy:
Solution
Make a shim script that Traefik/Lego can call with the exec
provider and that then makes the appropriate API call to Mail-in-a-Box. Here's what I came up with. It uses the same environment variables as acme.sh (MIAB_Username
, MIAB_Password
, and MIAB_Server).
/usr/local/bin/miab-dns.sh
#!/bin/bash
systemd Example
There are a hundred ways to configure and run Traefik but I'll share a complete systemd solution as one example.
/etc/systemd/system/traefik.service
[Unit]
Traefik Proxy
/
-online.target
network
[Service]
traefik
traefik
/root/.traefik.env
CAP_NET_BIND_SERVICE
CAP_NET_BIND_SERVICE
"EXEC_PATH=/usr/local/bin/miab-dns.sh"
/usr/local/bin/traefik \
--log.level=INFO \
--entrypoints.web.address=:80 \
--entrypoints.web.http.redirections.entrypoint.to=websecure \
--entrypoints.websecure.address=:443 \
--entrypoints.websecure.http.tls.certresolver=miab \
--certificatesresolvers.miab.acme.dnschallenge=true \
--certificatesresolvers.miab.acme.dnschallenge.provider=exec \
--certificatesresolvers.miab.acme.email=mark@mrkc.net \
--certificatesresolvers.miab.acme.storage=%S/traefik/acme.json
.d
traefiktrue
true
true
traefik
0750
true
true
[Install]
-user.target
multi
/root/.traefik.env
Make sure this file is secure (e.g. chmod 0640
)!
MIAB_Username=REDACTED
MIAB_Password=REDACTED
MIAB_Server=REDACTED