Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting up forwarding and port spec round trip do not appear to support UDP under IPv6 #547

Open
plm opened this issue Aug 20, 2021 · 0 comments

Comments

@plm
Copy link

plm commented Aug 20, 2021

As of commit 0b631022, vpnkit/forward/udp.go's makeUDP method and vpnkit/port.go's spec method do not appear to fully support IPv6 addresses.

Under Docker Desktop 3.6.0 (67351) on macOS, I had been trying to publish a UDP port to an IPv6 address but received the error too many colons in address:

$ docker run --rm --publish [::1]:8080:80/udp nginx:latest
docker: Error response from daemon: Ports are not available: unable to resolve frontend address for port docker-proxy-port-approver/approver-7121331846359289064 udp forward from ::1:8080 to 0.0.0.0:0: address ::1:8080: too many colons in address.
ERRO[0000] error waiting for container: context canceled 

In triaging this, I found that IPv6 doesn't appear to be supported by the Docker daemon on macOS and (unsurprisingly) is not enabled on my Docker install:

$ jq -r ".ipv6 // false" < ~/.docker/daemon.json
false

However, testing port creation with TCP suggests that despite what is documented, IPv6 TCP publish doesn't appear to fail, and, if it does, it doesn't do so in the same way that IPv6 UDP does above:

$ docker run --rm --publish [::1]:8080:80/tcp nginx:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/08/20 05:06:12 [notice] 1#1: using the "epoll" event method
2021/08/20 05:06:12 [notice] 1#1: nginx/1.21.1
2021/08/20 05:06:12 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6) 
2021/08/20 05:06:12 [notice] 1#1: OS: Linux 5.10.47-linuxkit
2021/08/20 05:06:12 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/20 05:06:12 [notice] 1#1: start worker processes
2021/08/20 05:06:12 [notice] 1#1: start worker process 31
2021/08/20 05:06:12 [notice] 1#1: start worker process 32
2021/08/20 05:06:12 [notice] 1#1: start worker process 33
2021/08/20 05:06:12 [notice] 1#1: start worker process 34
2021/08/20 05:06:12 [notice] 1#1: start worker process 35
2021/08/20 05:06:12 [notice] 1#1: start worker process 36

Looking through the code, I believe the UDP-specific error is assembled from code in two files:

Looking at the tests associated with these two files, I applied the patch (udp-ipv6-tests.txt) to demonstrate that:

  • Round trip for the port spec representation fails for IPv6 addresses with both TCP and UDP:
    --- FAIL: TestParseRoundTrip (0.00s)
      /Users/philip/Source/External/docker/vpnkit/go/pkg/vpnkit/port_test.go:60: Cannot parse port spec: Failed to parse port spec: tcp:2001:db8::2:8443:tcp:2001:db8::1:443
    
  • Binding to a random port on an IPv6 address works for TCP but fails for UDP:
    --- FAIL: TestRandomPortsUDP (0.00s)
        /Users/philip/Source/External/docker/vpnkit/go/pkg/vpnkit/forward/  forward_test.go:304: 
              Error Trace:  forward_test.go:304
              Error:        Received unexpected error:
                            address ::1:0: too many colons in address
                            unable to resolve frontend address for port udp forward from   ::1:0 to ::1:2
                            github.com/moby/vpnkit/go/pkg/vpnkit/forward.makeUDP
                              /Users/philip/Source/External/docker/vpnkit/go/pkg/vpnkit/  forward/udp.go:19
                            github.com/moby/vpnkit/go/pkg/vpnkit/forward.Maker.Make
                              /Users/philip/Source/External/docker/vpnkit/go/pkg/vpnkit/  forward/forward.go:47
                            github.com/moby/vpnkit/go/pkg/vpnkit/  forward.TestRandomPortsUDP
                              /Users/philip/Source/External/docker/vpnkit/go/pkg/vpnkit/  forward/forward_test.go:303
                            testing.tRunner
                              /usr/local/Cellar/go/1.16.6/libexec/src/testing/  testing.go:1193
                            runtime.goexit
                              /usr/local/Cellar/go/1.16.6/libexec/src/runtime/  asm_amd64.s:1371
              Test:         TestRandomPortsUDP
    

Is the IPv6 UDP behavior observed here expected?

My Docker information is included for completeness:

$ docker version
Client:
 Cloud integration: 1.0.17
 Version:           20.10.8
 API version:       1.41
 Go version:        go1.16.6
 Git commit:        3967b7d
 Built:             Fri Jul 30 19:55:20 2021
 OS/Arch:           darwin/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.8
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.6
  Git commit:       75249d8
  Built:            Fri Jul 30 19:52:10 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.9
  GitCommit:        e25210fe30a0a703442421b0f60afac609f950a3
 runc:
  Version:          1.0.1
  GitCommit:        v1.0.1-0-g4144b63
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
$ docker info | sed "s/ ID: .*/ ID: REDACTED/"
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Build with BuildKit (Docker Inc., v0.6.1-docker)
  compose: Docker Compose (Docker Inc., v2.0.0-rc.1)
  scan: Docker Scan (Docker Inc., v0.8.0)

Server:
 Containers: 10
  Running: 1
  Paused: 0
  Stopped: 9
 Images: 15
 Server Version: 20.10.8
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: e25210fe30a0a703442421b0f60afac609f950a3
 runc version: v1.0.1-0-g4144b63
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 5.10.47-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 6
 Total Memory: 7.773GiB
 Name: docker-desktop
 ID: REDACTED
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

$ ifconfig lo0 inet6
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	nd6 options=201<PERFORMNUD,DAD>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant