docker / for-win

Bug reports for Docker Desktop for Windows
https://www.docker.com/products/docker#/windows
1.86k stars 291 forks source link

How to disable Link-local IPv6 Address #14063

Open kkbruce opened 6 months ago

kkbruce commented 6 months ago

Description

We ran a Windows container for the demo web and found that the Docker network was always enabled as "Link-local IPv6 Address". We want to disable this function.

Ethernet adapter vEthernet (nat):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::8a9e:ba55:a3ff:2bf4%8
   IPv4 Address. . . . . . . . . . . : 172.19.0.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Ethernet adapter vEthernet (Default Switch):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::b439:d43a:7244:6f0e%32
   IPv4 Address. . . . . . . . . . . : 172.18.16.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Reproduce

  1. docker run -it --rm -p 8000:8080 --name aspnetcore_sample mcr.microsoft.com/dotnet/samples:aspnetapp
  2. ipconfig
Ethernet adapter vEthernet (nat):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::8a9e:ba55:a3ff:2bf4%8
   IPv4 Address. . . . . . . . . . . : 172.19.0.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Ethernet adapter vEthernet (Default Switch):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::b439:d43a:7244:6f0e%32
   IPv4 Address. . . . . . . . . . . : 172.18.16.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Expected behavior

Disable "Link-local IPv6 Address" function by Docker for Windows.

docker version

Client:
 Version:           26.1.0
 API version:       1.45
 Go version:        go1.21.9
 Git commit:        9714adc
 Built:             Mon Apr 22 17:07:39 2024
 OS/Arch:           windows/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          26.1.0
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.21.9
  Git commit:       c8af8eb
  Built:            Mon Apr 22 17:06:23 2024
  OS/Arch:          windows/amd64
  Experimental:     false

docker info

Client:
 Version:    26.1.0
 Context:    default
 Debug Mode: false

Server:
 Containers: 2
  Running: 2
  Paused: 0
  Stopped: 0
 Images: 2
 Server Version: 26.1.0
 Storage Driver: windowsfilter
  Windows:
 Logging Driver: json-file
 Plugins:
  Volume: local
  Network: ics internal l2bridge l2tunnel nat null overlay private transparent
  Log: awslogs etwlogs fluentd gcplogs gelf json-file local splunk syslog
 Swarm: inactive
 Default Isolation: process
 Kernel Version: 10.0 20348 (20348.1.amd64fre.fe_release.210507-1500)
 Operating System: Microsoft Windows Server Version 21H2 (OS Build 20348.2402)
 OSType: windows
 Architecture: x86_64
 CPUs: 4
 Total Memory: 7.999GiB
 Name: twqwn1
 ID: b9714ae6-4151-4120-879e-d7c5da51b9b6
 Docker Root Dir: D:\docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine

Diagnostics ID

None

Additional Info

None

robmry commented 6 months ago

Hi @kkbruce - could you tell us a bit more about your use-case? What problems is the IPv6 link local address causing?

kkbruce commented 6 months ago

@robmry

Let me briefly explain the situation we encountered. We have other services on the host where Docker is located. Let's call it Service N.

When Service N receives a request, it first performs DNS resolution. When Service N gets the same domain name as the Docker host, we found that the original DNS should respond with IPv4 and let the service that ends at IPv4:Port complete the operation. We have confirmed that the physical network card has canceled the IPv6 setting. Still, we saw the appearance of IPv6 in the log, which was regarded as an abnormal request from Service N. After investigation, we found that the Docker network will generate an IPv6 address by default.

When a host has IPv6 and IPv4, IPv6 has a high priority in DNS responses, so DNS always responds with IPv6 when querying its IP.

Correct: request --> a.com --> N Service --> dns --> a.com --> IPv4 (from Host NIC) Incorrect: request --> a.com --> N Service --> dns --> a.com --> IPv6 (from Docker NIC)

Therefore, we are looking for a way to turn off this feature in Docker for Windows. If anything is unclear, I will add more information.

robmry commented 6 months ago

Thank you - to check I understand ...

Service-N has IPv4 and IPv6 addresses in DNS (?).

Because it's on the same host (on the same IPv6-link), the application in the container uses its Windows-assigned link-local address to make its request to Service-N's IPv6 address.

And that's a problem because, although it has an IPv6 address, Service-N doesn't accept IPv6 requests?

kkbruce commented 6 months ago

No, the current situation with the host network card is as follows:

PS C:\> ipconfig

Windows IP Configuration
Ethernet adapter Ethernet0:

   Connection-specific DNS Suffix  . :
   IPv4 Address. . . . . . . . . . . : 192.168.0.105
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.0.1

Ethernet adapter vEthernet (f1bd5d873bc0da8):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::4bff:ef63:cf6d:ec62%20
   IPv4 Address. . . . . . . . . . . : 172.29.96.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Ethernet adapter vEthernet (nat):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::3862:55f0:5e83:ce70%32
   IPv4 Address. . . . . . . . . . . : 172.28.160.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

The host only has one physical network card set up with IPv4; the rest are generated by Docker, and the network cards generated by Docker will carry IPv6. Under normal circumstances, our external services will be bound to a certain port of IPv4. For example, Docker provides ports 2375 and 2376 to the outside.

For example, when the request is from outside to inside, I request twqwn1.example.com:80. There will be no problem. But when the request is sent to a particular service within the same host, for example, the API service, this API service accepts a DomainName parameter and decides the subsequent action after resolving the IP according to the DomainName parameter. This usually won’t be a problem. However, because the Docker network card in the same host provides IPv6, the API gets IPv6 instead of IPv4 when performing DNS resolution, resulting in abnormal subsequent processing.

For example, when I perform a ping operation on the same host, it is obvious that IPv6 will be used.

PS C:\> ping twqwn1

Pinging twqwn1.example.com [fe80::3862:55f0:5e83:ce70%32] with 32 bytes of data:
Reply from fe80::3862:55f0:5e83:ce70%32: time<1ms
Reply from fe80::3862:55f0:5e83:ce70%32: time<1ms
Reply from fe80::3862:55f0:5e83:ce70%32: time<1ms
Reply from fe80::3862:55f0:5e83:ce70%32: time<1ms

Ping statistics for fe80::3862:55f0:5e83:ce70%32:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

As mentioned, we found many abnormal logs in Service N on the same host. We saw a lot of IPv6:Port connection information. Because it happened to be on the same host as Docker, we discovered this problem. I believe that non-Docker services on the same host, such as Port 80, cannot be bound to the IPv6 provided by Docker to provide services. So, we'd like to find a way to turn off this default IPv6 feature.

robmry commented 6 months ago

The IPv6 link-local addresses aren't provided or managed by Docker, they're added by the OS. I don't see a way to tell it not to, other than perhaps by registry settings to disable IPv6 on the host - but that's not something docker should do, and I don't know all the implications. (Someone with better Windows networking knowledge may be able to jump in here.)

But - what's resolving the name twqwn1 to the link-local address of the NAT adapter? If it's DNS, how was it populated with that LL address?