最近租了一台便宜的雲主機。我想把雲主機的公網ip上的一些端口映射到宿舍台式機上的一些服務上(例如SSH、jupyter lab),這樣就可以遠程登陸管理自己的台式機了。
我採取的辦法是
- 使用Zerotier組成一個局域網,使得雲主機和宿舍台式機可以互相訪問;
- 使用端口映射,將宿舍台式機的服務暴露到公網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端口為例):
=0.0.0.0 listenport=8888 connectaddress=localhost connectport=8888 netsh interface portproxy add v4tov4 listenaddress
刪除轉發規則:
=0.0.0.0 listenport=8888 netsh interface portproxy delete v4tov4 listenaddress
4 後記
本文的背景是將自己台式機上的一些網絡服務暴露到公網。這其實還蠻危險的,需要注意
- 可以盡量改用比較複雜的密碼
- 不使用默認的端口號,例如不把SSH服務開放在22端口,而是隨機選擇一個端口
- 能不開放的服務盡量不開放,而只在要使用的時候,臨時搭一個端口映射。例如可以臨時用ssh命令搭一個端口映射,用完就關閉