OpenSSL verify报error 62:证书主机名不匹配与-verify_hostname排查

证书链已经显示OK,加上主机名却报 error 62: hostname mismatch,先别急着重签。链信任回答"谁签的、是否可信",名称验证回答"是不是我要访问的服务"。下面用OpenSSL 1.1.1的参数把这两件事拆开,再检查SNI选证书和Shell退出码。能连上,不等于找对了人。

一、error 62检查的是名称,不是所有TLS问题

error 62是主机名不匹配,常见位置是叶子证书的depth 0;error 20/21则指向链构建问题。错误编号不等于Shell退出码,脚本不能拿进程返回值62当判断条件。多个检查也可能同时失败,要保留完整输出。

这里要纠正一个容易说满的结论:OpenSSL默认名称检查在没有DNS类型SAN时,可以回退到subject的CN;有DNS SAN时,默认不再靠CN补救。现代HTTPS应按SAN部署,RFC 9525不再接受CN-ID。命令行兼容旧证书,不代表浏览器也接受它。

二、把SAN读全,别只截两行

准备叶子证书leaf.pem、受信任根root.pem及中间证书intermediate.pem。fullchain不是天然可信的根库。先确认读的是最终证书,而非CSR或本地另一个同名文件;SAN可能换行,固定截取两行容易漏掉名称。

bash 复制代码
openssl x509 -in leaf.pem -noout -subject -issuer -dates
openssl x509 -in leaf.pem -noout -ext subjectAltName
openssl x509 -in leaf.pem -noout -sha256 -fingerprint

没有DNS SAN但CN匹配时,OpenSSL可能通过;这应当促使你补齐现代客户端需要的SAN,而不是宣布证书通用兼容。记录指纹,后面才能比较"磁盘上的"和"入口发出的"是否同一张。

三、同一份材料,分开验证链与域名

在Bash里逐条运行,分别记录退出码。加入sslserver用途检查;根和中间证书角色不要对调。下例关闭默认CA目录,避免旁边的信任材料干扰结果。

bash 复制代码
HOST=api.example.com
openssl verify -no-CApath -CAfile root.pem -untrusted intermediate.pem \
  -purpose sslserver leaf.pem
printf "chain_rc=%s\n" "$?"
openssl verify -no-CApath -CAfile root.pem -untrusted intermediate.pem \
  -purpose sslserver -verify_hostname "$HOST" leaf.pem
printf "hostname_rc=%s\n" "$?"

只验链通过、带名称失败,才把重心转向目标名称和SAN。HOST只填域名,不带https://、端口或路径。若两条都失败,先处理链和用途;不要靠关闭验证,把红灯拆掉当修好了。

四、连接IP、SNI和验证名是三个输入

连接IP决定去哪里,SNI帮助服务端选择证书,验证名决定客户端接受谁。三者应分别显式设置;固定某个节点IP时,SNI和验证名通常仍是业务域名。HTTP Host属于后续请求路由,不能替代TLS名称验证。

将示例保留地址换成获准检测的节点。下面是独立Bash片段:子Shell关闭errexit,确保失败后仍能保存PIPESTATUS;外层若启用errexit,仍可据其非零状态停止。

bash 复制代码
(
set +e
set -o pipefail
IP=192.0.2.10
PORT=443
SNI=api.example.com
NAME=api.example.com
openssl s_client -connect "$IP:$PORT" -servername "$SNI" \
  -verify_hostname "$NAME" -verify_return_error \
  -no-CApath -CAfile root.pem </dev/null 2>&1 | tee sclient.log
st=("${PIPESTATUS[@]}")
printf "tls_rc=%s log_rc=%s\n" "${st[0]}" "${st[1]}"
(( st[0] == 0 && st[1] == 0 ))
)

普通管道的?可能只是tee成功。pipefail虽能报非零,也不能区分TLS失败还是日志写失败;这里立即复制整个数组,再分别判定。别先echo或保存?,它们会覆盖PIPESTATUS。默认s_client是诊断工具,验证报错后仍可能退出0,所以还要启用verify_return_error并看握手详情。

五、验证IP用verify_ip,别把64写成62

如果访问身份本来就是IP,应匹配iPAddress SAN,不能把IP字符串放进DNS SAN或CN就算数。此时使用专门的参数:

bash 复制代码
openssl verify -no-CApath -CAfile root.pem -untrusted intermediate.pem \
  -purpose sslserver -verify_ip 192.0.2.10 leaf.pem
printf "ip_rc=%s\n" "$?"

IP不匹配是error 64: IP address mismatch,不是error 62。仅仅固定连接IP、但访问身份仍为域名时,不要改用verify_ip。默认完整通配符*.example.com匹配一个左侧标签,不覆盖裸域或a.b.example.com;多个SAN也不豁免链、用途和其他策略检查。

六、换证后仍失败,先确认入口发了什么

别只盯证书文件日期。负载均衡某个节点未更新、SNI选到默认站点,或应用传入了另一个验证名,都可能让本地验证与线上结果分叉。逐入口保留名称、SAN、指纹和时间,不要把一个节点的成功外推给全站。

现象 信号 先做什么
链构建失败 error 20/21 检查根与中间证书
域名不匹配 error 62 核对验证名和DNS SAN
IP不匹配 error 64 检查iPAddress SAN
日志写入失败 log_rc非零 检查路径与空间,勿归因于证书

七、回归要有反例,边界也要写清

正例之外,换错误验证名、错误根,确认探针确实会拒绝;再模拟日志写入失败,避免把磁盘问题报成证书故障。离线验证与回环TLS实验能说明参数行为,不能冒充浏览器或生产验收。本文配套复现限定OpenSSL 1.1.1k、临时根和中间CA,回环握手固定TLS 1.2;不修改系统CA和生产服务。

八、收尾检查与官方依据

收尾保留四组证据:完整SAN与指纹;链和名称各自结果;固定IP、SNI、验证名的严格握手;TLS与日志的独立退出码。修复后回到真实客户端验证HTTP响应和业务行为,证书名称正确不等于授权正确。共享日志前去除内部地址和会话信息,不上传私钥。

参数与规范可核对:OpenSSL verify手册、s_client手册及RFC 9525服务身份规范。老版本实验用于解释行为,不是部署版本建议。

相关推荐
Canmag 兴隆磁性13 分钟前
中大型钕铁硼产品的磁通测量与自动分选:一条产线自动化的工程实现思路
运维·学习·自动化·永磁材料
xuefeiniao2 小时前
PHP2Shell漏洞修复
运维·服务器·php
便利店10243 小时前
系统活动一抓留存!深入 Linux C/C++ 调试工具之 sysdig
linux·运维·服务器·sysdig
智能运维指南4 小时前
企业 IT 运维自动化平台怎么选?从场景匹配到 POC 验证的完整评估框架
运维·自动化·自动化运维·嘉为蓝鲸
toooooop85 小时前
CentOS 7 内核 3.10.0-1160.119.1 升级指南
linux·运维·centos
云飞云共享云桌面5 小时前
广东东莞制造工厂10人共享一台三维设计服务器
运维·服务器·3d·自动化·制造
kkkkkkkkkk_Z6 小时前
新手自学嵌入式 | 学习日记:Linux驱动复习之系统移植(U-Boot篇)
linux·运维·学习
hz567896 小时前
企业视频会议系统方案:总部与分支机构高效协同如何落地?
运维·服务器·网络·安全·实时音视频·信息与通信
sun153690275726 小时前
露天矿边坡滑坡怎么预警?QY-19GNSS 自动化地表位移监测系统介绍
运维·安全·自动化