OpenSSL verify报error 62:证书主机名不匹配与-verify_hostname排查
证书链已经显示OK加上主机名却报error 62: hostname mismatch先别急着重签。链信任回答“谁签的、是否可信”名称验证回答“是不是我要访问的服务”。下面用OpenSSL 1.1.1的参数把这两件事拆开再检查SNI选证书和Shell退出码。能连上不等于找对了人。一、error 62检查的是名称不是所有TLS问题error 62是主机名不匹配常见位置是叶子证书的depth 0error 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可能换行固定截取两行容易漏掉名称。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目录避免旁边的信任材料干扰结果。HOSTapi.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仍可据其非零状态停止。( set e set -o pipefail IP192.0.2.10 PORT443 SNIapi.example.com NAMEapi.example.com openssl s_client -connect $IP:$PORT -servername $SNI \ -verify_hostname $NAME -verify_return_error \ -no-CApath -CAfile root.pem /dev/null 21 | 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就算数。此时使用专门的参数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 SANIP不匹配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服务身份规范。老版本实验用于解释行为不是部署版本建议。