基于路由协议的ip分流(RouterOS为例)
我的例子里做到的效果是(本文以分流中国大陆IP/非中国大陆IP为例)1. 正常状态: ip分流,DNS无污染,中国大陆直连出去,除了少量特殊配置比如icloud啥的强制直连,剩下的走隧道
2. 异常状态: 自动切换到全部直连,DNS有污染
3. 故障恢复: 自动恢复到正常状态
实际上通过多个tun设备分别连接不同的隧道出口+细化的路由表,是可以做到更细粒度的控制的
比如亚太方向流量走HK的隧道,美洲方向流量走LA隧道,欧洲走荷兰隧道等等
如有需要请自行研究,大体框架和下面的是一样的
这个和基于L7或者Address Lists分流方案的主要区别有两点
1. 性能: 通过路由器最擅长的路由来处理,因为直接网段/接口隔离不需要使用mangle来给流量打标,且不使用L7识别,不需要破坏硬件加速转发特性
2. 故障波及范围小: 假设隧道故障,大陆IP不受影响,且未被墙的非大陆IP会在短时间后快速变为直连状态(尽管也可以通过script处理,但是如果你体验过大批量导入/删除Address Lists的卡卡卡卡卡,我猜你是不会这么选的)
前提,你要收一份对应的路由表
方法1. 参考BakaCai的博客《在家也要玩BGP 之 Mikrotik Fan Boy版》自己收全表过滤出来
方法2. 利用nchnroutes项目跑一份出来
方法3. 直接拿别人跑好的,比如我用GitHub action定时跑的这个项目
方法4. 其他现成的地址段配置转换
接下来需要一台支持路由协议(BGP/OSPF等)的主路由,和一台可以运行clash等隧道+bird的隧道端点机(openwrt或者debian等常见linux发行版都可以)
我这边的环境如下
设备及系统版本
- 主路由MikroTik AC^2(ros 6.48.6 lt)
- 隧道端点NUC5(debian 11.3)
网段
- PC/WLAN等需要透明网关的(lan桥): 192.168.1.0/24
- 直通(ether5): 192.168.255.0/24
这边把ether5这个口踢出lan桥,单独给分配192.168.255.1/24,lan桥分配192.168.1.1/24
端点机分配192.168.255.254/24
路由配置打通两个网段
/ip route
add distance=1 gateway=pppoe-out routing-mark=bypass
add distance=1 dst-address=10.0.0.0/8 gateway=lan routing-mark=bypass
add distance=1 dst-address=169.254.0.0/16 gateway=lan routing-mark=bypass
add distance=1 dst-address=172.16.0.0/12 gateway=lan routing-mark=bypass
add distance=1 dst-address=192.168.0.0/16 gateway=lan routing-mark=bypass
add distance=1 dst-address=224.0.0.0/4 gateway=lan routing-mark=bypass
add distance=1 dst-address=255.255.255.255/32 gateway=lan routing-mark=bypass
/ip route rule
add interface=lan table=main
add interface=ether5 table=bypass
两边互ping一下确认是否ok(windows防火墙可能会拦截icmp)
接下来给lan配一个dns劫持,还有dns自动切换
/ip firewall nat
add action=dst-nat chain=dstnat comment="Hijacking for DNS" dst-port=53 protocol=udp src-address=192.168.1.0/24 to-addresses=192.168.1.1 to-ports=53
/system script
add dont-require-permissions=yes name=use-default-dns owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/ip dns set allow-remote-requests=yes servers=119.29.29.29,223.5.5.5 \r\n/ip dns cache flush"
add dont-require-permissions=yes name=use-sgw-dns owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/ip dns set allow-remote-requests=yes servers=192.168.255.254\r\n/ip dns cache flush"
注意netwatch要在隧道端点的dns服务启动后再加(比如这个例子里的clash),或者添加后先disable,最后再回来enable,不然就半断网了(解析不了dns)
/tool netwatch
add down-script=use-default-dns host=192.168.255.254 interval=5s up-script=use-sgw-dns
接下来是路由协议的配置,我之前使用7.x版本的ros+ospf,不是很稳定,时不时有一些小毛病,这里就回退到6.x的LT版本上用bgp来跑,截至目前没有发现不正常的地方
不管是BGP还是OSPF在这个场景上作用都是一样的,就是把端点机上宣过来的路由加到main表里,如果使用OSPF需要在防火墙放行ospf协议和组播(或者使用点对点模式),bgp的话有上面的路由规则就可以了
/routing bgp instance
set default router-id=192.168.255.1
/routing bgp peer
add multihop=yes name=sgw remote-address=192.168.255.254 remote-as=65531
然后是debian的配置
软件选择bird2来跑路由协议,clash premium跑隧道(自带tun和dns,可以省下tun2socks和smartdns)
替换你的clash订阅地址,按需修改external-controller/external-ui
/etc/clash/config.yaml
dns:
enable: true
ipv6: true
listen: 0.0.0.0:53
enhanced-mode: redir-host
use-hosts: true
default-nameserver:
- 119.29.29.29
- 223.5.5.5
nameserver:
- 119.29.29.29
- 223.5.5.5
fallback:
- https://dns.google/dns-query
- https://cloudflare-dns.com/dns-query
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
- https://8.8.4.4/dns-query
fallback-filter:
geoip: true
ipcidr:
- 240.0.0.0/4
tun:
enable: true
stack: system
auto-detect-interface: true
port: 7890
socks-port: 7891
redir-port: 7893
allow-lan: true
mode: Rule
log-level: silent
external-controller: '0.0.0.0:8080'
proxy-groups:
- name: PROXY
type: select
use:
- subscribe
proxy-providers:
subscribe:
type: http
url: 替换成你的clash订阅地址
interval: 86400
path: ./proxy/subscribe.yaml
health-check:
enable: false
interval: 600
# lazy: true
url: http://www.gstatic.com/generate_204
rule-providers:
icloud:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/icloud.txt"
path: ./ruleset/icloud.yaml
interval: 86400
apple:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/apple.txt"
path: ./ruleset/apple.yaml
interval: 86400
google:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/google.txt"
path: ./ruleset/google.yaml
interval: 86400
proxy:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/proxy.txt"
path: ./ruleset/proxy.yaml
interval: 86400
direct:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/direct.txt"
path: ./ruleset/direct.yaml
interval: 86400
private:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/private.txt"
path: ./ruleset/private.yaml
interval: 86400
telegramcidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/telegramcidr.txt"
path: ./ruleset/telegramcidr.yaml
interval: 86400
cncidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/cncidr.txt"
path: ./ruleset/cncidr.yaml
interval: 86400
lancidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/lancidr.txt"
path: ./ruleset/lancidr.yaml
interval: 86400
applications:
type: http
behavior: classical
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/applications.txt"
path: ./ruleset/applications.yaml
interval: 86400
rules:
- PROCESS-NAME,clash,DIRECT
- RULE-SET,applications,DIRECT
- RULE-SET,private,DIRECT
- RULE-SET,icloud,DIRECT
- RULE-SET,apple,DIRECT
- RULE-SET,google,DIRECT
- RULE-SET,proxy,PROXY
- RULE-SET,direct,DIRECT
- RULE-SET,lancidr,DIRECT
- RULE-SET,cncidr,DIRECT
- RULE-SET,telegramcidr,PROXY
- GEOIP,LAN,DIRECT
- GEOIP,CN,DIRECT
- MATCH,PROXY
最好用yacd之类接进去确认一下GLOBAL是不是direct
如果有smartdns或者dnsmasq会变得很麻烦,需要解决端口冲突问题改成解析链,再加上对应的PROCESS-NAME DIRECT规则,总之不建议开这些
/etc/bird/bird.conf
log syslog all;
router id 192.168.255.254;
protocol device {
scan time 60;
}
protocol kernel {
ipv4 {
import none;
export all;
};
}
protocol static {
ipv4;
include "routes4.conf";
}
protocol bgp {
local as 65531;
neighbor 192.168.255.1 as 65530;
source address 192.168.255.254;
ipv4 {
import none;
export all;
};
}
crontab添加2条定时刷新路由
0 2 * * * curl -s https://api.xn--7ovq92diups1e.com/ncr?device=utun -o /etc/bird/routes4.conf
0 3 */1 * * /etc/init.d/bird reload
手动执行一次初始化
curl -s https://api.xn--7ovq92diups1e.com/ncr?device=utun -o /etc/bird/routes4.conf
就可以启动clash和bird2的服务了(以及使能前面的netwatch)
再加一个健康检查脚本,访问Google异常并且重试失败后关闭bird和icmp响应,触发ros自动切换
/root/check.sh
#!/usr/bin/bash
COUNT=0
MAX_COUNT=3
while [ $COUNT -lt $MAX_COUNT ]
do
SER=0
NET=0
if [ $(curl --connect-timeout 5 --interface utun -w "%{http_code}" -s https://www.google.com/generate_204) -eq 204 ];then
NET=1
fi
if /etc/init.d/bird status|grep Active|grep -q running;then
SER=1
fi
if [ $NET -eq 1 ] && [ $SER -eq 0 ];then
/etc/init.d/bird start
echo 0 >/proc/sys/net/ipv4/icmp_echo_ignore_all
exit 0
fi
if [ $NET -eq 0 ] && [ $SER -eq 1 ];then
let COUNT+=1
if [ $COUNT -eq $MAX_COUNT ];then
/etc/init.d/bird stop
echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all
fi
continue
fi
exit 0
done
crontab添加规则
* * * * * /root/check.sh
测试一下
可见访问国外ip和国内ip已经不一样了,分流完成 还是mangle灵活一点,可以指定端口爬梯,这样只翻80443 953之类的,不用担心bt和游戏之类的流量乱跑 有哭的时候。 最近也想研究下,先mark 老饭 发表于 2022-8-22 13:46
还是mangle灵活一点,可以指定端口爬梯,这样只翻80443 953之类的,不用担心bt和游戏之类的流量乱跑 ...
主要是mangle开了之后NAT的硬件加速就寄了,端口规则可以加到clash里,只对特定DST-PORT,其他direct就可以了 不推荐用nchnroutes,用ASN分流 Darcychiu 发表于 2022-8-22 14:47
不推荐用nchnroutes,用ASN分流
有条件自己收表ASN过滤肯定是最稳的,但是其他论坛看其实还有不少人是一周一更新的状态....
nchnroutes起码不至于滞后这么多 mark下。学习下。 Ryo_ 发表于 2022-8-22 14:46
主要是mangle开了之后NAT的硬件加速就寄了,端口规则可以加到clash里,只对特定DST-PORT,其他direct就可以 ...
我是CHR,没有nat硬件加速[傻笑] 不懂搞成这样的意义,尤其是用了Clash的情况下 XHY 发表于 2022-8-22 17:45
不懂搞成这样的意义,尤其是用了Clash的情况下
你要是不嫌吵,主路直接用一台Juniper SRX的防火墙(比如比较入门便宜的240),可以配出来和这个一样的组网
这种组网下网络的稳定性可靠性可以做的很高,隧道炸了影响也小 本帖最后由 xenosccc 于 2022-9-2 14:34 编辑
小白请教下“proxy-groups:
- name: PROXY
type: select
use:
- subscribe
proxy-providers:
subscribe:
type: http
url: 替换成你的clash订阅地址
interval: 86400
path: ./proxy/subscribe.yaml
health-check:
enable: false
interval: 600
# lazy: true
url: http://www.gstatic.com/generate_204” [傻笑] 高手高手 学习下ros的ip分流方法,收藏 xenosccc 发表于 2022-9-1 22:59
小白请教下“proxy-groups:
- name: PROXY
type: select
订阅 就是yaml的链接,顺便最近最好别在CHH讨论这个...你看下版头锁定贴 本帖最后由 xenosccc 于 2022-9-2 15:03 编辑
Ryo_ 发表于 2022-9-2 14:12
订阅 就是yaml的链接,顺便最近最好别在CHH讨论这个...你看下版头锁定贴
已编辑了。[生病] 来学习 不知道如何是好 各种分流都折腾过了 各种问题 后来改用option来指定网关和dns了 Darcychiu 发表于 2022-8-22 14:47
不推荐用nchnroutes,用ASN分流
如果没有喂到嘴里的教程,可能需要考完ccnp才能折腾吧~ tunluan 发表于 2022-9-5 15:22
如果没有喂到嘴里的教程,可能需要考完ccnp才能折腾吧~
其实细化ASN分流如果把隧道端点换成ISP接入点, 不就是 IDC 机房 BGP 多线接入那套东西吗[偷笑] 我那个ospf,还没搞定apple系列的问题
具体表现为:
1. appstore有时候进不去
2. homekit 在外面无法使用
dns用的smartdns,默认配置。。。。不知掉咋设置 我这边就是死活无法放行openwrt的流量
openwrt也是单独和ros另外一个网卡连的
添加了bypass放行的表,但是就是出不去,一直进入死循 本帖最后由 guitengyue 于 2022-9-17 15:49 编辑
/ip route
add distance=1 gateway=pppoe-out routing-mark=bypass
我这条一加,整个系统就不能fq了
而且这条应该是这样的吧?dst-address必须要添加?
add distance=1 dst-address=0.0.0.0/0 gateway=pppoe-out routing-mark=bypass guitengyue 发表于 2022-9-17 15:43
/ip route
add distance=1 gateway=pppoe-out routing-mark=bypass
我这条一加,整个系统就不能fq了
完整展开应该是
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=pppoe-out pref-src=0.0.0.0 routing-table=bypass scope=30 suppress-hw-offload=no target-scope=10
正常不写应该也会自动给你加的 Ryo_ 发表于 2022-9-18 23:08
完整展开应该是
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=pppoe-out pref-src=0.0.0.0 ...
嗯,就是这样的,加了就直接不行了,你博客里面也留言了,搞不定
今天整回去用了ip分流方案 guitengyue 发表于 2022-9-18 23:11
嗯,就是这样的,加了就直接不行了,你博客里面也留言了,搞不定
今天整回去用了ip分流方案 ...
建议尝试一下通过socks5接clash能不能正常访问,确认下是clash出去的方向有问题还是main表收到的路由有问题,如果ospf在ros报错可能是组播的毛病,可以试着把ospf换成点对点模式或者直接bgp来跑 Ryo_ 发表于 2022-9-18 23:58
建议尝试一下通过socks5接clash能不能正常访问,确认下是clash出去的方向有问题还是main表收到的路由有问 ...
我用的是ros+openwrt(bird+passwall)
clash没用过,用你博客教程照抄后,ubuntu中的bird运行后提示这个,ospf1: Bad HELLO packet from nbr 192.168.1.1 on ens192 - prefix length mismatch (23)
弄不下去了。。。牺牲0.1s的体验算了,还是用回ip分流了[睡觉] Mark,我先在虚拟机里模拟部署一遍再上真机。 请问下,pt网站怎么处理,都是国外ip,还都是变化的? chengwanyu 发表于 2022-10-13 17:33
请问下,pt网站怎么处理,都是国外ip,还都是变化的?
我目前是对特定端口进来的流量直接走另一个路由表放行出去,然后把下载机之类的挂在这个端口下
这么别扭的做法主要是为了保留ROS的NAT加速,如果不是因为这个的话直接在mangle表按照原地址打route marking就可以了 直接在mangle表按照原地址打route marking就可以了这个求解 怎么做的,,不太懂
页:
[1]
2