Trouble self hosting services using DDNS, Caddy and more

1. The problem I’m having:

I’m trying to self host a bunch of services, Immich and Jellyfin to start with. I’d like to share it publicly using DDNS while keeping it secure enough for daily personal needs. I do not want to use a VPN, that’s non negotiable. So after long hours of research I’ve picked a few tools to achieve the goal - Caddy, Authentik, DuckDNS, Let’s Encrypt and Docker. The thing is, I’m not IT specialist, not even much of a hobbyst (most I’ve ever done was port forwarding for minecraft servers) and I have no idea how to do any of that. I’ve spent 2 days trying to set it up and all I’ve managed to do was proxying localhost:2283 to localhost. I clearly have no idea what I’m doing and all the tutorials in the world couldn’t help me. Currently I’m stuck on getting a certificate from DDNS. I’d like to have nice, safe encrypted https on every device I connect from, with no loud, red warnings. Can’t use Cloudflare since their ToS don’t allow Jellyfin.

2. Error messages and/or full log output:

Got 2 different errors depending on the config. “Expected OK but got KO” and “Couldn’t get certificate from issuer”. 2nd one logs are below, 1st one couldn’t replicate.

2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1647232,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
2024-05-23 20:40:43 caddy-1  | {"level":"warn","ts":1716489643.1653807,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":10}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1657922,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1659787,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0005e1b00"}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1661506,"logger":"http.auto_https","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}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1661656,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
2024-05-23 20:40:43 caddy-1  | {"level":"debug","ts":1716489643.1661828,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{"subjects":["danielowy.duckdns.org"]},{}]}},"http":{"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"jellyfin:8096"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1663315,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1663868,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
2024-05-23 20:40:43 caddy-1  | {"level":"debug","ts":1716489643.166445,"logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":true}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1664739,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
2024-05-23 20:40:43 caddy-1  | {"level":"debug","ts":1716489643.1664965,"logger":"http","msg":"starting server loop","address":"[::]:80","tls":false,"http3":false}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1665096,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1665115,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["danielowy.duckdns.org"]}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.166624,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1666381,"msg":"serving initial configuration"}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1666844,"logger":"tls.obtain","msg":"acquiring lock","identifier":"danielowy.duckdns.org"}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1683922,"logger":"tls.obtain","msg":"lock acquired","identifier":"danielowy.duckdns.org"}
2024-05-23 20:40:43 caddy-1  | {"level":"warn","ts":1716489643.1684337,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"3e553092-fbc6-4db7-914c-667624d37dda","try_again":1716576043.1684327,"try_again_in":86399.99999972}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1684852,"logger":"tls","msg":"finished cleaning storage units"}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1685073,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"danielowy.duckdns.org"}
2024-05-23 20:40:43 caddy-1  | {"level":"debug","ts":1716489643.168519,"logger":"events","msg":"event","name":"cert_obtaining","id":"183937af-32a4-456c-bc84-36809894a9d6","origin":"tls","data":{"identifier":"danielowy.duckdns.org"}}
2024-05-23 20:40:43 caddy-1  | {"level":"debug","ts":1716489643.1686676,"logger":"tls.obtain","msg":"trying issuer 1/2","issuer":"acme-v02.api.letsencrypt.org-directory"}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.1688538,"logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["danielowy.duckdns.org"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
2024-05-23 20:40:43 caddy-1  | {"level":"info","ts":1716489643.168864,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["danielowy.duckdns.org"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
2024-05-23 20:40:43 caddy-1  | {"level":"debug","ts":1716489643.7153373,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"GET","url":"https://acme-v02.api.letsencrypt.org/directory","headers":{"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["746"],"Content-Type":["application/json"],"Date":["Thu, 23 May 2024 18:40:43 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-05-23 20:40:43 caddy-1  | {"level":"debug","ts":1716489643.884846,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"HEAD","url":"https://acme-v02.api.letsencrypt.org/acme/new-nonce","headers":{"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Date":["Thu, 23 May 2024 18:40:43 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["gEGAwOe-U9PDISuheQ7ZgRA64h2k_SwPygjBmPEntbCYJ9Sw93g"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-05-23 20:40:44 caddy-1  | {"level":"debug","ts":1716489644.172973,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/new-order","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Boulder-Requester":["1741042762"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["347"],"Content-Type":["application/json"],"Date":["Thu, 23 May 2024 18:40:44 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/1741042762/271954006772"],"Replay-Nonce":["YEjsK0piNh9z7vogXbZVRkY0p6T7u7J8fuQzIXre7HCHt41UZZs"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":201}
2024-05-23 20:40:44 caddy-1  | {"level":"debug","ts":1716489644.3412802,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/354515874452","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Boulder-Requester":["1741042762"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["805"],"Content-Type":["application/json"],"Date":["Thu, 23 May 2024 18:40:44 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["gEGAwOe-qhOyV8YOuOaiHMVGZRbHKoGsXBR5vj4yTl0tJFssFCk"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-05-23 20:40:44 caddy-1  | {"level":"info","ts":1716489644.341411,"logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"danielowy.duckdns.org","challenge_type":"dns-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
2024-05-23 20:40:48 caddy-1  | {"level":"error","ts":1716489648.342362,"logger":"tls.issuance.acme.acme_client","msg":"cleaning up solver","identifier":"danielowy.duckdns.org","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.danielowy.duckdns.org\" (usually OK if presenting also failed)"}
2024-05-23 20:40:48 caddy-1  | {"level":"debug","ts":1716489648.521384,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/354515874452","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Boulder-Requester":["1741042762"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["809"],"Content-Type":["application/json"],"Date":["Thu, 23 May 2024 18:40:48 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["YEjsK0pi-UColGD4mYaqcOeavwss5EvYjWHdPS0XWVRCH-fiGb4"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-05-23 20:40:48 caddy-1  | {"level":"error","ts":1716489648.5214741,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"danielowy.duckdns.org","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[danielowy.duckdns.org] solving challenges: presenting for challenge: could not determine zone for domain \"_acme-challenge.danielowy.duckdns.org\": unexpected response code 'SERVFAIL' for _acme-challenge.danielowy.duckdns.org. (order=https://acme-v02.api.letsencrypt.org/acme/order/1741042762/271954006772) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
2024-05-23 20:40:48 caddy-1  | {"level":"debug","ts":1716489648.5214932,"logger":"tls.obtain","msg":"trying issuer 2/2","issuer":"acme.zerossl.com-v2-DV90"}
2024-05-23 20:40:48 caddy-1  | {"level":"info","ts":1716489648.5217586,"logger":"tls.issuance.zerossl","msg":"waiting on internal rate limiter","identifiers":["danielowy.duckdns.org"],"ca":"https://acme.zerossl.com/v2/DV90","account":"caddy@zerossl.com"}
2024-05-23 20:40:48 caddy-1  | {"level":"info","ts":1716489648.5217772,"logger":"tls.issuance.zerossl","msg":"done waiting on internal rate limiter","identifiers":["danielowy.duckdns.org"],"ca":"https://acme.zerossl.com/v2/DV90","account":"caddy@zerossl.com"}
2024-05-23 20:40:48 caddy-1  | {"level":"debug","ts":1716489648.768832,"logger":"tls.issuance.zerossl.acme_client","msg":"http request","method":"GET","url":"https://acme.zerossl.com/v2/DV90","headers":{"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Content-Length":["645"],"Content-Type":["application/json"],"Date":["Thu, 23 May 2024 18:40:48 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-05-23 20:40:49 caddy-1  | {"level":"debug","ts":1716489649.0781674,"logger":"tls.issuance.zerossl.acme_client","msg":"http request","method":"HEAD","url":"https://acme.zerossl.com/v2/DV90/newNonce","headers":{"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Type":["application/octet-stream"],"Date":["Thu, 23 May 2024 18:40:49 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["Xegd8C04lSDqEiDCWBE0jhqvZNfw79oBQf2h2r9jCjE"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-05-23 20:40:49 caddy-1  | {"level":"debug","ts":1716489649.4409516,"logger":"tls.issuance.zerossl.acme_client","msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/newOrder","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["283"],"Content-Type":["application/json"],"Date":["Thu, 23 May 2024 18:40:49 GMT"],"Location":["https://acme.zerossl.com/v2/DV90/order/PgnvetJqm8ddLjWOoV1Z3Q"],"Replay-Nonce":["O0TSW0C1CVTbJB37JJPrAdCcM-IU1uC3vftsAyJehLY"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":201}
2024-05-23 20:40:49 caddy-1  | {"level":"debug","ts":1716489649.765614,"logger":"tls.issuance.zerossl.acme_client","msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/authz/Cy_EbVtDVe75K2Zg8Aqepg","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["451"],"Content-Type":["application/json"],"Date":["Thu, 23 May 2024 18:40:49 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["7Owj_LixgHNe73f-G7k1ppVvCkWLFh9zBMOBTdYgBQo"],"Retry-After":["5"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-05-23 20:40:49 caddy-1  | {"level":"info","ts":1716489649.765708,"logger":"tls.issuance.zerossl.acme_client","msg":"trying to solve challenge","identifier":"danielowy.duckdns.org","challenge_type":"dns-01","ca":"https://acme.zerossl.com/v2/DV90"}
2024-05-23 20:40:53 caddy-1  | {"level":"error","ts":1716489653.7670057,"logger":"tls.issuance.zerossl.acme_client","msg":"cleaning up solver","identifier":"danielowy.duckdns.org","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.danielowy.duckdns.org\" (usually OK if presenting also failed)"}
2024-05-23 20:40:54 caddy-1  | {"level":"debug","ts":1716489654.1021712,"logger":"tls.issuance.zerossl.acme_client","msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/authz/Cy_EbVtDVe75K2Zg8Aqepg","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["133"],"Content-Type":["application/json"],"Date":["Thu, 23 May 2024 18:40:54 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["1dbZ-8cUjewsrg0xlTOxOZ_L7HIUdukz3uo-IM81U8Q"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-05-23 20:40:54 caddy-1  | {"level":"error","ts":1716489654.1022627,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"danielowy.duckdns.org","issuer":"acme.zerossl.com-v2-DV90","error":"[danielowy.duckdns.org] solving challenges: presenting for challenge: could not determine zone for domain \"_acme-challenge.danielowy.duckdns.org\": unexpected response code 'SERVFAIL' for _acme-challenge.danielowy.duckdns.org. (order=https://acme.zerossl.com/v2/DV90/order/PgnvetJqm8ddLjWOoV1Z3Q) (ca=https://acme.zerossl.com/v2/DV90)"}
2024-05-23 20:40:54 caddy-1  | {"level":"debug","ts":1716489654.1022816,"logger":"events","msg":"event","name":"cert_failed","id":"91930939-9441-4b5e-a836-818cc83de3f1","origin":"tls","data":{"error":{},"identifier":"danielowy.duckdns.org","issuers":["acme-v02.api.letsencrypt.org-directory","acme.zerossl.com-v2-DV90"],"renewal":false}}
2024-05-23 20:40:54 caddy-1  | {"level":"error","ts":1716489654.1023266,"logger":"tls.obtain","msg":"will retry","error":"[danielowy.duckdns.org] Obtain: [danielowy.duckdns.org] solving challenges: presenting for challenge: could not determine zone for domain \"_acme-challenge.danielowy.duckdns.org\": unexpected response code 'SERVFAIL' for _acme-challenge.danielowy.duckdns.org. (order=https://acme.zerossl.com/v2/DV90/order/PgnvetJqm8ddLjWOoV1Z3Q) (ca=https://acme.zerossl.com/v2/DV90)","attempt":1,"retrying_in":60,"elapsed":10.933917722,"max_duration":2592000}

3. Caddy version:

docker-compose exec caddy caddy version
returned
no configuration file provided: not found
Docker Desktop says it’s Caddy:2 (“Newer image available”) and Alpine:3.18. I checked out github Dockerfile for the new version but it’s long, complicated and I don’t want to mess something up even more.

4. How I installed and ran Caddy:

I’m using custom build with this Dockerfile

FROM caddy:builder-alpine AS builder
RUN xcaddy build --with github.com/caddy-dns/duckdns
FROM caddy:latest
COPY --from=builder /usr/bin/caddy /usr/bin/caddy

a. System environment:

Docker Desktop 4.30.0
Windows 10 19045.4412 64
AMD Ryzen 5-5600X CPU,
“Connect Box” Router, it’s an ISP local brand afaik. Pretty restrictive software, but has some form of DDNS and port forwarding, which should be enough.

b. Command:

I’m on Windows, I’m not using commands unless I really have to. I know what you’re thinking, please don’t laugh :sweat_smile: also, since I’m using Windows, I don’t know where to paste Linux commands. WSL? Docker?

c. Service/unit/compose file:

services:
  caddy:
    image: caddy-duckdns:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./site:/srv
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - caddy_network

volumes:
  caddy_data:
  caddy_config:

networks:
    caddy_network:
        external: true

d. My complete Caddy config:

{
	debug
}

danielowy.duckdns.org {
	reverse_proxy jellyfin:8096
	tls {
		dns duckdns (123)
	}
}

5. Links to relevant resources:

https://blog.gurucomputing.com.au/Reverse%20Proxies%20with%20Caddy/Introduction/

Where did you run that? You should run it in the same directory that your docker-compose.yml is found.

I think this issue might be fixed in the latest Caddy version, i.e. v2.8.0-rc.1. To use that version you can change your Dockerfile to use caddy:2.8.0-rc.1-builder-alpine, and caddy:2.8.0-rc.1-alpine instead of caddy:latest.

FYI I don’t think you’ll need Authentik, Jellyfin has its own authentication. You can just use that.

1 Like

Thanks for replying. I’ve updated Caddy, docker-compose exec caddy caddy version returns v2.8.0-rc.1 h1:OkAxqZMDUVP7jGtEpE+sh1NJTv9CkFWsopEmZ2eWAFc=. Still failing. Logs below

2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.893346,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.894258,"msg":"adapted config to JSON","adapter":"caddyfile"}
2024-05-24 17:36:46 caddy-1  | {"level":"warn","ts":1716565006.8942757,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":10}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.894821,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8949618,"logger":"http.auto_https","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}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.894981,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
2024-05-24 17:36:46 caddy-1  | {"level":"debug","ts":1716565006.8949962,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{"subjects":["danielowy.duckdns.org"]},{}]}},"http":{"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"jellyfin:8096"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8950589,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc00037aa80"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8952389,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8953152,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
2024-05-24 17:36:46 caddy-1  | {"level":"debug","ts":1716565006.895424,"logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":true}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8954556,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
2024-05-24 17:36:46 caddy-1  | {"level":"debug","ts":1716565006.8954816,"logger":"http","msg":"starting server loop","address":"[::]:80","tls":false,"http3":false}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8954988,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8955019,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["danielowy.duckdns.org"]}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8957605,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8957822,"msg":"serving initial configuration"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8960438,"logger":"tls.obtain","msg":"acquiring lock","identifier":"danielowy.duckdns.org"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.897283,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"3e553092-fbc6-4db7-914c-667624d37dda","try_again":1716651406.8972821,"try_again_in":86399.99999976}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8974748,"logger":"tls","msg":"finished cleaning storage units"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.898599,"logger":"tls.obtain","msg":"lock acquired","identifier":"danielowy.duckdns.org"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8986502,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"danielowy.duckdns.org"}
2024-05-24 17:36:46 caddy-1  | {"level":"debug","ts":1716565006.8987105,"logger":"events","msg":"event","name":"cert_obtaining","id":"4433ac18-4445-41d2-b85b-345a74de7bd6","origin":"tls","data":{"identifier":"danielowy.duckdns.org"}}
2024-05-24 17:36:46 caddy-1  | {"level":"debug","ts":1716565006.8988466,"logger":"tls.obtain","msg":"trying issuer 1/1","issuer":"acme-v02.api.letsencrypt.org-directory"}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8990653,"logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["danielowy.duckdns.org"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8990767,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["danielowy.duckdns.org"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
2024-05-24 17:36:46 caddy-1  | {"level":"info","ts":1716565006.8990836,"logger":"tls.issuance.acme","msg":"using ACME account","account_id":"https://acme-v02.api.letsencrypt.org/acme/acct/1741042762","account_contact":[]}
2024-05-24 17:36:47 caddy-1  | {"level":"debug","ts":1716565007.5786018,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"GET","url":"https://acme-v02.api.letsencrypt.org/directory","headers":{"User-Agent":["Caddy/2.8.0-rc.1 CertMagic acmez (linux; amd64)"]},"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["746"],"Content-Type":["application/json"],"Date":["Fri, 24 May 2024 15:36:46 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-05-24 17:36:47 caddy-1  | {"level":"debug","ts":1716565007.5787737,"logger":"tls.issuance.acme.acme_client","msg":"creating order","account":"https://acme-v02.api.letsencrypt.org/acme/acct/1741042762","identifiers":["danielowy.duckdns.org"]}
2024-05-24 17:36:47 caddy-1  | {"level":"debug","ts":1716565007.8017395,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"HEAD","url":"https://acme-v02.api.letsencrypt.org/acme/new-nonce","headers":{"User-Agent":["Caddy/2.8.0-rc.1 CertMagic acmez (linux; amd64)"]},"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Date":["Fri, 24 May 2024 15:36:46 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["tHmr_zjyh7vNVFtDazJ94gJYW0WgceeLiODGafuf9tYYHacURGg"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-05-24 17:36:48 caddy-1  | {"level":"debug","ts":1716565008.170689,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/new-order","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.0-rc.1 CertMagic acmez (linux; amd64)"]},"response_headers":{"Boulder-Requester":["1741042762"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["347"],"Content-Type":["application/json"],"Date":["Fri, 24 May 2024 15:36:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/1741042762/272207318172"],"Replay-Nonce":["rOJGG1BXzRSypiRIRY0kCnE7BHoDXV5HLx56lPQNCffCOz5P6bo"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":201}
2024-05-24 17:36:48 caddy-1  | {"level":"debug","ts":1716565008.3888905,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/354891593772","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.0-rc.1 CertMagic acmez (linux; amd64)"]},"response_headers":{"Boulder-Requester":["1741042762"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["805"],"Content-Type":["application/json"],"Date":["Fri, 24 May 2024 15:36:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["rOJGG1BXcgLF2GFg4tBmImQmOdtN_1XHGDUdHhn0jPQ0hwAC5tA"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-05-24 17:36:48 caddy-1  | {"level":"info","ts":1716565008.3890378,"logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"danielowy.duckdns.org","challenge_type":"dns-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
2024-05-24 17:36:49 caddy-1  | {"level":"error","ts":1716565009.0559106,"logger":"tls.issuance.acme.acme_client","msg":"cleaning up solver","identifier":"danielowy.duckdns.org","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.danielowy.duckdns.org\" (usually OK if presenting also failed)"}
2024-05-24 17:36:49 caddy-1  | {"level":"debug","ts":1716565009.2917478,"logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/354891593772","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.0-rc.1 CertMagic acmez (linux; amd64)"]},"response_headers":{"Boulder-Requester":["1741042762"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["809"],"Content-Type":["application/json"],"Date":["Fri, 24 May 2024 15:36:48 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["tHmr_zjyJ4p2vg7ZH5-25gBFIFlr19ic-hF29fbW-qU5aXqdxiM"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-05-24 17:36:49 caddy-1  | {"level":"error","ts":1716565009.2918804,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"danielowy.duckdns.org","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[danielowy.duckdns.org] solving challenges: presenting for challenge: adding temporary record for zone \"duckdns.org.\": DuckDNS request failed, expected (OK) but got (KO), url: [https://www.duckdns.org/update?domains=danielowy.duckdns.org&token=%123456&txt=shokBjr1bpioBLjvQaMEKI9O8t-ZuOZppXA3Odad1Wg&verbose=true], body: KO (order=https://acme-v02.api.letsencrypt.org/acme/order/1741042762/272207318172) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
2024-05-24 17:36:49 caddy-1  | {"level":"debug","ts":1716565009.29195,"logger":"events","msg":"event","name":"cert_failed","id":"10e85087-ad7d-4ee9-8a68-1b4718421137","origin":"tls","data":{"error":{},"identifier":"danielowy.duckdns.org","issuers":["acme-v02.api.letsencrypt.org-directory"],"renewal":false}}
2024-05-24 17:36:49 caddy-1  | {"level":"error","ts":1716565009.2919602,"logger":"tls.obtain","msg":"will retry","error":"[danielowy.duckdns.org] Obtain: [danielowy.duckdns.org] solving challenges: presenting for challenge: adding temporary record for zone \"duckdns.org.\": DuckDNS request failed, expected (OK) but got (KO), url: [https://www.duckdns.org/update?domains=danielowy.duckdns.org&token=%123456&txt=shokBjr1bpioBLjvQaMEKI9O8t-ZuOZppXA3Odad1Wg&verbose=true], body: KO (order=https://acme-v02.api.letsencrypt.org/acme/order/1741042762/272207318172) (ca=https://acme-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":2.393713692,"max_duration":2592000}

Are you sure your token is correct? It should be 36 hex characters with - in between.

I’ve redacted the token in the logs, thought it’s sensitive info. The actual token is exactly 36 hex chars, including -, copy-pasted from DuckDNS website. Any chance something’s wrong with router config?

I don’t see any issue with your setup :man_shrugging: I think DuckDNS might be having an outage or something.

What do you get if you try to hit that URL that’s in logs by hand? Do you get KO from that too?

The DuckDNS API is super simple (too simple tbh) so if it rejects the request, it’s hard to blame the plugin. There’s really not much going on. See Duck DNS - spec

1 Like

I’m still messing around with all of this so I’ll keep the topic open, but for anyone having the same problem, here’s the solution Francis came up with on discord:

Turns out I didn’t understand the networking properly. When you use DDNS as a form of static IP (config your router and DDNS account for that), and open ports 80, 443 (port forward them on router), you don’t have to put TLS in config file nor use DDNS provider module. I’ve removed the DuckDNS module, removed TLS from reverseproxy config and it worked - no error, website appeared publicly encrypted with HTTPS.

Also speaking of DuckDNS, I’ve noticed it sometimes assigns a wrong, seemingly random IP. Switched to no-ip.com DDNS just to be sure, works flawlessly so far.

1 Like

That doesn’t make sense. How are you setting the IP, exactly? You can always confirm what your IP is by googling “what is my IP”. Are you sure your ISP isn’t just changing the IP semi-frequently?

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.