1. Caddy version (caddy version
):
v2.2.0-rc.1
2. How I run Caddy:
Docker, based on caddy:2
image from Docker Hub.
Caddy binary has been custom built with lego-deprecated
in order to use Namecheap with DNS challenge.
My goal is to run split horizon DNS so intranet services are not exposed to the internet at large. Internally, *.internal.chris-cartwright.com
resolves to the computer running the Caddy container. Externally, it resolves to a VM hosted on LunaNode.
Dockerfile
# Go 1.15 does not work with one or more of the dependencies.
# Link is only tangentally related, but fixed the issue.
# https://github.com/syncthing/syncthing/issues/6889#issuecomment-672791645
FROM golang:1.14-buster AS builder
RUN go get -u github.com/caddyserver/xcaddy/cmd/xcaddy
# Need to use v2.2.0-rc.1 to work around a pinning issue with a dependency.
# The tag can be removed once Caddy v2.2.0 is released.
# https://github.com/caddy-dns/cloudflare/issues/11
RUN xcaddy build v2.2.0-rc.1 \
--with github.com/caddy-dns/lego-deprecated
FROM caddy:2 AS runner
COPY --from=builder /go/caddy /usr/bin/caddy
docker-compose.yml
version: "3"
services:
caddy:
image: ccartwright/caddy
container_name: caddy
networks:
- web
- default
volumes:
- ./data/:/etc/caddy/
- ./files/:/usr/share/caddy/
environment:
- "NAMECHEAP_API_USER=CCartwright"
- "NAMECHEAP_API_KEY=*****"
ports:
- 80:80
- 443:443
networks:
web:
external: true
The web
network was created with docker network create web
. Services I wish to proxy are added to this network.
Caddyfile
# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace the line below with your
# domain name.
# :80
{
debug
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
email cartwright.christopher@gmail.com
admin :2019
}
# Set this path to your site's directory.
#root * /usr/share/caddy
# Enable the static file server.
# file_server
whoami1.internal.chris-cartwright.com {
tls {
dns lego_deprecated namecheap
}
reverse_proxy whoami-1_whoami_1:80
}
# Another common task is to set up a reverse proxy:
#reverse_proxy whoami1.internal.chris-cartwright.com {
# to whoami-1_whoami_1:80
#}
#reverse_proxy whoami2.internal.chris-cartwright.com {
# to whoami-2_whoami_1:9090
#}
# Or serve a PHP site through php-fpm:
# php_fastcgi localhost:9000
#tls {
# dns lego_deprecated namecheap
#}
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile
3. The problem I’m having:
The TXT record for the domain is not created, which causes the Let’s Encrypt validation to fail. Credentials are confirmed working via Traefik. It could create the TXT record, but didn’t work for me because of other reasons.
4. Error messages and/or full log output:
{"level":"info","ts":1598659581.950414,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
{"level":"info","ts":1598659581.9514906,"logger":"admin","msg":"admin endpoint started","address":"tcp/:2019","enforce_origin":false,"origins":[":2019"]}
{"level":"warn","ts":1598659581.9515183,"logger":"admin","msg":"admin endpoint on open interface; host checking disabled","address":"tcp/:2019"}
{"level":"info","ts":1598659581.9527543,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0002fb9d0"}
{"level":"info","ts":1598659582.457994,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1598659582.458037,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"debug","ts":1598659582.45882,"logger":"http","msg":"starting server loop","address":"[::]:443","http3":false,"tls":true}
{"level":"debug","ts":1598659582.4588857,"logger":"http","msg":"starting server loop","address":"[::]:80","http3":false,"tls":false}
{"level":"info","ts":1598659582.458891,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["whoami1.internal.chris-cartwright.com"]}
{"level":"info","ts":1598659582.4589417,"logger":"tls","msg":"cleaned up storage units"}
{"level":"info","ts":1598659582.4589846,"msg":"autosaved config","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1598659582.4589891,"msg":"serving initial configuration"}
{"level":"info","ts":1598659582.4591625,"logger":"tls.obtain","msg":"acquiring lock","identifier":"whoami1.internal.chris-cartwright.com"}
{"level":"info","ts":1598659582.4594145,"logger":"tls.obtain","msg":"lock acquired","identifier":"whoami1.internal.chris-cartwright.com"}
{"level":"debug","ts":1598659582.8578024,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"GET","url":"https://acme-staging-v02.api.letsencrypt.org/directory","headers":{"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":200,"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["724"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:22 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"debug","ts":1598659582.9345744,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"HEAD","url":"https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce","headers":{"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":200,"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Date":["Sat, 29 Aug 2020 00:06:22 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0001TmtJ7Lka2f0-SaDBH6uH5v1Nxb33qmPfKciYR1Soufk"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"debug","ts":1598659583.0256824,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-staging-v02.api.letsencrypt.org/acme/new-acct","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":201,"response_headers":{"Boulder-Requester":["15376743"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["334"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:22 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf>;rel=\"terms-of-service\""],"Location":["https://acme-staging-v02.api.letsencrypt.org/acme/acct/15376743"],"Replay-Nonce":["0002nOoaQ2nxsDOTKUbnUZ6uD0JMc-eQq-CfIqQsUFna48o"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"info","ts":1598659583.0283735,"logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["whoami1.internal.chris-cartwright.com"]}
{"level":"info","ts":1598659583.028401,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["whoami1.internal.chris-cartwright.com"]}
{"level":"debug","ts":1598659583.1193461,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-staging-v02.api.letsencrypt.org/acme/new-order","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":201,"response_headers":{"Boulder-Requester":["15376743"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["381"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:23 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-staging-v02.api.letsencrypt.org/acme/order/15376743/138836523"],"Replay-Nonce":["0002ZkoQybwmCpYAO96sMWtkJwPUWd3RhJKCkde_enYYHJY"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"debug","ts":1598659583.1988206,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/101510630","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":200,"response_headers":{"Boulder-Requester":["15376743"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["836"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:23 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0002lM6qTkpmkRxypjtaWOJVvl1s-3_joKLtytB2-55HJtQ"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"debug","ts":1598659583.1989594,"logger":"tls.issuance.acme.acme_client","msg":"no solver configured","challenge_type":"tls-alpn-01"}
{"level":"debug","ts":1598659583.198965,"logger":"tls.issuance.acme.acme_client","msg":"no solver configured","challenge_type":"http-01"}
{"level":"info","ts":1598659583.1989684,"logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"whoami1.internal.chris-cartwright.com","challenge_type":"dns-01","ca":"https://acme-staging-v02.api.letsencrypt.org/directory"}
{"level":"debug","ts":1598659589.4328656,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/101510630/YxrjIA","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":200,"response_headers":{"Boulder-Requester":["15376743"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["191"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:29 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/101510630>;rel=\"up\""],"Location":["https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/101510630/YxrjIA"],"Replay-Nonce":["0002wheQBRMTCrTmZjzS1JVbw47ckYdfuXZWqPzZrhKlsAU"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"debug","ts":1598659589.4329436,"logger":"tls.issuance.acme.acme_client","msg":"challenge accepted","identifier":"whoami1.internal.chris-cartwright.com","challenge_type":"dns-01"}
{"level":"debug","ts":1598659589.7647457,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/101510630","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":200,"response_headers":{"Boulder-Requester":["15376743"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["659"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:29 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["00027kQ_WHBiR5ldi_0piVtJJ22-C7HGyaISfoBnkS9Kr4s"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"error","ts":1598659590.6208777,"logger":"tls.issuance.acme.acme_client","msg":"challenge failed","identifier":"whoami1.internal.chris-cartwright.com","challenge_type":"dns-01","status_code":400,"problem_type":"urn:ietf:params:acme:error:dns","error":"DNS problem: NXDOMAIN looking up TXT for _acme-challenge.whoami1.internal.chris-cartwright.com - check that a DNS record exists for this domain"}
{"level":"error","ts":1598659590.6209447,"logger":"tls.issuance.acme.acme_client","msg":"validating authorization","identifier":"whoami1.internal.chris-cartwright.com","error":"authorization failed: HTTP 400 urn:ietf:params:acme:error:dns - DNS problem: NXDOMAIN looking up TXT for _acme-challenge.whoami1.internal.chris-cartwright.com - check that a DNS record exists for this domain","order":"https://acme-staging-v02.api.letsencrypt.org/acme/order/15376743/138836523","attempt":1,"max_attempts":3}
{"level":"debug","ts":1598659591.717692,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-staging-v02.api.letsencrypt.org/acme/new-order","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":201,"response_headers":{"Boulder-Requester":["15376743"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["380"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:31 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-staging-v02.api.letsencrypt.org/acme/order/15376743/138836604"],"Replay-Nonce":["0002dGxgN5rzeRbrAgu_ejoGTkfTwJq5wGA_FsWkkmG-cMI"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"debug","ts":1598659591.7980237,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/101510704","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":200,"response_headers":{"Boulder-Requester":["15376743"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["836"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:31 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0001IZCTZTEW2ED-nqWEFTnSBYzJWjoYU1lVVXNoKGZHCsk"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"debug","ts":1598659591.7981493,"logger":"tls.issuance.acme.acme_client","msg":"no solver configured","challenge_type":"tls-alpn-01"}
{"level":"debug","ts":1598659591.7981727,"logger":"tls.issuance.acme.acme_client","msg":"no solver configured","challenge_type":"http-01"}
{"level":"debug","ts":1598659591.8842742,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/101510704","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.2.0-rc.1 CertMagic acmez (linux; amd64)"]},"status_code":200,"response_headers":{"Boulder-Requester":["15376743"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["840"],"Content-Type":["application/json"],"Date":["Sat, 29 Aug 2020 00:06:31 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0002o-bezinnSIQIqN6VGNg0HEVk-1rEjI9cul2MmToxNOs"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
{"level":"error","ts":1598659591.884386,"logger":"tls.obtain","msg":"will retry","error":"[whoami1.internal.chris-cartwright.com] Obtain: [whoami1.internal.chris-cartwright.com] solving challenges: whoami1.internal.chris-cartwright.com: no solvers available for remaining challenges (configured=[dns-01] offered=[http-01 dns-01 tls-alpn-01] remaining=[http-01 tls-alpn-01]) (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/15376743/138836604) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":9.4249488,"max_duration":2592000}
5. What I already tried:
Not sure what else I can try. It just doesn’t work and doesn’t provide useful output. I don’t see any log entries regarding Namecheap or the TXT record. Caddy seems to jump right to asking Let’s Encrypt perform their verifications.
I could not find alternatives to lego-deprecated
that support Namecheap.
6. Links to relevant resources:
Caddy 2 can support all 75+ DNS providers - basic info
GitHub - caddy-dns/lego-deprecated: (DEPRECATED) DNS modules so Caddy can solve the ACME DNS challenge with over 75 providers - basic info
Caddy2 with DNS challenge and Namecheap in Docker - other issues, unresolved