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

错误信息

x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs

也可能输出为

  • tls: failed to verify certificate: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs

该地址就是客户端连接的地址。如果证书中有 IP 类型的 SAN,但不包含这个地址,Go 报出的则是“x509: certificate is valid for <ips>, not <ip>”。通过 TLS 拨号建立连接时,会加上“tls: failed to verify certificate: ”前缀。

Go crypto/x509 — HostnameError when the target is an IP address and the certificate has DNS SANs only

含义

客户端连接的是 IP 地址,因此 Go 必须在证书的 IP 类型 SAN 条目中找到该地址,但证书中只有 DNS 名称。Go 从不拿 IP 地址与 DNS 名称或通用名称比较。消息中的地址就是你的客户端所连接的地址。

原因

修复方法

  1. 1.

    保留地址,验证名称

    把 tls.Config.ServerName 设置为证书中的某个 DNS 名称。这样 Go 会验证该名称,并在连接该地址时把它作为 SNI 发送。

    go
    // Dial the address, verify the certificate's DNS name (also sent as SNI)
    transport := &http.Transport{TLSClientConfig: &tls.Config{ServerName: "api.example.com"}}
    client := &http.Client{Transport: transport}
    resp, err := client.Get("https://10.0.0.5:443/healthz")
  2. 2.

    把地址添加为 IP SAN

    私有 CA 可以签发包含 IP 条目的证书;公共 CA 很少这样做。

    bash
    # Or put the address into the certificate as an IP SAN
    openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \
      -addext "subjectAltName=DNS:api.example.com,IP:10.0.0.5"
  3. 3.

    Kubernetes:把地址添加到 API 服务器证书中

    在执行 kubeadm init 时传入额外的 SAN(或者用新的 SAN 重新生成 apiserver 证书),然后分发更新后的 kubeconfig。

    bash
    # Kubernetes API server reached by a new IP (load balancer, node address)
    kubeadm init --apiserver-cert-extra-sans=10.0.0.5,k8s.example.com
    openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -ext subjectAltName

相关错误

浏览完整的签名错误库