Docker IPv6 has wrong default gateway


Recommended Posts

I'm running Unraid 6.10.2, with my Docker containers in macvlan mode and with "Network Type" set to "Custom: br0". 

I'm then assigning a static IPv4 and a static IPv6 through the "Fixed IP address" option. 

 

However, the Docker container is only reachable (through IPv6) from my local network, not from "outside". IPv4 traffic is working fine.

My router is definitely configured to accept that incoming IPv6 traffic to the container's IPv6.

 

I suspect the issue is a wrong gateway. When I run "docker network inspect br0" on the UnRAID host, this is what I get: 

 

[
    {
        "Name": "br0",
        "Id": "xxx",
        "Created": "2022-06-11T15:25:56.860307501+02:00",
        "Scope": "local",
        "Driver": "macvlan",
        "EnableIPv6": true,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.0.0.0/16",
                    "Gateway": "10.0.1.1",
                    "AuxiliaryAddresses": {
                        "server": "10.0.1.5"
                    }
                },
                {
                    "Subnet": "2001:db8:1234::/64",
                    "Gateway": "2001:db8:1234::1",
                    "AuxiliaryAddresses": {
                        "server6": "2001:db8:1234:0:1122:33ff:fe44:5566"
                    }
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "yyy": {
                "Name": "mycontainer",
                "EndpointID": "zzz",
                "MacAddress": "02:42:0a:00:18:07",
                "IPv4Address": "10.0.24.7/16",
                "IPv6Address": "2001:db8:1234::24:7/64"
            }
        },
        "Options": {
            "parent": "br0"
        },
        "Labels": {}
    }
]

 

For the IPv4 gateway, it correctly lists "10.0.1.1" as the gateway (which is my router's private IPv4 address). However, for the IPv6 gateway, it lists 2001:db8:1234::1 as the gateway - an address that does not exist in my network at all. 

 

Thus, while my packets from the internet may reach the Docker container, I suspect the response never arrives because Docker tries to send the packets to that nonexistant address instead of the proper network gateway. 

 

In UnRAID under Settings -> Network Settings the "IPv6 default gateway" is correctly set to my router's link-local IPv6 address. Where does that weird 2001:db8:1234::1 address as IPv6 gateway in the Docker network come from? 

 

Under Settings -> Docker it also correctly lists "IPv6 custom network on interface br0: Subnet: 2001:db8:1234::/64, Gateway: fe80::1234:56ff:fe78:90ab".

 

Unfortunately it looks like it's impossible to alter a Docker network after it's been created, so I can't just throw some code into the "go" file on the flash drive to automatically correct this after each boot. Also, even if that was possible, it sounds like a terrible hack. 

Where does UnRAID get that gateway from and how do I change it? 

Under "Network Settings" it correctly displays "IPv6 default fe80::1234:56ff:fe78:90ab via br0" as the route.

Is there any custom settings as to how the br0 custom network is created that I could modify? What am I doing wrong?

 

I grep'd through the whole USB drive for "2001:db8:1234::1" hoping to find any place where that'd be hardcoded but I didn't find any. Does UnRAID assume the gateway can always be reached through the 1st address from the IPv6 subnet? That'd be ... stupid.

 

If necessary I can post a diagnostics ZIP, but I'd rather not have all my IPs and container names and stuff published (yeah, security by obscurity ...) so I'd need a bit of time to anonymize them all. If the ZIP is needed for this particular issue please just mention it. 

 

 

EDIT: 

I just found code in /etc/rc.d/rc.docker that explicitly implements this buggy behaviour: 

 

      if [[ -n $IPV6 ]]; then
        SUBNET6=$(ip -6 route show dev $NETWORK $IPV6|awk '{print $1;exit}')
        SERVER6=${IPV6%%/*}
        DHCP6=${NETWORK/./_}
        DHCP6=DOCKER_DHCP6_${DHCP6^^}
        RANGE6=${!DHCP6}
        GATEWAY6=$(ip -6 route show dev $NETWORK default|awk '{print $3;exit}')
        # replace link local address for first address in subnet
        [[ ${GATEWAY6:0:4} == fe80 ]] && GATEWAY6=${SUBNET6%%/*}1
      fi

 

So it first determines the gateway as it should, using "ip -6", but then it decides to just ignore what it found and hardcodes the first address in the subnet instead? What's the point? That completely breaks stuff apparently. 

I'm going to try removing that code and see if that fixes my issue.

Edited by Leseratte10
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.