对于 RouterOS 的用户们,谈到国内外智能分流都是泪。这种 OpenWRT 可以很简单的完成的任务在 RouterOS 上基本上都需要用策略路由这种杀鸡用牛刀的方式来进行。另外,PBR 还有很多缺点,比如更新起来麻烦(一不小心 CLI 也可能搞坏路由器配置),而且没有健康检查,如果旁路由断网或者掉电 RouterOS 还是会傻傻的把流量转发过去,结果就是旁路由一挂国外 IP 全部不通。
这篇问题记录了我在 RouterOS 上通过 OSPF 协议把国外的流量动态拉取到旁路由上的配置过程。这样也算是让 RouterOS 干最擅长的工作。而路由的动态更新也可以直接在旁路由上完成。文章里面包含了 IPv4 和 IPv6 的配置。
根据一个月来的实验,效果非常好,中间有两次隧道断线,BIRD 都成功的检测到了故障,及时的从主路由 withdraw announcement,这样最起码国外 IP 还是通的。
这个文章只侧重了 3 层的分流,对于比如 DNS 污染就没有讨论,所以不是一个完整的解决方案。反正架设无污染的 DNS 方法网上一搜一大把,就不值得再写一遍了。
1
zro 2020-12-29 02:46:45 +08:00
谢谢楼主,又了解到一些知识。。
另外借楼问一下,ROS 自带的协议,有哪个是能稳定穿墙的?谢谢~~ |
3
EPr2hh6LADQWqRVH 2020-12-29 02:56:32 +08:00 via Android
虽然涨了一些有趣的知识但不得不说楼主你这个真是事倍功半啊。。。。
|
4
dndx OP @avastms 相对于 PBR 的好处上面也都说了,的确是比较折腾一些,但是也能学到不少知识。另外的确可用性要比 PBR 和静态路由高一些。具体需不需这么高的可用性就看每个人各自的需求了。。。
其实我想说那些用 PBR 的看起来也挺折腾的...虽然看起来旁路由上配置简单,但是 ROS 上的配置可就复杂多了。 |
5
miyunda 2020-12-29 07:43:17 +08:00
图里有个 typo 。。。114
|
6
ericbize 2020-12-29 08:20:30 +08:00 via iPhone
我是在国内的 ros 写静态路由, 把国内地址全部写进去, 然后通过 ospf 在 hk 把默认路由宣告回来。
至于过墙, 要不就 iepl 或者是利用 udp 无状态的特性,4 台 ros 在线路稳定情况下可以稳定过墙 |
7
sonicboy17 2020-12-29 08:30:23 +08:00 1
虽然看不懂,但是还是要战略性 mark 下
|
8
ihipop 2020-12-29 09:21:40 +08:00 via Android
vrrp 就能解决的问题用到了 ospf 。。
|
10
noahzh 2020-12-29 10:12:15 +08:00
使用 WireGuard 这种 UDP 很受运营商限制,能不能搭配 v2ray 使用?
|
11
cwbsw 2020-12-29 11:11:29 +08:00
我想知道的是查询几万条路由的效率是否能比几万条 ipset 高?灵活性易用性上后者强太多了。
|
12
Linkinternet 2020-12-29 12:10:45 +08:00
RouterOS 可以通过检测网关 脚本 netwatch 等多种检测手段
|
13
dndx OP @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 |
14
dndx OP @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 |
16
stevefan1999 2020-12-29 16:38:35 +08:00
Route your network with OSPF~
|
17
dndx OP |
18
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 秒 搞定。 |
20
dndx OP @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 。 |
21
kennylam777 2020-12-29 16:58:41 +08:00
好方法,對於正規的路由器用標準協議準沒錯,魔改還是留給樹莓派擔當
|
22
stevefan1999 2020-12-29 17:23:11 +08:00
另外如果是 BGP 的 可以嘗試下 gobgp
|
23
dndx OP @stevefan1999 要是跑 BGP,@noahzh 提到的的按照源 IP 路由的功能就能基于 BGP FlowSpec 做了,然而 Mikrotik 太懒了,到现在还没有加 FlowSpec 支持。。
|
24
ericbize 2020-12-29 18:46:03 +08:00 via iPhone
@dndx 我都是写好一个文件, 然后在命令行 import 这样不卡啊,8000 条大概一分钟就好了
|
25
ericbize 2020-12-29 18:49:36 +08:00 via iPhone
@ihipop 之前用阿里云 hk 跑满 30m, 广东电信 家宽。iepl 是公司的,成本大概 150/m/月
|
28
bclerdx 2020-12-30 00:01:53 +08:00
很好的文章及科普,收藏了。多谢楼主。
|
30
terrancesiu 2020-12-30 09:28:40 +08:00
我的方法,目前运行了半年了。有国内 vds 的朋友都可以照我的搞,没 vds 也可以用树莓派,n1 替代。我目前用的是 n1,放在楼道的 gpon onu 交换机那(我们这 fttb 上下行对等),用自己的第二条宽带账号拨号。
一、n1 安装了 armbian 后,安装和配置 pppoe 、ddclient 、strongswan 、clash premium 这几个基本服务。非常重要的一点,clash 需要开启 dns 且端口是 53,并用 fakeip 模式,最后做好防火墙白名单,只开放 22 端口。 二、routeros 通过 ikev2 vpn 拨入 n1,拿到 n1 下发的 ip 后,并和 n1 之间打 gre 隧道。然后互加对方的路由,这样 3 层就通了,最后加入一条策略路由将 198.18.0.0/16 的目的地址都交给 n1 处理。 三、再 routeros 上做 dns fwd,将需要走 n1 的域名写入 /ip dns static 内,因为可以用正则表达式,基本上常用的流媒体,社交网络、新闻和其他的,我 30 行就解决了。转发地址为 n1 上 clash tun 的地址 198.18.0.1 。 四、灵活运用 clash 的策略,分流不通区域的流媒体。 五、至于其他需要依靠 ip 直接通信的应用,比如 tg 就直接将 ip 加入 ros 的策略路由表,然后在 n1 的 iptales 写 redir 到 clash 的 redir 端口。最后做个 dns 劫持,避免 chromecast 走 4 个 8. 六、如果 n1 和 routeros 之间的 gre 速度很慢,看看 tcp mss,我改成了 1260 才正常。最后建议用 iperf3 打流测,避免瓶颈。如果 ros 的物理设备不支持 aes 解密,那么只能做未加密的 gre 隧道了。 |
31
ttvast 2020-12-30 10:06:03 +08:00
@cwbsw
我以前用的静态路由表,cpu 是 j1900. 宽带升级 500m 以后,测速老觉得跑不满带宽,后来发现是路由器 cpu 利用率 100%。 后来改成了 ipset,现在 1000m 宽带,cpu 利用率也不超过 20%。 主要是因为,ipset 使用 hash 查询, 而路由表匹配不到的话,是逐条查询。 |
32
dndx OP @ttvast 这就很奇怪了,实际上 Linux 的内核路由表一开始也是哈希查询,2.6 之后为了优化前缀查询性能才改成了 trie 树。另外只有第一个数据包需要走 trie,后面往同一地址的数据包直接走路由缓存,O(1)。
https://vincent.bernat.ch/en/blog/2017-performance-progression-ipv4-route-lookup-linux 因为改成 ipset 也不是个小改动,CPU 100% 很有可能不是路由导致的。可以在 RoS 里跑一下 profiler 看看是什么东西用了 CPU 。 我在 hEX 上实测的,200M 跑满测速 CPU 最高峰也只用了 10%。平均在 3-7% 之间。 |
33
ixiaoyui 2020-12-30 15:11:19 +08:00
这家用都上 OSPF 了.....
|
34
asdgsdg98 2020-12-30 23:46:05 +08:00
相比于爱快之类的系统,ROS 有什么优势吗,有人说 ROS NAT 性能更好,那为什么不用硬路由 NAT+智能网关解决呢?
希望有人能解答 |
35
JamesLewisLiu 2020-12-31 15:06:05 +08:00
弱弱的问一句 能配合 OpenWRT 使用吗
|
36
dndx OP @JamesLewisLiu 当然可以的,如果用 OpenWRT 作为主路由,只要在上面跑 OSPF 协议即可,树莓派这边的配置是一样的。
因为 OSPF 是常见的标准协议,同理主路由可以为任何支持 OSPF 的系统,OpenWRT,Cisco IOS,JunOS 等等都应该可以。 |
37
DopaminePlz 2021-01-02 08:54:23 +08:00 via Android
楼主在诱惑我折腾家庭网络了,在骗我去学习 ospf
|
38
oovveeaarr 2021-01-03 14:43:13 +08:00
感谢 LZ 分享,LZ 做了我一直想做,但是一直懒得做的事情))
|
39
smileawei 2021-01-03 16:44:32 +08:00
感谢提供思路。我这边用 openVPN 打隧道成功了。
不过没用 ROS 我设置 ROS 的 mtu 总是设置不到最优,导致用 ROS 卡卡的。直接用 Linux 做了网关。 |
40
jdwinter 2021-01-07 00:05:47 +08:00
家用网络都上 ospf 了,我们公司还在用腾达
|
41
chinni 2021-04-08 11:42:17 +08:00
我 linux 下 bird 配置好了,route 检查也没问题了 但是我 ros 上 设置了 OSPF 后 没有得到 neighbor 。
网络是 ROS 主路由 MikrotikAC2 做 ap,所有端口都桥一起了。 我 linux 接在 AC2 后 网段是同一个网段。 请问会是啥问题。。。 |
42
dndx OP @chinni 按照文章里的配置建议检查一下 `/routing ospf instance` `/routing ospf interface` `/routing ospf network` 。确保 IP 和 ID 符合实际配置。
另外可以 `sudo bird show protocols` 看一下 BIRD 的具体状态显示的是什么。 |
43
chinni 2021-04-08 13:54:33 +08:00
@dndx
大佬 我这里的返回贴一下。麻烦帮忙看下 方便的话 可以加我 profile 里的 tg 谢谢 ``` birdc show protocols BIRD 2.0.8 ready. Name Proto Table State Since Info kernel1 Kernel master4 up 10:54:51.242 device1 Device --- up 10:54:51.242 static1 Static master4 up 10:54:51.242 ospf1 OSPF master4 up 10:54:51.242 Alone ``` ``` /routing ospf> instance print Flags: X - disabled, * - default 0 * name="default" router-id=192.168.11.1 distribute-default=never redistribute-connected=no redistribute-static=no redistribute-rip=no redistribute-bgp=no redistribute-other-ospf=no metric-default=1 metric-connected=20 metric-static=20 metric-rip=20 metric-bgp=auto metric-other-ospf=auto in-filter=ospf-in out-filter=ospf-out ``` ``` /routing ospf> interface print Flags: X - disabled, I - inactive, D - dynamic, P - passive # INTERFACE COST PRIORITY NETWORK-TYPE AUTHENTICATION AUTHENTICATION-KEY 0 br-lan 10 1 broadcast none ``` 我这里 bird 里配置也是没有认证的所以这里是 none ``` /routing ospf> network print Flags: X - disabled, I - invalid # NETWORK AREA 0 192.168.11.0/24 backbone ``` |
44
dndx OP BIRD 显示 Alone 说明没有找到邻居。再检查一下接口配置确认是对的。
|
45
adoal 2021-06-10 00:18:01 +08:00
ipset 的好处是可以到 dnsmasq 后面,根据 gfw2dnsmasq 转出的遇难域名列表来动态加到要走隧道的清单。当然 dnsmasq+ipset 在 ROS 上就没办法了,要 EdgeRouter 或者 OpenWRT 或者正常的 Linux 发行版。
当然,从楼主贴的链接里看,楼主更看重的是,哪怕没遇难的外国网段,走隧道也大多比直连快一些。 但对我等穷人来说,国外流量都走隧道的话,那首先要找又便宜又快又稳定又不会在 3 月 6 月 10 月等特殊时期卡顿的隧道……这是个大难题。国外的机子,不管是什么线路,总是会不可控的卡顿。而 UOVZ 之类的,又死贵。 |
46
dudulangjiao 2021-08-31 21:41:16 +08:00
@dndx 楼主,麻烦问一下,如果旁路由是 openwrt 的,不是树莓派的,可以用这个方案吗?
|
47
dndx OP @dudulangjiao 可以,OpenWrt 本质上就是 Linux,BIND 这些肯定都是有包的。
|
48
dudulangjiao 2021-09-03 01:09:42 +08:00 via iPhone
@dndx 谢谢
|
49
xuesumin 2021-09-09 13:54:30 +08:00
下载了以后 make 即可生成国外 IP 地址的路由表。注意如果树莓派上的隧道连接的是国外的 IP,那么需要从生成的 IP 段里剔除,否则隧道的流量也会被 RouterOS 发给树莓派,形成路由环路。可以参考 README.md 的说明通过 --exclude 选项把这些不应该走隧道的 IP 排除。
注意如果树莓派上的隧道连接的是国外的 IP ?这句话是啥意思?我旁路由是 openwrt,科学上网是机场,好多节点 谢谢! |
50
dndx OP @xuesumin 如果你需要连接国外的 IP 来建立隧道,那么必须把这些 IP exclude 掉,这样这些流量不会被发往隧道,不然你的隧道连接会无法建立。
|
52
xxb 2022-04-28 16:14:55 +08:00
不错,有空试试
|
53
aoxiangtianji 2022-06-07 22:58:09 +08:00 via Android
@dndx 我是 ROS+openwrt 的配置,openwrt 用 openclash tun 模式建立隧道。有没有可能在 ROS 上设置,使 openwrt 走一个仅有默认路由的空路由表,来让 openclash 再分一遍流? IP 分流表总不是特别准确,而且也能达到节省隧道流量的效果。
|
54
creepersssss 216 天前
@dndx 希望可以更新一下,将 bird4.conf 的 export all 注释掉,OSPF 宣布机器就不会添加路由表,就可以进行二次分流了
|
55
creepersssss 216 天前
@xuesumin 将 bird4 的 export all 注释掉后广播机里就不会有路由,OSPF 广播机器放在 ROS 的另一个 passthrough 网段中,就不用 exclude ,也不会回环
|
56
garryforreg420 197 天前
更合适的方法是 openwrt 旁路由用 fakeip 模式,域名解析全部交给 openwrt,需要分流的域名会返回 fakeip,在 routeros 上做个路由规则,把 fakeip 段路由回 openwrt,这样 routeros 完全不用搞什么动态路由了,要分流的自动交给 openwrt 上的 openclash 了。
|
57
garryforreg420 197 天前
@aoxiangtianji 用 fakeip
|