双栈OS中::和0.0.0.0的语义


10

在仅使用IPv4的日子里,显示netstat为“侦听” 的LISTEN连接0.0.0.0将响应系统中任何IPv4接口上的连接。

据我了解,新的IPv6习惯用法会::侦听所有可用的IPv6 IPv4接口。对于所有操作系统(Unix,Windows,Mac),这是否正确?是否有只在IPv6接口上侦听的习惯用法?

Answers:


17

不幸的是,这取决于所使用的操作系统。

在Microsoft Windows上,将套接字绑定到::仅绑定到IPv6端口。因此,要侦听IPv4和IPv6上的所有地址,您需要绑定到0.0.0.0::。以下摘录来自Vista盒子:

C:\>netstat -an | find "445"
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING
  TCP    [::]:445               [::]:0                 LISTENING

我给出的示例是端口445,该端口在不使用NetBIOS时用于SMB通信。如您所见,它绑定到两者,0.0.0.0::分别使IPv4和IPv6客户端都能工作。

在Linux上,::正如您已经正确猜到的,它包含与IPv4兼容的地址,因此0.0.0.0也不必进行绑定。我编写了一个简单的Python程序,该程序仅绑定到上的AF_INET6套接字::。即使我也没有绑定到AF_INET(IPv4)套接字,它仍然接受来自IPv4客户端的连接。例如,如果10.1.1.3连接到它,它将显示为从连接::ffff:10.1.1.3

除了长毛。如果/proc/sys/net/ipv6/bindv6only将设置为1,则以上内容不适用于Linux ,在这种情况下,其行为与Windows完全相同-绑定到::将仅侦听IPv6请求。如果还要监听IPv4请求,则需要创建一个AF_INET套接字并监听0.0.0.0。幸运的是,的默认bindv6only值为0,因此您将不得不面对极小的机会(除非您使用Debian(实际上默认为bindv6only = 1)。

在检查服务是否支持IPv6以及是否也支持IPv4时,所有这些信息都很容易掌握。这是我的SSH服务器:

$ netstat -64ln | grep 22
tcp6    0    0 :::22    :::*    LISTEN

如您所见,SSH仅侦听::端口22。但是,它不仅侦听IPv6客户端,而且由于IPv4兼容的绑定,它在IPv4客户端也可以正常工作。为了证明这一点,如果您看一下:

$ cat /proc/sys/net/ipv6/bindv6only 
0

bindv6only禁用(默认)。如果将其设置为1,那么我将不得不鼓励SSH也监听0.0.0.0(或改为监听)。

很抱歉在Mac OS X方面没有任何信息。我过去曾经使用过它,但是我更喜欢GNOME的美学,因此我已经很长时间没有使用它了。但是,我想它的行为与Linux相同。

希望这可以帮助。


4

这是不可能的,因为IPv6地址空间的一部分与IPv4空间相同,因此,即使您可以某种方式禁用IPv4套接字,您仍然可以将IPv4数据包发送到IPv6套接字。在IPv4 Wikipedia页面中检出IPv4过渡部分。

编辑:啊,它的确更进一步说:

某些常见的IPv6堆栈不支持IPv4映射地址功能,原因是IPv6和IPv4堆栈是单独的实现(Vista / Longhorn之前的Microsoft Windows:例如XP / 2003),或者是出于安全考虑(OpenBSD)。在这些操作系统上,有必要为要支持的每个IP协议打开一个单独的套接字。在某些系统(例如Linux,NetBSD,FreeBSD)上,此功能由RFC 3493中指定的套接字选项IPV6_V6ONLY控制

-1

您可以使用您的网络ID AAAA:BBBB:CCCC:DDDD ::或任何适合您的网络ID来完成此操作。这样可以确保只有IPv6接口可以选择它。我认为。我不是IPv6主服务器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.