Reverse proxy to dynamic IPv4 only

1. The problem I’m having:

I would like to reverse proxy to a host by using its name from DNS, but only connect over IPv4, not IPv6. The host has both. However, access logs on the remote service show Caddy is connecting via IPv6.

I expected that using a dynamic a block with versions ipv4 set within reverse_proxy would achieve this, but caddy is still discovering and using an IPv6 address.

2. Error messages and/or full log output:

2024/07/03 10:46:12.362	DEBUG	http.reverse_proxy.upstreams.a	refreshing A upstreams	{"version": "ip", "name": "potoroo", "port": "8123"}
2024/07/03 10:46:12.363	DEBUG	http.reverse_proxy.upstreams.a	discovered A record	{"ip": "xxxx:xxxx:8c5e:42:3ac9:86ff:fe40:8637"}
2024/07/03 10:46:12.363	DEBUG	http.reverse_proxy.upstreams.a	discovered A record	{"ip": "xxxx:xxxx:8c5e:42::18"}
2024/07/03 10:46:12.363	DEBUG	http.reverse_proxy.upstreams.a	discovered A record	{"ip": "192.168.42.18"}
2024/07/03 10:46:12.363	DEBUG	http.reverse_proxy.upstreams.a	discovered A record	{"ip": "fd5d:61f5:a84a:42::18"}
2024/07/03 10:46:12.363	DEBUG	http.reverse_proxy.upstreams.a	discovered A record	{"ip": "fd5d:61f5:a84a:42:3ac9:86ff:fe40:8637"}
2024/07/03 10:46:12.363	DEBUG	http.handlers.reverse_proxy	provisioned dynamic upstreams	{"count": 5}
2024/07/03 10:46:12.363	DEBUG	http.handlers.reverse_proxy	selected upstream	{"dial": "[fd5d:61f5:a84a:42:3ac9:86ff:fe40:8637]:8123", "total_upstreams": 5}

3. Caddy version:

v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

4. How I installed and ran Caddy:

Installed with xcaddy build. Start with caddy run.

a. System environment:

Debian 12 on amd64. Not running in Docker / systemd.

b. Command:

caddy run

d. My complete Caddy config:

{
	debug
}

:9000 {
	reverse_proxy {
		dynamic a potoroo 8123 {
			versions ipv4
		}
	}
}

caddy adapt shows that the versions part was successfully turned into {"ipv4":true}, and I see the caddy source has unit tests of this also.

I don’t know if I need to set {"ipv6":false} somehow but I can’t see how to do this from the Caddyfile. I tried !ipv6, -ipv6 but those don’t work. It works if I set that in a JSON config.

Is there a way to set ipv6: false from Caddyfile?

As an alternative I found this works, and it probably better anyway as the IP address won’t be changing:

:9000 {
	reverse_proxy tcp4/potoroo:8123
}

Ah, good catch. The code logic short-circuits when ipv6 isn’t set.

Would you mind creating an issue on GitHub to track it? If I may trouble you, include this topic link on the GitHub issue then post the GitHub issue link here as well. We’ll get to it.

2 Likes

Thanks for looking into it. I’ve opened can't disable IPv4/IPv6 for dynamic reverse proxy from Caddyfile · Issue #6442 · caddyserver/caddy · GitHub

Actually, this also doesn’t work, it will sometimes connect on IPv6 despite the tcp4. @Mohammed90 would you consider this also a bug?

Yes. The Go documentation defines tcp4 as IPv4 only. We should match that.

2 Likes

Fixed on master now. Thanks.