-1

python3 -m http.server --bind :: launches a python web server, as shown in Python 3: Does http.server support ipv6?. However, it also supports IPv4, because I can visit the web server with localhost:8000 (edit: even 127.0.0.1:8000 works). I don't want that. The python http.server is dual-stack even though I used --bind:

By default, server binds itself to all interfaces. The option -b/--bind specifies a specific address to which it should bind. docs

Is there a way to disable IPv4? I asked it to bind to ::.

Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167
  • The "localhost" name is an alias in both IPv4 and IPv6. "localhost" maps to "::". Does it work if you do `127.0.0.1:8000`? – Tim Roberts Oct 27 '22 at 22:23
  • Yea, my browser can visit `127.0.0.1:8000`. Though, I didn't know localhost resolves to `::`. It's true: `dig AAAA localhost` gets `::1`. Thanks! – Ben Butterworth Oct 27 '22 at 22:25

1 Answers1

0

There is no way to do this because the support for IPv4 is not provided by Python, but by the OS. I'm not 100% sure though.

More details

The output of lsof -nP -i4TCP | grep LISTEN (open network files/sockets on IPv4) include (notice the IPv6)

Python    30838  ben    3u  IPv6 0xb364e79e7fc44213      0t0  TCP *:8000 (LISTEN)

This is alongside the IPv6 network file lsof -nP -6 (warning: lsof -nP -i6TCP doesn't show it ):

Python    30838  ben    3u  IPv6 0xb364e79e7fc44213      0t0  TCP *:8000 (LISTEN)

I think the OS creates a network file/socket for IPv4 packets even though Python did not ask for it (for convenience). From my understanding of lsof and the docs:

When an open IPv4 network file's address is mapped in an IPv6 address, the open file's type will be IPv6, not IPv4, and its display will be selected by '6', not '4'.

I've just realized this is a very similar "feature" to one I was reading yesterday...

This means it's no longer a Stack Overflow answer but a Linux one: How do you turn off dual-stack networking for the server?

Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167