多个pppoe负载均衡
Linux下pppoe负载均衡方案
前言
- 有多个pppoe账号,但是每个带宽都比较小,因此就想多拨,做个负载均衡
- iptables的方法没有成功,但是我依旧会写下思路
- 想看成功的解决方案请直接拉到最下面
- 如果有大佬能指出iptables方法的问题,不胜感激,联系方式blog上就有
设备和需求
设备
- pppx —-> 多个pppoe拨号后的接口
- tun0 —-> openvpn的接口,网段为
10.8.8.0/24
- eth0
需求
- 从openvpn来的流量全都从pppoe的接口出去(因为机器都在内网,内网的地址直接自己添加静态路由即可)
- 多个pppoe出口实现负载均衡
基于iptables和iproute的路由选择
主要参考 海运的博客 和 qiuske的ChinaUnix博客 。文中是针对两个接口,多个的话自己手动改一下即可
iptables配置
首先, MASQUERADE
openvpn的网段:
iptables -t nat -A POSTROUTING -s 10.8.8.0/24 -j MASQUERADE
这是iptables最基础的应用,详情请自己搜索关键词 iptables MASQUERADE
然后,给每条连接打上 CONNMARK
:
iptables -t mangle -A PREROUTING -s 10.8.8.0/24 -m state --state NEW -m statistic --mode nth --every 2 --packet 0 -j CONNMARK --set-mark 1
iptables -t mangle -A PREROUTING -s 10.8.8.0/24 -m state --state NEW -m statistic --mode nth --every 2 --packet 1 -j CONNMARK --set-mark 2
解释一下:
mangle
表在nat
表之前生效-m state --state NEW
—-> 匹配新建的连接-m statistic --mode nth --every n --packet x
—-> 统计,每n个包,对第x个进行匹配-j CONNMARK --set-mark x
—-> 交给CONNMARK
处理,打上标记 xCONNMARK
打上的标记是针对连接的,由iptables管理的,因此,还需要将标记打到每个包
将连接上的标记打到每个包上:
iptables -t mangle -A PREROUTING -m connmark --mark 1 -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m connmark --mark 2 -j CONNMARK --restore-mark
解释:
-m connmark --mark x
—-> 对于CONNMARK
标记为x的-j CONNMARK --restore-mark
—-> 将连接的标记打到包上- 在这里并没有加源地址和状态的过滤条件,因为所有的包都应该被检测(?)
参考 海运的博客 和 iptables-extensions的文档
iproute配置
ip route add 10.8.8.0/24 dev tun0 table p0
ip route add default dev ppp0 table p0
ip route add 10.8.8.0/24 dev tun0 table p1
ip route add default dev ppp1 table p1
ip rule add fwmark 1 table p0
ip rule add fwmark 2 table p1
说明:
- table后可以接数字或者在
/etc/iproute2/rt_tables
中指定的名字 fwmark
即为之前打在包上的标记,按照这个标记来走路由,就能实现按连接的负载均衡
出现的问题
traceroute
能到pppx
的路由地址,但是接下来的包全都在服务器端,并没有发回openvpn
的客户端(抓包发现的)- 在一台外网服务器上
nc -vv -l -p 23333
,客户端nc -vv x.x.x.x 23333
,外网服务器端通过netstat
可以看到连接的状态是SYN_RECV
。也就是说,三次握手,第一个包收到了,发出了第二个包,在等待第三个包,然而这第二个包看起来并没有被客户端收到 - 将
MASQUERADE
分解开来,改成SNAT
+DNAT
发现SNAT
有包被匹配到,而DNAT
几乎没有
附加说明
这种方法比较古老了,效率也不高,但是思路是没有问题的,因此依旧想将这个方法实现。如果有大佬发现问题出在哪里欢迎联系
iproute直接ECMP
就一句话:
ip route add default nexthop dev ppp0 weight 1 nexthop dev ppp1 weight 1
说明:
nexhop
指定下一跳dev
指定接口weight
指定权重,全1就好
当然,别忘了
iptables -t nat -A POSTROUTING -s 10.8.8.0/24 -j MASQUERADE
BTW,遇到已经存在默认路由的,删掉就好
说明:
- 这个方法来自 49
pppoe
下不用指定via
参数,因为pppoe
本身就是点对点,不像以太网那样靠广播,需要手动指定网关。这个知识点来自49师傅和另外一位不愿意透露联系方式的大佬(大雾)