This is more of a question than a support request. I couldn’t find a better suited Category, hence posting here. ( Community moderators, feel free to move this topic elsewhere if deemed fit )
There are host matchers all over the place. Almost to the point of confusion.
In my very little usage so far, I’ve come across at least 3 places :
-
apps.https.servers[*].routes[*].match[*].host[*]
; then there’s the same thing inside of thesubroute
handler ( obviously, because nesting is cool ) apps.https.servers[*].tls_connection_policies[*].match.sni[*]
apps.tls.automation.policies[*].subjects[*]
And the best part is that all of these trigger automatic HTTPS ( if enabled ).
Now, here’s my question : what if I didn’t want automatic HTTPS to trigger on one of these? viz, on apps.https.servers[*].routes[*].match[*].host[*]
I get the part that we need to trigger automatic HTTPS from anywhere where there is a host match ( because that is the USP of caddy, right? ). However, I think that triggering it on apps.https.servers[*].routes[*].match[*].host[*]
is kind of over-kill if apps.https.servers[*].tls_connection_policies[*].match.sni[*]
and apps.tls.automation.policies[*].subjects[*]
are already present in the configuration. Here’s an example configuration :
{
"apps" : {
"http" : {
"servers" : {
"caddy.test.shinenelson.xyz" : {
"listen" : [
":80",
":443"
],
"automatic_https" : {
"disable_redirects" : true
},
"routes" : [
{
"group" : "shine",
"match" : [
{
"host" : [
"shine.caddy.test.shinenelson.xyz"
]
}
],
"handle" : [
{
"handler" : "static_response",
"body": "Hi there, love from shine and Caddy!"
}
],
"terminal" : true
},
{
"group" : "shine",
"match" : [
{
"host" : [
"*.shine.caddy.test.shinenelson.xyz"
]
}
],
"handle": [
{
"@id" : "proxy_shine",
"handler" : "reverse_proxy",
"upstreams" : [
{
"dial" : "localhost:8080"
},
{
"dial" : "localhost:8081"
}
]
},
{
"handler": "static_response",
"body" : "hey, you were not supposed to get here. - shine"
}
],
"terminal" : true
},
{
"group" : "shine",
"@id" : "static_shine",
"terminal" : true
}
],
"tls_connection_policies" : [
{
"match" : {
"sni" : [
"shine.caddy.test.shinenelson.xyz",
"*.shine.caddy.test.shinenelson.xyz",
]
}
}
]
}
}
},
"tls" : {
"automation" : {
"policies" : [
{
"subjects" : [
"shine.caddy.test.shinenelson.xyz",
"*.shine.caddy.test.shinenelson.xyz"
],
"issuer" : {
"module" : "acme",
"ca" : "https://acme-staging-v02.api.letsencrypt.org/directory",
"challenges" : {
"dns" : {
"provider" : "digitalocean",
"auth_token" : "[REDACTED]"
}
}
}
}
]
}
}
}
}
( PS : I’ve posted different iterations of the same configuration in another thread )
With the above configuration, on caddy run
, the automatic HTTPS trigger kicks in and fetches the TLS certificates for the SNIs - shine.caddy.test.shinenelson.xyz
and *.shine.caddy.test.shinenelson.xyz
per the apps.tls.automation.policies[*].subjects[*]
( and caches the certificates in memory as well? ) which is all well and good. That’s how it is supposed to be.
The last route with "@id" : "static_shine"
is put in dynamically via the admin API. The curl
request for that is :
curl -sSL -X PATCH -H 'Content-Type: application/json' -d "{ \"group\" : \"shine\", \"@id\" : \"shine\", \"match\" : [ { \"host\" : [ \"static.shine.caddy.test.shinenelson.xyz\" ] } ], \"handle\": [ { \"handler\" : \"static_response\", \"body\" : \"static_reponse. much wow. - shine\", \"terminal\" : true }" localhost:2019/load
PS : I’ve unfurled the data into the curl
command by hand. I’m actually passing it from a shell script that generates the JSON payload. The shell script itself doesn’t do anything fancy except take some user environment parameters and puts them in the configuration ( everywhere you find shine
above came from whoami
, etc ).
As soon as I load this new configuration in, caddy server validates the configuration and reloads. This time however, it sees there’s a new host ( static.shine.caddy.test.shinenelson.xyz
) in the matchers and tries to fetch a new certificate for the new host.
Ideally, it should look for a TLS certificate that’s already available and see whether the new host matches any of the existing TLS certificates before attempting to fetch a new certificate for the host.
Especially, in this case, static.shine.caddy.test.shinenelson.xyz
matches the wildcard certificate for *.shine.caddy.test.shinenelson.xyz
. The reason I got a wildcard certificate in the first place was to avoid the overhead of requesting new certificates and hitting Let’s Encrypt’s rate limits ( contrary to my earlier request for the on-demand wildcard TLS certificates. I was unaware of the abuse vector there at that point ).
Is this a valid question? Or am I missing some configuration magic that I fail to understand here?