用Linux作「多進多出」的NAT

NAT伺服器除了很標準的「只有一個對外IP」外,也有一些變形作法像是「有兩個對外IP」的NAT就是一種(通常稱為DualWan),這種NAT伺服器在家裡可以輕鬆的把兩條線路(例如吃到飽的3.5G上網與ADSL線路)合併成一條,讓下載速度更快。

但是如果今天的狀況是,我想花錢跟中華電信多租一條線路,但是我不想重新拉房子的線、也不想多買一台IP分享器,而這條線路我要獨享,該怎麼作呢?呆呆和上網找了蠻多說明,不過都沒有解決到適合的答案,所以到處尋找再加上一點自己的嘗試後,終於做出來了。為了避免自己忘記,就把過程記錄下來。

首先,當然是要先把多的對外介面卡都先設定好才行囉,CentOS、Red Hat Enterprise Linux或Fedora的多網路設定資料蠻多的,如果你的虛擬主機商只有給你「CentOS的設定」,可以參考一下呆呆翰幾個月前寫的文章——RHEL與Debian的多網路設定

呆呆翰的主機網路設定如下:

## 對外網路卡
eth0   157.1.1.2/24 使用預設(main)路由表
eth1   157.1.2.2/24 使用gw2路由表
eth1:0 157.1.2.3/24 使用gw3路由表

## 對內網路卡,根據使用者設定不同的IP,從不同的IP出去
## Client設定192.168.2.0/24的IP,就以157.1.1.2出去
## Client設定192.168.3.0/24的IP,就以157.1.2.2出去
## Client設定192.168.4.0/24的IP,就以157.1.2.3出去
eth2   192.168.2.1/24
eth2:0 192.168.3.1/24
eth2:1 192.168.4.1/24

都設定好之後,可用下面幾個指令確認設定:
# ip addr show:查詢設定的IP
# ip route show:查詢預設路由表的設定
# ip route show table gw2:查詢gw2路由表的設定

用ip route 2把IP跟路由表都設定好、並確認沒問題後,我們還得把預設路由表當中的路由規則,寫入其他的路由表才行。除了一行一行輸入外,其實有個更偷懶的方法可以把預設路由表的內容複製到其他路由表:
# ip route show | grep -Ev ^default | while read ROUTE
# do
#     ip route add table gw2 $ROUTE
# done

如果有多張路由表,那麼在外面多加一層for迴圈也可以輕鬆搞定,而且要寫進成可執行的腳本時,也不用擔心要常常更改一堆設定。

完成後,可以再次使用# ip route show table gw2指令檢查路由表設定是否正確。

好了以後,開始準備NAT的相關設定了。

千萬別忘了把/etc/sysctl.conf中的net.ipv4.ip_forward改成1喔,不然Linux是不能作封包轉發的。

如果不想重開主機,可以用# echo 1 > /proc/sys/net/ipv4/ip_forward直接把封包轉發的功能打開(但是只要重開機就會變回/etc/sysctl.conf裡面的設定囉)。

開啟封包轉發之後,接著我們要先用iptables設定SNAT(根據來源修改封包上IP位置):
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 157.1.1.2
# iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 157.1.2.2
# iptables -t nat -A POSTROUTING -o eth1:0 -j SNAT --to-source 157.1.2.3

設定好SNAT之後,應該會發現所有的對內網路都通了,只是出去之後IP都是157.1.1.2對吧?

這時候我們可以用iptables先幫特定的(非192.168.2.0/24網路)過來的封包,打上記號:
# iptables -t mangle -A PREROUTING -s 192.168.2.0/24 -j MARK --set-mark 2
# iptables -t mangle -A PREROUTING -s 192.168.3.0/24 -j MARK --set-mark 3

打上記號以後,如果沒有對應的動作,也只是打辛酸的。所以我們再次使用ip route 2設定,把有記號的封包丟進特定的路由表:
# ip rule add fwmark 2 table gw2
# ip rule add fwmark 3 table gw3

設定都差不多了以後,我們就要清除ip route 2的cache,讓剛剛做好的設定起作用囉(iptables指令輸入完馬上就起作用了,不需另外處理):
# ip route flush cache

這時候,底下的電腦如果設定了192.168.3.0/24的IP、閘道也設定為192.168.3.1,對外的IP就會變成157.1.2.2而不是157.1.1.2囉!!

那麼,這樣的設定可以幹嘛嗎?

有啊,除了前面講的「兩條線路兩組人馬各用各的」外,也可以設定「往學網就走學校無線網路、往日本就走HiNET、往YouTube就走So-NET」等等,只要稍微修改一下「幫封包打記號」的部分就行。

又或者是「我有一隻3G吃不飽的門號,想作為家裡網路爆炸時,連入伺服器的線路,但是我希望家裡其他人不會用到這條線路」,那麼這也行!

如果有錯誤,歡迎提出指正,也歡迎在下面討論。

參考資料:

徐秉義:實做多條 WAN 線路 NAT 主機
linux-ip.net: 10.4. Multiple Connections to the Internet

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料