現公司目前給用戶上網有兩條線路 一條高新網的10M光纖(Linux,iptables+squid),一條8M的電信ADSL(Cisco 2811),其中10M的光纖給公司內部用戶使用,ADSL給無線用戶使用。有個比較嚴重的問題是是光纖鏈路經常會有人下載導致擁塞很嚴重,爲了解決這個問題,最近本人決定改變現有環境.
用一臺三個網卡的IBMX346服務器做策略路由+透明代理來解決,用光纖只走WEB端口80流量.剩餘的其他流量走ADSL,這樣就可以解決用戶使用下載工具時而不至於上網訪問網頁慢的現象。
Eth0接ADSL eth1接內網交換機:192.168.0.1eth2接光纖:218.17.X.X
增加兩個路由表100 gx和200dx
cat /etc/iproute2/rt_tables
# reserved values
255 local
254 main
253 default
0 unspec
100 gx
200 dx
用iptables的MARK來爲流量打標記,80標記爲1,剩餘的流量標記爲2
iptables -t mangle -A PREROUTING -i eth1 -ptcp -m multiport --dports 80 -j MARK--set-mark 1
iptables -t mangle -A PREROUTING -i eth1 -j MARK --set-mark 2
設置路由規則
ip rule add fwmark 1 table gx pre 2000
ip rule add from 218.17.X.242 table gx pre 3000
ip rule add fwmark 2 table dx pre 4000
用IPTABLES做NAT轉換
iptables -t nat -A POSTROUTING -s192.168.0.0/16 -o ppp0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s192.168.0.0/16 -o eth2 -j SNAT --to 218.17.X.242
把80端口重定向到3128做透明代理
iptables -t nat -A PREROUTING -i eth1 -s192.168.0.0/16 -p tcp --dport 80 -j REDIRECT --to 3128
爲內網用戶轉發
iptables -A FORWARD -s 192.168.0.0/16 -jACCEPT
iptables -A FORWARD -d 192.168.0.0/16 -jACCEPT
把Linux的路由轉發打開
編輯vim /etc/sysctl.conf
把net.ipv4.ip_forward = 0改爲net.ipv4.ip_forward= 1
[root@gw ~]# sysctl –p
使其立即生效
但是接下還有個問題,每次ADSL重新撥號的時候,會將系統默認路由強制改寫爲
default dev ppp0 scope link
並且會把dx路由表的路由中抹去
編輯ip-up.local,加入下面兩條命令,使ppp0啓動時候自動執行
[root@gw ~]#vim /etc/ppp/ip-up.local
#!/bin/bash
ip rule del table dx pre 5000
IP_ADD=`ifconfig ppp0 |grep "inet addr" |cut -d: -f2 |cut -d" " -f1`
IP_GW=`ifconfig ppp0 |grep "P-t-P" |cut -d: -f3 |cut -d" " -f1`
ip rule add from $IP_ADD table dx pre 5000
ip route add default via $IP_GW dev ppp0 src $IP_ADD table dx
ip route add default via 218.17.X.129 dev eth2 src 218.17.X.242 table gx
ip route replace default via 218.17.X.129 dev eth2 ###把默認路由改寫爲光纖出去,否則代理會出問題的
Iptables具體的一些規則和squid的配置文件我就省略了
附加:
不過我這還做了open***,做了策略路由之後open***只能ping通Linux本機 到內網的全部都不通了,解決辦法如下
編輯vim /etc/iproute2/rt_tables
加入一個路由表300 ***
iptables -t nat -A POSTROUTING -s192.168.99.0/24(OPEN×××撥入的網段) -o eth1 -j SNAT --to 192.168.0.1
ip route add to 192.168.99.0/24 via192.168.99.1 dev tun0 table ***
ip rule add from 192.168.0.0/16 table *** pre 1000 (數字越小優先級越高,必須放前面 不然×××流量不能通過)
這樣open***撥入的客戶端就可以和內網通訊了
驗證一下系統路由表
[root@gw ~]# ip route show
192.168.99.2 dev tun0 proto kernel scope link src 192.168.99.1
219.134.212.1 dev ppp0 proto kernel scope link src 219.134.213.95
218.17.X.0/24 dev eth2 proto kernel scope link src 218.17.X.242
192.168.99.0/24 via 192.168.99.2 dev tun0
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.1
169.254.0.0/16 dev eth0 scope link metric 1002
169.254.0.0/16 dev eth1 scope link metric 1003
169.254.0.0/16 dev eth2 scope link metric 1004
192.168.0.0/16 via 192.168.0.254 dev eth1
default via 218.17.X.129 dev eth2
驗證一下dx路由表
[root@gw ~]# ip route show table dx
default via 219.134.212.1 dev ppp0 src 219.134.213.95
驗證一下gx路由表
[root@gw ~]# ip route show table gx
default via 218.17.X.129 dev eth2 src 218.17.X.242
驗證一下策略路由的規則
[root@gw ~]# ip rule show
0: from all lookup local
1000: from 192.168.0.0/16 lookup ***
2000: from all fwmark 0x1 lookup gx
3000: from 218.17.X.242 lookup gx
4000: from all fwmark 0x2 lookup dx
5000: from 219.134.213.95 lookup dx
32766: from all lookup main
32767: from all lookup default
把命令寫入腳本
[root@gw ~]# vim/etc/init.d/iproute.sh
#!/bin/bash
iptables -t mangle -F
iptables -t mangle -X
iptables -t mangle -Z
iptables -t mangle -A PREROUTING -i eth1 -p tcp -m multiport --dports 80 -j MARK --set-mark 1
ip route add default via 218.17.X.129 dev eth2 src 218.17.X.242 table gx
iptables -t mangle -A PREROUTING -i eth1 -j MARK --set-mark 2
ip route replace default via 218.17.X.129 dev eth2
iptables -t nat -A POSTROUTING -s 192.168.99.0/24 -o eth1 -j SNAT --to 192.168.0.1
ip route add to 192.168.99.0/24 via 192.168.99.1 dev tun0 ta ***
ip rule add from 192.168.0.0/16 table *** pre 1000
ip rule add fwmark 1 table gx pre 2000
ip rule add from 218.17.X.242 table gx pre 3000
ip rule add fwmark 2 table dx pre 4000
並添加到rc.local中讓開機自動運行
[root@gw ~]# vim /etc/rc.local
#!/bin/sh
sh /etc/init.d/iproute.sh