[教程] 使用 RouterOS, OSPF 和树莓派为国内外 IP 智能分流

2020-12-29 02:26:45 +08:00
 dndx

对于 RouterOS 的用户们,谈到国内外智能分流都是泪。这种 OpenWRT 可以很简单的完成的任务在 RouterOS 上基本上都需要用策略路由这种杀鸡用牛刀的方式来进行。另外,PBR 还有很多缺点,比如更新起来麻烦(一不小心 CLI 也可能搞坏路由器配置),而且没有健康检查,如果旁路由断网或者掉电 RouterOS 还是会傻傻的把流量转发过去,结果就是旁路由一挂国外 IP 全部不通。

这篇问题记录了我在 RouterOS 上通过 OSPF 协议把国外的流量动态拉取到旁路由上的配置过程。这样也算是让 RouterOS 干最擅长的工作。而路由的动态更新也可以直接在旁路由上完成。文章里面包含了 IPv4 和 IPv6 的配置。

根据一个月来的实验,效果非常好,中间有两次隧道断线,BIRD 都成功的检测到了故障,及时的从主路由 withdraw announcement,这样最起码国外 IP 还是通的。

全文在此:https://idndx.com/use-routeros-ospf-and-raspberry-pi-to-create-split-routing-for-different-ip-ranges/

这个文章只侧重了 3 层的分流,对于比如 DNS 污染就没有讨论,所以不是一个完整的解决方案。反正架设无污染的 DNS 方法网上一搜一大把,就不值得再写一遍了。

18865 次点击
所在节点    宽带症候群
57 条回复
zro
2020-12-29 02:46:45 +08:00
谢谢楼主,又了解到一些知识。。

另外借楼问一下,ROS 自带的协议,有哪个是能稳定穿墙的?谢谢~~
dndx
2020-12-29 02:51:31 +08:00
@zro 自带的肯定都不行,但是在树莓派上稍微伪装一下就可以。
EPr2hh6LADQWqRVH
2020-12-29 02:56:32 +08:00
虽然涨了一些有趣的知识但不得不说楼主你这个真是事倍功半啊。。。。
dndx
2020-12-29 03:01:03 +08:00
@avastms 相对于 PBR 的好处上面也都说了,的确是比较折腾一些,但是也能学到不少知识。另外的确可用性要比 PBR 和静态路由高一些。具体需不需这么高的可用性就看每个人各自的需求了。。。

其实我想说那些用 PBR 的看起来也挺折腾的...虽然看起来旁路由上配置简单,但是 ROS 上的配置可就复杂多了。
miyunda
2020-12-29 07:43:17 +08:00
图里有个 typo 。。。114
ericbize
2020-12-29 08:20:30 +08:00
我是在国内的 ros 写静态路由, 把国内地址全部写进去, 然后通过 ospf 在 hk 把默认路由宣告回来。
至于过墙, 要不就 iepl 或者是利用 udp 无状态的特性,4 台 ros 在线路稳定情况下可以稳定过墙
sonicboy17
2020-12-29 08:30:23 +08:00
虽然看不懂,但是还是要战略性 mark 下
ihipop
2020-12-29 09:21:40 +08:00
vrrp 就能解决的问题用到了 ospf 。。
ihipop
2020-12-29 09:43:38 +08:00
@ericbize 可是 UDP 国内限速啊 ipel 一条线多少钱?
noahzh
2020-12-29 10:12:15 +08:00
使用 WireGuard 这种 UDP 很受运营商限制,能不能搭配 v2ray 使用?
cwbsw
2020-12-29 11:11:29 +08:00
我想知道的是查询几万条路由的效率是否能比几万条 ipset 高?灵活性易用性上后者强太多了。
Linkinternet
2020-12-29 12:10:45 +08:00
RouterOS 可以通过检测网关 脚本 netwatch 等多种检测手段
dndx
2020-12-29 15:26:15 +08:00
@cwbsw 路由器最基本的功能就是根据路由表决定下一跳,如果这个性能都做不好那也不可能有性能更好的办法了。ipset 这种要走防火墙额外处理的只会比路由表更慢。

实际上 BGP 全表就算聚合后现在的大小也有快 50 万条路由了,10000 条跟这个比起来是小巫见大巫。用 ROS 跑 BGP 全表的人很多,要是这些都处理不了 ROS 就没法用了。

另外 Linux 的路由表查询其实是有缓存的,并不是每个数据包都要完整的查一遍。

http://linux-ip.net/html/routing-cache.html
https://superuser.com/questions/419659/iptables-vs-route
https://serverfault.com/questions/334885/use-iptables-or-null-route-for-blacklisting-about-1-million-ip-addresses
dndx
2020-12-29 15:38:53 +08:00
@noahzh 只要能 tunnel 跑 UDP 就可以,实际上我用了 udp2raw,把 UDP 包装成 TCP 。关键是要把 MTU 设对,否则一分片马上延迟爆炸。目前找到的好办法就是 `tcpdump` 配合 `ping -s` 来看封装后的 IP 包的大小。

@ericbize 这个方法我一开始考虑过,然而 RoS 不知道为什么导入静态路由速度爆炸,后来被迫放弃。后来我在找解决方法的时候还是在网上搜到了 RoS 论坛里有人抱怨这个问题 https://forum.mikrotik.com/viewtopic.php?t=117529 才想到可以跑路由协议。不过如果有国外的 IP 路由表,那也可以在隧道另一头拉路由,这样就可以不用默认路由了。

@ihipop VRRP 的话,因为不希望国内流量也走旁路由,所以不能满足需求

@miyunda fixed
noahzh
2020-12-29 16:15:15 +08:00
@dndx 这个方案是否没有办法控制哪些设备不需要分流,都走运营商,还要一个疑问,为什么这么依赖 UDP?谢谢
stevefan1999
2020-12-29 16:38:35 +08:00
Route your network with OSPF~
dndx
2020-12-29 16:38:40 +08:00
@noahzh 这个是不行的,如果要按照来源来路由那就只能走 PBR 了。

这套方案不依赖于 UDP,比如你在旁路由上跑个 ss-redir + iptables 来转发效果也是一样的。
onion83
2020-12-29 16:41:27 +08:00
思路很好我也会愿意尝试一下,不过为了解决路由闪断问题,是否可以考虑用 diff 的方法来更新,这样就没必要先全量删再全量加了,就是如何写脚本需要费点心思。

另外 firewalls 里面有个 address list 等价于 ipset 一般配合 mangle 打标路由标识后,再配一条静态路由转到旁路由,这样静态路由表会干净些,也确保静态路由的安全避免误删断网。

mangle 防火墙配置命令为:

chain=prerouting action=mark-routing new-routing-mark=free passthrough=no
dst-address-type=!local src-address-list=!bypass dst-address-list=!cn
in-interface=bridge-core log=no log-prefix=""


src-address-list 后跟的 bypass 是不打标签的主机列表,例如 192.168.1.1 (路由器本身) 192.168.1.254 (树莓派之类的旁路由,避免环路)

dst-address-list 后跟的就是 cn 路由列表了 https://github.com/17mon/china_ip_list

当然还有一些自定义路由需要脚本自己再合并一下性能:CCR1009 导入 6000 来条路由 address list 到大概 3 秒,x86 软路由 1 秒 搞定。
noahzh
2020-12-29 16:48:26 +08:00
@onion83 同意楼上,我现在就是这么搞的,网关下线也是又感知的,楼主写了自动更新地址的脚本了吗?谢谢.
dndx
2020-12-29 16:55:47 +08:00
@onion83 是的,如果 ipset + routing mark + 监控脚本自动切路由,那效果可以达到基本一致。最大的坑就是 RoS 6 到现在也不支持 IPv6 的 PBR,所以如果想搞 IPv6 的分流就没辙了。虽然有传言 RoS 7 支持,但是看论坛里报的那个 bug 的数量。。实在是不敢用

实际上跑 OSPF 除了一开始配置稍微麻烦点,后面更新起来和健康检查什么的都要好做的多。因为都可以在旁路由上实现,路由器上的配置就只有几行,也没有频繁修改配置的风险。

@noahzh 更新的话,先把 https://github.com/dndx/nchnroutes/blob/main/Makefile 里面最后的几行注释去掉,然后直接在旁路由上用 root 跑了个 cron:

```
0 0 * * 0 make -C /home/pi/nchnroutes
```

然后 BIRD 就会自动把变更了的的 prefix 宣告给 RoS 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/739809

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX