libnetwork icon indicating copy to clipboard operation
libnetwork copied to clipboard

IPv6 ingress traffic is DNATed by docker-proxy

Open alehed opened this issue 4 years ago • 1 comments

It seems that for some reason the docker-proxy destination-NATs ingress ipv6 traffic while not doing the same for ipv4 traffic.

This behavior is quite confusing.

How to reproduce:

Setup on machine 1 (assuming it has addresses 192.168.1.2 and 2a57::2):

docker network create --ipv6 --subnet 2001:db8:6::/64 my_ipv6_network
docker run --publish 80:80 --network my_ipv6_network traefik/whoami

Then on machine 2 (assuming it has addresses 192.168.1.3 and 2a57::3) run:

curl "http://192.168.1.2"
curl "http://[2a57::2]"

Output for ipv4:

Hostname: 0e28009b4a10
IP: 127.0.0.1
IP: ::1
IP: 172.XXX.XXX.XXX
IP: 2001:db8:6::2
IP: fe80::XXXX
RemoteAddr: 192.168.1.3:33714
GET / HTTP/1.1
Host: 192.168.1.2
User-Agent: curl/7.68.0
Accept: */*

Output for ipv6:

Hostname: 0e28009b4a10
IP: 127.0.0.1
IP: ::1
IP: 172.XXX.XXX.XXX
IP: 2001:db8:6::2
IP: fe80::XXXX
RemoteAddr: [2001:db8:6::1]:48142
GET / HTTP/1.1
Host: [2a57::2]
User-Agent: curl/7.68.0
Accept: */*

Expected output for ipv6 (note RemoteAddr):

Hostname: 0e28009b4a10
IP: 127.0.0.1
IP: ::1
IP: 172.XXX.XXX.XXX
IP: 2001:db8:6::2
IP: fe80::XXXX
RemoteAddr: [2a57::3]:48142
GET / HTTP/1.1
Host: [2a57::2]
User-Agent: curl/7.68.0
Accept: */*

Docker configuration in daemon.json:

{
    "ipv6": true,
    "fixed-cidr-v6": "2001:db8::/64"
}

Version:

Docker version 20.10.5-ce, build 363e9a88a11b

As a sanity check, I checked using iptables that the dnat is not happening on the host before the docker-proxy.

sudo ip6tables -t security -A INPUT -p tcp --destination-port 80 -j LOG

this produced the following log messages:

kernel: IN=wlXXX OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=2a57::3 DST=2a57::2 LEN=80 TC=0 HOPLIMIT=64 FLOWLBL=859264 PROTO=TCP SPT=60398 DPT=80 WINDOW=64800 RES=0x00 SYN URGP=0 
kernel: IN=wlXXX OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=2a57::3 DST=2a57::2 LEN=72 TC=0 HOPLIMIT=64 FLOWLBL=859264 PROTO=TCP SPT=60398 DPT=80 WINDOW=507 RES=0x00 ACK URGP=0 
kernel: IN=wlXXX OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=2a57::3 DST=2a57::2 LEN=174 TC=0 HOPLIMIT=64 FLOWLBL=859264 PROTO=TCP SPT=60398 DPT=80 WINDOW=507 RES=0x00 ACK PSH URGP=0 
kernel: IN=wlXXX OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=2a57::3 DST=2a57::2 LEN=72 TC=0 HOPLIMIT=64 FLOWLBL=859264 PROTO=TCP SPT=60398 DPT=80 WINDOW=505 RES=0x00 ACK URGP=0 
kernel: IN=wlXXX OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=2a57::3 DST=2a57::2 LEN=72 TC=0 HOPLIMIT=64 FLOWLBL=859264 PROTO=TCP SPT=60398 DPT=80 WINDOW=505 RES=0x00 ACK FIN URGP=0 
kernel: IN=wlXXX OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=2a57::3 DST=2a57::2 LEN=72 TC=0 HOPLIMIT=64 FLOWLBL=859264 PROTO=TCP SPT=60398 DPT=80 WINDOW=505 RES=0x00 ACK URGP=0 

alehed avatar Apr 11 '21 19:04 alehed

Add into daemon.json:

  "ip6tables": true,
  "experimental": true,

Then systemctl restart docker and you should get the expected RemoteAddr value for IPv6.

polarathene avatar Dec 28 '22 03:12 polarathene