现公司目前给用户上网有两条线路 一条高新网的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