双对等端 OpenVPN 链路:静态密钥还是 TLS?
OpenVPN 的静态密钥模式无法轮换其流量密钥。如果两个对等端需要自动续期,请改用 TLS 模式,并保持点对点布局不变。
只与彼此通信的两台机器可以保留这种拓扑,同时仍能获得协商出来的流量密钥。网络形态与保护模式是两个独立的选择,把它们混为一谈,才会让人试图在两端守护进程都继续运行时通过替换文件来轮换静态密钥。在运行中的一对节点下替换密钥文件并不会轮换任何东西。OpenVPN 2.6 标记为已弃用的静态密钥模式在隧道整个生命周期内只持有一个密钥,因此磁盘上的文件与内存中的密钥只有在两端都重启后才会重新一致。如果需求是自动续期,保护模式就必须改变。
静态密钥模式做不到什么
在秘密模式下,两个对等端共享一个预共享密钥,由它直接加密并认证隧道。没有握手,因此也没有任何机制让任一方提出新的密钥材料、证明身份,或在没有操作员介入的情况下从不一致中恢复。这两个性质都源于缺少控制通道,而不是缺少某个选项,并且没有任何配置开关能为这种模式添加控制通道。
OpenVPN 2.6 手册明确指出,密钥会一直保留到生成新密钥为止。对实验室链路或具有书面轮换流程的固定设备对来说,这是可以接受的;而在长期密钥构成真实风险的任何地方,这都不可接受。替换文件并不会为运行中的一对节点生成新密钥,只会造出两个不一致的对等端。因此替换文件只增加中断,不增加轮换。
除了持有文件之外,也不存在对等端身份的概念。任何持有密钥的人就是对等端,隧道中没有任何东西记录哪一侧是哪一侧,所以吊销只能是全有或全无。
不改动链路设计就迁移到 TLS
TLS 模式增加了控制通道,也随之带来协商数据通道密钥的能力。在点对点部署中,一侧承担服务器角色,另一侧承担客户端角色,但拓扑仍是两个对等端之间的链路:每一侧都知道对端的端点,也不会出现任何连接池或多用户服务。角色只是握手的细节,不是新的架构。
给每台机器各自的身份。每一侧都需要证书和私钥、用于验证对端的信任锚,以及一个写明期望对象的对等端验证规则。不要为了省事在对端复用某一侧的私钥;那会把两个身份变成一个,并去掉分别吊销任一侧的能力。注册阶段才是把这件事做对的地方,因为事后修正意味着重新签发证书。
保护方式改变时,网络契约保持不变。相同的隧道地址、路由和允许的服务在变更前后都应适用,这样迁移期间的故障就是保护问题,而不是伪装成路由的意外。变更前把地址和路由写下来;事后比对比凭记忆重建更快。
有些部署还用自己独立的静态密钥保护控制通道,这个密钥不随数据通道轮换。它守护的是握手而不是载荷,因此泄露它暴露的是协商,而不是流量。把它与数据通道材料分开存放,并为它指定一个由具名负责人承担的更换日期。轮换它意味着在协调好的时间窗口内重启两端,所以它值得写进日历,而不是只靠记忆。
谁在什么时候续期什么
在 TLS 模式下,续期由配置的上限驱动:时间间隔、字节数或包数。文档中记载的时间控制是大多数部署所依赖的,而两端中较低的有效值就可能触发替换,所以只在一侧调高并不会阻止该事件。基于流量的上限之所以存在,是因为繁忙的链路可能在时钟到期之前很久就用尽密钥。这两个上限都不是健康检查,也都不会告诉你续期是否成功。
这就是为什么仅凭一个配置文件去诊断反复出现的重新协商会产生误导。要读两端的设置,然后看日志中的转换,而不是先假定有故障。干净完成的续期看起来像控制通道流量的一次短暂突发,而不像断开连接。
在脑中把对象分开。证书证明长期身份,按你掌控的日程更换。数据通道密钥会自动刷新,而单独的认证交换(如果部署需要)遵循账号策略,并且可能需要为后续交换另作安排。
把时间间隔设为零来彻底关闭续期,并不是对吵闹日志的修复。它把一次健康的生命周期事件变成永久密钥,从而把你带回原本想摆脱的那种性质。
接受这次变更
从所安装版本受支持的示例出发构建新配置,而不是沿用从别处继承算法和文件路径的旧最小片段。协调切换,让两端一起改变;并保留一条已批准的恢复路径,以防一侧起不来。要有意把链路断开,而不是等一次故障来测试回滚。演练过的回滚比只写下来的回滚更有价值。
测试三件事:初始身份验证成功、预期的应用流程可用、受控续期在不丢流量的情况下发生。然后读日志中的转换,看它真正证明了什么:新的密钥标识符意味着两端完成了替换,而不是隧道重新连接了。把它当作单一步骤的证据,并在宣布迁移完成之前检查流量计数器。
零中断的承诺会掩盖的是你尚未看到的故障。失败的续期、过期的证书或路径故障仍可能扰动链路,而干净的一次测试并不能排除其中任何一个。值得设计的性质更窄也更有用:常规的密钥更换不再是一次手动替换文件。