跳到主要内容
ecdsa.com
Go crypto/x509Go

错误信息

x509: certificate is valid for example.com, not api.example.com

这两处名称随每次失败而填入:先是证书覆盖的名称,然后是你的客户端请求的名称。

Go crypto/x509 — HostnameError from VerifyHostname / TLS dials

含义

TLS 连接已经进行到能够读取证书的阶段,但证书中没有任何一个主题备用名称(SAN)与客户端连接的主机名匹配。错误消息列出了双方,因此差异一目了然:证书覆盖的是 X,而你请求的是 Y。注意,现代的验证只使用 SAN——旧式的通用名称字段会被忽略。

原因

修复方法

  1. 1.

    重新签发证书,包含实际使用的所有名称

    签发时把所有主机名都添加为 SAN;查看当前的 SAN 列表,了解目前覆盖了哪些名称。

    bash
    echo | openssl s_client -connect host:443 -servername api.example.com 2>/dev/null \
      | openssl x509 -noout -ext subjectAltName
    # request with SANs:
    openssl req -new -key key.pem -out req.csr \
      -subj "/CN=example.com" -addext "subjectAltName=DNS:example.com,DNS:api.example.com"
  2. 2.

    连接该名称,或显式设置 ServerName

    如果网络地址必须与证书中的名称不同(VIP、端口转发、sidecar),就明确告诉 TLS 你期望的是哪个身份,让验证依然严格有效。

    go
    conn, err := tls.Dial("tcp", "10.0.0.5:443", &tls.Config{
        ServerName: "api.example.com",   // matched against SANs, sent as SNI
    })

相关错误

浏览完整的签名错误库