I'm trying to use Traefik v2 dns challenge with duckdns along with a CNAMEd domain without success. If I use duckdns.org directly, say mydomain.duckdns.org in the static config it works:
Now I'm trying to gen certs to my own domain, e.g. traefik.mydomain.com.br that is properly CNAMEd to mydomain.duckdns.org, and has another CNAME entry for _acme-challenge.traefik.mydomain.com.br that points to mydomain.duckdns.org. So I've changed my config to reflect this setup:
Problem is that the update request to duckdns is failing (url parameter domains has wrong value, see below). Is this a bug or am I forgetting something here?
msg="Unable to obtain ACME certificate for domains \"traefik.mydomain.com.br\" : unable to generate a certificate for the domains [traefik.mydomain.com.br]:
error: one or more domains had a problem:\n[traefik.mydomain.com.br] [traefik.mydomain.com.br]
acme: error presenting token: request to change TXT record for DuckDNS returned the following result (KO) this does not match expectation (OK)
used url [https://www.duckdns.org/update?clear=false&domains=br&token=xxxxxxxxx-a0a5-4caa-a5a5-xxxxxxxx&txt=sR2pZSxxxxxxxxxvAp6jqdLmizIvWq7QCyYqk-8qySs]\n" providerName=duckdns.acme
If I manually submit the http request to duckdns, obviously exchanging the wrong (br) value in the domains parameter with the correct (CNAMEd) one then it results OK.
Any ideais? How can I instruct Traefik to use the correct domain? TIA.
Your TXT record has to be updated on the traefik.mydomain.com.br domain. So you should update your certificateProviders to the provider/account that traefik.mydomain.com.br is on.
A TXT record and CNAME are different records. CNAMEing _acme-challenge.traefik.mydomain.com.br won't result in a query of TXT following a CNAME.
I thought that my TXT record could be updated/submited for the CNAMEd domain (mydomain.duckdns.org), like Caddy server does with the override_domain directive in the DNS challenge plugin, please see this link.
Also, this behavior is supported by Let’s Encrypt, let's see:
Since Let’s Encrypt follows the DNS standards when looking up TXT records for DNS-01 validation, you can use CNAME records or NS records to delegate answering the challenge to other DNS zones. This can be used to delegate the _acme-challenge subdomain to a validation-specific server or zone. It can also be used if your DNS provider is slow to update, and you want to delegate to a quicker-updating server.
In my case, I can't simply update or change the certificateProviders because my current DNS provider is unsupported (by Traefik).
Hi, did you get a solution to this? I'm having the same problem. The documentation says that traefik supports domain delegation, but it keeps trying to resolve the DNS challenge against the domain I do not control.
No. It's for a hosted SaaS. Customers own the domain and we run the servers on a docker swarm cluster. Currently we simply instruct customers to CNAME their domain to our traefik server and then use the HTTP challenge, but this means that we can have only traefik node as ingress controller. If we want to add more traefik nodes and have some form of DNS load balancing, the only way to do it would be to have DNS challenge working.
The documentation says that it traefik can do DNS delegation, but there is no good example in the documentation showing how it could be done.
Great to meet someone using Docker Swarm. Traefik-CE does not support clustered LetsEncrypt, so the only way to work around this is using dnsChallenge or an external process (wild PoC).
Developer feedback is usually just on GitHub, but they also close support tickets there, so it's complicated
We currently handle LetsEncrypt certs with two external scripts.
Create TLS certs
#!/bin/zsh
# Use a here document to define a list of domains
DOMAINS=$(cat <<EOF
example.com
sub.example.com
many.more.com
EOF
)
# Iterate over each domain
for DOMAIN in ${(f)DOMAINS}; do
echo "\n\n\n********** DOMAIN ${DOMAIN} **********\n\n\n"
# Run the acme.sh command for each domain
USER="123" \
PASSWORD="456" \
acme.sh \
--force \
--issue \
--server letsencrypt \
--dns dns_provider \
--home . \
-d "$DOMAIN" -d "*.$DOMAIN" \
--cert-file "./certificates/$DOMAIN.cer" \
--key-file "./certificates/$DOMAIN.key" \
--fullchain-file "./certificates/$DOMAIN.pem" \
echo sleep 5
sleep 5
done
Inline all TLS certs into single dynamic config file
#!/bin/bash
# Define the certificates directory and the output file
CERT_DIR="./certificates"
FILE="./traefik-tls.yml"
# Start writing the Traefik dynamic configuration file
echo "TRAEFIK TLS FILE GENERATION"
printf "tls:\n options:\n default:\n minVersion: VersionTLS12\n certificates:\n" > $FILE
# Find all .key files in the certificates folder, strip the .key extension, and iterate over them
for KEY_FILE in $(find $CERT_DIR -maxdepth 1 -name "*.key" -type f | sort); do
# Remove the .key extension to get the domain name (or file prefix)
DOMAIN=$(basename "$KEY_FILE" .key)
# Add the domain's certFile and keyFile to the Traefik configuration
echo "TRAEFIK TLS FILE ADD $DOMAIN"
printf " # CERT FILE $DOMAIN\n" >> $FILE
printf " - certFile: |-\n" >> $FILE
sed -e 's/^/ /' "$CERT_DIR/$DOMAIN.pem" >> $FILE
printf " keyFile: |-\n" >> $FILE
sed -e 's/^/ /' "$KEY_FILE" >> $FILE
printf "\n\n\n" >> $FILE
done
echo "Traefik dynamic configuration file created at $FILE"