为什么重新导入 Client VPN 证书需要新的终端节点
Client VPN 终端节点在创建时就绑定了证书。重新导入 ACM 对象不会改变这层绑定,因此恢复连接意味着新建终端节点。
Client VPN 连接断了,ACM 里的证书被替换,却什么都没变。证书对象从来就不是终端节点在使用的东西。终端节点在创建时保存的是对证书的关联,以及它将用于验证的客户端 CA、身份验证类型、子网和授权规则,而这些关联都没有可以接受替换证书的修改调用。替换 ARN 背后的字节改变的是证书,而不是记录了这个关联的终端节点。
终端节点保存的是引用,不是证书
这个机制值得说清楚,因为它解释了整个故障。create-client-vpn-endpoint 接收 服务器证书的 ARN 和客户端根证书链的 ARN,生成的终端节点把这些引用连同身份验证选项作为固定属性保存下来。API 没有提供在现有终端节点上更换服务器证书的操作。
不用猜也能确认这层绑定。aws ec2 describe-client-vpn-endpoints --client-vpn-endpoint-ids cvpn-endpoint-0123456789abcdef0 会输出证书 ARN、客户端根链 ARN、身份验证类型、客户端 CIDR 以及关联的子网,这就是你必须复现的完整属性集合。在重新导入前后各执行一次,输出不会变化。这就是重新导入从来帮不上忙的证据。
为什么重新导入到不了终端节点
重新导入会在既有 ARN 下写入新的证书主体。当证书临近到期时这是合法操作,只要私钥匹配、证书链验证通过,ACM 就会接受。但它不会重跑终端节点创建时的校验,所以关联关系以及关联背后的材料仍停留在终端节点建成时的样子。
症状读起来像网络故障也是这个原因。TLS 握手在授权被评估之前就失败或重置,于是安全组、路由和授权规则看起来都无辜,而它们确实无辜。
证书链是客户端证书的一部分
故障的另一半在客户端证书上,而且更容易被忽略。客户端证书必须连同签发它的证书链一起导入,即使导入表单把该字段显示为可选。缺少证书链,终端节点就无法从客户端证书构建到所配置的客户端根 CA 的路径,连接会以一次软重置结束,听起来像防火墙在丢包。openssl verify -CAfile root-ca.pem client.crt 能在本地一秒内回答这个问题,它应该是你执行的第一条命令。
带证书链重新导入对那一半是真正的修复,但仅此还不够。ACM 对象一旦改变,仍持有旧关联的终端节点就是不该继续用来测试的对象。两步属于同一次修复,所以这个两部分方案并不矛盾。
重建终端节点是一次迁移
创建替代终端节点是一次迁移,不是重试,把它当成重试正是团队最后留下两个半配置终端节点的原因。新终端节点会得到新的 ID,如果没有提前规划,每个用户还会得到新的 DNS 名称。让客户端配置文件指向名称而不是地址,切换就变成记录变更,而不是重新分发。
保证安全的顺序很短:用相同的 CIDR、子网和授权规则创建新终端节点,用 aws ec2 export-client-vpn-client-configuration 导出新配置文件,并用一个用户验证。之后才下线旧终端节点。
下线旧终端节点有自己的顺序。先吊销你打算退役的客户端证书,再删除它,因为仍信任旧 CA 的新终端节点会继续接受你以为已经消失的证书。然后删除旧终端节点并移除它的授权规则,使旧配置文件无法重新连回你以为已经关闭的目标网络。把旧终端节点的 ID 和关联标识写进变更记录,因为拿记忆去比对的迁移,正是把可用终端节点重建两次的原因。
安排诊断顺序
改任何配置之前,先把三种故障分开。客户端完不成 TLS,客户端完成 TLS 但没有被授权,或者客户端连上了却到不了目的地。证书关联属于第一种,未覆盖客户端地址的授权规则属于第二种,路由或安全组属于第三种,在这种情况下重建终端节点几乎总是错的。
一个正常工作数月后停止、证书和策略都没变的终端节点是另一种情况。用完全相同的设置重建可能恢复服务,但那是保持配置可复现的理由,不是每次事故都重建的理由。
把四样东西放进版本控制,让下一次重建是一次 diff 而不是临场发挥:终端节点参数、证书与证书链的 ARN、授权规则以及客户端 CIDR。Client VPN 身份验证文档列出了哪个证书扮演什么角色,在假定证书就是问题之前值得先查一遍。如果重新导入没有改变任何东西、终端节点仍在重置,那么可疑的是关联,答案是用记录下来的参数新建的终端节点。如果终端节点确实接收了新对象,那关联本来就是对的,故障在客户端证书链或授权层。