在仅限 IPv4 的时代,显示netstat
为正在监听的LISTEN 连接0.0.0.0
将响应系统中任何 IPv4 接口上的连接。
据我了解,新的 IPv6 习惯用法::
监听所有可用的 IPv6和IPv4 接口。对于所有操作系统(Unix、Windows、Mac),这是否正确?是否有只在 IPv6 接口上监听的习惯用法?
答案1
不幸的是,这取决于您使用的操作系统。
在 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
这会变得很棘手。如果设置为,则上述情况不适用于 Linux 1
,在这种情况下,行为与 Windows 完全相同——绑定到::
将仅侦听 IPv6 请求。如果您还想侦听 IPv4 请求,则需要创建一个AF_INET
套接字并侦听。幸运的是0.0.0.0
, 的默认值为,因此您极有可能不得不处理这个问题(除非您使用 Debian,它实际上默认为)。bindv6only
0
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
,那么我必须鼓励 SSH0.0.0.0
也进行监听(或代替监听)。
抱歉,我没有关于 Mac OS X 方面的信息。我以前用过它,但我更喜欢 GNOME 的美感,所以我很长时间没用它了。不过,我猜它的行为和 Linux 的行为是一样的。
希望这可以帮助。
答案2
这是不可能的,因为 IPv6 地址空间的一部分与 IPv4 空间相同,所以即使你能以某种方式禁用 IPv4 套接字,你仍然可以将 IPv4 数据包发送到 IPv6 套接字。请查看IPv4 维基百科页面。
编辑:啊,再往下一点确实说了:
一些常见的 IPv6 堆栈不支持 IPv4 映射地址功能,这是因为 IPv6 和 IPv4 堆栈是单独的实现(Vista/Longhorn 之前的 Microsoft Windows:例如 XP/2003),或者出于安全考虑(OpenBSD)。在这些操作系统上,需要为要支持的每种 IP 协议打开单独的套接字。在某些系统(例如 Linux、NetBSD、FreeBSD)上,此功能由套接字选项 IPV6_V6ONLY 控制,如RFC 3493
答案3
您可能可以使用您的网络 ID 来执行此操作,AAAA:BBBB:CCCC:DDDD:: 或任何适合您的 ID。这将保证只有 IPv6 接口会接收它。我想。我不是 IPv6 大师。