8192 位密钥拖慢握手,1024 位 DH 被拒绝
两个方向相反的大小故障:过大的密钥会一直消耗握手时间,直到对端超时;而过小的 DH 组还没开始就被拒绝。
一台服务器的客户端会卡住一段时间再重连,另一台则立刻拒绝连接,并给出关于密钥大小的提示。它们看起来像两种不同的故障,其实是同一个故障指向相反的两端。握手加密的成本随参数规模增长,同时现代库还有一个不会跌破的下限。给材料定尺寸就是检查清单,而第一项是先判断你遇到的究竟是哪一种故障。
先读懂失败,再重新生成任何东西
时序能说明大部分问题。握手耗掉好几秒后失败,通常意味着计算时间超过了对方的耐心,指向的是对硬件或超时而言过大的参数。立刻被拒绝并点名密钥或组的尺寸,则指向另一端——库根本不接受的参数。
这两种情况需要相反的修复,而大多数尝试恰恰在这里出错。在已经拒绝过小组的客户端上重新生成 8192 位参数,只会让慢的情形更糟,对快的情形毫无帮助。在动手改任何文件之前,先写下你观察到的症状。
接着要检查对方被要求做什么。为大型有限域组配置的服务器会迫使每个客户端在每次重新协商时都花同样的 CPU 时间,而不只是连接时如此。如果问题按固定间隔出现,而不是在启动时出现,这个间隔就是判断哪项设置昂贵的有力线索。重新协商会重做整个计算,所以每小时复发的卡顿通常只是同一笔开销又被付了一次。
慢的情形:硬件负担不起的参数
Diffie-Hellman 与 RSA 的运算量随密钥规模迅速增长,而这一切都发生在隧道里有任何流量之前。在小型路由器或低功耗客户端上,足够大的组会把交换推到对方的超时之外,于是连接要么重试,要么干脆毫无报错地看起来卡住。
修复办法是降到一个每个对端都支持、每台设备都能从容计算的尺寸。2048 位 RSA 密钥和 2048 位组仍是兼容性很广的基线;只有各方都同意、且 CPU 能在每次重新协商时付得起,采用更大尺寸才划算。超过这条基线的一切都是有意的取舍,而不是升级。
尺寸不是评分,比较表里最大的数字并不自动等于正确选择。挑选策略允许、且所有对端都接受的最小值,然后实测握手,而不是假定它变好了。仍然超时的更小组,说明尺寸从来就不是全部原因。
快的情形:库拒绝接受的组
现代 OpenSSL 构建会直接拒绝最小的有限域组,而提高安全等级会把下限推得更高。附带几十年前参数文件的路由器固件是最常见的来源,症状是连接立刻失败,并给出点名组或密钥尺寸的消息。这种失败没有任何间歇性,正因如此它很容易辨认。
应当替换文件,而不是改配置去跳过检查。生成一个当前可用的组,验证它,然后装到守护进程真正读取的位置。在新文件被客户端成功连接之前,先保留旧文件:
openssl dhparam -out /etc/openvpn/ffdhe2048.pem 2048
openssl dhparam -in /etc/openvpn/ffdhe2048.pem -check -noout
ls -l /etc/openvpn/ffdhe2048.pem检查命令会验证文件,通过时不输出任何有用内容;清单则确认你替换的是服务加载的那个文件,而不是旁边那份陈旧副本。把配置指向那个路径,重启守护进程,并确认先前失败的客户端现在能完成握手。
如果服务器还设置了安全等级或证书配置,先读这些设置,再断定组有问题。要求更严格等级的配置可能会拒绝默认设置本会接受的参数,而移除那项设置,比全局关掉检查更精准。
为对端和硬件选择合适的尺寸
在生成任何稀奇参数之前,先弄清远端能承受什么。对 2048 位组来说太旧的设备,该换的是设备,因为把服务器指向更弱的组,只会把兼容性投诉变成故障。持久的修复应当走向更新的软件,而不是更旧的参数。这一领域里的每一个临时例外,最后往往都会变成永久配置。
如果瓶颈在服务器 CPU,就换算法,而不是降到策略允许值以下。像 X25519 这样的椭圆曲线密钥交换 比大型有限域组便宜得多,而且支持广泛,因此在面对性能投诉时,它比缩小 RSA 模数更合适。
无论选什么,都用一条真实连接实测,并观察握手耗时,而不只看它最终能否连上。十二秒才成功的连接,与十五秒才失败的连接,根因是同一个。
记录选择,让重建无法推翻它
把参数文件纳入配置管理,并在旁边写下尺寸、原因和日期。重建的服务器悄悄生成自己的默认值,正是同一个故障在半年后复发、却没人解释得清最初决定的原因。
把同样的信息记在端点和配置旁边,这样评审时不必从文件大小反推。下一次连接卡住时,那条记录就是五分钟排查与从头调查之间的差别。它也阻止下一位工程师用针对快情形的修复去处理慢情形。