type
status
date
slug
summary
tags
category
icon
password
前一篇文章尝试使用RouterOS Address List配合防火墙Mangle的Prerouting规则进行国内外流量的自动分流,效果还不错,秉承着不把家里网络搞塌就不算完的态度,我又尝试寻找更好(更复杂)的分流方法,原来在2020年就已经有人在使用Ospf进行路由表分流,那我也来尝试配置一下看看。在通过ospf分流后,我的旁路网关这时候才真的称得上是一个旁路由,因为真的在进行路由路径的分流。
📝 OSPF介绍
OSPF(开放最短路径优先)是一种常用的路由协议,一般用于大型企业和网络服务提供商的网络中,家庭网络使用有点杀鸡用牛刀。它的主要功能是帮助路由器找到通往目标网络的最短路径,并自动更新这些路径信息。OSPF的工作原理是通过收集整个网络的路径信息,然后使用一种算法计算出到每个目的地的最优路径。当网络中的某条线路发生变化时,OSPF可以迅速做出调整,保证数据能够继续以最快的方式传输。
📝 配置背景
整体是All In One(All in Boom),采用PVE虚拟机方式,以下所有设备均在PVE内。
- 主路由器:RouterOS
- 光猫桥接,通过PPPoE Client建立pppoe-out1建立拨号
- 4个网口,分别为eth1 ~ eth4,其中eth4作为WAN口,pppoe-out1也是这个接口; 其他三个接口建立桥接,为bridge1
- 版本为7.16(stable)
- 旁路由(旁路网关):Debian
- 接口为ens18,网关为主路由bridge1地址
- 运行DAED作为科学服务
📝 配置指南
Debian配置
开启IPv4及IPv6转发
打开
/etc/sysctl.conf
确认包括以下内容,并没有被注释:如果进行了修改,需要通过
sysctl -p
命令使其生效。安装Bird及配置
在网络中使用OSPF协议时,需要一个路由守护进程来实现其功能,Bird作为轻量且高性能的解决方法,同时支持IPv4及IPv6路由表。Bird是一款支持多种路由协议的软件,广泛使用于Unix类系统,例如Linux和FreeBSD,在大多数常见系统中均可找到安装及使用方法。
- 通过apt进行安装:
bird2安装完成后默认为运行状态,我们需要先将其关闭:
- 编辑配置文件:
Deiban系统在安装Bird后,配置文件默认存放位置位于
/etc/bird/bird.conf
,需要对其编辑。配置说明如下:
1.
log syslog all;
- 作用:将BIRD的所有日志输出到系统日志(syslog),可以通过
journalctl -xeu bird
进行bird日志查看
2.
router id 10.0.0.10;
- 作用:定义了BIRD路由器的标识(Router ID),Router ID是一个唯一的IPv4地址形式,需要自行更改配置为自己旁路由(旁路网关)的IPv4地址
3.
protocol device { scan time 60; }
- 作用:
device
协议的配置,负责发现和监控网络接口的状态。scan time 60;
表示BIRD每60秒扫描一次所有网络接口,以更新接口状态信息。
4.
protocol kernel { ipv4 { import none; export none; }; } 和 protocol kernel { ipv6 { import none; export none; }; }
- 作用:
kernel
协议用于在BIRD的路由表和操作系统的内核路由表之间同步路由信息。 import none
:不从内核路由表导入路由信息。export none
:不将BIRD中的路由信息导出到内核路由表。- 禁止BIRD与操作系统的内核交换任何路由信息,完全独立管理IPv4和IPv6的路由表,避免将Bird的静态路由信息导入到内核路由表造成本地回环,同时减少内核路由表内路由规则数目,便于进行debug。
5.
protocol static { ipv4; include "/etc/bird/routes4.conf"; } 和 protocol static { ipv6; include "/etc/bird/routes6.conf"; }
- 作用:
static
协议用于定义静态路由。静态路由不会根据网络拓扑的变化自动更新,需要手动配置。 ipv4
:该协议块是针对IPv4的静态路由。ipv6
:该协议块是针对IPv6的静态路由。include "/etc/bird/routes4.conf";
:从指定的文件/etc/bird/routes4.conf
中导入IPv4静态路由配置。include "/etc/bird/routes6.conf";
:从指定的文件/etc/bird/routes6.conf
中导入IPv6静态路由配置。
6.
protocol ospf v2 { ... }
- 作用:这部分配置定义了OSPFv2(用于IPv4)的路由协议。
ipv4 { export all; }
:将BIRD中的所有路由信息导出到OSPFv2,供其他OSPF路由器学习。area 0.0.0.0
:配置OSPF的区域,这里是骨干区域0.0.0.0
。在OSPF中,所有非骨干区域必须通过骨干区域连接。interface "ens18" { type pointopoint; }
:指定OSPFv2在接口ens18
上运行,并且接口类型为点对点(point-to-point)。点对点类型通常用于没有中间广播域的直接链路。- 需要根据自己实际情况修改为旁路由(旁路网关)接口名称。
7.
protocol ospf v3 { ... }
- 作用:这部分配置定义了OSPFv3(用于IPv6)的路由协议。
ipv6 { export all; }
:将BIRD中的所有路由信息导出到OSPFv3,供其他OSPF路由器学习。area 0.0.0.0
:配置OSPF的区域,和OSPFv2一样,这里也是骨干区域0.0.0.0
。interface "ens18" { type pointopoint; }
:指定OSPFv3在接口ens18
上运行,类型为点对点,和OSPFv2的配置类似。- 需要根据自己实际情况修改为旁路由(旁路网关)接口名称。
生成静态路由规则
与上一篇文章RouterOS自动分流方案(支持IPv4 & IPv6)所使用的方式不同,这次我们需要生成所有非中国大陆地区的IPv4和IPv6地址信息,在Github上有dndx/nchnroutes: !chnroutes - chnroutes negated可以使用。
- 克隆仓库
- 编辑Produc.py
在第10行附近,修改
—next
后的default
参数wg0
为自己的旁路由(旁路网关)接口名称, 例如我的是ens18,就改成ens18。2024年12月28日更新:
删除48行
IPv4Network('172.16.0.0/12')
的保留地址,或者替换为172.24.0.0/13
,避免影响Cloudflare访问。原因在于Cloudflare IP Range中包括:172.64.0.0/13
这个地址范围,如果将IPv4Network('172.16.0.0/12')
配置为保留地址,那么Cloudflare所使用的172.64.0.0/13
也会被标记为直接从主网关出去,不需要经过旁路网关,所以会出现部分使用Cloudlfare CDN的网站无法访问的情况,例如Linux.do
。- 编辑Makefile
取消5、6、7行的注释。因为使用的是Bird2,没有Birdc6命令,所以不做修改。
2024年12月28日更新:
更换
china_ip_list
上游地址,原来的17mon的国内ip地址表太久未更新,存在地址范围错误,无法应对墙中墙(各种反诈劫持)的情况。delegated-apnic-latest是一个37M左右的大文件,下载速度会有点慢,需要耐心等待。
如果在你的旁路网关上访问
raw.githubusercontent.com
存在问题(例如本机无法被代理等情况),可以将raw.githubusercontent.com
更换为镜像raw.staticdn.net
- 生成静态路由表
需要确保你已经安装make,如果没有安装可以通过
apt install make
进行安装,然后执行:返回结果:
即表示Bird2生成OSPF动态路由表成功。
- 确认Bird2状态
执行
systemctl status bird.service
来查看bird2的运行状态:如果
Active
处于inactive
状态,需要手动执行systemctl start bird.service
- 确认Bird2路由表状态
执行命令
birdc show route protocol static1
查看IPv4路由表,返回结果太多,大概是如图:执行命令
birdc show route protocol static2
查看IPv6路由表:到这里Debian(旁路网关)的Bird2配置完成,下面可以开始进行RouterOS配置
RouterOS配置
在WinBox中点击左侧菜单
Routing
进行配置Router ID配置
点击
Routing
→ Router ID
进行配置。 Name自己喜欢填什么就填什么,ID填写RouterOS的地址,Dynamic ID
选择only vrf
,Select From VRF
选择main
,点击OK提交。OSPF配置
点击
Routing
→ OSFP
进行配置Instances配置
点击
New
新建,填入Name
(自己根据喜好填),也可以默认根据我的来。Version
版本选择2,VRF
使用main
表,Router ID
选择刚刚创建的main
,或者直接输入RouterOS的IP地址。其他不动。如果你使用IPv6,那么需要再新建一个
Instances,Version
选择为3,其他的一样。Areas配置
点击
Areas
,点击New
新增一个Area
。 Name
随便,Instance
选择刚刚创建IPv4的Instance(Version版本为2),Area ID为0.0.0.0
,Type为default
,其他不用填写。同样,如果你需要使用IPv6,那么也需要新建一个Area,并在Instance中选择刚刚创建的Version版本为3的Instance。
Interface Templates配置
点击
Interface Templates
,点击New
新增一个模板。Area
选择刚刚创建的IPv4的区域,Network Type
为ptp
(点对点,因为我们只有两个点),Cost
为10
,Priority
为32
,其他的不用管。同样,如果使用IPv6再新建一个Templates,
Area
选择IPv6的区域查看结果
上述配置完成后,点击
Neighbors
进行节点匹配查看,如果正常的话,应该可以发现Debian(旁路网关)上配置Bird2的节点:同时在
IP
→ Routes
中应该可以看到Debian(旁路网关)上Bird2发送过来的状态为DAo的路由表(D代表动态,A是活动状态,o为ospf)避免路由环路配置
在以上配置完成后,在我们访问国外流量时会发生环路,即
客户端 → RouterOS → Debian旁路网关 → RouterOS → Debian旁路网关…
不断的循环,所以需要对来源为Debian(旁路网关)
的流量进行特殊处理,这里又要用到我们的老朋友Managle。- 首先在
Routing - Tables
新建一个路由表,名为bypass
,并勾选FIB:
- 在
IP → Firewall → Managle
新建规则:
- General
- Chain:
prerouting
- In.Interface:
bridge1
- Advanced
- Src.MAC Address:
Debian旁路由(旁路网关)的网卡MAC地址
- Action
- Action:
Mark Routing
- New Route Mark:
选择刚刚新建的Bypass
- 如果你需要使用IPv6的话,在
IPv6 → Firewall → Mangle
也新建一条一样的规则。
- 配置
Bypass
路由表内路由规则
- 如果发现配置后从旁路由(旁路网关)Ping不通主路由RouterOS或者无法访问,提示
Destination Host Unreachable
或者Redirect Host(New nexthop: 10.0.0.1)
,可以在Dst.Address
添加一项局域网地址范围,例如我的10.0.0.0/24
,并点击前面空白方块出现“!
”,即目标地址不为局域网地址的流量。这样旁路由在使用Tailscale时候也可以正确的访问局域网内其他设备。
通过以上规则,在来源为Debian旁路由(旁路网关)的流量进入到RouterOS后,使用
bypass
路由表进行路由,默认这个表是空的,也就是无法对流量进行路由,所以会断网,我们需要添加一些默认的规则进去,基本照抄main
表的默认规则就行:- 新建IPv4局域网路由规则
Dst.Address
: 局域网IP地址范围,如果你是主路由是192.168.1.1
,那么这里写192.168.1.0/24
Gateway
: 填写网桥地址,例如我的是bridge1
,也是RouterOS建立网桥时默认名字Distance
:1
Routing Table
:bypass
- 新建IPv4广域网路由规则
Dst.Address
:0.0.0.0/0
Gateway
: 填写PPPoE拨号接口名称,例如我的是pppoe-out1
Distance
:1
Routing Table
:bypass
如果你没有公网IP,运营商分配给你的是一个大内网的IP地址(
100.x.x.x
),可能需要手动添加一条指向大内网网关的路由规则。 由于每次拨号后IP地址会变,运营商内网的网关也会变,所以需要使用RouterOS的脚本进行定时检查和修改:- 新建IPv6局域网路由规则
Dst.Address
:fe80::/64%bridge1
Gateway
: 填写网桥接口名称,例如我的是bridge1
Distance
:1
Routing Table
:bypass
然后依葫芦画瓢,把其他相关的
fe::
f*::
的内网路由规则添加进去- 新建IPv6广域网路由规则
Dst.Address
:::/0
Gateway
: 填写PPPoE接口名称,例如我的pppoe-out1
Distance
:1
Routing Table
:bypass
但是这样配置完成后,我们的IPv6还是没有办法访问互联网,通过与main表比对发现,因为缺少一条上级网关的地址:
但是这个地址是动态的,所以我们需要通过一个RouterOS脚本来进行动态处理:
至此,RouterOS部分的全部配置完成,同时整体的基于OSPF动态路由的国内外分流也已经完成。但分流的基础还是基于IP地址,所以需要使用无污染的DNS公共服务器,同时尽量使用DOH、DOT等方式进行查询,避免运营商的DNS劫持。
🤗 总结归纳
相比上一篇使用的
Address List
方式,因为是直接查询路由表,不用对目标IP进行取反匹配,而且不用对所有流量进行mangle标记,仅需要对来源旁路由的流量进行标记处理,在系统性能占用上会少一些,同时也可以开启RouterOS的fast forward
功能、fast track
功能以及fast path
,进一步降低CPU对流量处理所需资源,N4100在Fast.com
300M跑满时CPU占用30%左右,内网2.5G跑满CPU占用不到10%。而且避免了旁路由(旁路网关)挂断之后国外网站完全无法访问的情况。我认为即便是在使用Dae这种直连效率非常高的透明代理解决方案的情况下,直连流量尽可能的不经过旁路由(旁路网关)才是最佳的效率选择,所以相比使用Mihomo或者其他的软件,在分流规则的第一层通过路由表方式将国内流量直接发出去才能避免产生更多的问题(例如NAT等等等)并获得最佳的访问速度。
至于为什么要实用RouterOS来做,当然是因为RouterOS相对来说配置起来更为顺手,稳定性更好一些。当然,这些通过OpenWRT也可以实现。
OpenWRT版本已更新《🌐OpenWRT配置Bird使用OSPF国内外动态路由分流》
📎 参考文章
有关旁路由(旁路网关)安装或者使用上的问题,欢迎您在底部评论区留言,一起交流~