命令行工具

cannot verify certificate:wget 证书校验失败怎么修

作者: · 最后核实

报错信息ERROR: cannot verify example.com's certificate, issued by 'CN=Example Issuing CA': Unable to locally verify the issuer's authority.

cannot verify example.com's certificate 的意思是:wget 没法把服务器证书和它信任的任何根证书连起来。 下一行写了原因,最常见的 “Unable to locally verify the issuer's authority” 指向服务器证书链不完整,或者本机 CA 库里缺少对应的根证书。

快速修复

服务器缺中间证书就修服务器,证书链完整就让 wget 用上正确的 CA 文件。先看服务器是否发送了完整证书链:

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null | grep -E "^ *[0-9] s:|Verify return"
  • 只有第 0 张证书: 服务器缺中间证书,到服务器上修(见缺少中间证书)。
  • 链完整,但根证书陌生(公司代理或内部 CA): 信任这张根证书:
wget --ca-certificate=/path/to/company-root.pem https://example.com/file.tar.gz
  • 链完整,根证书是公网 CA: 更新本机的 CA 证书包。

原因

最常见的提示是 “Unable to locally verify the issuer's authority”,对应服务器缺中间证书或本机 CA 证书包过旧。下一行的提示文字能区分以下 6 种原因。

1. 服务器证书链不完整

  • 确认: openssl s_client 只显示站点证书,Verify return code: 21。
  • 修复: 服务器配置完整证书链;只有站点证书时,用证书链补全工具生成。

2. CA 证书包过旧或缺失

CentOS 7 等老系统、精简镜像可能缺少较新的根证书。

  • 确认: 同一个地址在新系统上能下载;wget --version 能看到所用的 TLS 库,其 CA 文件很旧或不存在。
  • 修复: 更新 ca-certificates(apt-get install --reinstall ca-certificates、yum update ca-certificates)。

3. 私有 CA 或企业代理解密

  • 确认: 报错里 issued by 后面是公司名或安全厂商名。
  • 修复: 把根证书加入系统信任库(Debian 系放 /usr/local/share/ca-certificates/ 后 update-ca-certificates;RHEL 系放 /etc/pki/ca-trust/source/anchors/ 后 update-ca-trust),或用 --ca-certificate。

4. 自签名证书

此时报错是 “Self-signed certificate encountered”。

  • 修复: 取下证书,和负责人核对指纹后用 --ca-certificate 指定。更好的办法是给服务器换一张正规证书。

5. 证书过期或时钟错误

“Issued certificate has expired” 表示日期检查失败。

  • 修复: 服务器续期,或者修复客户端的 NTP 时间同步。

6. 域名不匹配

另一条报错 certificate common name ... doesn't match requested host name 表示证书里没有这个主机名。用正确的主机名访问,或者修改证书的 SAN 列表。

各环境修法

各系统的修法都是更新 CA 证书包、把私有根证书加入系统信任库,或用 --ca-certificate 指定。

Debian / Ubuntu:

sudo cp company-root.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

CentOS / RHEL / Rocky / Alibaba Cloud Linux:

sudo cp company-root.pem /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Alpine / BusyBox: BusyBox 自带的 wget 是否校验证书取决于编译选项,建议安装完整的 wget 包和 ca-certificates,或改用 curl。

Windows 上的 wget.exe: 在可执行文件旁边或 %HOME% 里放 .wgetrc,设置 ca_certificate 指向 PEM 证书包(可以用 curl.se 发布的那份)。

一键安装脚本: 很多国内软件和面板(包括宝塔)的安装命令是 wget ... && bash install.sh 形式。遇到证书报错时先更新系统 CA 证书包再执行,不要给安装命令加 --no-check-certificate。

公司代理: wget 读取 https_proxy 和 http_proxy 环境变量。如果代理会解密 TLS,即使代理变量配置正确,也仍然需要信任代理的根证书,否则还是同样的报错。

脚本里访问内部服务器: 显式传 --ca-certificate,不依赖每台机器的信任库状态。

不要这样做

--no-check-certificate 能让下载继续,但会关闭全部证书校验。

  • 在安装脚本里用 --no-check-certificate。 下载下来马上执行的脚本,会变成网络上任何人都能利用的远程代码执行入口。
  • 在 /etc/wgetrc 里写 check_certificate = off。 所有用户、所有下载都会悄悄失去校验。
  • 把地址改成 http://。 下载内容的保密性和完整性都没有了。

常见问题

同一台机器上 curl 正常、wget 报错,为什么?

两者可能用了不同的 TLS 库和 CA 路径。有的发行版的 wget 用 GnuTLS 编译,有的用 OpenSSL,各自读自己的默认路径。用 wget --version 对比,必要时让两者指向同一个证书包。

怎么让修改长期生效?

把私有根证书加入系统信任库;或者在 /etc/wgetrc(所有用户)或 ~/.wgetrc(单个用户)里写 ca_certificate = /path/to/ca-bundle.pem。

提示 Issued certificate has expired 怎么办?

服务器证书或链中某张证书过期了,或者本机时间不对。用 date -u 和 SSL 检测工具检查,参见 openssl 验证错误 10。

资料来源

  1. GNU Wget manual (HTTPS options)
  2. curl: CA certificates extracted from Mozilla
  3. OpenSSL openssl-s_client