关于dns泄露的那些事情 路由器 mosdns分流 clash
#dns 为什么会被泄露
因为默认情况下家庭网络的dns都是走 明文 udp的53端口。但是即便是配置了走doh/dot也会泄露。
#dns 泄露后有什么不好的
如果 你对运营商或者国内dns 发起了一个 查询某一个域名dns的请求,随后你又加密连接到了一个境外ip并传输了大流量数据。
你在干什么 就非常显而易见了。 在这个红色恐怖充斥的2023年,这是一个非常作死的事情。
#什么是dns污染 阻断和劫持
简单的说,就是 你请求了某一个公共dns,但返回的数据是错误的,或者半路被篡改掉了。
返回错误数据 是因为国内政策要求,所以公共dns服务器对某一些域名进行了阻断,一般会返回一个本地局域网i或者随意一个国外ip。所以需要使用国外公共dns来处理一些域名的解析。
数据被篡改,只有你在明文进行dns请求的时候,返回数据被运营商或者某部门或者恶意第四方篡改掉,这种情况仅限明文dns请求的情况下。所以有了doh和dot的加密dns请求。
#什么是doh和dot
dns over tls 和 dns over https 就是用用tcp tls 或者 https 加密你的 dns请求。
一般浏览器和操作系统 都支持。
#doh和dot可以避免污染 阻断 劫持和 泄露吗
并不能完全避免。
doh和dot是可以避免dns解析记录被中间人篡改和窥探的,但是使用国内公共dns无法解决政策原因导致的污染。
如果你 doh/dot到 国内的 doh/dot的dns服务,那么只是你上游网络(宽带运营商)无法得知你的dns请求了而已。但是对应的国内dns服务商依旧可以得知。
你直接使用国外加密dns,理论去是可以的避免所有问题,但是国外加密dns有三个问题:
- 国内直接访问速度太慢 严重影响使用
- 国外加密dns都已经被干扰并且不定期阻断和重定向 无法正常稳定使用
- 有一些国内网站基于dns做了分地区或者一些优化,例如你访问某一个网站用的国外的dns可能会被重定向到对方的国际站点。
#怎么完美解决
三句话:
- 使用clash代理国外主流doh/dot的dns服务,一般情况下所有的第三方clash转换规则包括机场自带的规则 以及常见的路由器分流配置 都可以识别到这部分流量 都会帮你代理出去。
- 国内域名到 国内的doh/dot的dns服务商,gfw清单中的域名到国外主流doh/dot的dns服务商
- 如果非gfw清单中域名,但是返回了国外ip,那么到国外主流doh/dot上再次查询一次
这样就完美规避了上述所有问题。
#怎么实现
mosdns分流搞定一切。如果有特殊需求,加辅助dns的上游,例如AdGuardHome和自建doh。
#怎么优雅实现
#原理
使用mosdns,mosdns 判断是gfw域名直接请求 google和cf或者你的自建doh。否则请求国内doh/dot 如果请求了国内dns但是返回了一个国外ip,那么再次请求 google和cf或者你的自建doh 确认修正一次。
国内doh/dot 我们也可以作为AdGuardHome的上游,顺带去广告或者处理一下别的情况。
#最佳方案(新手推荐)
mosdns 作为网内的主dns,或者路由器的上游主dns。
两个 AdGuardHome 分别处理 境外网站和国内网站,这两个AdGuardHome作为mosdns的上游dns.
这样的好处是 AdGuardHome有较为直观的webui管理界面,并顺带处理广告问题。
另外一个猴版方案 是 AdGuardHome作为主dns, mosdns作为 AdGuardHome 的上游,一样可以实现。这样省一个AdGuardHome,但是有特殊要求的情况下不适用。
#单mosdns方案(老手推荐)
也是我目前使用的方案,优点是更加灵活性能也比较好。
https://dev.leiyanhui.com/route/mosdns-all-in-one
#为什么不直接用clash自带的dns劫持
主要是自带的clash dns规则较为复杂,一不消息就会泄露dns。
#这么复杂不会拖累速度吗
不会,因为mosdns速度非常快,而且自己有良好的缓存机制。 我们使用运营商的dns他也会逐级请求上层dns,只是不需要我们配置而已。
#准备:
1、mosdns和对应的geoip.dat,geosite.dat
2、(可选)cfwork自建一个doh
3、(可选)AdGuardHome顺带去广告
#mosdns
建议docker安装 推荐 https://hub.docker.com/r/601096721/mosdns
#cfwork自建doh
因为cf和google包括其他知名国外的dns,无论是否doh/dot都被干扰了,非常不稳定甚至某些时候无法使用。 而有时候我们需要直连查询。
推荐index.js https://github.com/tina-hello/doh-cf-workers
记得绑定一个自己的域名,因为cfwork默认分配的域名本身是被墙的状态,那么你自己搭建的反向代理也就无意义了。
cfwork每个账户每天有免费10万次查询额度,自己用足够了。上面的代码中没有包含路由功能,你可以自己配置一下,防止被盗用。
这个方式自建doh 速度肯定是不好的,因为我们一般会在clash或者软路由的分流规则直连这个地址,本身速度就不快,而且我们的自建doh实际是反向代理了一次cf的doh,所以速度方面就不用想会多快了。这只是在我们无法使用代理,并且需要正确dns的时候最后的手段。
因为cfwork只支持http/https请求,所以不能搭建dot只能doh,理论上doh因为基于http协议需要携带http头部信息,数据包大一些,速度会慢一点,实际上两者使用体验上并无差别
上面的脚本可以适当的修改后缀,或者在cf面板中添加规则防止被别人白嫖。js语法很简单,自己看注释修改一下即可。
#AdGuardHome
为什么要AdGuardHome ? 除了去广告之外 AdGuardHome的并发dns查询可以加快访问速度。另外ddns的域名,我们可以直接指向内网ip,这样在我们ip变化后但是ddns因为受到ttl的限制不能马上刷新的情况下不会影响内网使用。
AdGuardHome的配置较为简单 就不用多说了。dns里面加一堆国内的dot运营商即可,参考下面的上游 DNS 服务器 分别配置的阿里云 360和腾讯dnspod的dot
tls://223.5.5.5
tls://223.6.6.6
tls://101.226.4.6
tls://123.125.81.6
tls://1.12.12.12
tls://120.53.53.53
建议全部直接用ip走dot或doh 而不是用域名 ,这样可以避免Bootstrap dns配置错误导致的问题。
你可以先用https://ip地址 访问对应的dns如果没有提示证书错误 那么他就是支持ip直连doh,那也可以ip走dot。也可以查询对应dns服务器的文档。
#在爱快和ros openwrt下如何配置
建议 mosdns和AdGuardHome都不要劫持本地的dns.而在 路由器设置吧mosdns的内网ip或者dockerip作为路由的首选dns。
爱快3.7.7 体验版本已经支持 dns的第三方代理模式 配置主dns(mosdns)和三个备用dns(国内公共dns),虽然目前测试存在问题,但是后续版本应该会修复。
#openclash里面怎么配置
直接吧clash的dns 所有dns全部替换为mosdns
#mosdns配置文件
mosdns 相当于是我们的核心dns了。我目前的配置如下。
# 日志
log:
level: error #日志级别。可选 "debug" "info" "warn" "error"。默认 "info"
file: ""
production: false
# api:
# http: 127.0.0.1:8888
# include: []
plugins:
# forward 可以将所有的 upstream 写一起,sequence 里按需调用 "$插件tag 上游tag..."。看下一条注释。
- tag: cache
type: cache
args:
size: 1024
lazy_cache_ttl: 0
# 自定义Hosts
- tag: hosts
type: hosts
args:
files:
- "./hosts"
- tag: upstreams
type: forward
args:
upstreams:
- tag: adguardhome
addr: udp://10.10.1.3 #上游是境内dns
enable_pipeline: true
idle_timeout: 30
insecure_skip_verify: true
- tag: adguardhome2 #上游是境外dns
addr: udp://10.10.1.5
enable_pipeline: true
idle_timeout: 30
insecure_skip_verify: true
# 后面的作为备用暂时不使用,这里直接使用两个adg作为上游
- tag: cf_worker
addr: https://xxxxx #自己在cfwork搭建的doh
enable_pipeline: true
idle_timeout: 50
insecure_skip_verify: true
- tag: cloudflare_tls
addr: tls://1.0.0.1
enable_pipeline: true
idle_timeout: 50
insecure_skip_verify: true
- tag: google_tls
addr: tls://8.8.8.8
enable_pipeline: true
idle_timeout: 50
insecure_skip_verify: true
- tag: dnspod
addr: tls://1.12.12.12
enable_pipeline: true
idle_timeout: 30
insecure_skip_verify: true
- tag: aliyun
addr: tls://dns.alidns.com
bootstrap: 223.5.5.5
enable_pipeline: true
idle_timeout: 30
insecure_skip_verify: true
# cn域名的规则
- tag: geosite_cn_seq
type: sequence
args:
- exec: $upstreams adguardhome
# 替换 cloudflare 的 IP 成自己的最优 IP 的规则
# 没找到txt,不用这条
# - tag: fastest_cf
# type: sequence
# args:
# - matches: resp_ip &./geoip_cloudflare.txt # 是不是 cloudflare 的 IP
# exec: black_hole 1.1.1.1 ::1 # 用 black_hole 强制换成这些 IP 的应答。注意,这里的 IP 只是示例不是 cloudflare 的。
# 远程域名的规则
- tag: remote_seq
type: sequence
args:
- exec: prefer_ipv4 # 希望 remote 优先 ipv4.
#- exec: $upstreams adguardhome2 cf_worker cloudflare_tls google_tls
- exec: $upstreams adguardhome2
# - exec: jump fastest_cf # jump 相对于把 fastest_cf 的规则链插到此处。
# 这个 sequence 转发请求到本地,返回只包含 cn IP 的应答。(过滤掉非 cn 的应答)
- tag: local_must_has_cn
type: sequence
args:
#- exec: $upstreams adguardhome dnspod aliyun
- exec: $upstreams adguardhome
- matches: "!resp_ip &./geoip_cn.txt"
exec: drop_resp # 如果应答里没有 cn IP,丢掉。
# 利用 fallback 机制按 IP 分流。如果 local 服务器返回了 cn 的应答就接受,非 cn 的应答会被丢弃,使用 remote 服务器的应答。
- tag: fallback_ip
type: fallback
args:
primary: local_must_has_cn # 空应答(本地服务器返回了非cn IP然后应答被丢弃了)触发 fallback。
secondary: remote_seq # fallback 后就会使用 remote 的应答。
always_standby: true
##############################
# 配置主 sequence 规则,作为服务器的入口。
- tag: main
type: sequence
args:
- exec: $hosts
- exec: query_summary entry
#- matches:
# - qname &./geosite_category-ads-all.txt #自带的广告过滤
# exec: reject 0
- exec: $cache
- {matches: has_resp, exec: accept} # cache/hosts 等插件不再“命中记录自动跳过后续插件”,需用户自行判断是否有应答。
# 方便需要 ipset/nftables 用户定制流程。
# yaml 支持这种简写。
- matches:
- qname &./geosite_cn.txt # cn 域名
exec: goto geosite_cn_seq # goto 到 local 规则,不在执行后续规则。
- matches:
- qname &./geosite_geolocation-!cn.txt # 非 cn 域名
exec: goto remote_seq # goto 到 remote 规则。
- exec: $fallback_ip # 剩余域名用 ip 分流。
#### 动态路由 + cache。
# 新版的cache只会将命中的应答放在请求,不再自动终止后续规则。所以需要动态路由时,可以将
# sequence 的转发操作用 !has_resp 短路。做到每次请求都能刷新路由表。
# - tag: s1
# type: sequence
# args:
# - exec: $cache
# - matches:
# - "!has_resp" # 上一步cache命中缓存有应答了就不转发了。
# exec: $forward_remote
# - exec: ipset ...... # ipset 每次请求都能执行。
#####
####### mark 使用示例
# mark 在 exec 内是打标。在 matches 内是匹配。
# mark 当作开关的示例。
# - tag: s1
# type: sequence
# args:
# - exec: mark 1 2 # 先打标。
# - matches:
# - mark 1
# exec: $cache # 有 mark 1 缓存会生效
# - matches:
# - mark 2
# exec: ecs 1.2.3.4 # 有 mark 2 请求会被附加 ecs
# ...
# - matches:
# - mark 3
# exec: jump fastest_cf # 没 mark 3 不会替换 cloudflare ip。
#### 最后配置 server........略
- tag: server
type: udp_server # 目前有 udp/tcp/http_server
args:
entry: main
listen: 0.0.0.0:53
- tag: server_tcp
type: tcp_server
args:
entry: main
listen: 0.0.0.0:53
- tag: "server_http"
type: "http_server"
args:
entries: # []extry
- path: /dns-query # 本路径执行
exec: main # 可执行插件的 tag。
src_ip_header: "X-Forwarded-For" # 从 HTTP 头获取用户 IP。
listen: 0.0.0.0:80 # 监听地址。
cert: "" # 留空 cert 和 key 后会禁用 TLS。 这里没有配置证书,外网使用我这里另外有acme和nginx处理https
key: ""
idle_timeout: 10 # 空连接超时。单位秒。默认 30。
#######
#手动更新mosdns的分流数据
601096721/mosdns的docker镜像没有添加计划任务,只有在更新镜像的时候 才会更新。
可以在容器内部执行下面的命令更新数据库文件,也可以在容器内部安装crond 定时更新。
wget https://raw.githubusercontent.com/IceCodeNew/4Share/master/geoip_china/china_ip_list.txt -O /geoip_cn.txt
wget https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/reject-list.txt -O /geosite_category-ads-all.txt
wget https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/proxy-list.txt -O /geosite_geolocation-!cn.txt
wget https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/direct-list.txt -O /geosite_cn.txt
cp -u /geoip_cn.txt /etc/mosdns/geoip_cn.txt
cp -u /geosite_category-ads-all.txt /etc/mosdns/geosite_category-ads-all.txt
cp -u /geosite_geolocation-!cn.txt /etc/mosdns/geosite_geolocation-!cn.txt
cp -u /geosite_cn.txt /etc/mosdns/geosite_cn.txt
#补充
adguardhome 本身可以利用规则的方式实现分流协议。有第三方作者的规则,实际测试效果不好,主要是速度不理想。
adguardhome 搭建自己的私有doh需要强制证书,略微不方便。而mosdns 性能更好,且可以不使用证书搭建 dns over http(非https),而后用nginx+acme.sh统一反代到https。
但是mosdns没有简单方便的webui管理工具,去广告功能也没有adguardhome那么方便。所以如果不是内存特别紧张的情况下,mosdns+adguardhome依旧是新手的最佳方案。
adguardhome 本身大概需要 40-80M内存,我在使用mosdns+双adguardhome的时候,大概需要消耗150-180M内存。
如果对可视化管理没有需求,建议用单mosdns方案 https://dev.leiyanhui.com/route/mosdns-all-in-one