Serve some subdomains to private ranges only, public for others

1. The problem I’m having:

I have a wildcard domain configured. I’m moving all my subdomains from their own blocks to matchers inside the wildcard block. There are some public-facing subdomains with public DNS A records, and some that are intended to be local only (with DNS A records only on my internal DNS server). If I manually add a hosts file entry to a remote machine with the “private” subdomain and my public IP address, the request gets served when I don’t want it to be.

A post I referenced did mention using abort but I thought that adding remote_ip private_ranges would mean it only gets served to private IPs, not all.
The post: Is it possible to have some subdomains on the public internet; some not?

Also a side question: Is it possible to just specify the encode parameters for all sub-domains by default?

2. Error messages and/or full log output:

Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: caddy.AppDataDir=/var/lib/caddy/.local/share/caddy
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: caddy.AppConfigDir=/var/lib/caddy/.config/caddy
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: caddy.ConfigAutosavePath=/var/lib/caddy/.config/caddy/autosave.json
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: caddy.Version=v2.6.3 h1:QRVBNIqfpqZ1eJacY44I6eUC1OcxQ8D04EKImzpj7S8=
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: runtime.GOOS=linux
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: runtime.GOARCH=amd64
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: runtime.Compiler=gc
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: runtime.NumCPU=8
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: runtime.GOMAXPROCS=8
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: runtime.Version=go1.19.2
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: os.Getwd=/
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: LANG=en_CA.UTF-8
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: LANGUAGE=en_CA:en
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: NOTIFY_SOCKET=/run/systemd/notify
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: HOME=/var/lib/caddy
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: LOGNAME=caddy
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: USER=caddy
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: INVOCATION_ID=8d588955671a467aa092f9ade2b341ac
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: JOURNAL_STREAM=8:42625683
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: PDNS_API_KEY=foobar
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: PDNS_API_URL=https://foobar.com/dns
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383684.823004,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":""}
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383684.825807,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
Feb 25 22:54:44 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383684.8260224,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000295030"}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0173032,"logger":"http","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}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.017334,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0179658,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0179882,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/var/lib/caddy/.local/share/caddy"}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0180364,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size for details."}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383685.0181286,"logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":true}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0181453,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383685.018187,"logger":"http","msg":"starting server loop","address":"[::]:80","tls":false,"http3":false}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0182016,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0182085,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["*.lavado.ca"]}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383685.0185883,"logger":"tls","msg":"loading managed certificate","domain":"*.lavado.ca","expiration":1680245886,"issuer_key":"acme-v02.api.letsencrypt.org-directory","storage":"FileStorage:/var/lib/caddy/.local/share/caddy"}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383685.0188403,"logger":"tls.cache","msg":"added certificate to cache","subjects":["*.lavado.ca"],"expiration":1680245886,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"82aa1bd26105c512f842c29717887b237abc9060d70747a950366736321e0430","cache_size":1,"cache_capacity":10000}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383685.018865,"logger":"events","msg":"event","name":"cached_managed_cert","id":"f6073ca8-4190-425b-9ba1-ebc1e7061daa","origin":"tls","data":{"sans":["*.lavado.ca"]}}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0190334,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.01909,"msg":"serving initial configuration"}
Feb 25 22:54:45 teneo.lavado.ca systemd[1]: Started Caddy.
Feb 25 22:54:45 teneo.lavado.ca caddy[2028373]: {"level":"info","ts":1677383685.0202284,"logger":"tls","msg":"finished cleaning storage units"}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.2871609,"logger":"events","msg":"event","name":"tls_get_certificate","id":"7317123d-5375-4278-a7e3-f94a9d3c1160","origin":"tls","data":{"client_hello":{"CipherSuites":[4866,4867,4865,49196,49200,49195,49199,52393,52392,159,158,52394,49327,49325,49326,49324,49188,49192,49187,49191,49162,49172,49161,49171,49315,49311,49314,49310,107,103,57,51,157,156,49313,49309,49312,49308,61,60,53,47,255],"ServerName":"video.lavado.ca","SupportedCurves":[29,23,30,25,24],"SupportedPoints":"AAEC","SignatureSchemes":[1027,1283,1539,2055,2056,2057,2058,2059,2052,2053,2054,1025,1281,1537,771,769,770,1026,1282,1538],"SupportedProtos":["http/1.1"],"SupportedVersions":[772,771],"Conn":{}}}}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.2872932,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"video.lavado.ca"}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.2873018,"logger":"tls.handshake","msg":"choosing certificate","identifier":"*.lavado.ca","num_choices":1}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.2873142,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"*.lavado.ca","subjects":["*.lavado.ca"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"82aa1bd26105c512f842c29717887b237abc9060d70747a950366736321e0430"}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.2873244,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"192.168.0.150","remote_port":"45440","subjects":["*.lavado.ca"],"managed":true,"expiration":1680245886,"hash":"82aa1bd26105c512f842c29717887b237abc9060d70747a950366736321e0430"}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.2888649,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"127.0.0.1:8096","total_upstreams":1}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.2977817,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"127.0.0.1:8096","duration":0.008875244,"request":{"remote_ip":"192.168.0.150","remote_port":"45440","proto":"HTTP/1.1","method":"GET","host":"video.lavado.ca","uri":"/Sessions","headers":{"Accept":["*/*"],"X-Mediabrowser-Token":["foobar"],"Accept-Charset":["UTF-8,*"],"User-Agent":["Home-Assistant/2023.2.5"],"X-Forwarded-For":["192.168.0.150"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["video.lavado.ca"],"Accept-Encoding":["gzip"],"Content-Type":["application/json"],"X-Emby-Authorization":["MediaBrowser Client=Home Assistant, Device=Willow, DeviceId=93b802f6db46ecfce24c09be0fd3a660, Version=2023.2.5, UserId=099d45bc90a248299196e6b3ae3254a7"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"http/1.1","server_name":"video.lavado.ca"}},"headers":{"Content-Type":["application/json; charset=utf-8"],"Date":["Sun, 26 Feb 2023 03:54:49 GMT"],"Server":["Kestrel"],"X-Response-Time-Ms":["8"]},"status":200}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.9529855,"logger":"events","msg":"event","name":"tls_get_certificate","id":"7d91ca82-3cfb-4b03-9d9c-7dd33087fc04","origin":"tls","data":{"client_hello":{"CipherSuites":[4866,4867,4865,49196,49200,159,52393,52392,52394,49195,49199,158,49188,49192,107,49187,49191,103,49162,49172,57,49161,49171,51,157,156,61,60,53,47,255],"ServerName":"esphome.lavado.ca","SupportedCurves":[29,23,30,25,24],"SupportedPoints":"AAEC","SignatureSchemes":[1027,1283,1539,2055,2056,2057,2058,2059,2052,2053,2054,1025,1281,1537,771,769,770,1026,1282,1538],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"Conn":{}}}}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.9530466,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"esphome.lavado.ca"}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.9530554,"logger":"tls.handshake","msg":"choosing certificate","identifier":"*.lavado.ca","num_choices":1}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.9530678,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"*.lavado.ca","subjects":["*.lavado.ca"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"82aa1bd26105c512f842c29717887b237abc9060d70747a950366736321e0430"}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.953077,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"68.183.204.193","remote_port":"37354","subjects":["*.lavado.ca"],"managed":true,"expiration":1680245886,"hash":"82aa1bd26105c512f842c29717887b237abc9060d70747a950366736321e0430"}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.9660816,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"127.0.0.1:6052","total_upstreams":1}
Feb 25 22:54:50 teneo.lavado.ca caddy[2028373]: {"level":"debug","ts":1677383690.9672742,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"127.0.0.1:6052","duration":0.001154467,"request":{"remote_ip":"68.183.204.193","remote_port":"37354","proto":"HTTP/2.0","method":"GET","host":"esphome.lavado.ca","uri":"/","headers":{"User-Agent":["curl/7.74.0"],"Accept":["*/*"],"X-Forwarded-For":["68.183.204.193"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["esphome.lavado.ca"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"esphome.lavado.ca"}},"headers":{"Server":["TornadoServer/6.2"],"Date":["Sun, 26 Feb 2023 03:54:50 GMT"],"Etag":["\"e2bd1cbed1ac7e60c3f1caed48177ac04077ff37\""],"Content-Type":["text/html; charset=UTF-8"],"Content-Length":["755"]},"status":200}

3. Caddy version:

v2.6.3 h1:QRVBNIqfpqZ1eJacY44I6eUC1OcxQ8D04EKImzpj7S8=
I built it using xcaddy to include the deprecated lego provider.

Build command: xcaddy build --with github.com/caddy-dns/lego-deprecated

4. How I installed and ran Caddy:

a. System environment:

Debian 11 Bullseye

b. Command:

Since it’s a service:

sudo systemctl start caddy

c. Service/unit/compose file:

# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateDevices=yes
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
EnvironmentFile=/etc/default/caddy-conf

[Install]
WantedBy=multi-user.target

The Environment file contains (actual domain here is redacted as is key):

PDNS_API_KEY=foobar
PDNS_API_URL=https://foobar.com/dns

d. My complete Caddy config:

In this case, the esphome subdomain is intended to be access only locally, while the video subdomain can be accessed from anywhere.

{
        debug
}
*.lavado.ca {
        tls {
                dns lego_deprecated pdns
        }

        @esphome host esphome.lavado.ca remote_ip private_ranges
        handle @esphome {
                encode zstd gzip
                reverse_proxy 127.0.0.1:6052
        }

        @video host video.lavado.ca
        handle @video{
                encode zstd gzip
                reverse_proxy 127.0.0.1:8096
        }
}

I previously used to limit things to local access like the following example, but getting an LE cert with this required a public A record, which felt a little bit like leaking information, which is why I went the wildcard route.

esphome.lavado.ca {
       @internal {
               remote_ip 192.168.0.0/24
       }

      handle @internal {
              encode zstd gzip
              reverse_proxy 127.0.0.1:6052
       }
       respond 403
}

5. Links to relevant resources:

Reference on matchers from the docs:

Example config from here:

A post I looked at for inspiration:

1 Like

That’s invalid syntax. If you want to use more than one type of matcher, you need to use braces.

@esphome {
	host esphome.lavado.ca
	remote_ip private_ranges
}

Careful, you need to make sure there’s a space before the {.

Yeah, just put it at the top of the site, outside of the handle blocks.

2 Likes

Hey! Thanks for replying.

That’s a transcription error on my part. There is a space, and I was trying to format things nicely :sweat_smile:

Aha! I figured it was something along these lines but I couldn’t quite put my finger on it. Will do.

Again, thank you!

2 Likes

Let us know if you have any other questions. We’ll make sure to get it working with you :slight_smile:

Thanks for your great work on Jellyfin!

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.