标签 分流 下的文章

RouterOS使用DNS转发功能实现域名分流解析

20220718更新:更新域名匹配正则,添加每周更新脚本。由于缓存查询时间增加过多,此方法不推荐,详情参考文章后部。

之前写过两篇文章介绍实现域名分流解析的方案,一个是使用dnsmasq基于大陆域名白名单分流解析域名,另一个是使用overture替换dnsmasq做域名分流解析
这次介绍的方案与dnsmasq类似,默认使用境外dns服务器解析,境内域名使用白名单转发到境内dns服务器。
routeros在v6.47中增加了静态条目规则type属性,其中包含FWD类型。FWD类型可以将指定域名转发到指定的DNS服务器。
以下以routeros v7.3.1的chr版本为环境,dns服务器是8.8.8.8和8.8.4.4
增加alicdn.com域名及子域名转发给114.114.114.114解析。正则匹配如下

^(.*\.)?alicdn\.com$

命令如下

/ip/dns/static/add regexp="^(.*\\.)?alicdn\\.com\$" forward-to=114.114.114.114 ttl=300s

详细命令请参考官方wiki
这里使用dnsmasq-china-list做白名单转发给境内dns服务器解析,生成脚本如下

/ip/dns/static/remove [/ip/dns/static/find type=FWD]
/ip/dns/static/add regexp="^(.*\\.)?0-100\\.com\$" forward-to=114.114.114.114 ttl=300s
/ip/dns/static/add regexp="^(.*\\.)?0-6\\.com\$" forward-to=114.114.114.114 ttl=300s
/ip/dns/static/add regexp="^(.*\\.)?00\\.net\$" forward-to=114.114.114.114 ttl=300s
/ip/dns/static/add regexp="^(.*\\.)?000\\.link\$" forward-to=114.114.114.114 ttl=300s
/ip/dns/static/add regexp="^(.*\\.)?00000\\.host\$" forward-to=114.114.114.114 ttl=300s
/ip/dns/static/add regexp="^(.*\\.)?00042\\.com\$" forward-to=114.114.114.114 ttl=300s
/ip/dns/static/add regexp="^(.*\\.)?00058\\.com\$" forward-to=114.114.114.114 ttl=300s
/ip/dns/static/add regexp="^(.*\\.)?0006266\\.com\$" forward-to=114.114.114.114 ttl=300s
/ip/dns/static/add regexp="^(.*\\.)?0007\\.net\$" forward-to=114.114.114.114 ttl=300s
...

脚本有接近7万行,使用intel i5-7200u分配2逻辑核心的虚拟机首次执行需要约3.5分钟,阿里云1核心服务器首次执行需要2.5分钟,再次执行需要7.5分钟,再次执行时会先删除type=FWD的静态条目,脚本执行时cpu占用100%,所以cpu性能较差时需要耐心等待。

这里下载每周自动生成的脚本。
导入方法:使用

/import dns.rsc

导入,等待完成。

使用RouterOS自带dns转发功能做域名分流解析优点是可以抛弃openwrt或者linux服务器的小尾巴,实现routeros单一系统完成全部网络功能,特别适合不支持直通的cpu裸装routeros的情况。
缺点和使用dnsmasq分流解析一样,境内域名列表更新不及时,可能导致一些新的域名解析成境外地址。

另外,导入dns转发脚本后不要使用webfig打开dns静态列表,条目太多会卡死。
附:自动生成dns.rsc脚本

#!/bin/bash
echo "/ip/dns/static/remove [/ip/dns/static/find type=FWD]">/tmp/dns.rsc && curl -s https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf|sed '/#/d'|sed 's/\/114.114.114.114//g'|sed 's/\./\\\\./g'|sed 's/server=\//\/ip\/dns\/static\/add regexp=\"^(.*\\\\.)?/g'|sed 's/$/&\\$\" forward-to=114.114.114.114 ttl=300s/g'>>/tmp/dns.rsc

发现问题:
1,routeros的dns本地缓存查询时间显著增加,使用dig命令发现未导入时缓存查询时间小于1ms,导入后缓存查询时间约28ms,白名单域名反而查询时间更短。
2,在dns设置增加缓存到1gb后观察,发现导入后占用约180mb缓存。另可以通过观察缓存大小来大致确定导入进度。

使用overture替换dnsmasq做域名分流解析

20210617更新:RouterOS使用DNS转发功能实现域名分流解析
之前分享过使用dnsmasq基于大陆域名白名单分流解析域名,这种办法受限于白名单列表的更新,列表总是滞后于网站实际使用的域名,造成一些境内网站cdn解析到了境外,影响境内网站打开速度。
由于gfw的dns污染只会使用境外地址和私有地址,可以利用这个特性做dns分流解析:所有域名用境内dns服务器解析,如果域名解析得到境内ip则直接采用,如果得到境外ip则使用境外dns服务器解析。
开源软件overture就可以实现这个功能。overture有AB两组dns服务器,AB组各有一个IP列表和域名列表,假设A组为境内dns服务器,A的ip列表是大陆IP列表,A的域名列表是境内域名白名单,B的域名列表是被墙的域名gfwlist。

下面是overture的安装及配置步骤
安装脚本overture_install.sh

#! /bin/bash
apt update && apt install curl wget unzip
wget -q https://github.com/shawn1m/overture/releases/download/v1.7/overture-linux-amd64.zip
unzip overture-linux-amd64.zip  "overture-linux-amd64"
mv overture-linux-amd64 /sbin/overture
cat << EOF > /lib/systemd/system/overture.service
[Unit]
Description=overture-dns-server
After=syslog.target network-online.target
[Service]
ExecStart=/sbin/overture -c /etc/overture/config.yml
StandardOutput=syslog
Restart=on-abnormal
[Install]
WantedBy=multi-user.target
EOF
mkdir /etc/overture
cat << EOF > /etc/overture/config.yml
bindAddress: :53
debugHTTPAddress:
dohEnabled: false
primaryDNS:
  - name: dns1
    address: 114.114.114.114:53
    protocol: udp
    socks5Address:
    timeout: 2
    ednsClientSubnet:
      policy: disable
      externalIP:
      noCookie: true
  - name: dns2
    address: 223.5.5.5:53
    protocol: udp
    socks5Address:
    timeout: 2
    ednsClientSubnet:
      policy: disable
      externalIP:
      noCookie: true
alternativeDNS:
  - name: google8888
    address: 8.8.8.8:53
    protocol: udp
    socks5Address:
    timeout: 3
    ednsClientSubnet:
      policy: disable
      externalIP:
      noCookie: true
  - name: google8844
    address: 8.8.4.4:53
    protocol: udp
    socks5Address:
    timeout: 3
    ednsClientSubnet:
      policy: disable
      externalIP:
      noCookie: true
onlyPrimaryDNS: false
ipv6UseAlternativeDNS: false
alternativeDNSConcurrent: true
whenPrimaryDNSAnswerNoneUse: alternativeDNS
ipNetworkFile:
  primary: /etc/overture/china_ip_list.txt
  alternative: /etc/overture/china_ip_list.txt
domainFile:
  primary: /etc/overture/china_list.txt
  alternative: /etc/overture/gfw_list.txt
  matcher: suffix-tree
hostsFile:
  hostsFile:
  finder: full-map
minimumTTL: 0
domainTTLFile:
cacheSize: 0
cacheRedisUrl:
cacheRedisConnectionPoolSize:
rejectQType:
  - 255
EOF
systemctl enable overture

列表更新脚本 overture_update_fliters.sh,首次运行overture前需要执行此脚本。

#! /bin/bash
cd /etc/overture
rm china_list.txt gfw_list.txt china_ip_list.txt
curl -s https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt > china_ip_list.txt
curl -s https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf  | sed 's/server=\///g;s/\/114.114.114.114//g' > china_list1.txt
curl -s https://raw.githubusercontent.com/hq450/fancyss/master/rules/WhiteList_new.txt  | sed 's/Server=\///g;s/\///g' > china_list2.txt
cat china_list1.txt china_list2.txt | sort -u > china_list.txt
rm china_list1.txt china_list2.txt
curl -s https://raw.githubusercontent.com/Loukky/gfwlist-by-loukky/master/gfwlist.txt | base64 -d | sort -u | sed '/^$\|@@/d'| sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' | sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /qq\.com/d' | sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' | grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u > gfwlist.txt
curl -s https://raw.githubusercontent.com/hq450/fancyss/master/rules/gfwlist.conf | sed 's/ipset=\/\.//g; s/\/gfwlist//g; /^server/d' > koolshare.txt
cat gfwlist.txt koolshare.txt | sort -u > gfw_list.txt
rm gfwlist.txt  koolshare.txt
systemctl restart overture

配置定时任务定期更新overture的域名和IP列表

0 3 * * 1 /root/overture_update_fliters.sh

参考:
docker 搭建 overture 无污染 DNS

Routeros V7配置策略路由

20230529更新:增加ipv6策略路由实现境内外ipv6地址分流的方法。

在两年前我写过一篇routeros配置vpn分流大陆ip的文章,里面主要介绍了使用routeros基于源地址和目的地址的策略路由。在使用Routeros V7 测试版的过程中发现V7相比于V6版在路由配置方便有很大变更,所以这篇文章会以Routeros V7为基础介绍策略路由的配置。

网络基本情况
routeros作为家庭唯一路由,通过pppoe接入互联网,通过wireguard连接香港的routeros。

策略路由目标
1,需要翻墙的内网ip:目的地址是境内ip走pppoe默认路由,目的地址是境外IP走wireguard通过香港routeros进入墙外互联网
2,其他内网ip全部走pppoe默认路由

IP地址分配参考上一篇文章Routeros 配置WireGuard

本地lan的地址是192.168.1.1/24,wg-access地址是10.0.0.1/24,wg-hk的地址是10.0.1.1/30,手机wireguard的地址是10.0.0.2/32,笔记本电脑的地址是10.0.0.3/32
香港wg0地址是10.0.1.2/30

配置步骤
1,导入大陆IP地址表
参考Routeros的address-list大陆分流列表
把cnip.rsc上传到routeros,执行

/import cnip.rsc

2,配置分流路由表
Routeros V7取消了通过firewall的mangle里添加路由标记自动添加路由表功能,所有这里需要手动添加路由表

/routing/table/add name="gfw" fib

添加IP分流策略路由

/ip/route/add dst-address=0.0.0.0/0 routing-table="gfw" gateway=10.0.1.2

3,新建需要翻墙的内网地址列表,假定192.168.1.100和192.168.1.200需要翻墙

/ip/firewall/address-list/add list=gfw address=192.168.1.100/32
/ip/firewall/address-list/add list=gfw address=192.168.1.200/32

4,给需要翻墙的内网ip添加标记

/ip/firewall/mangle/add chain=prerouting action=mark-routing new-routing-mark=gfw passthrough=yes dst-address-type=!local src-address-list=gfw dst-address-list=!CNIP log=no log-prefix=""

5,配置无污染DNS服务器
参考使用dnsmasq基于大陆域名白名单分流解析域名使用overture替换dnsmasq做域名分流解析

6,测试目的IP分流
在192.168.1.100上执行traceroute命令

traceroute 8.8.4.4
192.168.1.100--->192.168.1.1--->10.0.1.2--->香港服务器公网路由--->8.8.4.4
traceroute 114.114.114.114
192.168.1.100--->192.168.1.1--->PPPoE公网路由---->114.114.114.114

ps,按照上述ipv4的策略路由配置方法,ipv6并不会生效。
此问题是ipv6策略路由的路由表问题。截至v7.10beta8,mikrotik还没有修复ipv6的路由表问题,或者是mikrotik将来会调整策略路由配置方法。
ipv6的firewall的对应mangle条目的counter有计数,说明修改routing-mark已经生效,但是数据包没有走routing-mark设置的路由表。
经过搜索mikrotik官方论坛,需要另外增加一条设置

/routing/rule/add action=lookup-only-in-table routing-mark=gfw table=gfw

使用dnsmasq基于大陆域名白名单分流解析域名

20210617更新:RouterOS使用DNS转发功能实现域名分流解析
20210127更新:使用overture替换dnsmasq做域名分流解析
有朋友问我怎么用dnsmasq做分流解析,其实挺简单,下面介绍一下。

以下以debian系linux为例,已在路由器做ip地址分流,参考routeros配置vpn分流大陆ip

1,安装dnsmasq

apt update
apt install dnsmasq

2,配置dnsmasq,默认使用8.8.8.8和8.8.4.4解析

vi /etc/dnsmasq.conf

粘贴下面三行到文件末尾

no-resolv
server=8.8.8.8
server=8.8.4.4

3,配置dnsmasq的解析白名单
这里使用了felixonmars/dnsmasq-china-list的大陆域名白名单
这个列表使用了114.114.114.114的dns服务器,这里建议使用运营商给你的dns服务器,一是解析会快一点,二是cdn识别会更准确

这里假设拨号获得的dns服务器是223.5.5.5,可以使用下面命令来生成使用运营商dns服务器的域名列表

curl -s https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf|sed 's/114.114.114.114/223.5.5.5/g' >/etc/dnsmasq.d/accelerated-domains.china.223.5.5.5.conf

如果需要使用大陆dns服务器解析apple或者google的域名,可以使用下面命令生成对应列表,这里我不推荐。

curl -s https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf|sed 's/114.114.114.114/223.5.5.5/g' >/etc/dnsmasq.d/apple.china.223.5.5.5.conf
curl -s https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/google.china.conf|sed 's/114.114.114.114/223.5.5.5/g' >/etc/dnsmasq.d/google.china.223.5.5.5.conf

4,重启dnsmasq服务使配置生效

service dnsmasq restart

5,测试dns分流解析
首先使用大陆dns服务器解析google.com,多次测试得到的ip地址并不是google的ip,可以用ipip.net来查询ip所属

dig google.com @223.5.5.5

然后使用dnsmasq解析google.com,多次测试可以发现ip地址是google的

dig google.com @127.0.0.1

6,自己添加域名到白名单
别人制作的域名列表中如果不包含自己需要的域名,可以向列表追加

echo 'server=/你需要的域名/223.5.5.5' >>/etc/dnsmasq.d/accelerated-domains.china.223.5.5.5.conf

Routeros的address-list大陆分流列表

20230529更新:添加clang.cn的大陆IPv6地址。
20230529更新:添加clang.cn的大陆IP地址的CIDR合并后的地址列表,合并前8K+,合并后5K+。
20220822更新:由于ipip的数据很长时间不更新,添加clang.cn的大陆地址列表。

原来一直使用apnic的ip地址按CN生成Routeros的address-list分流列表,偶然发现列表里有境外ip,检查发现是大陆厂商的ip宣告到美国了。
平时用ipip.net来查看ip地址所在地,通过几年使用发现ipip.net的地址库对比其他ip查询网站来说更准确些,并且ipip.net在github每月发布大陆地址列表
上述ip地址宣告变化可以从ipip.net大陆ip列表的20190304这个github commit看出,这个commit中203.20.138.0/23被删除,用ip.cn站长之家查看,发现是福建电信ip,如图
ip.cn
通过apnic最新CN列表查找发现在203.20.136.0/21这个段里面,如图
apnic
但是ipip.net查询,是印尼电信,如图
ipip.net
而且通过路由追踪到了印尼,如图
路由追踪

于是写了行命令自动从github下载并转成routeros的address-list,并添加了私有ip地址192.168.0.0/16,172.16.0.0/12和10.0.0.0/8

curl -s https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt |sed -e 's/^/add address=/g' -e 's/$/ list=CNIP/g'|sed -e $'1i\\\n/ip firewall address-list' -e $'1i\\\nremove [/ip firewall address-list find list=CNIP]' -e $'1i\\\nadd address=10.0.0.0/8 list=CNIP comment=private-network' -e $'1i\\\nadd address=172.16.0.0/12 list=CNIP comment=private-network' -e $'1i\\\nadd address=192.168.0.0/16 list=CNIP comment=private-network'>cnip.rsc

并添加了定时任务每月生成一次放在我的网站,可以在这里下载
基于clang.cn的中国大陆IP地址列表的routeros分流脚本,点击这里下载
基于clang.cn的中国大陆IP的CIDR合并后的地址列表的routeros分流脚本,点击这里下载
基于clang.cn的中国大陆IPv6的地址列表的routeros分流脚本,点击这里下载