1. The problem I’m having:
I am trying to configure caddy to work with on-demand TLS for a set of wildcard subdomains AND also with normal automatic certificates for a specific subdomain known in advance. In other words I want one specific hostname (sub.gpp.garden) to use the default automatic HTTPS, and I want every other hostname (e.g. gpp.gpp.garden) to use on_demand_tls
. I have defined an ask
endpoint, and the on-demand endpoints actually work great! The issue is the endpoint that DOESN’T use on-demand tls, i.e sub.gpp.garden, see Caddyfile at the bottom
Actually while writing this I tried the solution in this post [On Demand TLS for the front-end only], where instead of using wildcards they matched https://
, and that actually worked! So I guess my issue is basically solved, but I’d be interested to know why exactly the other way doesn’t work (unless using a catch-all like https:// can also lead to issues)
2. Error messages and/or full log output:
> curl -vL https://sub.gpp.garden
* Host sub.gpp.garden:443 was resolved.
* IPv6: (none)
* IPv4: 157.180.126.12
* Trying 157.180.126.12:443...
* Connected to sub.gpp.garden (157.180.126.12) port 443
* ALPN: curl 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.13: error:0A000438:SSL routines::tlsv1 alert internal error
* Closing connection
curl: (35) OpenSSL/3.0.13: error:0A000438:SSL routines::tlsv1 alert internal error
{"level":"info","ts":1759768416.7432668,"msg":"maxprocs: Leaving GOMAXPROCS=2: CPU quota undefined"}
{"level":"info","ts":1759768416.7435856,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":3605007974,"previous":9223372036854775807}
{"level":"info","ts":1759768416.7436604,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1759768416.7462163,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"info","ts":1759768416.7485256,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1759768416.7491105,"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}
{"level":"info","ts":1759768416.7492373,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1759768416.7491288,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0005f0980"}
{"level":"debug","ts":1759768416.7494326,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{"subjects":["sub.gpp.garden"]},{"subjects":["*.gpp.garden","gpp.garden"],"on_demand":true},{}],"on_demand":{}}},"http":{"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"body":"{http.request.host}","handler":"static_response"}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"body":"{http.request.host}","handler":"static_response"}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
{"level":"debug","ts":1759768416.7498596,"logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":false}
{"level":"info","ts":1759768416.7499595,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1759768416.7502544,"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."}
{"level":"info","ts":1759768416.7505631,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"debug","ts":1759768416.7507508,"logger":"http","msg":"starting server loop","address":"[::]:80","tls":false,"http3":false}
{"level":"warn","ts":1759768416.7508128,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"warn","ts":1759768416.7508342,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"info","ts":1759768416.750851,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1759768416.750908,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["sub.gpp.garden","*.gpp.garden","gpp.garden"]}
{"level":"debug","ts":1759768416.7510214,"logger":"events","msg":"event","name":"started","id":"656b31e9-5ba4-451e-9efa-e61620e0117a","origin":"","data":null}
{"level":"info","ts":1759768416.75142,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1759768416.751475,"msg":"serving initial configuration"}
{"level":"info","ts":1759768416.753164,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"95f3e742-1cd4-4ede-ab6d-20b444c5c009","try_again":1759854816.7531605,"try_again_in":86399.999999438}
{"level":"info","ts":1759768416.7532907,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"debug","ts":1759768424.558122,"logger":"events","msg":"event","name":"tls_get_certificate","id":"899e5cc2-ec2a-4112-8e5c-51b8f73764a9","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4867,4866,49195,49199,52393,52392,49196,49200,49162,49161,49171,49172,156,157,47,53],"ServerName":"sub.gpp.garden","SupportedCurves":[4588,29,23,24,25,256,257],"SupportedPoints":"AA==","SignatureSchemes":[1027,1283,1539,2052,2053,2054,1025,1281,1537,515,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"45.92.33.168","Port":39633,"Zone":""},"LocalAddr":{"IP":"157.180.126.12","Port":443,"Zone":""}}}}
{"level":"debug","ts":1759768424.5583076,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"sub.gpp.garden"}
{"level":"debug","ts":1759768424.558315,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.gpp.garden"}
{"level":"debug","ts":1759768424.5583181,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*.garden"}
{"level":"debug","ts":1759768424.5583212,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*.*"}
{"level":"debug","ts":1759768424.5583634,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"45.92.33.168","remote_port":"39633","server_name":"sub.gpp.garden","remote":"45.92.33.168:39633","identifier":"sub.gpp.garden","cipher_suites":[4865,4867,4866,49195,49199,52393,52392,49196,49200,49162,49161,49171,49172,156,157,47,53],"cert_cache_fill":0,"load_or_obtain_if_necessary":true,"on_demand":false}
{"level":"debug","ts":1759768424.5584762,"logger":"http.stdlib","msg":"http: TLS handshake error from 45.92.33.168:39633: no certificate available for 'sub.gpp.garden'"}
{"level":"debug","ts":1759768424.8022497,"logger":"events","msg":"event","name":"tls_get_certificate","id":"3afc1e38-8f34-44f5-aac2-cdddb27972af","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4867,4866,49195,49199,52393,52392,49196,49200,49162,49161,49171,49172,156,157,47,53],"ServerName":"sub.gpp.garden","SupportedCurves":[29,23,24,25,256,257],"SupportedPoints":"AA==","SignatureSchemes":[1027,1283,1539,2052,2053,2054,1025,1281,1537,515,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"45.92.33.168","Port":59530,"Zone":""},"LocalAddr":{"IP":"157.180.126.12","Port":443,"Zone":""}}}}
{"level":"debug","ts":1759768424.802429,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"sub.gpp.garden"}
{"level":"debug","ts":1759768424.8024473,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.gpp.garden"}
{"level":"debug","ts":1759768424.8024783,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*.garden"}
{"level":"debug","ts":1759768424.8024883,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*.*"}
{"level":"debug","ts":1759768424.8025143,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"45.92.33.168","remote_port":"59530","server_name":"sub.gpp.garden","remote":"45.92.33.168:59530","identifier":"sub.gpp.garden","cipher_suites":[4865,4867,4866,49195,49199,52393,52392,49196,49200,49162,49161,49171,49172,156,157,47,53],"cert_cache_fill":0,"load_or_obtain_if_necessary":true,"on_demand":false}
{"level":"debug","ts":1759768424.802716,"logger":"http.stdlib","msg":"http: TLS handshake error from 45.92.33.168:59530: no certificate available for 'sub.gpp.garden'"}
3. Caddy version:
4. How I installed and ran Caddy:
a. System environment:
Running Ubuntu 24.04.3 with Docker:
version: '3.9'
services:
caddy:
container_name: caddy
image: caddy:2
network_mode: host
restart: unless-stopped
volumes:
- type: bind
source: ./caddy/data
target: /data
- type: bind
source: ./caddy/etc/caddy
target: /etc/caddy
d. My complete Caddy config:
{
email my@email.com
on_demand_tls {
ask http://localhost:3000/tls-check
}
}
sub.gpp.garden {
respond "A response: {http.request.host}"
}
*.gpp.garden, gpp.garden {
tls {
on_demand
}
respond "A different response: {http.request.host}"
}