🔀RouterOS自动分流方案(支持IPv4 & IPv6)

2024-9-30|2025-1-1
Yawatasensei
Yawatasensei
type
status
date
slug
summary
tags
category
icon
password
😀
随着更换了路由方案,我也用上了MikroTik RouterOS作为主路由,但依然没有更换主路由 + 旁路网关(旁路由)的整体网络拓扑。为了加强国内网站及服务的访问速度,同时减少网关跃点,也就通过RouterOS的防火墙和路由功能做了一些分流配置。目前Google到的大部分都是IPv4部分的分流配置,IPv6部分的内容很少,自己的配置过程中也遇到了一些坑,整理一下,作为参考。

📝 背景

为什么使用RouterOS作为主路由

  1. 我所使用的主路由还是ASUS-ACRH17,已经是6年前的设备,刷了OpenWRT。尽管OpenWRT有SFE功能,但是CPU的处理性能已经落后太多。同时我又有2.5G网络的需求,千兆网络已经不太满足于我的内网使用需求,在添加一个2.5G交换机和更换主路由为支持2.5G的软路由之间,我选择了后者。
  1. 一直听闻RouterOS作为商用路由系统在流控方面做的很好,也相对完善。OpenWRT已经玩的差不多了,尝试一下新的东西。
  1. 其他路由系统我也有调研和尝试,例如Opnfense,但是在IPv4的NAT方面做的不是很好,即便经过配置,NAT类型稳定在FullCone(全锥)也很难。
  1. 作为主路由,要稳定且可控。
当然RouterOS与OpenWRT相比也有一些问题,上手难度较高,配置项复杂。另外最明显的就是在NAT方面,在电信大内网的情况下,原来OpenWRT开启DMZ可以获得映射公网的NAT级别,现在用RouterOS最高到FullCone全锥。

为什么要在RouterOS进行分流

旁路由我认为是在国内环境下满足基本需求的同时,兼容多种服务,扩展性和稳定性综合考虑最好的方案。但是旁路由这种拓扑下本身也存在问题:国内网站及服务的访问速度和非对称路由。
一般来说,我们正常访问国内网站的跃点应该是这样的:
notion image
就像这样:
notion image
第一跳为本地路由地址,第二跳为运营商的区域网关地址。但是在具有旁路由的环境下变成:
整体链路请求需要内网两个网关的跃点,第一跃点为旁路网关,第二跃点为主路由网关,尽管内网速度很高,延迟很低,但是还是因为数据多了一层的处理,即便是开启绕过中国大陆IP相关功能,也还是会产生影响。
notion image
而网站/服务的响应请求返回时,在主路由层面直接可以路由到客户端,不再经过旁路由,这就造成了非对称路由问题,在家庭层面可能日常使用感觉不出,但是偶尔一些小小的奇怪问题排查起来也会非常的难受,尤其是存在NAT(网络地址转换)的情况下。
还有由于在IPv6网络环境下,客户端会把RA服务器作为默认网关,在原有双OpenWRT情况下会存在两个RA服务器,或者客户端实际上并没有正确通过旁路由的RA服务器进行配置,出现类似于网心云IPv6待连通的情况,通过RouterOS一个RA服务器并进行IPv6国内外地址分流,也可以一并解决掉。
所以,这次方案的目标就是:
  1. 实现国内网站只需要经过主路由一层网关。
  1. 实现对称路由。避免因为非对称路由产生的防火墙失效以及合法连接误判为非法而丢弃问题。

📝 配置指南

网络基本配置

这部分基本是RouterOS的基础配置,包括IP地址范围、IPv4 DHCP服务器、IPv6地址获取、IPv6 ND等部分。

IP地址配置

主要是配置RouterOS的本地地址,例如我的是10.0.0.1
notion image

IPv4 DHCP配置

主要配置内容在Network下, 配置下发的默认网关和DNS。默认网关配置为RouterOS的本地地址即可,DNS服务器配置为旁路网关,由旁路网关上的代理软件或者MosDNS这种软件提供DNS请求的解析。
notion image

IPv4 DNS配置

RouterOS的DNS服务器配置意义不大,只是用来进行一些类似*.arpa*.lan 这种本地服务的DNS请求解析。开启就勾选Allow Remote Requests,关闭就取消勾选。上游DNS选择一个可靠,尽量无污染的公共DNS服务。如果家里没有设备默认使用DHCP分类的网关作为DNS服务器的话,也可以不填写。
 

IPv6 地址获取

正常RouterOS通过PPPoE获取的配置就可以,网上一搜一大把。
 

IPv6 ND

需要注意的就是IPv6 ND中需要将DNS Server配置为旁路网关地址,勾选Advertise MAC AddressAdvertise DNS两个选项。
notion image
Managed Address Configuration不勾选,不需要通过DHCPv6进行IPv6地址的配置,全部都用SLACC就可以了,这样Android设备也没问题,也不用再配置DHCPv6服务,省事。
Other Configuration不勾选,既然已经不需要DHCPv6服务器了,那么也就没有必要通知客户端从DHCPv6服务器获取其他配置信息,全部走SLACC无状态就可以了。

添加路由表

左侧Routing → Tables,新建一个路由表,名字自己随便写,我这里写的bypass,后面配置防火墙Mangle表Prerouting规则时会用到。
  • Enable: 勾选
  • FIB: 勾选

其他设置

采用Mangle进行路由标记并进行静态路由方式,需要关闭RouterOS的fast pathfast track以及fast forward,否则部分连接可能无法正确被进行路由标记,导致分流错误。关闭后会对转发性能有所影响,采用静态路由方式无法避免,如果需要内网的高转发性能,建议增加交换机。
  • Fast Forward关闭位置位于左侧菜单栏 → Bridge → 双击Bridge
notion image
  • Fast Path关闭位置位于左侧菜单栏 → Bridge → Configuration → Settings
notion image
  • Fast Track没有关闭入口, 需要确认IP和IPv6防火墙filter表中没有fasttrack-connection 相关规则即可。
同时,如果是X86软路由方式使用RouterOS,建议将HW Offload 也关闭,因为X86软路由没有硬件转发芯片。

OpenWRT旁路网关(旁路由)配置

关闭所有的DHCP服务,关闭所有的IPv6 RA服务,也就是不管WAN口、LAN口、还是LAN6接口,DHCP服务器中的IPv6设置全部配置为禁用。

IPv4自动分流

RouterOS的分流是通过路由表和防火墙Mangle表Prerouting标记方式实现,其实理论上OpenWRT也可以实现,但是因为没有GUI,所以需要自己通过命令行方式进行路由表的导入以及防火墙路由标记等等,上手难度较高。

导入IPv4路由表

具体原理就是导入别人整理好的国内CN IP列表到Address List里,这里也就不搞手动敲命令导入那一套了,直接通过脚本走起:
  1. SystemScripts, 新建一个脚本,Name随便写,写个自己能记得住这个脚本是什么的名称。
  1. Source输入如下内容:
具体意思就是从https://raw.githubusercontent.com/PaPerseller/chn-iplist/master/cn.rsc 下载RouterOS支持的RSC格式国内IP列表,然后导入,导入完成之后删除下载的文件并在log日志中输出update done
  1. Apply之后,点击一下右边的Run Script。如果没问题的话,IPFirewallAddress Lists里面应该添加了List名称为CN 的一堆地址。
  1. SystemScheduler,新建一个定时任务,Name一样写个自己记得这个定时任务是干什么的名称。
  1. One Event输入以下内容:
其他内容按照图里填吧,我这里是3天执行一次。
notion image
  1. ApplyOK,保存关闭。

添加IPv4防火墙规则

点击左侧IPFirewallMangle,新建一条规则,Comment随便写,只是一个备注,让你记得这条规则是用来做什么的。
  • General
    • Chain: prerouting
    • Dst.Address List: 下拉选择CN,然后点击前面的空白方块为 ,即目标地址不属于CN这个Address List。
    • Src.Address List: 非必选。源地址范围,如果不选择的话,就是默认全部。如果希望局域网内只有部分设备使用这个自动分流规则,那么可以自己去Address List添加一个列表
  • Extra
    • Dst.Address Type: 下拉选择local,然后点击前面空白方块为 ,即目标地址不属于局域网地址
  • Action
    • Action: 选择makr routing
    • New Routing Mark: 选择你添加的路由表,我这里是bypass
    • Passthrough: 勾选
点击OK保存。为了避免产生路由环路,我们需要对旁路网关发送来的流量进行特殊处理,避免被路由标记。同样还是在Mangle下新建一条规则:
  • General
    • Chain: prerouting
    • Src.Address: 填写旁路网关的IP地址
    • In.Interface: 选择bridge1 ,如果桥接端口名字不是这个,那么就选你桥接端口的名称,例如Lan什么的。
  • Advanced
    • Src.MAC Address: 如果你填写了Src.Address,那么这里也可以不填写。 如果你没填写,那么这里写旁路网关的MAC地址,如果旁路网关有WAN口,那就写WAN口地址。
  • Action
    • Action:Accept
到这里防火墙规则就配置完成,大致意思就是如果访问的目标地址不属于中国大陆的IP地址,就打上一个路由标记。如果访问的来源是旁路网关地址,就直接接受,不打路由标记。

添加IPv4路由规则

左侧菜单IPRoutes,新建一条路由规则:
  • Enable:勾选
  • Dst.Address:0.0.0.0/0
  • Gateway: 旁路网关IP地址
  • Distance:1
  • Scope:30
  • Target Scope:10
  • Routing Table: 最开始建立的那个路由表名称,选中即可,例如我的是bypass
点击ApplyOK,保存提交。
 
到这里,IPv4部分配置完成,可以通过tracert (Windows)或者tracerout (macOS或者Linux)分配对国内和国外网站进行路由追踪测试,测试结果应符合:
  • 国内:客户端 → 主路由 → …
  • 国外:客户端 → 主路由 → 旁路网关 → 主路由 → …
 

IPv6自动分流

IPv6自动分流的原理与IPv4的基本相同,也是通过防火墙Mangle表对连接进行Prerouting打路由标记,唯一不同的部分在于对旁路网关的特殊处理上。由于IPv6地址在下发过程中,会为每个设备都分配一个公网的IPv6地址,例如240e: 开头的这种,同时设备自身还具有一个本地链路地址,例如fe80: 这种,在进行数据传输的过程中,无法确切判定是使用的公网地址还是本地链路地址(RouterOS在这部分很模糊),我尝试通过脚本定时获取旁路网关的所有IPv6地址并加入Address List进行标记也无法正常解决,RouterOS的防火墙无法对来自旁路网关的流量直接进行Accept,最终造成路由环路,IPv6请求全部超时。但是,如果放弃三层交换方式,使用二层交换方式,设置Src.Mac Address即可正常解决环路问题。

导入IPv6路由表

具体原理就是导入别人整理好的国内CN IPv6列表到Address List里:
  1. SystemScripts, 新建一个脚本,Name随便写,写个自己能记得住这个脚本是什么的名称。
  1. Source输入如下内容:
  1. Apply之后,点击一下右边的Run Script。如果没问题的话,IPFirewallAddress Lists里面应该添加了List名称为CN 的一堆地址。
  1. SystemScheduler,新建一个定时任务,Name一样写个自己记得这个定时任务是干什么的名称。
  1. One Event输入以下内容:
  1. ApplyOK,保存关闭。

添加IPv6防火墙规则

点击左侧IPv6FirewallMangle,新建一条规则,Comment随便写,只是一个备注,让你记得这条规则是用来做什么的。
  • General
    • Chain: prerouting
    • Dst.Address List: 下拉选择chnroutes.ipv6,然后点击前面的空白方块为 ,即目标地址不属于chnroutes.ipv6这个Address List。
  • Action
    • Action: 选择makr routing
    • New Routing Mark: 选择你添加的路由表,我这里是bypass
    • Passthrough: 勾选
点击OK保存。为了避免产生路由环路,我们需要对旁路网关发送来的IPv6流量进行特殊处理,避免被路由标记。还是在Mangle下新建一条规则:
  • General
    • Chain: prerouting
    • In.Interface: 选择bridge1 ,如果桥接端口名字不是这个,那么就选你桥接端口的名称,例如Lan什么的。
  • Advanced
    • Src.MAC Address: 写旁路网关的MAC地址,如果旁路网关有WAN口,那就写WAN口地址。
  • Action
    • Action:Accept
到这里防火墙规则就配置完成,大致意思就是如果访问的目标地址不属于中国大陆的IP地址,就打上一个路由标记。如果访问的来源是旁路网关地址,就直接接受,不打路由标记。
需要确认后面添加的旁路由规则要在路由标记规则上面。防火墙规则匹配是由上至下顺序进行。

添加IPv6路由规则

左侧菜单IPv6Routes,新建一条路由规则:
  • Enable:勾选
  • Dst.Address:::/0
  • Gateway: 旁路网关的本地链路IPv6地址 ,例如fe80::d359:6e90:0:be24:11ff:feff:ff6b
  • Distance:1
  • Scope:30
  • Target Scope:10
  • Routing Table: 最开始建立的那个路由表名称,选中即可,例如我的是bypass
点击ApplyOK,保存提交。
 
到这里,IPv6部分配置完成,可以通过tracert -6 (Windows)或者tracerout -6 (macOS或者Linux)分配对国内和国外网站进行路由追踪测试,测试结果应符合:
  • 国内:客户端 → 主路由 → …
  • 国外:客户端 → 主路由 → 旁路网关 → 主路由 → …

🤗 其他脚本

一个RouterOS获取所有局域网下IPv6客户端,并写入到Address List的脚本:
另外,通过使用OSPF动态路由方式实现国内及国外IP分流可以参考:《🔀RouterOS使用OSPF智能分流国外流量》;OpenWRT版本可以参考:《🌐OpenWRT配置Bird使用OSPF国内外动态路由分流

📎 参考文章

 
💡
有关RouterOS安装或者使用上的问题,欢迎您在底部评论区留言,一起交流~
RouterOS使用OSPF智能分流国外流量OpenWRT从Hper-V迁移至PVE指引
Loading...