Linux iptables ssh 埠轉發(火星拒絕)
我有一個為我的家庭網路執行 NAT 的 Linux 網關。我有另一個網路,我想將數據包透明地轉發到,但只能轉發到/來自特定 IP/埠(即不是 VPN)。以下是一些可使用的範例 IP 和埠:
Source Router Remote Gateway Remote Target 192.168.1.10 -> 192.168.1.1 -> 1.2.3.4 -> 192.168.50.50:5000
我希望源機器能夠與遠端目標上的特定埠通信,就好像它可以直接從路由器路由一樣。在路由器上,eth0 是專用網路,eth1 是面向網際網路的。遠端網關是另一台我可以通過 ssh 進入的 Linux 機器,它可以直接路由到遠端目標。
我嘗試一個簡單的解決方案是在路由器上設置 ssh 埠轉發,例如:
ssh -L 5000:192.168.50.50:5000 1.2.3.4
這適用於路由器,它現在可以本地連接到埠 5000。因此“telnet localhost 5000”將按預期連接到 192.168.50.50:5000。
現在我想通過現在建立的 ssh 隧道重定向來自 Source 和漏斗的流量。我為此嘗試了一個 NAT 規則:
iptables -t nat -D PREROUTING -i eth0 -p tcp -s 192.168.1.10 --dport 5000 -d 1.2.3.4 -j DNAT --to-destination 127.0.0.1:5000
並且由於路由器已經是我的 NAT 網關,它已經具有所需的後路由規則:
-A POSTROUTING -s 192.168.1.0/24 -o eth1 -j MASQUERADE
本網站或其他地方的大多數問答似乎都處理轉發伺服器埠或髮夾 NAT,我在其他地方都可以正常工作,但都不適用於這種情況。我當然可以通過遠端網關 DMZ 轉發遠端目標埠,但我不希望這些埠可以通過網際網路訪問,我希望它們只能通過安全的 SSH 隧道訪問。
我能找到的最佳答案與 Linux 核心中的火星數據包拒絕有關:
我已經啟用了火星人的日誌記錄,並確認核心將這些數據包作為火星人拒絕。除了它們不是:我確切地知道這些數據包的用途,它們來自哪里以及它們要去哪裡(我的 ssh 隧道)。
那裡提出的“迂迴”解決方案適用於那個原始問題,但不適用於我的情況。
但是,在編寫/研究這個問題時,我已經通過使用 SSH 源 IP 綁定來解決我的問題,如下所示:
ssh -L 192.168.1.1:5000:192.168.50.50:5000 1.2.3.4 iptables -t nat -D PREROUTING -i eth0 -p tcp -s 192.168.1.10 --dport 5000 -d 1.2.3.4 -j DNAT --to-destination 192.168.1.1:5000
因為我沒有使用環回,所以這繞過了火星拒絕。
我仍然在這裡發布問題有兩個原因:
- 希望將來嘗試做類似事情的人可能會在他們的搜尋中發現這一點,而這種解決方法可能會對他們有所幫助。
- 我仍然更喜歡保持我的 ssh 埠轉發連接僅綁定到環回並能夠通過 iptables 路由到它們的想法。既然我確切地知道這些數據包是什麼以及它們要去哪裡,難道我不應該有某種方法來標記它們,這樣 Linux martian 過濾器就不會拒絕它們嗎?我在這個主題上的所有搜尋都導致了 rp_filter,這對我的測試沒有任何幫助。即使它確實有效,它也不是特定於我試圖允許的確切數據包。
我有興趣將我的問題和解決方法貢獻給一般搜尋,以節省其他人的搜尋時間,我只是想出死胡同,並希望有人回答我的問題的環回/火星部分仍然開放對我來說。
對 127.0.0.1:5000 執行 DNAT 的問題在於,當遠端端響應時,這些數據包返回到路由引擎,就好像它們來自本地(來自 127.0.0.1)但它們具有外部目標地址。與外部介面匹配的 SNAT/MASQUERADE 會擷取並重寫它們,但是必須首先做出使數據包到達該介面的路由決策,並且它們不允許這些預設情況下偽造的數據包。路由引擎不能保證你以後會記得重寫。
您應該能夠做的事情是在 iptables INPUT 上拒絕任何與 192.168.1.1:5000 的外部連接,而不是使用源地址規範
!
之前的參數來自 192.168.1.10 的外部連接。-s
如果您使用 TCP 重置作為拒絕機制(-j REJECT --reject-with tcp-reset
,而不是預設的 ICMP 目標不可達),那麼就外部世界而言,它與甚至沒有任何東西監聽該地址:埠組合的情況基本相同。