检查 VPN 证书而不导出私钥
读取公开字段、日期和指纹,而不打印任何密钥材料。哪条命令安全,取决于文件里装着什么,以及谁会收到输出。
读取证书的公开字段从不需要显示与之匹配的私钥,而完成这件事的工具随每一个终止 VPN 的系统一同提供。风险其实早一步出现:你拿到的文件可能根本不是证书。PEM 证书、DER 数据块、PKCS#12 打包文件和 OpenVPN 配置文件可能同名而来,内容却完全不同,所以在选择命令之前先确认容器类型。
三件事决定哪条命令是安全的:文件里装着什么、你需要从中读出什么、以及谁会看到输出。任何一项判断错误,检查本身就会变成事故。
你拿到的是三种文件中的哪一种
PEM 证书是带有可见 BEGIN 与 END 标记的文本,DER 文件是需要输入格式标志的二进制,而 打包文件是一种容器,可能在证书旁边放着私钥。file server.crt 能在一秒内区分文本与二进制,扫一眼第一行就能区分裸证书与内嵌证书的配置文件。在这里凭猜测行事,正是把检查变成事故的原因。
如果文件是配置文件而不是证书,在证明相反之前,请把它当作凭据对待。这个假设不花任何代价,却能避免整个任务中最常见的错误。
读取 PEM 证书的公开字段
对于你有权检查的证书,带 -noout 的 x509 子命令只打印你选定的字段,别的什么都不打印。抑制正文才能让输出停留在元数据层面,这也正是它可以安全粘贴到工单里的原因。下面这些选择器都是公开的,其余选择器见 openssl x509 文档。
openssl x509 -in server.crt -noout -subject -issuer -dates -fingerprint -sha256
在本地生成的测试证书上,该命令会打印一行主体和一行签发者、notBefore 与 notAfter 这一对,以及一个 SHA-256 指纹。这些字段用于标识对象;它们并不建立有效的信任路径,那是另一项验证任务,有自己的命令和自己的答案。除非你自己逐条遍历文件,否则链文件也可能只打印第一张证书。用这种方式比较两个文件只花一条命令,就能确定对端实际出示的是哪一个。
在证书旁边存放私钥的打包文件
.p12 或 .pfx 文件可能携带私钥,除非你抑制输出中的那部分,否则解析命令会把它打印出来。加上 -nokeys 后,同一条命令仍会报告容器的结构,包括被遮蔽的密钥包,却不会输出任何密钥材料;去掉该标志,一个密钥块就会出现在终端和 shell 历史里。
openssl pkcs12 -in bundle.p12 -nokeys -info -passin env:P12PASS
OpenVPN 配置文件以文本形式内嵌同样的材料,所以只要知道该往哪里看,边界就是可见的。公开材料位于 BEGIN CERTIFICATE 与 END CERTIFICATE 之间,而 BEGIN PRIVATE KEY 与其对应 END 行之间的一切都是私钥,绝不允许离开主机。整份复制配置文件等于把两者一起公开。
从别处取得参考值
从你正试图验证的那条连接上读到的指纹什么也证明不了,因为提供它的是你不信任的一方。这并不是反对指纹的理由,而是关于出处的理由。请把该值与通过对端无法写入的渠道取得的值相比较,例如发布在内部仓库中的证书,或打印在已签名的变更记录里的哈希值。
在信任库执行验证的地方,就让它去验证,并读取它产生的错误,而不是用你自己的比较去替代。真正重要的区别是谁提供了参考值,而不是用了哪种哈希函数。
分享结果,以及出了差错之后该做什么
发送确切的验证错误、相关日期,以及接收方需要的身份细节。内部主机名和账户标识即使在没有私钥时依然敏感,而公开的粘贴服务是这类信息的错误去处。请粘贴到工单里,而不是别人也能看到的临时缓冲区。
如果密钥材料确实出现在屏幕上或文件里,请把它视为已泄露并轮换它,而不是指望没人看过。然后写下检查过的文件、用过的命令以及输出去了哪里,因为正是这份记录把一场惊吓变成一套流程。轮换的代价很低,远低于假设没人留下截图的代价,而同一份记录会让下一位工程师知道究竟碰过哪些文件。在工单关闭之前,两件事都要做完。