14

A docker container of mine exposes a HTTP interface on port 8500, which is mapped to host port 8500. It is not IPv6 enabled. This still means, I should be able to access it at localhost:8500. IPv6 is preferred, so I end up with a request to [::1]:8500. This one gets stuck, it never returns.

Reproducing this with curl, this command gets stuck:

curl -g -6 "http://[::1]:8500"

curl's --verbose option reveals nothing, neither does --ascii-trace. At the same time, a request to IPv4's localhost succeeds:

curl http://127.0.0.1:8500

giving me the expected HTML. If I run an IPv4 HTTP server on loopback, using

python -m SimpleHTTPServer 4001

then I get lots of HTML for IPv4's localhost

curl http://127.1:4001

and a proper connection failure for IPv6:

curl -g -6 "http://[::1]:4001"
curl: (7) Failed to connect to ::1 port 4001: Connection refused

Things to note: Docker 1.7.1. IPv6 is not enabled for the container, hence there are no IPv6 iptable rules. (ip6tables -v -L gives nothing)

My question is: Why does the request get stuck, and doing what?

mknecht
  • 241
  • 2
  • 4
  • 1
    Would you show us the output of "netstat -6 -an"? – Rui F Ribeiro Dec 01 '15 at 11:20
  • Yep, docker is listening on that port: `tcp6 0 0 :::8500 :::* LISTEN 1648/docker` Fascinating. Why? And why is it blocking? – mknecht Dec 01 '15 at 11:55
  • Listening and not configured, or IPv6 disabled in sysctl, I guess. nginx, apache, lighthttp, would you append the web server in question to the post, please? – Rui F Ribeiro Dec 01 '15 at 13:18
  • Inside the container, Consul, a key-value store for configuration, is listening. But I don't think it's relevant: the container has not been IPv6-enabled. That request should never reach Consul. I don't get on which layer it gets stuck, though. On the host, `/proc/sys/net/ipv6/conf/all/disable_ipv6` yields 0, so IPv6 should be enabled. – mknecht Dec 01 '15 at 13:39
  • 2
    That does not mean much. You can have IPv6 disabled even in sysctl, and in newer kernels, as long as the program binds to an IPv6 socket, the request is honoured. A pain in the ass, as you must go through each daemon that supports IPv6 and disable the IPv6 configuration. – Rui F Ribeiro Dec 01 '15 at 14:09
  • when invoking consul, change "-bind" to or add "-bind 127.0.0.1". It may be also necessary to peruse configuration files. – Rui F Ribeiro Dec 01 '15 at 14:18
  • @RuiFRibeiro Although what you are saying is truth, why to have ipv6 disabled when you want to use it? – Petr Jan 12 '18 at 14:21
  • @Petr Because in this case, the OP states "It is not IPv6 enabled." – Rui F Ribeiro Jan 12 '18 at 16:08
  • What do you have in your NAT table for iptables? Run "ip6tables -vnL -t nat" – Rabin Apr 02 '23 at 08:56

2 Answers2

0

Enable ipv6 and ebable forwarding.

# cat /etc/sysctl.conf | grep ipv6
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.disable_ipv6=0
net.ipv6.conf.default.disable_ipv6=0
Qteb
  • 1
  • 1
  • 2
    Apparently, the OP isn't trying to make something work; the actual question is "Why does the request get stuck, and doing what?". Does your answer provide an explanation for that? If so, may you please clarify how? – fra-san Jun 20 '19 at 13:19
0

If IPV6 forwarding is not enabled, the packets are just getting dropped. So, curl is constantly waiting for the response from the server whereas it will be getting none. It should timeout after some time.

You can replicate this by setting up a firewall such as UFW. Just block access to certain ports using firewall and then try to access them, curl will wait till timeout. Also, IP version has nothing specific to do with this.

  • 1
    If the docker container is not IPv6 enabled, then it should have no effect on connections dialling into the host's `::1` address. That is with no docker container at all you'd expect `Connection refused`. So why would a container with no IPv6 support change that? – Philip Couling Jan 20 '22 at 14:01
  • Firewall just drops your packets, `Connection Refused` occurs when the server just denies the connection. When firewall is in-place it doesn't let any traffic go in/out of that port, so no response, In case of docker, if things are not specified they are blocked by default using iptables, see https://docs.docker.com/network/iptables/ – soulphoenix Jan 20 '22 at 15:30
  • I think you missed my point. Why is docker setting up iptables IPv6 rules for this container when the container is not IPv6 enabled? – Philip Couling Jan 20 '22 at 16:08
  • Okay, so consider this scenario, a computer doesn't have an nic that supports ipv6, so you would never be getting any ipv6 address. Now, if the os is not aware of any ipv6 address, where do the ipv6 requests go? Nowhere. No service is there to respond those as the os is unaware and the request would timeout. – soulphoenix Jan 21 '22 at 06:04
  • That's not what happens. disconnect your WIFI and you'll notice it doesn't just sit there 2 minutes waiting for the connection to time out. Unplug your wificard and the result is the same... just try connecting your browser to any random port on local host (3756) http://localhost:3756/ it doesn't exist so it should immediately fail, not wait 2 minutes before timing out. – Philip Couling Jan 21 '22 at 09:20
  • Okay, so disabling ipv6 docker is not as simple as plugging out the nic card. Docker uses a software bridge by default, and when the interface is blocked (i.e forwarding is disabled for ipv6 in this case), the bridge does nothing. You can refer to an paper about linux software bridges [here](https://wiki.aalto.fi/download/attachments/70789083/linux_bridging_final.pdf). This will help you understand how the forwarding logic works. – soulphoenix Jan 21 '22 at 10:59