為什麼 MASQUERADE SNAT 可以阻止 localhost 連接?
我在 linux 上觀察到一個奇怪的行為:
首先,我清理所有路由和 iptables 規則:
ip route flush table main ip route flush table default ip route flush table local iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -t nat -F iptables -t mangle -F iptables -F iptables -X ip6tables -P INPUT ACCEPT ip6tables -P FORWARD ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -t nat -F ip6tables -t mangle -F ip6tables -F ip6tables -X
然後我添加一個本地路由:
ip route add local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 table local
然後,在一個終端上我打開一個埠,
nc -lp 12345
在另一個終端上我連接到它,nc 127.0.0.1 12345
我可以在 netcat 伺服器和客戶端之間發送和接收數據。所以現在,一切都很好。現在,從它並在殺死以前的 netcat 伺服器和客戶端之後,如果我執行:
iptables -t nat -A POSTROUTING -j MASQUERADE
然後我重新啟動 netcat 伺服器,然後客戶端無法連接。你知道為什麼嗎?
我注意到添加
ip route add local 192.168.0.10 dev wlan0 proto kernel scope host src 192.168.0.10 table local
使 netcat 連接再次起作用。但是,我不明白為什麼 wlan0 介面(IP 為 192.168.0.10)會影響環回介面?有關資訊,我正在使用 ArchLinux
我不知道這是錯誤還是故意的回退行為,但從我這裡可以看到,它與
wlan0
您提到的本地路由或所有預設網關等等都沒有任何關係(沒有冒犯,但它幾乎對我來說沒有意義)在另一個/“正確”答案中說明。通常
MASQUERADE
工作原理是,它為它執行的源 NAT選擇在出站介面上配置的地址(由路由確定,因此是)。POSTROUTING
(如果介面上分配了多個地址,它可能會選擇第一個或在相應路由中設置為首選源地址的一個;我不太熟悉,這裡超出範圍反正)。與預設路由的下一跳/網關地址無關。(無論如何,源 NAT 不是這樣工作的。)但是,當涉及到界面時
lo
,事情似乎變得有些棘手。更準確地說,它似乎與介面本身無關(除了它將是出站介面,因為目標是本地地址),而是127.0.0.0/8
塊中的地址不是範圍global
。雖然我不知道幕後發生了什麼,但如果主機沒有global
配置範圍 IP 地址但嘗試MASQUERADE
.我在這裡看到的是,即使您只是在任何介面(包括)上配置了一個對范圍
global
(例如)有效的地址,您也會看到它再次起作用。(您提到的本地路線將自動添加。但我沒有看到僅添加路線在這裡有效。)192.168.0.10/32``lo
值得一提的是,地址和介面在 Linux 中並沒有緊密綁定在一起(不是以直接的方式,只有當目標地址與入站介面上配置的地址匹配時,它才會回复流量,即使 IP 轉發是不關心)。所以它可能與此有關:如果
MASQUERADE
無法global
從出站介面上配置的內容中選擇範圍地址,它只是從任何中選擇一個(我懷疑優先級與預設路由有關),如果仍然不,它只是拒絕以某種方式工作。如果您確實需要
MASQUERADE
在所有介面上啟用的規則,但是lo
,您可以擁有:iptables -t nat -A POSTROUTING ! -o lo -j MASQUERADE