IPv4 or IPv6 preference for individual subdomains - Help - Caddy Community
1. The problem I’m having: I want specific subdomains to be either IPv4 or IPv6 only. My overall goal is that I run a service that relies on the X-Forwarded-For header to show the client’s IP address. My server has bot…
IPv4 or IPv6 preference for individual subdomains - Help - Caddy Community = 40rem)" rel="stylesheet" data-target="chat_desktop" /> = 40rem)" rel="stylesheet" data-target="discourse-reactions_desktop" /> = 40rem)" rel="stylesheet" data-target="poll_desktop" /> = 40rem)" rel="stylesheet" data-target="desktop_theme" data-theme-id="1" data-theme-name="caddy custom"/> IPv4 or IPv6 preference for individual subdomains Help albert (albert) July 22, 2025, 2:50pm 1 1. The problem I’m having: I want specific subdomains to be either IPv4 or IPv6 only. My overall goal is that I run a service that relies on the X-Forwarded-For header to show the client’s IP address. My server has both IPv4 and IPv6, but Caddy always forwards the IPv6 address when it’s available. I need to be able to access the client’s IPv4 as well, without disabling IPv6 entirely. So I want to make dedicated v4/v6 subdomains but I don’t know how… 2. Error messages and/or full log output: I can’t provide logs for it, since I can’t figure out how can I even do this. Currently everything responds to both v4 and v6. 3. Caddy version: caddy version v2.10.0 h1:fonubSaQKF1YANl8TXqGcn4IbIRUDdfAkpcsfI/vX5U= 4. How I installed and ran Caddy: I used xcaddy to build it with caddy-l4 and caddy-dns/cloudflare. xcaddy build --with github.com/caddy-dns/cloudflare --with github.com/mholt/caddy-l4 a. System environment: Debian 12 & 6.1.0-37-amd64, with systemd-- no docker. Domain: (*.)albert.lol b. Command: c. Service/unit/compose file: cat /lib/systemd/system/caddy.service [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/local/bin/caddy run --environ --config /etc/caddy/Caddyfile ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile --force TimeoutStopSec=5s LimitNOFILE=1048576 LimitNPROC=512 PrivateTmp=true ProtectSystem=full AmbientCapabilities=CAP_NET_BIND_SERVICE Environment="CLOUDFLARE_API_KEY=REDACTED" Restart=on-failure RestartSec=5s d. My complete Caddy config: caddy fmt /etc/caddy/Caddyfile { layer4 { udp/:9987 { route { proxy udp/192.168.1.103:9987 } } :25565 { route { proxy { proxy_protocol v2 upstream 192.168.1.104:25565 } } } :5432 { route { proxy 192.168.1.103:5432 } } :1022 { route { proxy 192.168.1.118:22 } } :3022 { route { proxy 192.168.1.119:22 } } } } (common) { header * { -Server -Via Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" X-Content-Type-Options "nosniff" X-Frame-Options "SAMEORIGIN" Referrer-Policy "strict-origin-when-cross-origin" Permissions-Policy "geolocation=(), microphone=(), camera=(), interest-cohort=()" } log { output file /var/log/caddy/access.log { roll_size 50MB roll_keep 5 roll_keep_for 168h } format json { time_format "iso8601" } } encode zstd gzip } (insecure) { transport http { tls_insecure_skip_verify } } (cf) { tls { dns cloudflare {env.CLOUDFLARE_API_KEY} } } :80, http://albert.lol { redir https://albert.lol{uri} permanent } *.demo.albert.lol { import common import cf @btdemo host budgetable.demo.albert.lol handle @btdemo { reverse_proxy 192.168.1.103:3006 } handle { abort } } albert.lol { import common import cf reverse_proxy 192.168.1.106:3000 } *.albert.lol { import common import cf import sites/* handle { redir https://albert.lol permanent } } Example from my sites/ directory: cat /etc/caddy/sites/bin.albert.lol @bin host bin.albert.lol handle @bin { reverse_proxy 192.168.1.103:8002 } 5. Links to relevant resources: timelordx (timelordx) July 22, 2025, 3:15pm 2 Not sure if this is what you’re looking for but you could try bind ferrybig (Fernando van Loenhout) July 26, 2025, 7:29pm 3 IPv4/IPv6 is a preference of the client, not the server. A connection over IPv6 is fully distinct form a connection over IPv4 If the service does not work with IPv6, remove the AAAA from the domain in the DNS ferrybig (Fernando van Loenhout) July 31, 2025, 10:33am 6 Your are incorrect, binding a server to just a single ip doesn’t work. Taking your example with nignx, if one site block is bound to IPv6 and IPv4, while the other is only bound to IPv4, if you try to access the latter over IPv6, the browser connects to the server, then gets an error from the server saying it doesn’t host the site. From the browsers perspective, there was a vaid connection and it never falls back to another IP Even in the case when you are hosting one website, it is still unreliable, as the browser might end up connecting to the other IP and hit a timeout. (or in the case of a DNS64 gateway, it never even sees the A record if there is an AAAA record introduced). You would also be depending on the Happy Eyeballs algoritmh in browsers, which is unreliable. And remember that letsencrypt and Zerotier doesn’t support this. If your website has an AAAA and A record, letsencrypt only tries AAAA (with a 1 time A request fallback that gets eaten up by the HTTP to HTTPS redirect). This is a common issue that gets posted on these forums and the letsencrypt forums by people asking why they cannot get a certificate