RouterOS 国内外分流环境下的网络高可用性设计
本文是继《使用 RouterOS,OSPF 和树莓派为国内外 IP 智能分流》后的第二篇文章。第一篇着重讲的是路由协议的配置,而这一篇着重讲这种配置情况下的失效模式 (failure mode) 和应对策略。
本文是继《使用 RouterOS,OSPF 和树莓派为国内外 IP 智能分流》后的第二篇文章。第一篇着重讲的是路由协议的配置,而这一篇着重讲这种配置情况下的失效模式 (failure mode) 和应对策略。
更新历史
2022.05 :修改为 RouterOS 7 配置格式
失效分析
按照上一篇文章配置好了分流路由以后,正常情况下国内外流量是会分开走了,但是我们没有考虑所有的实效情况。比如树莓派故障,或者隧道故障。这里重温一下上文使用的拓扑:
这里要讲到一点上一篇文章没有提到的地方,那就是 DNS 解析的问题,一看来说为了加速我们需要在树莓派上配置一个走隧道的 DNS 服务,而 DNS 服务也成为了一个网络的单点,所以也要一并考虑在内。
总结下来,可能的失效情况有这么几种(排除光猫故障,RouterOS 故障这类概率很低的事件):
- 树莓派宕机,比如掉电
- 树莓派正常运行,但是隧道故障
我们需要确保在这两种情况下:
- 所有的 IP 应该直接走运营商线路,而不会再去树莓派
- DNS 解析的上游从树莓派切换到运营商
下面我们就来具体分体如何实现这些目标。
树莓派宕机检测
为了保持树莓派宕机的情况下 DNS 可用,局域网内的客户通过 DHCP 获得的 DNS 服务器地址不可以是树莓派的 IP 地址。所以我们使用 RouterOS 内置的 DNS 服务器并且讲 RouterOS 的 IP 地址通过 DHCP 分发给客户端作为 DNS 的唯一选择。然后在树莓派宕机的时候自动把上游切换到运营商的递归 DNS。
这里要注意的是我们不可以使用运营商推送过来的地址,对于 PPPoE 接口和 DHCPv6 的实例都要设置 use-peer-dns=no
,这样设置完了后 /ip/dns/print
显示 dynamic-servers:
应该为空。
接下来我们创建两个 RouterOS script,用来切换 DNS 的上游:
/system/script
add dont-require-permissions=yes name=use-rpi-dns source=\
"/ip/dns/set servers=192.168.0.2\
\n/ip/dns/cache/flush"
add dont-require-permissions=yes name=use-ct-dns source=\
"/ip/dns/set servers=240e:xx:xxxx::xxxx,240e:xx:xxxx::xxxx\
\n/ip/dns/cache/flush
注意这里的第一个脚本, 192.168.0.2
应该替换成树莓派的 IP 地址。而第二个脚本里应该替换成运营商的递归 DNS 地址。如果有多个可以用逗号分隔。
这里的 dont-require-permissions=yes
是必须的,否则 Netwatch 执行的时候会报权限错误。
下一步配置 Netwatch 来监控树莓派的网络联通性,如果宕机就自动执行脚本切换 DNS。
/tool/netwatch
add down-script=use-ct-dns host=192.168.0.2 interval=30s up-script=\
use-rpi-dns
这样 Netwatch 工具会每隔 30s ping 树莓派,如果宕机就会切换到运营商 DNS,树莓派正常后会自动切回。
至于树莓派广播过来的国外路由,因为是走的 OSPF,如果宕机 RouterOS 会自动检测到并把这些路由删除,所以不需要特殊处理。
隧道故障检测
当隧道故障,但是树莓派还在正常工作的时候,Netwatch 无法判断和自动切换 DNS 上游。所以我们需要在树莓派上切换 DNS 的上游,这样虽然 DNS 请求还是发往树莓派,但是其实走的也是运营商的递归。
这里我写了一个简单的 shell 脚本,可以达到自动切换的效果,请根据需要和自己的 DNS 设置来修改:
注意这里我们同时在隧道不通的时候主动禁用 OSPF 实例。这个理论上不是必须的,因为 BIRD 会检查接口的联通性,如果接口状态为 DOWN 会自动的 withdraw 路由。但是考虑到有的隧道协议可能断了以后需要等几分钟才会显示为 DOWN 状态,我们这里顺便通过 ping
来达到快速检测,快速 withdraw 路由的效果。
给脚本加上执行权后,用 root
权限创建一个 crontab
条目,一分钟运行一次即可。
* * * * * /home/pi/check_tunnel.sh
验证
拔掉树莓派的网线,或者在 RouterOS 上禁用树莓派对应的网络接口,网络应该会保持畅通,而且局域网客户 DNS 解析正常。
在树莓派上人工停掉隧道接口,观察 1 分钟内 dnsmasq.conf
里的服务器地址变为运营商递归 DNS,并且 sudo systemctl status dnsmasq
看到 dnsmasq
进程被重启,而且局域网客户 DNS 解析正常。