预共享密钥这个词出现在 IPsec、OpenVPN 和 WireGuard 的文档里,但指的是三种不同的对象。一种用于认证,一种保护控制通道,还有一种为已经具备身份信息的握手追加材料。把它们当作可以互换的东西,连接就会在谁也没预料到的阶段失败。在把某个值填进那个字段之前,先读清楚它在该协议里做什么。

三种协议,三种含义

每种协议都在自己的规范里定义这把密钥的职责,而这些职责并不重叠。认证用的密钥证明两个对端知道同一个值。控制通道的密钥保护随后的协商。握手的附加项改变密钥计划,却不改变对端是谁。

这些角色都不认证人类用户,而这正是最耗时的混淆。预共享密钥在交换之前就配置到设备或网关上,因此每个持有者在另一端看来都一样。这个特性对两台路由器之间的站点到站点链路是优点,对拥有具名员工的远程接入服务却是负担。在描述部署的文档里,把账户凭据和密码学密钥分成两列。

IPsec 与 OpenVPN 对这个词用法不同

IKEv2 可以用预共享密钥代替证书来认证对端,该值必须在两端一致。由于同一个密钥通常为一组对端统一配置,任何持有者都能冒充其他人,而这次交换也得不到它从未拥有过的身份密钥所带来的前向保密。

OpenVPN 的 tls-auth 和 tls-crypt 选项为控制通道附加一把静态密钥,或加入 HMAC 签名,或直接加密协商过程。这把密钥不是用户密码,也不替代客户端证书。区分两者在续期时很重要,因为改密码并不会动到控制通道的密钥。

WireGuard 的 PSK 只是追加,不做身份识别

WireGuard 的对端本来就持有 Curve25519 公私钥,握手认证的正是这些身份。可选的预共享密钥会被混入链式密钥,在公钥交换之上再贡献一份对称材料。

它不提供自己的身份,也不提供用户账户,因此运维方无法靠 PSK 区分两个持有者。两端必须携带相同的值,否则握手会失败,而且不会给出有用的报错。所以轮换必须同时为两侧规划,而不是改一个文件了事。

检查分发、轮换与移除

分发是所有「一处密钥、多处使用」设计的薄弱环节。粘贴到聊天窗口、存进代码仓库、或在多个环境间复用的值,会积累出没人能清点的副本,每份副本都在悄悄扩大影响范围。

Base64 文本不是加密。和公开证书放在同一目录里的密钥,仍然是明文密钥。

openssl rand -base64 32
sudo wg show wg0 preshared-keys
sudo grep -R -n 'psk' /etc/ipsec.d/ 2>/dev/null

按计划轮换,并在任何疑似泄露之后轮换;先更新所有预期的对端,再作废旧值。然后从两端测试链路,因为密钥不匹配会在握手阶段失败,看起来和防火墙问题一模一样。

记录哪把密钥保护哪个阶段,这样重置密码就永远不会被误当成更新密码学密钥。这一行说明能在每次有人审计部署时省下一个小时。

相关文章