記錄一些端口映射的配置命令:iptables、ssh和netsh

本文瀏覽次數

Published

December 1, 2024

最近租了一台便宜的雲主機。我想把雲主機的公網ip上的一些端口映射到宿舍台式機上的一些服務上(例如SSH、jupyter lab),這樣就可以遠程登陸管理自己的台式機了。

我採取的辦法是

  1. 使用Zerotier組成一個局域網,使得雲主機和宿舍台式機可以互相訪問;
  2. 使用端口映射,將宿舍台式機的服務暴露到公網ip上;

在這個背景下,我寫下這篇筆記來記錄使用iptables配置端口映射的方法,同時順帶記錄一下如何用ssh命令以及Windows下的netsh命令配置端口映射。這幾種方法都很常用。

1 用iptables配置端口映射

在Linux系統上,可以使用iptables命令來配置端口的轉發規則。端口轉發技術允許網絡流量從一個端口轉發到另一個端口,通常是將流量從一個網絡接口轉發到另一個網絡接口上的不同端口。

例如,假設我們有A主機及其端口P_A, B主機及其端口P_B,我們想將P_A端口映射到B主機的P_B端口。假如P_B端口對應著B主機的ssh服務,那麼經過端口映射,我們可以使用

ssh ${USER_NAME}@${A} -p ${P_A}

命令來訪問P_B主機的服務。這裡我用${A}表示A主機的IP地址,${P_A}表示端口號。

1.1 添加規則

要實現這個任務,可以在A主機上使用以下命令:

sudo iptables -t nat -A PREROUTING -p tcp --dport ${P_A} -j DNAT --to-destination ${B}:${P_B}

這裡-t nat選項指定了要操作的表(table)。nat(network address translation)表用於網絡地址轉換,包括源地址轉換(SNAT)和目的地址轉換(DNAT)。-A是Append的縮寫,表示將一條規則添加到指定的鏈(chain)的末尾。PREROUTING是nat表中的一個鏈,用於處理進入(ingress)流量,在路由決策之前應用NAT規則。-p tcp這個選項指定了要匹配的協議類型,這裏是tcp,表示這條規則只適用於TCP協議的流量。--dport指定了要匹配的目的端口。-j是jump的縮寫,指定了匹配規則後的動作。DNAT表示目的地址轉換,即修改流量的目的IP地址。--to-destination選項指定了DNAT的目標地址和端口。

除了PREROUTING規則,你還需要添加一條命令處理POSTROUTING時的轉發:

sudo iptables -t nat -A POSTROUTING -p tcp -d ${B} --dport ${P_B} -j MASQUERADE

這裡MASQUERADE是一種特殊的NAT操作,用於動態地將出站流量的源地址替換爲出口接口的地址。這通常用於撥號或移動網絡,其中IP地址可能會變化。

這時,你就可以從第三個主機C嘗試訪問主機A上的P_A端口了。

假如不使用第三台機器,而是從主機A上訪問P_A端口,流量會無法轉發到B主機的P_B端口。這是因為來自主機A內部的連接不會經過PREROUTE規則。如果你想處理來自主機A內部的連接,可以增加一條命令:

sudo iptables -t nat -A OUTPUT -p tcp --dport ${P_A} -j DNAT --to-destination ${B}:${P_B}

這條命令應用於OUTPUT鏈,可以處理從主機A內部發起的連接。

1.2 羅列現有的NAT規則

可以用如下命令列出所有的NAT規則。

sudo iptables -t nat -L

1.3 刪除iptables的NAT規則

在羅列NAT規則時,我們可以讓iptables命令顯示每條規則的行號,然後用行號告訴iptables我們想刪除哪條規則:

sudo iptables --list -t nat -n --line-numbers

sudo iptables -t nat -D POSTROUTING 2  # ←刪除POSTROUTING鏈下的第二條規則

1.4 iptables規則的保存

用上面的命令設置的規則在機器重啟後將會丟失,你需要通過額外的命令將iptables的規則保存下來。

在Ubuntu 18.04 LTS系統上,可以用下面的命令保存iptables的規則:

sudo apt install iptables-persistant

執行該命令後,程序將詢問你是否保存規則。

後續你還可以通過使用sudo netfilter-persistent save命令,將iptables規則的更改保存下來。

2 SSH搭建端口映射

ssh命令也提供了一個非常方便的搭建端口映射的辦法:

ssh -L <本地的一個空閒端口>:$B:$P_B <用戶名>@$A

這段命令會將指定的本地端口映射到B主機的P_B端口。前提是你能登陸A主機,且A主機能夠訪問B主機的P_B端口。

3 在Windows的Powershell中配置端口映射

Windows系統帶有netsh命令,可以幫助你配置端口映射規則,使用方法如下。

首先你需要以管理員身份打開Powershell,然後才能執行各命令。

查看所有端口映射規則:

netsh interface portproxy show all

添加端口映射規則,(以8888端口為例):

netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8888 connectaddress=localhost connectport=8888

刪除轉發規則:

netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8888

4 後記

本文的背景是將自己台式機上的一些網絡服務暴露到公網。這其實還蠻危險的,需要注意

  1. 可以盡量改用比較複雜的密碼
  2. 不使用默認的端口號,例如不把SSH服務開放在22端口,而是隨機選擇一個端口
  3. 能不開放的服務盡量不開放,而只在要使用的時候,臨時搭一個端口映射。例如可以臨時用ssh命令搭一個端口映射,用完就關閉
By @執迷 in
Tags : #端口映射, #iptables, #網絡技術, #Linux,