看了不少關于用Iptables實作端口轉發的文章,但感覺都沒有把問題說得很清楚,現接合我自己設定和使用的經曆,談談它的實作過程.
設我們有一台計算機,有兩塊網卡,eth0連外網,ip為1.2.3.4;eth1連内網,ip為192.168.0.1.現在需要把發往位址1.2.3.4的81端口的ip包轉發到ip位址192.168.0.2的8180端口,設定如下:
1. Iptables -t nat -A PREROUTING -d 1.2.3.4 -p tcp -m tcp --dport 81 -j DNAT --to-destination192.168.0.2:8180
2. Iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.0.0 -d 192.168.0.2 -p tcp -m tcp --dport 8180 -j SNAT --to-source 192.168.0.1
真實的傳輸過程如下所示:
假設某客戶機的ip位址為6.7.8.9,它使用本機的1080端口連接配接1.2.3.4的81端口,發出的ip包源位址為6.7.8.9,源端口為1080,目的位址為1.2.3.4,目的端口為81.
主機1.2.3.4接收到這個包後,根據nat表的第一條規則,将該ip包的目的位址更該為192.168.0.2,目的端口更該為8180,同時在連接配接跟蹤表中建立一個條目,(可從/proc/net/ip_conntrack檔案中看到),然後發送到路由子產品,通過查路由表,确定該ip包應發送到eth1接口.在向eth1接口發送該ip包之前,根據nat表的第二條規則,如果該ip包來自同一子網,則将該ip包的源位址更該為 192.168.0.1,同時更新該連接配接跟蹤表中的相應條目,然後送到eth1接口發出.
此時連接配接跟蹤表中有一項:
連接配接進入: src=6.7.8.9 dst=1.2.3.4 sport=1080 dport=81
連接配接傳回: src=192.168.0.2 dst=6.7.8.9 sport=8180 dport=1080
是否使用: use=1
而從192.168.0.2發回的ip包,源端口為8180,目的位址為6.7.8.9,目的端口為1080,主機1.2.3.4的TCP/IP棧接收到該ip包後,由核心查找連接配接跟蹤表中的連接配接傳回欄目中是否有同樣源和目的位址和端口的比對項,找到後,根據條目中的記錄将ip包的源位址由 192.168.0.2更該為1.2.3.4, 源端口由8180更該為81,保持目的端口号1080不變.這樣伺服器的傳回包就可以正确的傳回發起連接配接的客戶機,通訊就這樣開始.