nerdctl icon indicating copy to clipboard operation
nerdctl copied to clipboard

`nerdctl run -p 8080:80` should listen on IPv6 as well

Open AkihiroSuda opened this issue 4 years ago • 6 comments

Currently, nerdctl run -p 8080:80 does not listen on IPv6, while docker run -p 8080:80 listens on IPv6 as well as on IPv4.

AkihiroSuda avatar Mar 01 '21 17:03 AkihiroSuda

@AkihiroSuda in my PR I added the fact of being able to explicitly set an ipv6 as we do for ipv4 Now, for default hostIP, in docker we should enable ipv6 on docker daemon to have both ipv4 and ipv6 when exposing port without any explicit adresse. Should we have the same mechanism on nerdctl or a default enabled ipv6 port ?

fahedouch avatar Mar 21 '21 23:03 fahedouch

current still not listen ipv6 port, Is there any solution?

I add ipv6 unspecified address to compose file

    ports:
      - "::0:5432:5432"

but got this error

INFO[0000] Ensuring image postgres:16.3-bookworm        
INFO[0000] Creating container postgres             
FATA[0000] failed to load networking flags: invalid ip address: [::0] 
FATA[0000] error while creating container postgres: exit status 1 

THLIVSQAZ avatar Jun 29 '24 14:06 THLIVSQAZ

In agreement with @THLIVSQAZ 's comment, the question of whether to expose both IPv4 and IPv6 by default is separate from basic functionality of enabling just IPv6 explicitly. As was noted in that comment, an explicit request to expose only IPv6 for any host address currently fails, with an "invalid ip address" error, which is problematic on its own.

From my cursory inspection, the logic parsing the host address is found in portutil.go, where the address is passed as-is to Go's net.ParseIP(). However, the address here is always either an IPv4 address in standard dotted-form (eg "192.168.3.1") or is an IPv6 address in bracketed form, always (eg "[2001:db8::1234]"). The brackets are not recognized by ParseIP(), and so the logic -- which should otherwise work -- does not handle any IPv6 host address.

One solution is to always append a colon to the host address, and then replace the invocation of net.ParseIP() with net.SplitHostPort(). The latter explicitly recognizes the bracket notation only if there is also a port number, which the appended colon satisfies, while still recognizing and validating IPv4 addresses. Since this part of portutil.go only seeks to validate the host address, SplitHostPort() should be a sufficient drop-in replacement.

As a reminder, this would only handle the scenario where an IPv6 host address is explicitly given. If no host address is given at all, then the behavior will still only act on the IPv4 localhost address. Resolving that behavior will require more discussion on what the sensible default should be -- though I personally think exposing dual-stack ports would make sense.

But in the meantime, there is currently no way to expose a container port to any IPv6 host address, at all. My proposal would at least deal with that issue.

compdude22 avatar Sep 15 '24 03:09 compdude22

LOL, I didn't see that @THLIVSQAZ actually came to the same conclusion and fixed that particular issue in #3217 . But it's not available in the stable release yet, but is available with the v2.0.0-rc.1 tag on main branch.

The gist is that -p [::]:8081:8081 will work for IPv6 forwarding now, using the RC release.

compdude22 avatar Sep 23 '24 02:09 compdude22

Hey folks. Curious where we stand with this now (post 2.0). Anything left to desire here?

apostasie avatar May 17 '25 02:05 apostasie

Nothing from my end.

compdude22 avatar May 20 '25 03:05 compdude22