I’ve a Raspberry Pi with a setup including PiHole and caddy.
PiHole serves as local DNS server for the network, and caddy is used as reverse proxy on a generic corresponding service.
Example:
- (DNS record set)
192.168.2.71 nextcloud.foo.duckdns.org
- (Caddyfile)
nextcloud.foo.duckdns.org { reverse_proxy localhost:11000 }
$ curl --head --verbose https://nextcloud.foo.duckdns.org
* Trying [2a02:a458:814f:0:a438:1aab:a24:12f7]:443...
* Trying 192.168.2.71:443...
* Connected to nextcloud.foo.duckdns.org (192.168.2.71) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN: server accepted h2
* Server certificate:
* subject: CN=nextcloud.foo.duckdns.org
* start date: May 1 05:58:44 2024 GMT
* expire date: Jul 30 05:58:43 2024 GMT
* subjectAltName: host "nextcloud.foo.duckdns.org" matched cert's "nextcloud.foo.duckdns.org"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
In the Caddyfile I also have a global option/block, { acme_dns duckdns <my-token> }
, and I’ve also generated a valid certificate with Let’s Encrypt using this guide: https://github.com/infinityofspace/certbot_dns_duckdns?tab=readme-ov-file#usage
This certificate includes both “foo.duckdns.org” and “*.foo.duckdns.org” as domains.
Now, however, I set up another service, home-assistant, and I added an entry in the Caddyfile, that is homeassistant.foo.duckdns.org { reverse_proxy localhost:8123 }
.
The issue is that the TLS handshake fails, and thus the HTTPS request.
curl --head --verbose https://homeassistant.foo.duckdns.org
* Trying 192.168.2.71:443...
* Connected to homeassistant.foo.duckdns.org (192.168.2.71) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS alert, internal error (592):
* OpenSSL/3.0.11: error:0A000438:SSL routines::tlsv1 alert internal error
* Closing connection 0
curl: (35) OpenSSL/3.0.11: error:0A000438:SSL routines::tlsv1 alert internal error
I’m still able to access the service via the localhost interface, though.
$ curl --verbose 192.168.2.71:8123
* Trying 192.168.2.71:8123...
* Connected to 192.168.2.71 (192.168.2.71) port 8123 (#0)
> GET / HTTP/1.1
> Host: 192.168.2.71:8123
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Referrer-Policy: no-referrer
< X-Content-Type-Options: nosniff
< Server:
< X-Frame-Options: SAMEORIGIN
< Content-Length: 4116
< Date: Sat, 04 May 2024 15:19:24 GMT
<
< HTML response
Why this difference? I also tried running sudo certbot renew but the tool says Certificate not yet due for renewal
The caddy logs related to this request are:
May 04 17:07:55 raspberrypi caddy[2499813]: {"level":"debug","ts":1714835275.669332,"logger":"http.stdlib","msg":"http: TLS handshake error from 172.24.0.8:52236: EOF"}
May 04 17:07:56 raspberrypi caddy[2499813]: {"level":"error","ts":1714835276.0812566,"logger":"tls.issuance.zerossl.acme_client","msg":"cleaning up solver","identifier":"homeassistant.foo.duckdns.org","challenge_type":"dns-01","error":"no memory of presenting a DNS record for "_acme-challenge.homeassistant.foo.duckdns.org" (usually OK if presenting also failed)"}
May 04 17:07:56 raspberrypi caddy[2499813]: {"level":"debug","ts":1714835276.4435985,"logger":"tls.issuance.zerossl.acme_client","msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/authz/PyhpCsoS_EhSSiEGi8UeIQ","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; arm64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["145"],"Content-Type":["application/json"],"Date":["Sat, 04 May 2024 15:07:56 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel="index""],"Replay-Nonce":["igkSNJLHTzdfI2aSomwLOusaK7Fz3HQEHXL8NYrFcWA"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
May 04 17:07:56 raspberrypi caddy[2499813]: {"level":"error","ts":1714835276.4437563,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"homeassistant.foo.duckdns.org","issuer":"acme.zerossl.com-v2-DV90","error":"[homeassistant.foo.duckdns.org] solving challenges: presenting for challenge: could not determine zone for domain "_acme-challenge.homeassistant.foo.duckdns.org": unexpected response code 'REFUSED' for _acme-challenge.homeassistant.foo.duckdns.org. (order=https://acme.zerossl.com/v2/DV90/order/uQxNVkgga-pcqKOgZWOJiA) (ca=https://acme.zerossl.com/v2/DV90)"}
May 04 17:07:56 raspberrypi caddy[2499813]: {"level":"debug","ts":1714835276.4437943,"logger":"events","msg":"event","name":"cert_failed","id":"9ff6162d-a94e-497f-aff9-5d068ddc2987","origin":"tls","data":{"error":{},"identifier":"homeassistant.foo.duckdns.org","issuers":["acme-v02.api.letsencrypt.org-directory","acme.zerossl.com-v2-DV90"],"renewal":false}}
May 04 17:07:56 raspberrypi caddy[2499813]: {"level":"error","ts":1714835276.4438388,"logger":"tls.obtain","msg":"will retry","error":"[homeassistant.foo.duckdns.org] Obtain: [homeassistant.foo.duckdns.org] solving challenges: presenting for challenge: could not determine zone for domain "_acme-challenge.homeassistant.foo.duckdns.org": unexpected response code 'REFUSED' for _acme-challenge.homeassistant.foo.duckdns.org. (order=https://acme.zerossl.com/v2/DV90/order/uQxNVkgga-pcqKOgZWOJiA) (ca=https://acme.zerossl.com/v2/DV90)","attempt":13,"retrying_in":1800,"elapsed":9168.216986793,"max_duration":2592000}