AllowedIPs 是路由表,不是防火墙规则
它负责为出站流量选择对端,并校验入站来源。它不是访问控制列表,关闭路由管理也修不好被拆分的隧道。
大多数人把 AllowedIPs 读成一份许可清单,即“允许连接某个对端的地址集合”,几乎把它当作写给隧道的防火墙规则。事实并非如此。这个字段是一张双向生效的路由表:它为出站数据包选择对端,也校验入站数据包的来源。把它当成访问控制列表来读,会写出把没人要求的流量也路由出去的配置。
一个字段,两种读者:出站选择与来源校验
在客户端,这些前缀决定哪些目标走该对端、哪些仍留在普通网络上。因此 0.0.0.0/0 的条目会捕获所有 IPv4 目标,这也正是导入全隧道配置后普通浏览会绕到远端机器的原因。窄条目则相反:只路由你列出的网段,其余一律留在原处。WireGuard 文档中的密码密钥路由一节把这两项工作放在一起讲:选择出站对端,以及校验入站来源。
在服务器上,同一个字段描述每个对端可以使用哪些源地址。这是密码学校验,而不是包过滤器:内层来源与该对端清单不符的数据包,会先被 WireGuard 丢弃,主机上的任何防火墙都还来不及看到它。两项工作共用同一份清单,正因如此,从别处照抄的清单才会在你没有考虑到的位置出问题。
客户端配置块正是大部分混乱的起点。拆分隧道会列出远端网段,而全隧道就是同一个字段里放一个默认前缀:
[Peer]
# split tunnel: only these networks
AllowedIPs = 10.77.0.0/24, 192.168.30.0/24
[Peer]
# full tunnel: everything, both families
AllowedIPs = 0.0.0.0/0, ::/0
两种写法本身都是完整的,它们是二选一,而不是先后步骤。前者只把这两个网段送进隧道;后者发送所有目标,其中 ::/0 条目为 IPv4 默认前缀再加上 IPv6。无论选哪一种,一旦 wg-quick 开始安装路由,这些前缀就是该对端全部的转发决策。
中心节点需要不同的清单
中心节点会把每个客户端的隧道地址列为主机前缀,再加上确实位于该客户端后面的网段。把客户端的宽泛清单复制到中心节点的每个对端上,等于告诉中心节点许多对端都可以使用同一批源地址,而这并不是地址规划。Endpoint 字段属于完全不同的层次:它指明对端的外层地址和端口,而绝不是隧道内部的目标。
[Peer]
# laptop: tunnel address 10.77.0.2, office LAN behind it
AllowedIPs = 10.77.0.2/32, 192.168.30.0/24
主机前缀承载隧道地址,网段前缀承载客户端身后的网络,两者缺一不可。没有主机前缀,中心节点就无法把客户端自身的流量送回去;没有网段前缀,其后的局域网就一直不可达;身后什么都没有的对端只会拿到主机前缀。
跳过路由安装会留下缺口
wg-quick 是负责从配置文件拉起接口的辅助工具,它会顺带安装接口地址和路由。设置 Table = off 等于让该工具跳过路由工作,这既不会安装替代路由,也不会让私有网络变得可达。当自动路由已经能完成工作时,明确写出需要的前缀才是更清晰的配置。关闭路由管理却又不写替代方案,不是设计,而是遗漏。
基础工具 wg 的行为不同:它只配置接口,从不碰路由,因此直接基于它搭建的方案需要自己的路由命令。为一种工具写的操作说明,拿到另一种工具上照做就可能出错。一次成功的 ping 也是弱证据,因为它只验证了一条路径,而不是你需要的每条应用路径。
DNS 与 IPv6 要分别判断
检查隧道通告的 DNS 服务器地址,并确认通过你选择的前缀确实存在通往该地址的路由。只设置解析器并不会让解析器变得可达,而收窄隧道有可能悄悄删掉原先通往它的路由。IPv6 也要单独检查,因为正确的 IPv4 拆分并不能说明仍指向物理链路的 IPv6 默认路由。修改一个对端配置块时,三项彼此独立的决定可能同时发生变化。
然后从已知的初始配置出发,打开一个私有资源和一个普通网站。如果资源能访问,而浏览仍然从本地连接出去,说明拆分生效了。如果浏览在同一时刻中断,说明隧道接管了默认路由,这时就该去看前缀清单。