在 Linux 上实现负载平衡和 NAT-ing 多个 ISP 连接

在 Linux 上实现负载平衡和 NAT-ing 多个 ISP 连接

我有两个来自不同 ISP 的互联网连接,我需要平衡这两个 ISP 之间往返于我网络的流量。我使用的是 Debian GNU/Linux。

我的设置是这样的 -

eth0(192.168.0.0/24)——本地网络

eth1(192.168.1.0/24)——ISP #1

eth2(192.168.2.0/24)——ISP #2

我的本地网络通过 eth0 连接到该服务器,并且该盒子是 LAN 中所有机器的 DHCP 服务器兼网关。

服务器需要在两个 ISP 之间进行负载平衡,还需要进行 NAT。

我已按照路线指示进行操作lartc.org但我仍然需要正确进行 NAT 的说明。

任何帮助将不胜感激。

PS-我了解 pFSense,但我需要使用 Linux。

答案1

我已经使用 lartc.org 和iptables方法,我发现iptables方法更容易理解和实现。唯一的缺点是你需要一个相当新的iptables版本可以使用统计模块

让我们假设几件事:

局域网:eth0:192.168.0.1/24

ISP1:eth1:192.168.1.1/24,网关:192.168.1.2/24

ISP2:eth2:192.168.2.1/24,网关:192.168.2.2/24

因此,下面是我使用 iptables 方法的操作:

路由表

首先编辑 /etc/iproute2/rt_tables,添加路由表编号和 ISP 名称之间的映射

...
10 ISP1
20 ISP2
...

因此表 10 和 20 分别用于 ISP1 和 ISP2。我需要用此代码片段(取自 hxxp://linux-ip.net/html/adv-multi-internet.html)将主表中的路由填充到这些表中。

ip route show table main | grep -Ev '^default' \
   | while read ROUTE ; do
     ip route add table ISP1 $ROUTE
done

并通过 ISP1 的网关添加至 ISP1 的默认网关:

ip route add default via 192.168.1.2 table ISP1

对 ISP2 执行相同操作

所以现在我有 2 个路由表,每个 ISP 一个。

iptables 目录

好的,现在我使用 iptables 将数据包均匀地分发到每个路由表。有关此工作方式的更多信息,请参见此处 (http://www.diegolima.org/wordpress/?p=36) 和这里 (http://home.regit.org/?page_id=7

# iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
# iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT
# iptables -t mangle -A PREROUTING -j MARK --set-mark 10
# iptables -t mangle -A PREROUTING -m statistic --mode random --probability 0.5 -j MARK --set-mark 20
# iptables -t mangle -A PREROUTING -j CONNMARK --save-mark

NAT

NAT 很简单:

# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
# iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE

答案2

mefat 的回答对我帮助很大,但不是将所有主表规则一次性复制到两个 ISP 表中,更好的方法可能是使用规则优先级在主表后添加默认规则。

正常设置 /etc/iproute2/rt_tables:

...
10 ISP1
20 ISP2
...

注意

ip rule show

显示规则 0->local、32766->main 和 32767->default。请参阅man ip以了解更多详细信息。

至关重要的是,路由过程将从低优先级到高优先级规则进行...但 32767 不是最高规则。因此,如果主路由表没有默认路由(但可能包含各种用于 VPN 等的动态变化路由)如果没有匹配,则会转到默认值(通常为空),然后寻找更高优先级的规则。

请参阅此处的“投掷”部分:http://linux-ip.net/html/routing-tables.html

现在设置

ip route add default dev $ISP1_IFACE table ISP1
ip route add default dev $ISP2_IFACE table ISP2

并确保它们在主表之后被查看:

ip rule add fwmark 20 table ISP1 prio 33000
ip rule add fwmark 10 table ISP2 prio 33000

使用

ip rule show

再次验证这些规则是否比主规则优先级更高

然后使用 CONNMARK mangling,正如 mefat 所说:

# iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
# iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT
# iptables -t mangle -A PREROUTING -j MARK --set-mark 10
# iptables -t mangle -A PREROUTING -m statistic --mode random --probability 0.5 -j MARK --set-mark 20
# iptables -t mangle -A PREROUTING -j CONNMARK --save-mark

注意事项:pppd 需要nodefaultroute在主程序中设置;当设备重新启动时,ISP1/ISP2 表会被清理,因此需要使用脚本进行恢复。

我使用 /etc/ppp/ip-{up,down}.d/dual-routing 中的脚本

# One of my connections is ~2x faster than the other
BALANCED=0.3
ALL_ISP1=0
ALL_ISP2=1

RULENUM=4
set_balance() {
    iptables -t mangle -R PREROUTING $RULENUM -m statistic --mode random --probability $0 -j MARK --set-mark 2
}

# if both up
set_balance $BALANCED
# if ppp1 down:
set_balance $ALL_ISP1
# if ppp0 down:
set_balance $ALL_ISP2

这是基于连接的负载平衡,因此我将研究使用负载来监控并替换统计规则:iptables -t mangle -R PREROUTING <n>来自用户空间。因此,如果一个连接上有长时间运行的下载,而另一个连接的负载较轻,我们应该优先选择负载较轻的连接。

相关内容