软路由折腾记录三

ADGuard

在路由器层面进行广告过滤, 并没有特别有效的方法, 到目前为止最有效的依旧是浏览器插件. 因为广告过滤的核心是拦截js/图片, 路由器上的透明代理很难窥视HTTPS传输的内容, 所以目前的路由器插件仅能对HTTP进行过滤. ADGuard Home另辟蹊径, 它提供DNS服务, 对黑名单里的广告域名进行拦截, 返回一个无法访问的IP.

部署

由于clash提供了DNS服务, 所以需要调整ADGuard/clash的上下游顺序.

1
dnsmasq -> ADGuard -> clash

首先启动ADGuard:

1
docker run --name adguardhome -v /my/own/workdir:/opt/adguardhome/work -v /my/own/confdir:/opt/adguardhome/conf -p 5301:53/tcp -p 5301:53/udp -p 3000:3000/tcp -d adguard/adguardhome

ADGuard的DNS服务监听5031端口, 而clash监听5300端口. 首先编辑dnsmasq配置文件, 设置上游服务器为ADGuard:

1
server=127.0.0.1#5301

接着访问软路由3000端口, 这是ADGuard提供的web界面, 在里面配置上游DNS为5300. 接下来就可以自有配置过滤规则, 配置完后可以执行命令验证广告域名是否被屏蔽:

1
dig ad.xxx.xxx

效果

由于广告推送技术的发展, 现在光屏蔽域名还远远不够. 实测效果来看, 国内各大视频网站的广告均无法过滤, 而类似于谷歌联盟的图片广告可以屏蔽. 另外ADGuard不仅仅用于广告过滤, 还能屏蔽一些统计js, 针对斗鱼/虎牙等还能屏蔽p2p通信, 这些都需要在web界面里勾选一些开源规则.
但需要注意, 屏蔽某些域名可能导致网站体验不佳, 例如禁用p2p后斗鱼/虎牙会偶尔卡顿.

ipset

在使用了tproxy透明代理UDP流量后, 所有TCP/UDP流量均由clash处理, 包括与大陆ip的通信. 由于UDP转发本身比较耗费CPU, 所以我考虑能不能让大陆ip直接在iptables层放行, 只有国外ip的流量会通过clash.
ipset是iptables提供的工具, 你可以给一组ip取一个名称, 然后在iptables规则中检测目标ip是否属于该组. 所以我们只需要把大陆的ip网段添加到一个组中, 取名为”china”, 接着新建规则, 如果ip属于”china”则不进行透明代理.

1
2
3
4
5
6
wget http://www.ipdeny.com/ipblocks/data/countries/cn.zone

ipset -N china hash:net
for i in $(cat ./cn.zone ); do
ipset -A china $i;
done

接着在iptables相应的表中添加规则:

1
2
iptables -t mangle -A CLASH -p udp -m set --match-set china dst -j RETURN
iptables -t nat -A CLASH -p tcp -m set --match-set china dst -j RETURN

配置完成后, 只有国外ip的访问会经过clash, 而大陆ip的访问由iptables直接转发.