Skip to content

访问控制 ​

访问控制决定谁能使用加密入口。它用 nftables 实现,不经过 mosproxy:没被放行的来源连 TLS 握手都做不了。

规则 ​

/var/lib/dns-stack/acl.txt,每行一个 CIDR 或单个地址(IPv4、IPv6 都可以)。空文件表示不启用,入口对全网开放。

启用后,内核里会有一张独立的 inet dns_acl 表,它的 input 链按顺序:

  1. 回环接口:放行;
  2. 隧道网段 10.100.0.0/24:放行;
  3. 已建立的连接:放行;
  4. 来自授权网段、去往 DOH_PORT / DOT_PORT 的 TCP 和 UDP:放行;
  5. 其它去往这两个端口的流量:丢弃并计数。

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.txt
  • add / 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 或改动清单。

自检里对应「访问控制」一项:清单与内核不一致时报失败,手动关闭时提示关注。

只有两台机器:一台国内,一台香港。