雙棧作業系統中 :: 和 0.0.0.0 的語義
netstat
回到純 IPv4 時代,顯示為正在偵聽的 LISTEN 連接0.0.0.0
將響應系統中任何 IPv4 介面上的連接。據我了解,新的 IPv6 慣用語
::
偵聽所有可用的 IPv6和IPv4 介面。對於所有作業系統(Unix、Windows、Mac),這是否正確?是否有隻聽 IPv6 介面的習慣用法?
不幸的是,這取決於您使用的作業系統。
在 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
連接到它,它將顯示為正在連接 from::ffff:10.1.1.3
。除了它會長毛。
/proc/sys/net/ipv6/bindv6only
如果設置為,則上述內容不適用於 Linux1
,在這種情況下,行為與 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
,那麼我將不得不鼓勵 SSH0.0.0.0
也(或相反)收聽。抱歉沒有關於 Mac OS X 方面的資訊。以前用過,不過我更喜歡GNOME的美學,所以很久沒用了。但是,我猜想這種行為與 Linux 的行為相同。
希望這可以幫助。