作者 主題: [心得] 五張網卡 (3 wan+2 Lan) 的 NAT 與 iproute2 整合連線全紀錄  (閱讀 19178 次)

0 會員 與 1 訪客 正在閱讀本文。

apage

  • 活潑的大學生
  • ***
  • 文章數: 337
    • 檢視個人資料
iproute2 心得

事由:

公司原本使用兩條 ADSL 線路,
一條是 seednet 雙向 512K,固五 IP,另一條是 HiNet 12M/1M 固三ADSL,
原本是使用一台 CentOS 3.5 的機器當作 SeedNet 那條專線的防火牆與 NAT,
同時本身也跑 DNS 跟 Mail 服務;
另外 HiNet 那條原來則是使用一台破破的 IP 分享器分享讓公司內部員工上網。

進入公司一陣之後,公司的另一個專案即將上線,
並告知要新申請一條專案專用的線路,

在這之前,我為了將 HiNet ADSL 固三的 IP 完全利用,
就先架了一台 NAT,這樣就可以把那台 IP 分享器給汰換下來,也順便弄了 Qos 控管 P2P 上傳量;
那台 Server 在當時已經使用了三張網卡。
先簡介一下:

eth0:接 HiNet ADSL 對外線路。
eth1:接公司區域網路員工專用網段。
eth2:接公司區域網路 Server 專用網段。


那專案專用的線路要怎麼裝呢?由於該專線以後需要使用到許多服務,
因此我也是打算使用那台 NAT Server 來整合,加上公司使用量也還好,
我也偷偷計畫要將原本所使用的 SeedNet 雙向 512K 線路整合,
就等於把三條的線路整合在一台機器上!(真是雄心壯志不怕死)

所以就再度買了兩張網卡,總共五張!

eth3:接新的專案專用線路。
eth4:接舊有 SeedNet 雙向 512K 線路。


PS:為了求效能,我買的網卡全都是 3c59x (這是 lsmod 看到的模組名稱啦)
每張約 $1300 (當然,身為上班族本身是很窮的,也只有是公司才能這樣玩囉!)

順便介紹一下機器的硬體 (硬體不強一點,效能會很差)

Motherboard: nForce 3 內建網卡音效全都停掉了。
CPU:AMD Athlon XP 系列之 Barton 2500+
RAM:DDR 333 256x2
算是蠻新的配備,插五張網卡沒事應該就是 IRQ 有 share 功能,因為舊版子這樣玩會衝來衝去。

那就開始設定 IP 吧!
由於每個對外連線的 ISP 都不只配發給公司一個IP,
所以就需要把 ISP 所配發的 IP 統統綁在該張對應連線的網卡上面。
用虛擬網卡的方式來綁,設定方式請參考基礎文件或文章;

eth0 的 IP = (for Example: 0.0.0.1) HiNet 提供。
eth0:0 的 IP = (for Example 0.0.0.2) HiNet 提供。
eth0:1 的 IP = (for Example 0.0.0.3) Hinet 提供。

#第一條線路的 IP ,有幾個 IP 就虛擬幾張網卡;以上為三個IP。

eth1 的 IP = 192.168.1.254
eth2 的 IP = 192.168.0.254

#這台機器本身的區網 IP,由於 0 網段與 1網段各有各的流量,因此不建議用虛擬網卡的方式去做。

eth3 的IP = (for Example: 1.0.0.1) ISP 提供。
eth3:0 的 IP = (for Example: 1.0.0.2) ISP 提供。
eth3:1 的 IP = (for Example: 1.0.0.3) ISP 提供。
eth3:2 的 IP = (for Example: 1.0.0.4) ISP 提供。
eth3:3 的 IP = (for Example: 1.0.0.5) ISP 提供。

#第二條線路的 IP,有幾個 IP 就虛擬幾張網卡。

eth4 的 IP = (for Example: 2.0.0.1) SeedNet 提供。
eth4:0 的 IP = (for Example: 2.0.0.2) SeedNet 提供。
eth4:1 的 IP = (for Example: 2.0.0.3) SeedNet 提供。
eth4:2 的 IP = (for Example: 2.0.0.4) SeedNet 提供。
eth4:3 的 IP = (for Example: 2.0.0.5) SeedNet 提供。

#第三條線路的 IP,有幾個 IP 就虛擬幾張網卡。

別忘了以 ping 跟 traceroute 確定連線,要先確認連線沒有問題,接下來的設定才可以一氣呵成。

確認沒問題之後,就可以開始設定了,總共要做的事情有三件:

1.作 nat
    a.作 gateway ( IP Forward )
2.作 iptables
    a.設定防火牆。
3,作 iproute2
    a.新增 routing table
    b.新增 rule 指定連線要走的 routing table
    c.清除 route cache 使之馬上生效


這三件事我分別用三個 shell script 來執行,
首先是 nat.sh 的設定:
代碼: [選擇]
#宣告變數
#網路介面卡對應
eth_wan_h="eth0"
#這張屬於 HiNet 對外網卡,取名為 eth_wan_h 方便辨認。
eth_lan_1="eth1"
#這張是客端網段,取名為 eth_lan_1 方便辨認。
eth_lan_0="eth2"
#這張是 Server 網段,取名為 eth_lan_0。
eth_wan_p="eth3"
#這張是專案專用線路,取名為 eth_wan_p。
eth_wan_sd="eth4"
#這張是舊有 Server 專用 seednet 線路,取名為 eth_wan_sd!

宣告好基本的變數之後,再宣告網段,方便稍後規劃 NAT 連線,這樣就不必每次都輸入目標IP了!
由於整個 LAN 只有被規劃成 Server 與 Client 兩個網段,因此就只要宣告兩個變數:
代碼: [選擇]
net_lan_0="192.168.0.0/24"
#這是 Server 專用網段,取名為 net_lan_0 代表!
net_lan_1="192.168.1.0/24"
#這是 User專用網段,取名為 net_lan_1!

宣告好之後自然就要輸出變數
代碼: [選擇]
#輸出變數
export PATH eth_wan_h eth_lan_0 eth_lan_1 net_lan_0 net_lan_1 eth_wan_4p eth_wan_sd

接著就是打開 Linux 基本的 router 功能!
代碼: [選擇]
#IP_Forward,打開router功能
echo "1" > /proc/sys/net/ipv4/ip_forward

以上提到的總結 nat.sh 的 shell script 內容為:
代碼: [選擇]
#!/bin/sh
eth_wan_h="eth0"
eth_lan_1="eth1"
eth_lan_0="eth2"
eth_wan_p="eth3"
eth_wan_sd="eth4"
net_lan_0="192.168.0.0/24"
net_lan_1="192.168.1.0/24"
export PATH eth_wan_h eth_lan_0 eth_lan_1 net_lan_0 net_lan_1 eth_wan_4p eth_wan_sd
echo "1" > /proc/sys/net/ipv4/ip_forward

現在 route 功能已經打開了,下一個要設定的是 nat,
以下這些語法是一定要載入的,因為是使用 iptables 模組做的。
代碼: [選擇]
modprobe ip_tables  2> /dev/null
#載入 iptables 模組,由於已經載入的話會有錯誤訊息,
#因此直接把訊息導入 /dev/null (這個動作就等於直接刪除該訊息)

然後要把 iptables 的規則做初始設定:
代碼: [選擇]
/usr/local/sbin/iptables -F
/usr/local/sbin/iptables -X
/usr/local/sbin/iptables -Z
/usr/local/sbin/iptables -F -t nat
/usr/local/sbin/iptables -X -t nat
/usr/local/sbin/iptables -Z -t nat
/usr/local/sbin/iptables -P INPUT DROP
/usr/local/sbin/iptables -P OUTPUT ACCEPT
/usr/local/sbin/iptables -P FORWARD ACCEPT
/usr/local/sbin/iptables -t nat -P PREROUTING ACCEPT
/usr/local/sbin/iptables -t nat -P POSTROUTING ACCEPT
/usr/local/sbin/iptables -t nat -P OUTPUT ACCEPT

接著就是開始規劃 nat 的設定:
代碼: [選擇]
/usr/local/sbin/iptables -A INPUT -i lo -j ACCEPT
#這個比較重要,大部分都保留著。
/usr/local/sbin/iptables -A INPUT -i $eth_lan_0 -j ACCEPT
/usr/local/sbin/iptables -A INPUT -i $eth_lan_1 -j ACCEPT
#接下來這個是同意網路介面可以通過這台機器做連線,除了 lo 那個拿掉可能會有問題之外,
#其他的意義就是讓 User 網段與 Server 網段都可以通過這台機器,
#互相 ping 到對方網段的 IP,或是連外上網。

然後就是設定對外網路介面了,語法如下:
代碼: [選擇]
/usr/local/sbin/iptables -t nat -A POSTROUTING -s $net_lan_1 -o $eth_wan_h -j MASQUERADE
#讓 User 的網段可以通過 HiNet 的介面出去上網。
/usr/local/sbin/iptables -t nat -A POSTROUTING -s $net_lan_0 -o $eth_wan_h -j MASQUERADE
#讓 Server 的網段可以通過 HiNet 的介面出去上網。
/usr/local/sbin/iptables -t nat -A POSTROUTING -s $net_lan_0 -o $eth_wan_4p -j MASQUERADE
#讓 Server 的網段可以通過專案專用的專線出去上網。
/usr/local/sbin/iptables -t nat -A POSTROUTING -s $net_lan_0 -o $eth_wan_sd -j MASQUERADE
#讓 Server 的網段可以通過 SeedNet 的專線出去上網。

另外,還需要允許連續性的封包不用一個一個等著通過:
代碼: [選擇]
/usr/local/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
由於這台 NAT 主機一開始就是使用 HiNet 對外連線,因此它預設的 routing table 是 HiNet 的,
所以,雖然可以打開每個連線的 NAT 功能,但是不用 iproute2 的語法做指定的話是無法隨心所欲
的讓你想要的機器透過其他線路出去。

記住,上面的設定是讓連線端『可以』透過該介面出去上網,不代表你設定了之後,
連線端一定會用你指定的介面出去。
這就是我們為什麼需要用 iproute2 的原因了,我們需要多個路由表來指定連線。

到此為止,nat.sh 算是告一個段落。
以下是 nat.sh 到目前為止所有的內容:
代碼: [選擇]
eth_wan_h="eth0"
eth_lan_1="eth1"
eth_lan_0="eth2"
eth_wan_p="eth3"
eth_wan_sd="eth4"
net_lan_0="192.168.0.0/24"
net_lan_1="192.168.1.0/24"
export PATH eth_wan_h eth_lan_0 eth_lan_1 net_lan_0 net_lan_1 eth_wan_4p eth_wan_sd
echo "1" > /proc/sys/net/ipv4/ip_forward

modprobe ip_tables  2> /dev/null
/usr/local/sbin/iptables -F
/usr/local/sbin/iptables -X
/usr/local/sbin/iptables -Z
/usr/local/sbin/iptables -F -t nat
/usr/local/sbin/iptables -X -t nat
/usr/local/sbin/iptables -Z -t nat
/usr/local/sbin/iptables -P INPUT DROP
/usr/local/sbin/iptables -P OUTPUT ACCEPT
/usr/local/sbin/iptables -P FORWARD ACCEPT
/usr/local/sbin/iptables -t nat -P PREROUTING ACCEPT
/usr/local/sbin/iptables -t nat -P POSTROUTING ACCEPT
/usr/local/sbin/iptables -t nat -P OUTPUT ACCEPT

/usr/local/sbin/iptables -A INPUT -i lo -j ACCEPT
/usr/local/sbin/iptables -A INPUT -i $eth_lan_0 -j ACCEPT
/usr/local/sbin/iptables -A INPUT -i $eth_lan_1 -j ACCEPT

/usr/local/sbin/iptables -t nat -A POSTROUTING -s $net_lan_1 -o $eth_wan_h -j MASQUERADE
/usr/local/sbin/iptables -t nat -A POSTROUTING -s $net_lan_0 -o $eth_wan_h -j MASQUERADE
/usr/local/sbin/iptables -t nat -A POSTROUTING -s $net_lan_0 -o $eth_wan_4p -j MASQUERADE
/usr/local/sbin/iptables -t nat -A POSTROUTING -s $net_lan_0 -o $eth_wan_sd -j MASQUERADE

/usr/local/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT



前面提到,需要 iproute2 來指定連線,那麼事前需要甚麼準備呢?
當然是需要,只要確認系統有沒有安裝這個套件就可以了,請執行:
代碼: [選擇]
$rpm -qa|grep iproute
只要出現
代碼: [選擇]
iproute-2.x.x-x
就是有裝了。

確認之後,首先要新增規則,
先開啟/etc/iproute2/rt_tables
設定要新增的 table:
代碼: [選擇]
100 hinet
150 seednet
200 isp

然後就可以開始進行各個 table 的設定,
這裡我是參考原本預設的路由表進行設定,
代碼: [選擇]
[root@dhcp ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.2.0   *               255.255.255.0 U     0      0        0 eth3
0.0.3.0   *               255.255.255.0 U     0      0        0 eth4
0.0.1.0    *               255.255.255.0   U     0      0        0 eth0
192.168.0.0     *               255.255.255.0   U     0      0        0 eth2
192.168.168.0   *               255.255.255.0   U     0      0        0 eth1
default         0.0.1.254 0.0.0.0         UG    0      0        0 eth0

上面可看到,default gateway 是使用 hinet 的,
就照樣的把這個路由表輸入到 hinet 的 table 中:
代碼: [選擇]
ip route replace 0.0.3.0/24 dev eth4 table hinet
ip route replace 0.0.2.0/24 dev eth3 table hinet
ip route replace 0.0.1.0/24 dev eth0 table hinet
ip route replace 192.168.0.0/24 dev eth2 table hinet
ip route replace 192.168.168.0/24 dev eth1 table hinet
ip route replace default via 0.0.1.254 table hinet

接下來就以此類推,只需要把 default gateway 改成另一條線路的 Gateway 來製作就可以了:
EX:seednet:
引用
ip route replace 0.0.3.0/24 dev eth4 table seednet
ip route replace 0.0.2.0/24 dev eth3 table seednet
ip route replace 0.0.1.0/24 dev eth0 table seednet
ip route replace 192.168.0.0/24 dev eth2 table seednet
ip route replace 192.168.168.0/24 dev eth1 table seednet
ip route replace default via 0.0.3.254 table seednet


EX:專案專用線路
引用
ip route replace 0.0.3.0/24 dev eth4 table isp
ip route replace 0.0.2.0/24 dev eth3 table isp
ip route replace 0.0.1.0/24 dev eth0 table isp
ip route replace 192.168.0.0/24 dev eth2 table isp
ip route replace 192.168.168.0/24 dev eth1 table isp
ip route replace default via 0.0.2.254 table isp


都製作好了之後,便可設定 rule 指定哪些範圍內的 IP 要用哪個路由表:
代碼: [選擇]
#add rule for each table
ip rule add from 192.168.168.0/24 table hinet
ip rule add from 192.168.0.11 table seednet
ip rule add from 192.168.0.14 table seednet
ip rule add from 192.168.0.15 table seednet
ip rule add from 192.168.0.10 table hinet
ip rule add from 192.168.0.20 table isp


再使路由馬上生效:
代碼: [選擇]
ip route flush cache

到此為止的 iproute.sh 內容為:

代碼: [選擇]
#!/bin/sh
#routing table of hinet
ip route replace 0.0.3.0/24 dev eth4 table hinet
ip route replace 0.0.2.0/24 dev eth3 table hinet
ip route replace 0.0.1.0/24 dev eth0 table hinet
ip route replace 192.168.0.0/24 dev eth2 table hinet
ip route replace 192.168.168.0/24 dev eth1 table hinet
ip route replace default via 0.0.1.254 table hinet
#routing table of seednet
ip route replace 0.0.3.0/24 dev eth4 table seednet
ip route replace 0.0.2.0/24 dev eth3 table seednet
ip route replace 0.0.1.0/24 dev eth0 table seednet
ip route replace 192.168.0.0/24 dev eth2 table seednet
ip route replace 192.168.168.0/24 dev eth1 table seednet
ip route replace default via 0.0.3.254 table seednet
#routing table of isp
ip route replace 0.0.3.0/24 dev eth4 table isp
ip route replace 0.0.2.0/24 dev eth3 table isp
ip route replace 0.0.1.0/24 dev eth0 table isp
ip route replace 192.168.0.0/24 dev eth2 table isp
ip route replace 192.168.168.0/24 dev eth1 table isp
ip route replace default via 0.0.2.254 table isp
#add rule for each table
ip rule add from 192.168.168.0/24 table hinet
ip rule add from 192.168.0.11 table seednet
ip rule add from 192.168.0.14 table seednet
ip rule add from 192.168.0.15 table seednet
ip rule add from 192.168.0.10 table hinet
ip rule add from 192.168.0.20 table isp
#clear route cache
ip route flush cache

到此為止連線指定已經完成。

不過還有一個部份沒有做,就是對於區域網路中提供服務的機器
防火牆那邊的設定並沒有開啟
如果各位已經有 NAT 架設的經驗,應該是早就設定了,所以這部份我現在才說明;
其實也不難,只要針對各個機器做 IP Mapping 就可以了,
例如我指定 192.168.0.11 這台機器走 seednet 線路,而它本身是跑 mail 的,
所以我的 iptables 語法應該是這樣設定:
代碼: [選擇]
/usr/local/sbin/iptables -t nat -A PREROUTING -d 0.0.3.5 -p tcp --dport 110 -j DNAT --to 192.168.0.11:110
/usr/local/sbin/iptables -t nat -A PREROUTING -d 0.0.3.5 -p tcp --dport 25 -j DNAT --to 192.168.0.11:25

其中的 0.0.3.5 自然就是 seednet 的 public ip 了,
不過這樣設還不算設定完全,因為我只是把外面的路打通而已,
內部還不知道 192.168.0.11 對應到 0.0.3.5 這個規則,
所以區域網路如果直接收 0.0.3.5 會造成封包回不來。
解決辦法就是要指定 SNAT
代碼: [選擇]
/usr/local/sbin/iptables -t nat -A POSTROUTING -d 192.168.0.11 -s $net_lan_1 -p tcp  -j SNAT --to 192.168.0.254
這行就是讓 net_lan_1 網段可以知道原來 0.0.3.5 是 192.168.0.11,
同樣的也可以多設一條
代碼: [選擇]
/usr/local/sbin/iptables -t nat -A POSTROUTING -d 192.168.0.11 -s $net_lan_0 -p tcp  -j SNAT --to 192.168.0.254
讓 Server 區段的網段也互相知道,這就見仁見智了。

像這些語法我都一律合在 nat.sh 裡面一併設定,才方便一起做修改。
不過還有另一種方法,利用公司內部 DNS 直接解析為區域網路 IP 即可更省資源。

到此為止此文結束 @_@

以上教學如果有不周全的,請各位不吝提出指正...
我的筆記
啊,就我的筆記阿...
-----以下兩個是屍體-----
AegisHK
Aegis
eAthena屍體
eathena

apage

  • 活潑的大學生
  • ***
  • 文章數: 337
    • 檢視個人資料
抱歉,有點小錯誤沒注意到,要修正一下
把 192.168.168.0 都改成 192.168.1.0
我的筆記
啊,就我的筆記阿...
-----以下兩個是屍體-----
AegisHK
Aegis
eAthena屍體
eathena

hsinan

  • 懷疑的國中生
  • **
  • 文章數: 66
    • 檢視個人資料
It's ok. Actually I have a similar idea like yours, but didn't have time to change it and want to have a good plan before doing that. After I read your post, it helps a lot and a very good reference. Thanks fot sharing! :-)

kenchlin

  • 懷疑的國中生
  • **
  • 文章數: 43
    • 檢視個人資料
太感謝分享了,不過想請教一下,如果說對外hinet 的線路如果斷了,lan 的user 上網是否會改由seednet 的線路出去,就是線路備援的意思!

apage

  • 活潑的大學生
  • ***
  • 文章數: 337
    • 檢視個人資料
引述: "kenchlin"
太感謝分享了,不過想請教一下,如果說對外hinet 的線路如果斷了,lan 的user 上網是否會改由seednet 的線路出去,就是線路備援的意思!


可以,可是不能自動,你要手動下 command... @@
另外,還可以用 iproute2 來做兩條線路負載平衡 (合併頻寬)
相關應用很多,建議找旗標那本 iptables 的書來研究研究...
我的筆記
啊,就我的筆記阿...
-----以下兩個是屍體-----
AegisHK
Aegis
eAthena屍體
eathena

akong

  • 鑽研的研究生
  • *****
  • 文章數: 523
    • 檢視個人資料
    • http://www.aspa.idv.tw
太感謝了
那想請問一下
假如我原本已經架設好2WAN+1Lan
現在想要多加一張網卡變成2WAN+2LAN
就是多加一個內網區段
只需要加哪幾行的script呢?
謝謝您哦

apage

  • 活潑的大學生
  • ***
  • 文章數: 337
    • 檢視個人資料
引述: "akong"
太感謝了
那想請問一下
假如我原本已經架設好2WAN+1Lan
現在想要多加一張網卡變成2WAN+2LAN
就是多加一個內網區段
只需要加哪幾行的script呢?
謝謝您哦


呃...您不妨先比較看看...
只是多加了幾個變數而已^^
我的筆記
啊,就我的筆記阿...
-----以下兩個是屍體-----
AegisHK
Aegis
eAthena屍體
eathena