Linux

為什麼 MASQUERADE SNAT 可以阻止 localhost 連接?

  • July 17, 2021

我在 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

引用自:https://serverfault.com/questions/1069718