caddy: ipv6: does not bind on ipv4 and ipv6 for sites that resolve to both
1. What version of Caddy are you running (caddy -version)?
0.8.3
2. What are you trying to do?
Serve a site that can be accessed using ipv4 and ipv6.
3. What is your entire Caddyfile?
http://ip6.nl:80 {
bind ip6.nl
root /var/www
}
4. How did you run Caddy (give the full command and describe the execution environment)?
ip6.nl resolves to 193.200.132.187 as well as [2a02:2308:10::c:19].
The server has both addresses configured (output of ip addr confirms this).
5. What did you expect to see?
$ netstat -lnp --inet6 | grep -F caddy
tcp6 0 0 2a02:2308:10::c:19:80 :::* LISTEN 8888/caddy
6. What did you see instead (give full error messages and/or log)?
Caddy does not listen on tcp6, only on tcp (--inet).
7. How can someone who is starting from scratch reproduce this behavior as minimally as possible?
#!/bin/bash
# Linux
ip -6 addr add 2a02:2308:10::c:19 dev lo
ip -4 addr add 193.200.132.187 dev lo
# or add something like this to your *home router's* nameserver
cat >>/etc/hosts <<<EOF
193.200.132.187 ip6.nl
2a02:2308:10::c:19 ip6.nl
EOF
cat >/tmp/Caddyfile-ds <<EOF
http://ip6.nl:80 {
bind ip6.nl
root /var/www
}
EOF
caddy -conf Caddyfile-ds &
sleep 1
netstat -lnpa | grep -F caddy
# tcp6, or only tcp?
# ----
kill $!
sed -i -e '/ip6.nl/d' /etc/hosts
ip -6 addr del 2a02:2308:10::c:19 dev lo
ip -4 addr del 193.200.132.187 dev lo
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 4
- Comments: 21 (7 by maintainers)
Commits related to this issue
- caddy-frontend: Server on IPv6 Caddy is able to bind only to all or one interface ( https://github.com/mholt/caddy/issues/864 ) By using 6tunnel this limitation is workarounded, and in the result li... — committed to SlapOS/slapos by lukenowak 6 years ago
- caddy-frontend: Server on IPv6 Caddy is able to bind only to all or one interface ( https://github.com/mholt/caddy/issues/864 ) By using 6tunnel this limitation is workarounded, and in the result li... — committed to SlapOS/slapos by lukenowak 6 years ago
So you’re now suggesting that for only $9,000 US, we’d improve our chances of getting a very basic and expected feature of a web server in Caddy, despite the fact that (to the best of my knowledge) Go itself still doesn’t support multi-binding, in an open-source and community-contributed-and-supported project.
Wow. I have no words. I’m not certain any longer who the target audience for Caddy is, but it would certainly seem that anyone with more complex requirements than a basic, single-homed, IPv4-only development web server isn’t part of it.
The resolver returns two addresses, the ipv4 and the ipv6 one. Caddy goes with the first one (ipv4) and ignores the ipv6-one. (It’s really a flaw in Golang.)(Just listening on
[::]:80is a no-go on multi-homed servers, or several sites.)Without this Caddy is not fully »ipv6 compliant«, and falling behind Nginx or Apache httpd.
Yes, I am suggesting using
http.Servewith two or moreListener. Due to possible shared state I recommend not just starting two servers in two goroutines. (Yes: 1←L, No: L×(1←1))This would most probably be achieved by an implementation along these lines:
bindgets more than one parameter, and/or…net.InterfaceAddrs()Listener, or reuse an existing one.MultiListenerencapsultes them all, acts as the soleListenerwe then pass tohttp.*(or any other server).Primer on ops:
ext0,intra0,storage0and so on. (It’s a good practice to rename aext0oren0p2and the such according to their function.)0.0.0.0:PPPPand[::]:PPPPfor that reason.ext0: For example, a machine-dependent one, and some free-floating ones (like, one for every customer).)/112or/128ipv6 addresses (which is sometimes done for free-floating ones (the largest DC operator in Austria does this)) the server gets an entire ipv6/64subnet. Therefore the subnet check in step (2) above.Websites for ipv4+ipv6:
(Yes, one-trick–pony installations can get away with
listen [::]:80 ipv6only=off;.)@rhester72
It’s $900 monthly – roughly the value of one day’s consulting/contracting work if you count hours. That’s totally appropriate to get a feature like this.
If you go this route, what you’re also paying for is a re-adjustment of the authors’ priorities. I’ve already said this is something Caddy will get, it’s just a matter of when.
Then it’s not “very basic” 😉 There be dragons in network stacks. But this feature is not super hard either. I suspect an extra loop will be needed in the function that groups site configs by listen address to create multiple listeners. Go may not support multi-binding in a single call to
Listen()in the way you/we think about it, but there’s nothing stopping us from creating multiple listeners each listening on a different bind address.Exactly. I would love to have your contributions to make it better (and the only cost then is your time). Honestly, I would prefer this. 👍
That’s why we’re in charge of it – we have the vision and we know where Caddy is going, because I and the other maintainers try to keep close tabs on what the community is doing with it. We can’t do everything at once. That’s why we appreciate the feedback, the interaction, and your involvement!
We use bind (and have to use bind) with IP-addresses because we’re on a multihomed server (multiple IP addresses), and use round-robin DNS which means that resolving our hostname will return IP addresses from more than one server.
So, what we need is to be able to specify multiple IP addresses with bind:
Or to specify bind more than once:
For now, I will use
firejail(orsocat, thanks @keks) as a workaround. But @mholt could you please give this issue the attention it deserves?will this issue be getting any attention? lack of parity with nginx for just this issue has me a bit confused about all the recent “use caddy!” hype from high profile aggregators and bloggers.
Hi, I’m the owner of the ip6.nl domain and I maintain the server to which the associated IP addresses are assigned.
I was surprised to see that these were used in an example, by someone I don’t know. For the record, I would like to add to this discussion that ip6.nl does not use Caddy, and that the user wmark is not associated with ip6.nl in any way.
It is generally a bad idea to re-use actual internet domain names and public routable IP addresses in examples or for local tests. This is why the domain name example.org (RFC2606) and the IPv6 prefix 2001:db8::/32 (RFC3849) exist.
wmark, please only use official example domains and IP addresses, or your own.
@mholt I totally understand, so no arguing from me. It’s just that the project I’d like to run caddy for is one I support pro-bono - a small grass-roots, donation supported podcast, so there’s no money for things like this. I’ll just have to wait until someone else picks up the issue, especially as I am a sysadmin, not a coder.
FYI, I wouldn’t label this as easy/for-beginners: The good implementation will require some knowledge of OS (as well as networking!) fundamentals a beginner won’t have. Plus, testing will be tricky.
But I support labelling this as bug and not RFE.
I would also love to see this fixed. For now I use socat as a workaround:
But seriously, this bug has been open for way too long.
I expected this to work, but it only listens on the last ‘bind’ statement. (I understand it working this way might be required to be able to override a default):
bind 2607:f238:3::222:0 bind 207.171.7.222
so alternatively having this work would be nice:
bind 2607:f238:3::222:0 207.171.7.222
There’s no way to use a set of specific IPs and have IPv4 and IPv6 work currently without duplicating the whole configuration.