Openwrt 多wan口upnp端口映射分流真香的解决方法,包含单线多拨、多线多拨场景。
去年下半年开始喜欢在软路由倒腾业务,用Openwrt单线多拨、多线多拨都搞过。业务也不止跑一个,最开始用mwan的ip分流,防火墙做端口映射。怎奈ttnode的端口老是飘,如果是升级Openwrt系统,那不仅端口全部都飘,有时连绑定的id也会跑,你想想ttnode一个容器4个端口,你跑三四个容器,不仅要重新绑定id,还要重新一个个去映射端口,烦。大家都是做技术的,这种办法既折磨又打脸。
本来这个问题可用upnp可以搞定,但我也查了网上无数文章,发现Openwrt下的upnp问题老生常谈,有个别的解决办法,但他们都没有搞定多拨加负载均衡的场景,尤其是两出口以上,根本不可能。无奈很多人选择加虚拟化外套或者前段再加个iKuai。这种方案也是特别麻烦,我非常怕麻烦,就是想用一个Openwrt搞定一切。仔细研究了半个月,终于搞定了,现分享出来以回馈我过去看过的各种各样的好教程。这是迄今为止最完美最彻底的openwrt多Wan口upnp解决方案!
现在分两个部分,先讲映射再说分流。
对外多出口,对内多网段的UPnP ,我是这么发现解决思路的。我发现openwrt启动后默认没有开启那个“启动 UPnP 与 NAT-PMP 服务”的选项,但docker默认的bridge网络照样可以产生映射记录,去查看“系统->进程”搜索upnp,果然看到它的运行程序:
miniupnpd -d -i pppoe-wan pppoe-wanb -o 117.174.127.112 -a docker0 -S -N -A allow 0 65535 0.0.0.0 0 0 65535
查看文档得知-d调试模式(可以去掉)。-i就是你对外的“interface”,-o后面是docker探测到的真实外网IP, -a是你的内网“device”,-S安全模式,-N是启用NAT-PMP功能,-A是范围权限,实际参数是0-65535 0.0.0.0/0 0-65535,(可以不填)。
对于怎样开启多路upnp,有两种方案:
1:有的版本miniupnpd -i后可以跟两个“interface”,就像上面的案列,用空格分开就行,对应两个外网。还想监视多个本地网段?你想当然的在-a后面填多个内网“device”也用空格分开?不行的!正确的做法应该是重复-a device1,-a device2这样。内网device去这里能查到:/etc/config/network
2:运行两个独立的miniupnpd 进程,比如像上面的案列可以改成类似这样:
miniupnpd -i pppoe-wan -o 117.174.127.112 -a macvlan1 -S -N &
miniupnpd -i pppoe-wanb -o 114.114.114.115 -a br-lan -S -N &
可以用这样的案列分别运行N次,左边外网右边内网,就分别独立监视着N个网段和外网。我觉得这种方式更妥,各司其职,逻辑清晰。
这里需要注意,如果你是大内网,这个-o后面可以不填你的真实外网IP,随便弄个假的公网IP也行,我们目的只是打通本地的。这里为啥一定要填个假公网IP?因为新版miniupnpd 查到你的外网接口上的IP不是公网,就直接停止服务了,stun模式又好像不能用,只能妥协填个假的。如果你就是想自动查询并填上大内网的真实对外IP,也可以,把上面的命令改进一下:
miniupnpd -i pppoe-wan -o $(curl -s --interface pppoe-wan ifconfig.me) -a device1 -S -N &
miniupnpd -i pppoe-wanb -o $(curl -s --interface pppoe-wanb ifconfig.me) -a br-lan -S -N &
但如果你的出口本来就是公网IP,那直接去掉-o ip,miniupnpd 会直接从你填的pppoe接口那里查到公网IP,这时乱填假IP反而有副作用(公网变成NAT)。公网的pppoe接口miniupnpd 启动参数就像这样就行,更简洁:
miniupnpd -i pppoe-wanc -a macvlan3 -S -N &
可以把命令加到系统自动启动中去使用就方便了,记得把系统自带的那个关了以免冲突。修改或启动新的miniupnpd监视进程时要搜一下进程先把同网段的结束了,以免冲突。
对于怎样多业务分流,我使用Docker的macvlan加路由表。
我是多个WAN口开多个macvlan,而不是开一个macvlan里面再划分IP网段分流。我觉得这样更直观,而且流量更分散均衡。
比如我开个veth1,IP用192.168.10.0/24,再开个veth2,IP用192.168.20.0/24,以此类推,这样我看到容器IP就知道它是哪条线哪个出口的。开macvlan指定硬网口的时候,我也是直接指定pppoe相应的那个网口,比如veth1的网口是eth0,它是第一个wan口,上面也运行着第一路pppoe拨号。这样的好处也是直观,而且pppoe流量已经隧道封装了,网卡也不用开混杂模式,流量互不影响。
开好macvlan之后,现在不用mwan分流了,得自己配路由表了。开始没摸过Linux的路由表,看着就头疼,其实也很好理解。
这里以两条线为列。找到/etc/iproute2/rt_tables,在里面建立两个表并指定他们的优先级,你打开后可以看到了255 local,254 main这样的格式,照着原格式在后面加200 wan1,210 wan2(数字越小优先级越高)。
路由表设置好后需要在这两张空表中分别增加两个网关,对应两条线路:
ip route add default via (第一个pppoe的网关IP) dev pppoe-wan table wan1
ip route add default via (第二个pppoe的网关IP) dev pppoe-wanb table wan2
然后需要在这两张路由表中分别增加那两个macvlan的网段:
ip route add 192.168.10.0/24 dev (你的macvlan1) table wan1
ip route add 192.168.20.0/24 dev (你的macvlan2) table wan2
然后你需要把两个网段的流量分别导进对应的表:
ip rule add from 192.168.10.0/24 table wan1
ip rule add from 192.168.20.0/24 table wan2
把它们划进新路由表去后你发现从br-lan就访问不了它们了,那你可以把你默认的局域网段192.168.100.0/24 br-lan也加进去:
ip route add 192.168.100.0/24 dev br-lan table wan1
ip route add 192.168.100.0/24 dev br-lan table wan1
(如果你不需要在局域网段管理访问里面的业务不加也行)
这样就大功告成了吗?没有,这样确实可以正常映射,正常分流了,但如果出现两种情况就报废了,1掉电重启,2pppoe掉线重播。掉电后路由表全部清空,而且pppoe掉线重播后网关的IP会变,你不可能随时监视着。而且手动去查IP然后改也痛苦。所以需要把这些代码写进pppoe程序的自动运行脚本里面,我这台机器的路径在/lib/netifd/ppp-up(/etc/里也有一个脚本但我这不生效),打开文件在代码最后面增加这样的代码:
case "$IFNAME" in
pppoe-wan)
# 添加到 wan1 路由表
ip route flush table wan1 # 首先复位路由表
ip route add default via $IPREMOTE dev pppoe-wan table wan1
ip route add 192.168.10.0/24 dev (你的macvlan1) table wan1
ip rule add from 192.168.10.0/24 table wan1
ip route add 192.168.100.0/24 dev br-lan table wan1
;;
pppoe-wanb)
# 添加到 wan2 路由表
ip route flush table wan2
ip route add default via $IPREMOTE dev pppoe-wanb table wan2
ip route add 192.168.20.0/24 dev (你的macvlan2) table wan2
ip rule add from 192.168.20.0/24 table wan2
ip route add 192.168.100.0/24 dev br-lan table wan2
;;
Esac
其中$IPREMOTE是网关文件中早就赋值好了,你直接用就行了。只需把dev名称和网段换成你自己的就行,如果三条线就把2改成3,wanb改成wanc加进去就行了,以此类推(所以说用简单直观的方法会更好)。另外提一下你的macvlan真实名称可以在/etc/config/network里查到(就是对应的device设备),这样不论掉电,还是掉网,只要能重新拨号成功,一切分流动作都可自动恢复。完美主义者在这里还可以再次改进代码,拨号同时自动探测大内网真实对外IP重新部署miniupnpd,把上面的代码移过来,增加一个部署前把之前的旧的结束就行,我这边已经搞定了。
自从把mwan删除,我这Upnp后直接变成映射公网型,业务效果明显更好!腰也不酸了,腿也不抽筋了。
还有手工设置单线多播,多线多播
其实也很简单。多线多播好理解,一个wan口对应一个账号就行。而手工单线多播,需要在单网口上增加多个macvlan,每个macvlan的mac地址不一样就行。在Openwrt的接口管理的设备管理列表里,点添加设备配置,设备类型是macvlan,基设备就是对应的硬网口,随机填个mac,模式私有就行,一个基设备可以承载多个macvlan设备(对应多个拨号线路),添加好设备后在“接口”界面添加新wan口时,选你刚才加的macvlan设备就行了。
我发现Openwrt可玩性相当高,上面的基设备可以不选硬网口。你可以先在基设备上建立一个或多个vlan设备,再以此vlan设备为基设备再建立多个macvlan设备,网口流量会自动进入至某vlan中,再在上面跑多个pppoe。所以去弄个网管交换机,还可以扩展wan口,单线多播,多线多播都更方便操作,真香!
Openwrt就是个五脏俱全的Linux系统,以前只摸Windows,通过捣鼓它还学了不少Linux的知识了,真香!
觉得有帮助,领个红包吧!