旨在解决ROS+OpenWrt模式下,子网内设备使用OP作为默认网关,一旦OP故障,导致断网问题。

通过ROS的分流策略,即使OP发生故障,也只影响原本就访问不了的留学网站。

思路

DNS需要使用OP进行分流,或者其他方式,确保获取到的是无污染的解析结果。

配置

基于ROS V7,相对于V6,策略表配置发生了一些变化。

# add gfw list
/ip firewall address-list
add address=github.com list=gfw
add address=youtube.com list=gfw

# add routing table for gfw
/routing table
add fib name=gfw

# add mangle for gfw
/ip firewall mangle
add action=mark-routing chain=prerouting comment="GFW Route" \
    dst-address-list=gfw new-routing-mark=gfw passthrough=yes \
    src-address=!192.168.88.2

# add route
/ip route
add disabled=no dst-address=0.0.0.0/0 \
    gateway=192.168.88.2 routing-table=gfw \

OP的网卡需要开启地址伪装,在本例中使用的是LAN口,需要在防火墙里将LAN区域的IP地址伪装打开。这样ROS才能根据源地址判断流量是否来自OP,如果是就直接放行。

如果不这么配置,那么数据包从ROS转发到OP之后,将具有相同的源地址和目的地址,这样的数据包将不会被转发到网络的其他网段。

ROS的地址列表可以填写域名,也可以填写大陆IP,如果是大陆IP,那么在配置标记的时候,在地址列表前勾选取反,表示非大陆IP地址走OP的路由。因此也需要将内网的私有地址加入到排除列表中,否则会出现数据包出不去的问题。

另外由于ROS并不支持域名通配符,所以必须填写完整的域名,包含二级域名,三级域名等等。维护比较费时费力,目前我想到的方案是,编写一个程序,自动根据GFW列表的通配域名,获取该顶级域名下所有子域名,并生成可供ROS导入的文件。最后通过ROS的定时任务导入这些脚本,实现自动化。

AddressList的维护(以IP白名单为例)

有一个专门的网站,提供每日更新的大陆IP段。

https://ispip.clang.cn

白名单的处理

这个站点提供HTML和TXT两种格式的IP列表,我们选择TXT格式,每行为一个CIDR地址段。

原本我的想法是通过ROS脚本下载TXT文件,然后遍历进行白名单的更新。很可惜此路不通。因为遍历需要将文件读入变量,而ROS的变量最大只能存储4KB内容,这一点是在官网查到的(https://help.mikrotik.com/docs/display/ROS/Fetch)。

既然无法通过ROS直接处理,那么就只能对下载的TXT文件进行预处理,将其转换成ROS直接执行的脚本,然后通过import导入。

简单说一下我的实现方法,提供参考。我在NAS上通过定时任务脚本,下载IP列表,使用sed,awk等工具进行处理,转换成ROS脚本。最后将脚放置到文件索引服务器。ROS只需要定时下载此文件导入即可。(没有NAS肯定有OpenWrt,也是一样的,文件索引也可以用FTP等ROS支持的文件传输方式替代)

最后就是脚本的实现了,分两个脚本。在地址列表中我还将保留地址加了进去,这些地址也不需要走代理。至少应该把局域网的地址加进入,否则会无法上网。

IP列表转换脚本
create_cn_cidr.sh

#!/bin/sh

# China IP list url
cn_cidr_url="https://ispip.clang.cn/all_cn.txt"
# ROS script name
cn_cidr_rsc="/volume1/web/yum-repos/openwrt/chn_list.rsc"
# ROS firewall address list name
address_list="chn_list"

# Init script
cat > $cn_cidr_rsc << EOF
# Remove old address list
/ip firewall address-list
:foreach i in=[ find list=$address_list ] do={ remove number=\$i }

# Add new address list
# # Private addresses
# # Class A private
add list=$address_list address=10.0.0.0/8
add list=$address_list address=127.0.0.0/8
add list=$address_list address=0.0.0.0/8
# # Class B private
add list=$address_list address=172.16.0.0/12
add list=$address_list address=169.254.0.0/16
# # Class C private
add list=$address_list address=192.168.0.0/16
# # China addresses list
EOF
curl -fsSL $cn_cidr_url | sed "s#^#add list=$address_list address=#g" >> $cn_cidr_rsc

ROS更新白名单脚本

/tool fetch url=http://dl.simaek.com/openwrt/chn_list.rsc dst-path=chn_list.rsc
/import chn_list.rsc

将这两个脚本在各自的系统里加入计划任务即可,频率的话,每天更新一次就足够了。

最后修改:2022 年 05 月 27 日
如果觉得我的文章对你有用,请随意赞赏