我试图在具有两个网关的Linux路由器上负载均衡来自内部局域网的stream量。 最初我去iproute执行没有按预期平衡负载,原因是路由被caching。
现在我正在使用iptables来标记使用CONNMARK的每个新连接,然后添加规则以通过不同的网关路由这些标记的连接。
Eth0 – LAN,Eth1 – ISP1,Eth2 – ISP2
以下是我正在使用的脚本,
#!/bin/bash echo 1 >| /proc/sys/net/ipv4/ip_forward echo 0 >| /proc/sys/net/ipv4/conf/all/rp_filter # flush all iptables entries iptables -t filter -F iptables -t filter -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables -t filter -P INPUT ACCEPT iptables -t filter -P OUTPUT ACCEPT iptables -t filter -P FORWARD ACCEPT # initialise chains that will do the work and log the packets iptables -t mangle -N CONNMARK1 iptables -t mangle -A CONNMARK1 -j MARK --set-mark 1 iptables -t mangle -A CONNMARK1 -j CONNMARK --save-mark iptables -t mangle -A CONNMARK1 -j LOG --log-prefix 'iptables-mark1: ' --log-level info iptables -t mangle -N CONNMARK2 iptables -t mangle -A CONNMARK2 -j MARK --set-mark 2 iptables -t mangle -A CONNMARK2 -j CONNMARK --save-mark iptables -t mangle -A CONNMARK2 -j LOG --log-prefix 'iptables-mark2: ' --log-level info iptables -t mangle -N RESTOREMARK iptables -t mangle -A RESTOREMARK -j CONNMARK --restore-mark iptables -t mangle -A RESTOREMARK -j LOG --log-prefix 'restore-mark: ' --log-level info iptables -t nat -N SNAT1 iptables -t nat -A SNAT1 -j LOG --log-prefix 'snat-to-192.168.254.74: ' --log-level info iptables -t nat -A SNAT1 -j SNAT --to-source 192.168.254.74 iptables -t nat -N SNAT2 iptables -t nat -A SNAT2 -j LOG --log-prefix 'snat-to-192.168.253.132: ' --log-level info iptables -t nat -A SNAT2 -j SNAT --to-source 192.168.253.132 # restore the fwmark on packets that belong to an existing connection iptables -t mangle -A PREROUTING -i eth0 \ -m state --state ESTABLISHED,RELATED -j RESTOREMARK # if the mark is zero it means the packet does not belong to an existing connection iptables -t mangle -A PREROUTING -m state --state NEW \ -m statistic --mode nth --every 2 --packet 0 -j CONNMARK1 iptables -t mangle -A PREROUTING -m state --state NEW \ -m statistic --mode nth --every 2 --packet 1 -j CONNMARK2 iptables -t nat -A POSTROUTING -o eth1 -j SNAT1 iptables -t nat -A POSTROUTING -o eth2 -j SNAT2 if ! cat /etc/iproute2/rt_tables | grep -q '^51' then echo '51 rt_link1' >> /etc/iproute2/rt_tables fi if ! cat /etc/iproute2/rt_tables | grep -q '^52' then echo '52 rt_link2' >> /etc/iproute2/rt_tables fi ip route flush table rt_link1 2>/dev/null ip route add 192.168.254.0/24 dev eth1 src 192.168.254.74 table rt_link1 ip route add default via 192.168.254.5 table rt_link1 ip route flush table rt_link2 2>/dev/null ip route add 192.168.253.0/24 dev eth2 src 192.168.253.132 table rt_link2 ip route add default via 192.168.253.5 table rt_link2 ip rule del from all fwmark 0x1 lookup rt_link1 2>/dev/null ip rule del from all fwmark 0x2 lookup rt_link2 2>/dev/null ip rule del from all fwmark 0x2 2>/dev/null ip rule del from all fwmark 0x1 2>/dev/null ip rule add fwmark 1 table rt_link1 ip rule add fwmark 2 table rt_link2 ip route flush cache
使用这个连接可以路由两个路由。 然而,他们中的一些被丢弃ie.connections不能通过。 在某些情况下,build立的连接中途中断。
我错过了什么吗?
这是另一种方法。 不要根据数据包计数来标记连接,而是希望不会重新初始化,重复或以其他方式进行更改,只需将数据包按源IP或目标IP划分即可。 对于任何足够大的连接,你应该有大约50-50的传播。
我发布了以下内容作为替代scheme,但是您可以更多地修改CONNMARK逻辑。
iptables -t mangle -A PREROUTING -m state --state NEW \ -d 0.0.0.0/0.0.0.1 -j CONNMARK1 iptables -t mangle -A PREROUTING -m state --state NEW \ -d 0.0.0.1/0.0.0.1 -j CONNMARK2
如果源IP有更多的差异,甚至可以将它们组合到括号中,也可以将目标更改为源。 (奇/偶甚至是CONNMARK1,奇/偶或偶/ CONNMARK2)。