WireGuard 握手时长不是会话超时
密钥更新计时器管理的是密钥,不是用户访问权。读取 latest-handshakes 只能说明某个对端的协议状态,不能说明它的授权是否过期。
一个停止转发流量的对端并不会因此失去密钥,一次新的握手也不能证明任何人续订了使用许可。WireGuard 的计时器让密钥保持新鲜、让数据包持续流动;它们并不模拟用户在若干分钟后登出。这里有三个问题被混为一谈,而每个问题的证据都不同。这个区分决定了你该用哪种工具。
三个问题,一条命令输出
运维人员会问对端是否可达、是否活跃、是否仍被允许。第一个是协议状态,第二个是流量计数器,第三个是授权。只有前两个能从 WireGuard 接口读出,而它们经常被用来回答全部三个问题。
| Question | Evidence it needs | What does not answer it |
|---|---|---|
| Is the peer reachable now? | A recent handshake and a working return path | An interface that exists |
| Has it been active? | Transfer counters moving over time | A handshake timestamp alone |
| Is access still granted? | The configuration or controller that authorizes it | Any protocol timer |
把这些行看作三项独立的调查。前两项成本很低,用接口自身的计数器就能回答。第三项需要授予访问权限的配置,它位于另一个文件或另一个系统里。选错行,就是让协议计时器去干策略的活。
计时器实际管理什么
协议为握手重试、传输密钥轮换以及拒绝受旧密钥保护的数据包定义了常量。它们响应的是流量和状态,而不是日历,也不是某人可以连接至 17:00 这样的策略。这就是为什么一个空闲对端可以连续数小时看起来不活跃,却仍然处于授权状态。
PersistentKeepalive常被误认为缺失的超时设置。它发送经过认证的空数据包以维持 NAT 映射,把它设为零会停止这些数据包,但不会撤销任何东西。
按对端读取运行状态,用公钥而不是注释:
wg show wg0 latest-handshakes
wg show wg0 transfer
最近一次握手说明完成了一次握手。它并不说明隧道后面的私有服务可达,而旧的时间戳可能属于一个只是安静的对端。
为什么空闲的对端不等于已登出的对端
WireGuard 没有带开始和结束的会话对象。对端就是一个带允许地址的公钥,保护其流量的握手按需替换,没有任何用户可见的登录过程。把近期没有流量当成登出,是把模型弄反了。
如果真正的抱怨是连接在闲置后失败,原因通常在别处:过期的 NAT 映射、进入睡眠的设备,或者丢失状态的防火墙。从远端发送流量并新建一条流来测试,然后比较发生了什么变化。
把截止时间放在授权所在的地方
如果访问必须在特定时间结束,截止时间就属于授予访问的那个东西。发放对端配置的控制器可以要求重新审批后才发放新的配置,这是控制器的属性,而不是接口上的隐藏参数。
对于手工管理的对端,删除必须同时到达两处:运行中的接口和已保存的配置。只在运行时删除对端,会被重启或协调循环撤销,从而恢复你以为已经过期的身份:
sudo wg set wg0 peer <public-key> remove
sudo wg-quick save wg0
然后测试边界,而不是标签。确认对端在截止时间后被拒绝,确认续期路径有效,确认状态在管理器重新加载后仍然存在。握手时长是有用的运维信号,它不是访问记录。