扫描器对 UDP 端口输出“开放”或“已过滤”,结论往往在几秒内就跟上:隧道坏了。也许确实如此,但扫描并没有证明这一点。UDP 不携带任何连接握手,而 WireGuard 对无法通过认证的内容一概不回应,所以沉默才是大多数探测的预期答复。

不妨反过来,从客户端向外排查,并把扫描当作若干薄弱数据点中的一个。

扫描器能看见什么,又看不见什么

UDP 扫描器发去一段载荷然后等待。如果返回 ICMP 端口不可达,它可以报告端口已关闭。如果什么也没返回,结果在设计上就是含糊的:被过滤的路径、不存在的主机,以及忽略载荷的运行中服务,都会产生同样的沉默。三种不同状态,同一个输出字符串。

WireGuard 有意让这种含糊变得更糟。协议只接受能通过认证的报文,因此密钥不符的探测会被直接丢弃,不会得到任何回应。没有横幅,没有版本字符串,也没有可供指纹识别的错误信息。

在同一端口号上做 TCP 测试,测的并不是同一件事。它运行的是另一个可能根本不存在的监听者,它的拒绝并不能说明 UDP 的任何情况。

所以“开放、已过滤”这类状态,描述的是扫描器的不确定,而不是你的服务器。

从配置档案向内,走一遍真正的客户端

先从客户端自身的视角入手。接口是否拿到了地址,配置是否写对了端点,连接尝试时握手计数器是否在变化?从未发出报文的客户端和被丢弃报文的客户端,在状态窗口里看起来完全一样。只有计数器能区分二者,所以请先看计数器。

随后在一次获准的尝试发生时观察服务端,而不是从第三个地点另做一次扫描:

wg show wg0 latest-handshakes
tcpdump -n -i eth0 udp port 51820 -c 10

第一条命令报告每个对端最近一次握手,这是认证交换已经完成的直接证据。第二条显示发往监听者的报文究竟有没有到达,从而一步区分路径问题与配置问题。

如果抓包什么也没看到,报文从未到达主机,隧道的配置就不是嫌疑对象。如果抓包显示报文确实来自预期地址,而握手始终为零,那么下一步该看的就是密钥或对端允许的地址。

由你管理服务器时,就在服务器上交叉比对

确认监听者确实存在,并确认服务商的防火墙放行了该 UDP 端口。主机防火墙规则与云安全组是两道彼此独立的闸门,任何一道都可能丢弃另一道已放行的报文。要用配置里的实际端口去核对两者,而不是凭记忆中的端口。

地址和端口同样重要。只监听某一地址的服务器,不会回应发往另一地址的报文;多网卡的主机还可能在你没打算用的那块网卡上收到探测。

把每一项测试都控制在你有权测试的系统之内。有意义的比较是真实客户端的一次尝试与预期的服务端路径之间,而不是去更大范围地扫一遍碰巧属于同一服务商的地址。

诚实地解读扫描结果

扫描是确认主机存在、端口没有被中间设备明显阻断的廉价手段。它不是认证协议的连通性证明,更绝不是配置测试。

更有力的证据,是你真正关心的客户端完成的一次握手,随后是一次走通隧道并拿到响应的请求。这个序列一次就检验了密钥、允许的地址、两道防火墙和回程路径。

当真实尝试失败时,仍要用客户端的计数器和服务器上的抓包去诊断,而不是再做一次探测。协议说明解释了为什么未通过认证的报文得不到回应,而这正是扫描结果含糊的全部原因。

相关文章