跳到主要内容
ecdsa.com
GNU Wget built with GnuTLS (Debian, Ubuntu before 22.04 used it too)curl

错误信息

ERROR: The certificate of 'api.example.com' is not trusted.

也可能输出为

  • ERROR: The certificate of 'api.example.com' doesn't have a known issuer.

只有使用 GnuTLS 构建的 wget 会打印这两行。使用 OpenSSL 构建的版本(Ubuntu 22.04 及更高版本、Alpine、Fedora 的 wget 1.x)把同样的情况报告为“ERROR: cannot verify <host>'s certificate, issued by '…'”,后面接着“Unable to locally verify the issuer's authority.”。

含义

Debian 构建 wget 时使用的 TLS 库 GnuTLS 无法验证服务器的证书,因此 wget 拒绝下载。这第一行是通用的;wget 紧接着打印的那一行才指出实际原因,最常见的是“doesn't have a known issuer”(没有通向受信任根证书的路径)或“has expired”。wget 以退出状态 5(SSL 验证失败)退出。

原因

修复方法

  1. 1.

    查看紧随其后的那一行

    第二条 ERROR 报错才是真正的诊断。“doesn't have a known issuer”指向 CA 或证书链问题;“has expired”和“is not yet activated”指向日期问题;“owner does not match hostname”指向名称不匹配。

    bash
    wget -O /dev/null https://api.example.com/ 2>&1 | grep '^ERROR'
    # ... is not trusted.
    # ... doesn't have a known issuer.   <- chain/CA problem
    # ... has expired.                   <- date problem
  2. 2.

    告诉 wget 信任哪个 CA

    --ca-certificate 接受一个包含一张或多张 CA 证书的 PEM 文件;在 ~/.wgetrc 或 /etc/wgetrc 中设置 ca_certificate 可以让它永久生效。--ca-directory 适用于以哈希命名的证书目录。

    bash
    wget --ca-certificate=/opt/certs/corp-root-ca.pem https://api.example.com/
    
    # permanently, for this user or system-wide (/etc/wgetrc)
    echo 'ca_certificate = /opt/certs/corp-root-ca.pem' >> ~/.wgetrc
  3. 3.

    把 CA 安装到系统证书包中

    在 Debian 和 Ubuntu 上,放在 /usr/local/share/ca-certificates 中、扩展名为 .crt 的证书,会由 update-ca-certificates 添加到 /etc/ssl/certs/ca-certificates.crt,而 GnuTLS 默认读取的正是这个文件。

    bash
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt
    sudo update-ca-certificates
    # minimal images: install the bundle first
    apt-get install -y --no-install-recommends ca-certificates
  4. 4.

    服务器所有者:发送完整证书链

    如果握手中只有一张证书,并且它的颁发者是中间 CA,就为服务器配置完整证书链文件。

    bash
    # Server side: count the certificates in the handshake (1 = leaf only)
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -c 'BEGIN CERTIFICATE'
  5. 5.

    临时诊断:只跳过一次检查

    --no-check-certificate 可以显示除信任之外是否还有其他问题。它会禁用全部证书验证,代理或攻击者因此可以悄无声息地替换你下载的内容;切勿把它用于安装程序或脚本。

    bash
    # Diagnostic only: proves the download works when trust is ignored
    wget --no-check-certificate -O /dev/null https://api.example.com/

相关错误

浏览完整的签名错误库