Can I use Caddy to pull certs for LAN only custom domains?

1. The problem I’m having:

I would like to host vaultwarden on my LAN and Tailnet only. But it does require a cert to run. Ideally I would get certs both for its custom domain in my DNS “vaultwarden.house” and its IP address.

2. Error messages and/or full log output:

s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service init-perms: starting
s6-rc: info: service init-perms successfully started
s6-rc: info: service init-secrets: starting
s6-rc: info: service init-secrets successfully started
s6-rc: info: service init-setup: starting
s6-rc: info: service init-setup successfully started
s6-rc: info: service init-setup-app: starting
s6-rc: info: service init-setup-app successfully started
s6-rc: info: service init-wireguard: starting
s6-rc: info: service init-wireguard successfully started
s6-rc: info: service service-caddy: starting
s6-rc: info: service service-caddy successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
{"level":"info","ts":1740078188.9225054,"msg":"using config from file","file":"/config/Caddyfile"}
{"level":"info","ts":1740078188.9228978,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"info","ts":1740078188.9250696,"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":1740078188.9251971,"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":1740078188.9252071,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1740078188.9252489,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000697b80"}
{"level":"info","ts":1740078188.9253843,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1740078188.9257417,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"warn","ts":1740078188.925773,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"warn","ts":1740078188.9257758,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"info","ts":1740078188.9257777,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1740078188.9257798,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["vaultwarden.house"]}
{"level":"info","ts":1740078188.9262793,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1740078188.9262972,"msg":"serving initial configuration"}
{"level":"info","ts":1740078188.9271572,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/config/caddy"}
{"level":"info","ts":1740078188.9274483,"logger":"tls.obtain","msg":"acquiring lock","identifier":"vaultwarden.house"}
{"level":"info","ts":1740078188.9278388,"logger":"tls.obtain","msg":"lock acquired","identifier":"vaultwarden.house"}
{"level":"info","ts":1740078188.9280157,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"vaultwarden.house"}
{"level":"info","ts":1740078188.928171,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1740078188.9284344,"logger":"http","msg":"creating new account because no account for configured email is known to us","email":"","ca":"https://acme-v02.api.letsencrypt.org/directory","error":"open /config/caddy/acme/acme-v02.api.letsencrypt.org-directory/users/default/default.json: no such file or directory"}
{"level":"info","ts":1740078188.9284632,"logger":"http","msg":"ACME account has empty status; registering account with ACME server","contact":[],"location":""}
{"level":"info","ts":1740078188.9289124,"logger":"http","msg":"creating new account because no account for configured email is known to us","email":"","ca":"https://acme-v02.api.letsencrypt.org/directory","error":"open /config/caddy/acme/acme-v02.api.letsencrypt.org-directory/users/default/default.json: no such file or directory"}
{"level":"info","ts":1740078189.100703,"logger":"http","msg":"new ACME account registered","contact":[],"status":"valid"}
{"level":"info","ts":1740078189.1093051,"logger":"http","msg":"waiting on internal rate limiter","identifiers":["vaultwarden.house"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
{"level":"info","ts":1740078189.1093311,"logger":"http","msg":"done waiting on internal rate limiter","identifiers":["vaultwarden.house"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
{"level":"info","ts":1740078189.1093698,"logger":"http","msg":"using ACME account","account_id":"https://acme-v02.api.letsencrypt.org/acme/acct/2240528595","account_contact":[]}
{"level":"info","ts":1740078189.2095022,"msg":"trying to solve challenge","identifier":"vaultwarden.house","challenge_type":"http-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
{"level":"error","ts":1740078189.550019,"msg":"challenge failed","identifier":"vaultwarden.house","challenge_type":"http-01","problem":{"type":"urn:ietf:params:acme:error:dns","title":"","detail":"DNS problem: NXDOMAIN looking up A for vaultwarden.house - check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for vaultwarden.house - check that a DNS record exists for this domain","instance":"","subproblems":null},"stacktrace":"github.com/mholt/acmez/v3.(*Client).pollAuthorization\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:557\ngithub.com/mholt/acmez/v3.(*Client).solveChallenges\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:378\ngithub.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:136\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:371\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/acmeissuer.go:249\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).manageOne.func1\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:415\ngithub.com/caddyserver/certmagic.(*jobManager).worker\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:73"}
{"level":"error","ts":1740078189.5500805,"msg":"validating authorization","identifier":"vaultwarden.house","problem":{"type":"urn:ietf:params:acme:error:dns","title":"","detail":"DNS problem: NXDOMAIN looking up A for vaultwarden.house - check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for vaultwarden.house - check that a DNS record exists for this domain","instance":"","subproblems":null},"order":"https://acme-v02.api.letsencrypt.org/acme/order/2240528595/356375761165","attempt":1,"max_attempts":3,"stacktrace":"github.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:152\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:371\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/acmeissuer.go:249\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).manageOne.func1\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:415\ngithub.com/caddyserver/certmagic.(*jobManager).worker\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:73"}
{"level":"info","ts":1740078190.6544921,"msg":"trying to solve challenge","identifier":"vaultwarden.house","challenge_type":"tls-alpn-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
{"level":"error","ts":1740078190.967189,"msg":"challenge failed","identifier":"vaultwarden.house","challenge_type":"tls-alpn-01","problem":{"type":"urn:ietf:params:acme:error:dns","title":"","detail":"DNS problem: NXDOMAIN looking up A for vaultwarden.house - check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for vaultwarden.house - check that a DNS record exists for this domain","instance":"","subproblems":null},"stacktrace":"github.com/mholt/acmez/v3.(*Client).pollAuthorization\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:557\ngithub.com/mholt/acmez/v3.(*Client).solveChallenges\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:378\ngithub.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:136\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:371\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/acmeissuer.go:249\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).manageOne.func1\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:415\ngithub.com/caddyserver/certmagic.(*jobManager).worker\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:73"}
{"level":"error","ts":1740078190.9672632,"msg":"validating authorization","identifier":"vaultwarden.house","problem":{"type":"urn:ietf:params:acme:error:dns","title":"","detail":"DNS problem: NXDOMAIN looking up A for vaultwarden.house - check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for vaultwarden.house - check that a DNS record exists for this domain","instance":"","subproblems":null},"order":"https://acme-v02.api.letsencrypt.org/acme/order/2240528595/356375766805","attempt":2,"max_attempts":3,"stacktrace":"github.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:152\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:371\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/acmeissuer.go:249\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).manageOne.func1\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:415\ngithub.com/caddyserver/certmagic.(*jobManager).worker\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:73"}
{"level":"error","ts":1740078190.9673014,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"vaultwarden.house","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 400 urn:ietf:params:acme:error:dns - DNS problem: NXDOMAIN looking up A for vaultwarden.house - check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for vaultwarden.house - check that a DNS record exists for this domain"}
{"level":"error","ts":1740078190.9673264,"logger":"tls.obtain","msg":"will retry","error":"[vaultwarden.house] Obtain: [vaultwarden.house] solving challenge: vaultwarden.house: [vaultwarden.house] authorization failed: HTTP 400 urn:ietf:params:acme:error:dns - DNS problem: NXDOMAIN looking up A for vaultwarden.house - check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for vaultwarden.house - check that a DNS record exists for this domain (ca=https://acme-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":2.039481867,"max_duration":2592000}

3. Caddy version:

latest

4. How I installed and ran Caddy:

Unraid hotio docker image

a. System environment:

Unraid 6.12 with Docker

d. My complete Caddy config:

vaultwarden.house {
        respond "Site not served from here"
}

Caddy only supports automatic SSL certificates in combination with tailscale when *.ts.net domains are used

1 Like

Here is a code block that I do that works for me.

subdomain.example.com {
        @denied not client_ip 10.1.0.0/16 10.201.201.0/24
        abort @denied
        reverse_proxy 10.0.254.10:8043 {
        transport http {
                tls
                tls_insecure_skip_verify
        }
    }
}

I have to make it publicly accessible, but then I block any traffic not coming from my internal LAN. the transport http is not needed for what you are asking about, but I left them in since the are in my config.

Thanks - I guess I can try that although i wish there was just way to get a pure LAN cert without setting up my own cert server.

[This is the information on local HTTPS].

Assuming Caddy’s container knows that hostname as the local IP, you should be able to that hostname as localhost. Caddy should be able to generate a local cert for it.

Another option is to use a free domain service like DuckDNS, which would need the corresponding module for it to get a Let’sEncrypt cert.