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

错误信息

x509: certificate signed by unknown authority

Go crypto/x509 — returned by Certificate.Verify and TLS dials

含义

Go 尝试从服务器的证书构建一条通向其信任的根证书的证书链,但失败了:没有任何路径终止于所配置根证书池中的证书。证书本身可能完全有效——只是 Go 没有理由信任它的颁发者。这是 Go 部署中最常遇到的 TLS 错误。

原因

修复方法

  1. 1.

    把 CA 添加到客户端的根证书池

    扩展系统证书池,而不是替换它,这样在使用内部 CA 的同时,公共网站也能继续正常访问。

    go
    roots, err := x509.SystemCertPool()
    if err != nil { roots = x509.NewCertPool() }
    pem, _ := os.ReadFile("internal-ca.pem")
    roots.AppendCertsFromPEM(pem)
    
    client := &http.Client{Transport: &http.Transport{
        TLSClientConfig: &tls.Config{RootCAs: roots},
    }}
  2. 2.

    修复服务器:提供完整证书链

    检查服务器实际发送的内容;如果只出现一张证书,就让服务器改用完整证书链文件(例如 Let's Encrypt 的 fullchain.pem)。

    bash
    openssl s_client -connect api.example.com:443 -showcerts </dev/null \
      | grep -c "BEGIN CERTIFICATE"   # 1 = leaf only (broken), 2+ = chain present
  3. 3.

    在镜像中附带 CA 证书

    对于精简镜像,在构建时把 CA 证书包复制进去。切勿用 InsecureSkipVerify 来“解决”这个问题——那会彻底禁用验证。

    docker
    FROM alpine AS certs
    RUN apk add --no-cache ca-certificates
    
    FROM scratch
    COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

相关错误

浏览完整的签名错误库