Summary
I’d like to use tls.get_certificate
function only for specific domains, while keeping the automatic HTTPS feature for other domains and Caddyfile
format.
I need to manage the same certificate in multiple instances (not only Caddy). For example, I need to get the certificate of domain.tld
and use it in multiple servers. The servers can be other types of TLS hosts aside from Caddy.
Caddy and system environment
Caddy compiled via: xcaddy build --with github.com/mastercactapus/proxyprotocol
with go1.21.3 is running on: the debian/bullseye (11) container in LXD host.
- v2.7.5 h1:HoysvZkLcN2xJExEepaFHK92Qgs7xAiCFydN5x5Hs6Q=
- debian/bullseye (11)
Failed workarounds
I tried to build a certificate server powered by dehydrated.sh
and distribute the certificate via http host. Then, I set the tls.get_certificate
config in Caddyfile
:
{
servers {
listener_wrappers {
proxy_protocol {
timeout 2s
allow 0.0.0.0/0
}
tls
}
}
}
domain.tld {
tls {
get_certificate http https://certificate_server/path/to/certificate.pem
}
}
otherdomain.tld {
reverse_proxy * internal-host:80
}
In this case, I thought Caddy should obtain the certificate from certificate_server
even they’re registered in automatic certificate management.
They did.
* Added domain.tld:443:x.x.x.x to DNS cache
* Hostname domain.tld was found in DNS cache
* Trying x.x.x.x:443...
* Connected to domain.tld (x.x.x.x) port 443 (#0)
* ALPN: offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN: server accepted h2
* Server certificate:
* subject: CN=domain.tld
* start date: Oct 12 05:37:54 2023 GMT
* expire date: Jan 10 05:37:53 2024 GMT
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* using HTTP/2
* h2 [:method: GET]
* h2 [:scheme: https]
* h2 [:authority: domain.tld]
* h2 [:path: /]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* Using Stream ID: 1 (easy handle 0x120014c00)
> GET / HTTP/2
> Host: domain.tld
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/2 302
HTTP/2 302
< alt-svc: h3=":443"; ma=2592000
alt-svc: h3=":443"; ma=2592000
< location: https://anotherlocation.domain.tld
location: https://anotherlocation.domain.tld
< server: Caddy
server: Caddy
< content-length: 0
content-length: 0
< date: Sat, 14 Oct 2023 14:03:46 GMT
date: Sat, 14 Oct 2023 14:03:46 GMT
<
* Connection #0 to host domain.tld left intact
However, the problem is that they served the certificate in other domains too. This means Caddy served the certificate from the certificate server defined in tls.get_certificate
instead of using acme
.
130 % curl https://otherdomain.tld
curl: (60) SSL: no alternative certificate subject name matches target host name 'otherdomain.tld'
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.