在VPS上调用HTTPS接口时,curl返回 (60) SSL certificate problem,代表TLS连接中的证书验证没有通过。它可能是服务端证书链配置错误,也可能是本机时间、CA信任库或HTTPS代理造成,不能一看到错误60就认定证书已经过期。
curl默认同时验证签发链和访问域名,这道检查是为了确认连接对象可信。 把命令改成 curl -k 虽然可能暂时请求成功,却等于关闭身份验证,不应作为生产环境的修复结果。

先记录具体的证书错误
先查看curl版本、TLS后端和完整握手信息:
curl -V
curl -vI https://example.com/
date -u
常见提示包括 certificate has expired、unable to get local issuer certificate、self signed certificate 和 no alternative certificate subject name matches。它们对应的处理方向不同,必须保留完整文本。
若命令通过代理访问,还要检查 HTTPS_PROXY、https_proxy 等环境变量。同一网址在浏览器正常、服务器curl失败,并不能证明服务端一定正常,因为两端使用的CA库和代理路径可能不同。
检查证书有效期与访问域名
服务器时间明显错误时,有效证书也可能被判断为尚未生效或已经过期。先确认UTC时间和同步状态,再检查目标证书:
timedatectl status
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
-servername 会发送SNI,虚拟主机环境缺少它时可能拿到默认站点证书。访问时必须使用证书SAN中覆盖的域名,直接请求IP地址通常会出现名称不匹配,除非证书明确包含该IP。
不要通过修改hosts把另一个域名硬指向目标IP后忽略名称错误。 正确做法是使用证书覆盖的主机名,或为实际域名重新签发证书。
判断服务端证书链是否完整
使用OpenSSL显示服务端发送的链并查看最终验证结果:
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
公开网站通常需要发送站点证书和必要的中间证书,根证书由客户端信任库提供。服务端漏发中间证书时,某些浏览器可能依靠缓存或自动补链继续工作,但干净的Linux服务器会报找不到签发者。
这种情况应在Nginx、Apache或负载均衡器上部署完整证书链,例如使用签发机构提供的fullchain文件。客户端反复导入中间证书只能掩盖服务端配置问题,无法保证其他访问者正常。
更新Linux系统的CA信任库
如果多个正规HTTPS站点都失败,先检查系统CA包是否缺失或过旧。Debian和Ubuntu可执行:
sudo apt update
sudo apt install --reinstall ca-certificates
sudo update-ca-certificates
RHEL、Rocky Linux和AlmaLinux可执行:
sudo dnf reinstall ca-certificates
sudo update-ca-trust
更新后重新运行 curl -vI,观察输出中的CAfile和CApath。容器内的CA库与宿主机相互独立,精简镜像还可能根本没有安装ca-certificates,因此要在实际发起请求的环境中修复。
私有CA应该怎样加入信任
企业内网、自建API或TLS检查代理可能使用私有CA。确认该CA确实由组织管理员提供并核对指纹后,可以只对单次请求指定:
curl --cacert /secure/path/company-root-ca.pem https://internal.example.com/
需要系统级信任时,Debian系通常把PEM格式的 .crt 文件放入 /usr/local/share/ca-certificates/ 后运行 update-ca-certificates;RHEL系放入 /etc/pki/ca-trust/source/anchors/ 后运行 update-ca-trust。
私有CA一旦加入系统信任库,就可能为多个域名签发被本机接受的证书。 只应导入可信组织正式分发的根证书,并限制文件写权限。
HTTPS代理要单独验证
curl连接HTTPS代理时,代理TLS连接与目标网站TLS连接是两层独立验证。官方选项中,目标站点使用 --cacert,HTTPS代理使用 --proxy-cacert:
curl --proxy https://proxy.example.com:8443 \
--proxy-cacert /secure/path/proxy-ca.pem \
https://example.com/
如果公司代理会重新签发目标证书,curl看到的issuer可能是企业CA而不是公网CA。此时要先确认代理属于预期链路,不能从报错页面随意下载一张证书就加入信任。
需要对比不同系统镜像或网络出口时,可以在 萤光云 建立干净测试机,也可用 LightNode 从其他地区复测证书链。测试只用于定位差异,生产修复仍应回到正确的证书和CA配置。
为什么不应长期使用-k
-k 或 --insecure 会跳过服务端身份验证,中间人、错误代理或被劫持的DNS都可能返回一个加密但不可信的连接。下载脚本、软件仓库和API凭据一旦在这种连接上传输,风险尤其高。
短时实验若必须使用,应限制在隔离环境,不传输凭据,并在命令旁记录原因和移除期限。生产验收必须在不带-k的情况下返回成功,并确认issuer、SAN、有效期和信任路径符合预期。
修复后的验收方式
再次执行:
curl -fsSvo /dev/null https://example.com/
确认退出码为0、没有证书警告、连接到预期域名和IP,并返回合理的HTTP状态。应用语言运行时可能使用自己的证书库,curl成功后还应在真实应用内复测。
完整验收不是只看到HTTP 200,而是证书校验开启、没有临时绕过、系统时间正确,并且自动任务或容器重启后仍能成功。
FAQ
浏览器能打开,curl为什么仍报60?
浏览器可能使用操作系统信任库、缓存过中间证书,或走了不同代理;curl的TLS后端和CA文件也可能不同。用 curl -V 与 curl -v 确认实际环境。
使用–cacert后还会校验域名吗?
会。--cacert 只指定信任的CA集合,curl仍会验证证书是否覆盖URL中的主机名。
自签名证书只能配合-k吗?
不是。可以把对应私有CA通过 --cacert 提供给curl,或在确认可信后加入系统信任库,从而保留完整验证。
温馨提示
证书错误可能提示服务端配置失误,也可能是在提醒你连接经过了未预期的代理。先弄清楚curl实际信任谁、连到哪里,再决定导入哪张CA证书,不能用关闭校验换取表面成功。


