IP 访问为什么会域名不匹配
证书里的身份用 SAN 扩展表达:DNS 名称写成 DNS 类型条目,IP 地址必须写成 iPAddress 类型条目。直接用 IP 访问 HTTPS 时,客户端会拿 IP 去比对 iPAddress 条目,只要证书里只有 DNS 名字,所有客户端都会报「证书与主机名不匹配」。现代客户端早就不再拿 CN 做匹配,把 IP 写进 CN 完全无效,这是内网设备调试与监控探活最常见的踩点。
基本信息
| 正确做法 | 在 SAN 中写入 iPAddress 类型条目 |
|---|---|
| 无效做法 | 把 IP 写进 CN(现代客户端已忽略 CN 匹配) |
| 校验入口 | openssl verify -verify_ip 10.0.0.10 cert.pem |
| 公网限制 | 对 IP 签发公开信任证书受 CA/B 规则严格限制 |
| 内网方案 | 用私有 CA 签发带 IP SAN 的证书,或统一改走域名访问 |
| 组合场景 | 同时含域名与 IP 时,两类条目都必须显式写入 |
典型使用场景
- 内网设备调试:交换机、带外管理口只提供 IP 访问,自签证书要补 IP SAN。
- 监控探活:拨测系统按 IP 发起请求,证书缺 IP 条目会持续告警。
- Kubernetes 内部调用:Pod 直连 IP 访问 HTTPS 服务时的证书设计。
- 证书模板设计:决定是否把网关与管理网段 IP 一并纳入 SAN。
- 故障排查:客户端报不匹配时,先确认访问用的是 IP 还是域名。
检查 IP SAN 是否存在
检查 IP SAN 是否存在
# 看证书里 SAN 条目的类型与内容
openssl s_client -connect 10.0.0.10:443 </dev/null 2>/dev/null | openssl x509 -noout -text | grep -A2 'Subject Alternative Name'
# 按 IP 做校验(不是 -verify_hostname)
openssl verify -CAfile ca.pem -verify_ip 10.0.0.10 cert.pem
# 生成测试证书时把 IP 一并写进 SAN
# openssl req -new -key k.pem -subj /CN=svc -addext 'subjectAltName=DNS:svc.internal,IP:10.0.0.10' -x509 -days 365 -out c.pem校验参数对照
| 参数 | 比对对象 | 适用场景 |
|---|---|---|
| -verify_ip | iPAddress 类型 SAN 条目 | 直接用 IP 访问的场景 |
| -verify_hostname | DNS 类型 SAN 条目 | 按域名访问的场景 |
| -checkhost / -checkip | s_client 内置的名称/IP 检查 | 连接测试时顺手校验 |
| 不指定 | 仅验证签名与有效期 | 会漏掉名称匹配问题 |
校验工具通常区分按域名与按 IP 两种模式,用错参数会得到与浏览器不一致的结论;排障时先确认访问方式,再选对应的校验参数。
浏览器与命令行工具对证书选择的偏好不同:同一条链上若有多张证书,某些客户端会按 SNI 精确匹配,另一些则退回默认证书,因此确认问题时要用与用户一致的客户端复现。
内网签发 IP 证书时,建议同时把管理域名写进 SAN:后续从 IP 切换到域名访问时无需重新签发,也给监控与巡检脚本留出迁移空间。