访问控制
访问控制决定谁能使用加密入口。它用 nftables 实现,不经过 mosproxy:没被放行的来源连 TLS 握手都做不了。
规则
/var/lib/dns-stack/acl.txt,每行一个 CIDR 或单个地址(IPv4、IPv6 都可以)。空文件表示不启用,入口对全网开放。
启用后,内核里会有一张独立的 inet dns_acl 表,它的 input 链按顺序:
- 回环接口:放行;
- 隧道网段
10.100.0.0/24:放行; - 已建立的连接:放行;
- 来自授权网段、去往
DOH_PORT/DOT_PORT的 TCP 和 UDP:放行; - 其它去往这两个端口的流量:丢弃并计数。
TCP 和 UDP 都覆盖,所以 DoH、DoH3、DoT、DoQ 四个入口一起受保护。其它端口不受影响。
命令
bash
sudo dns-stack acl # 列出授权网段与内核链状态
sudo dns-stack acl status # 同上,并打印内核里的规则
sudo dns-stack acl add 203.0.113.0/24 # 加入并立即下发
sudo dns-stack acl remove 203.0.113.128/25 # 从已有网段里挖掉一段并下发
sudo dns-stack acl set 203.0.113.0/24 198.51.100.7
sudo dns-stack acl apply --preview # 只打印将要下发的 nft 脚本
sudo dns-stack acl disable # 紧急关闭:移除内核链,保留 acl.txtadd/remove/set改完文件就直接下发,会先显示影响范围并要求确认;--yes跳过确认。- 写入时相邻网段会自动合并,
remove可以从大段里挖掉一部分。 - 清单被清空时,内核链随之移除,入口恢复对全网开放。
防止把自己锁在外面
家宽地址会变
家里的公网地址变了,就连不上自己的 DNS。出事时用 SSH 登录服务器执行 sudo dns-stack acl disable。
几道保护:
- 回环与隧道始终放行,本机自检和香港节点不受影响。
- 面板修改访问控制时,如果改完之后请求方自己不在授权网段里,直接拒绝、不写文件。这个判断只有面板做得到,因为只有它知道是谁在改。经 SSH 隧道走回环访问的不受此限。
- 空的白名单不会被下发成「全部丢弃」。
重启与看门狗
访问控制住在自己的 inet dns_acl 表里,和出口分流的 inet dns_route 表分开。分流服务随 wg0 停止时会删掉整张分流表——如果两者在同一张表里,隧道一断入口就对全网敞开(2026-10-02 的审计发现过这种情况,已经拆开)。
- 分流服务启动时,第一件事就是按
acl.txt恢复访问控制,哪怕隧道接口还没起来; - 看门狗每分钟检查一次,不管隧道状态:清单里有网段、内核里却没有这张表,就直接重新下发,失败才推送告警;
acl disable会留下一个「已手动关闭」的标记(/var/lib/dns-stack/acl.disabled),看门狗和重启都不会再把它装回来,直到你执行acl apply或改动清单。
自检里对应「访问控制」一项:清单与内核不一致时报失败,手动关闭时提示关注。