docker-ipv6nat icon indicating copy to clipboard operation
docker-ipv6nat copied to clipboard

Prefer ipv6 over ipv4

Open guysoft opened this issue 2 years ago • 12 comments

Hey, Is there a way to set that Ipv6 would be preferred to ipv4?

If I bring up a container I get that unless spefied (or ipv6-only site) ipv4 is used:

ping www.google.com
PING www.google.com (142.250.184.196): 56 data bytes
64 bytes from 142.250.184.196: seq=0 ttl=110 time=69.688 ms

Only if I force ipv6 it uses it:

/ # ping -6 www.google.com
PING www.google.com (2a00:1450:4001:80f::2004): 56 data bytes
64 bytes from 2a00:1450:4001:80f::2004: seq=0 ttl=116 time=59.688 ms

Its like this for every container I tried. docker-compose:

  ipv6:
    image: robbertkl/ipv6nat
    container_name: ipv6nat
    restart: always
    network_mode: "host"
    privileged: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /lib/modules:/lib/modules:ro
networks:
  default:
    enable_ipv6: true
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "true"
    ipam:
      driver: default
      config:
       - subnet: fd00:0000:0000:1::/64

/etc/docker/daemon.json:

 {
          "ipv6": true,
          "fixed-cidr-v6": "fd00::/80"
}
$ sudo docker version
Client: Docker Engine - Community
 Version:           20.10.10
 API version:       1.41
 Go version:        go1.16.9
 Git commit:        b485636
 Built:             Mon Oct 25 07:42:19 2021
 OS/Arch:           linux/arm
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.10
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.9
  Git commit:       e2f740d
  Built:            Mon Oct 25 07:40:35 2021
  OS/Arch:          linux/arm
  Experimental:     false
 containerd:
  Version:          1.4.11
  GitCommit:        5b46e404f6b9f661a205e28d59c982d3634148f8
 runc:
  Version:          1.0.2
  GitCommit:        v1.0.2-0-g52b36a2
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Thanks

guysoft avatar Jul 07 '22 19:07 guysoft

You can use the subnet 2001:db8::/64 The containers will prefer IPv6 over IPv4

7cio avatar Aug 01 '22 13:08 7cio

@vNa3006 That subnet type changes the preference?

From what I understand that is an address block (2001:db8::/64) used for documentation examples: https://en.wikipedia.org/wiki/IPv6_address#Special_addresses

guysoft avatar Aug 02 '22 12:08 guysoft

Yes, I don't know why it works that way, but when you use 2001:db8::/64, the containers will prefer ipv6

7cio avatar Aug 02 '22 15:08 7cio

I probably want though a subset not used for documentation :) Any other blocks or explanation why?

guysoft avatar Aug 03 '22 12:08 guysoft

I haven't tried anything else yet. I'm OK with that subnet for now.

7cio avatar Aug 03 '22 14:08 7cio

From #ipv6 on librechat I was updated that what sets the priority is /etc/gai.conf (getaddrinfo). I am not sure how to use it though

guysoft avatar Aug 04 '22 09:08 guysoft

You can backup the gai.conf file, then replace the content of the file to

label ::1/128 0 label ::/0 1 label 2002::/16 2 label ::/96 3 label ::ffff:0:0/96 4 label fec0::/10 5 label fc00::/7 6 #label 2001:0::/32 7

It should work also

7cio avatar Aug 04 '22 10:08 7cio

@vNa3006 Does this go in the container? host? or the docker-ipv6nat container? Does not seem to work in the container.

guysoft avatar Aug 04 '22 10:08 guysoft

I've just tested with a clean ubuntu container, it works right after editing the gai.conf file without restarting the container.

7cio avatar Aug 04 '22 11:08 7cio

For posterity sake, this is a quirk of glibc: https://codebrowser.dev/glibc/glibc/sysdeps/posix/getaddrinfo.c.html#1234.

It explicitly ignores ipv6 standards and returns ipv4 addresses first when using ULA addresses. The assumption is "ipv6 will never be NAT'd" :). This ignoring the RFC has caused many headaches.

That's why 2001 works. But ipv6nat only NATs ULA addresses, so I'm not sure how you're using the container.

jsravn avatar Mar 09 '23 13:03 jsravn

@jsravn Thanks for digging in and finding the root cause.

Its not that they don't expect ipv6 to be nated. More the logic is "if we have a ipv6 local address then we expect that we have only ipv6 locally and not globally". So they will only route IPv6 if if there is a global address to the device. Because the situarion of a local ipv6 and no global ipv6 is more common.

And the workaround we are doing is assigning a global address to make glibc think it has a global address and route correctly.

Sounds like a reason to file a bug on glibc: https://sourceware.org/bugzilla/

guysoft avatar Apr 12 '23 23:04 guysoft

I doubt they would change it at this point. I also noticed RFC 6724 updates the source selection logic to follow what glibc does - so it seems it will become the standard soon. As a result, seems like the "use example range" hack is going to be codified into ipv6 for all of time :).

jsravn avatar May 20 '23 09:05 jsravn