VPS执行curl时出现curl: (60) SSL certificate problem,表示curl无法用当前信任配置确认远端证书和访问域名的关系。常见细分提示包括“unable to get local issuer certificate”“self-signed certificate”“certificate has expired”和“no alternative certificate subject name matches”。
先保存完整错误,再判断失败发生在时间、域名、服务端证书链、本机CA证书库还是HTTPS代理。curl默认进行证书校验;直接加-k只是关闭检查,不是修复。
错误60不是单一原因,先看后半句
| 错误片段 | 常见方向 | 优先检查 |
|---|---|---|
| unable to get local issuer certificate | 证书链不完整或本机缺少可信CA | 服务端链、CA存储、代理证书 |
| self-signed certificate | 自签名证书未被信任 | 证书来源、内部CA、使用边界 |
| certificate has expired | 证书过期或系统时间异常 | UTC时间、证书有效期、自动续期 |
| not yet valid | 本机时间过早或证书生效时间异常 | NTP、时区、虚拟机时钟 |
| subject name does not match | 访问域名与证书名称不一致 | URL、DNS、SNI、反向代理配置 |
| certificate signed by unknown authority | 签发CA不在当前信任库 | CA文件、企业HTTPS检查、容器镜像 |
只截取(60)会丢失最重要的线索。排查记录应包括完整命令、目标域名、时间、curl版本、TLS后端、是否使用代理以及错误原文,但要删除Cookie、令牌和Authorization请求头。
第一步:确认VPS时间和时区
date -u
timedatectl status证书包含生效和失效时间。本机时钟明显错误时,正常证书也可能被判断为尚未生效或已经过期。先检查云平台时间同步、NTP或chrony状态,再重新测试。
不要为了让某张证书通过而把系统时间手工改到任意日期。错误时间还会影响日志排序、软件源签名、任务调度和令牌有效期。APT更新同时报签名问题时,可参考VPS软件源签名与系统时间排查,但APT仓库签名和HTTPS证书属于两套不同验证链。
第二步:确认访问域名和DNS结果
TLS证书通常签发给域名,而不是随意替换后的IP地址。直接用服务器IP访问HTTPS,或者DNS把域名解析到错误主机,都可能导致证书名称不匹配。
getent ahosts <目标域名>
curl -v <目标HTTPS地址>从详细输出中关注解析到的IP、连接目标、证书主题和验证错误,不要把包含认证信息的完整日志公开。若VPS能访问IP却无法正确解析域名,应先按resolv.conf与出站53端口检查修复DNS路径。
第三步:查看服务端实际发送的证书链
openssl s_client -connect <目标域名>:443 -servername <目标域名> -showcerts </dev/null-servername用于发送SNI,避免共享IP上的服务器返回另一个站点证书。检查输出时重点关注:
- 叶子证书的域名是否覆盖目标域名;
- 证书是否在有效期内;
- 服务端是否发送了所需的中间证书;
- 验证返回码和错误深度指向哪一层;
- 同一域名从不同网络访问时证书是否一致。
如果服务端遗漏中间证书,客户端可能无法建立从站点证书到可信根CA的完整路径。正确修复通常在服务器或反向代理侧补齐证书链,而不是要求所有客户端跳过验证。
第四步:检查curl使用哪套CA证书库
curl -V
curl -v <目标HTTPS地址>不同系统和curl构建方式可能使用系统原生证书库,也可能使用文件形式的CA bundle。详细输出通常会给出TLS后端及CA文件线索。常见问题包括:
- 精简系统或容器镜像没有安装CA证书包;
- CA包长期未更新或文件损坏;
- 环境变量把curl指向了错误的CA文件;
- 容器内CA存储与宿主机不同;
- 应用进程没有权限读取指定CA文件;
- 企业内部CA只安装在浏览器或办公电脑,没有安装到VPS。
更新CA证书包时,应使用当前发行版官方的软件包和流程。Debian、Ubuntu、RHEL系及容器镜像的命令不同,不要从搜索结果下载未知的整包证书后直接覆盖系统文件。
第五步:自签名或内部CA应缩小信任范围
内部服务使用自签名证书或私有CA时,先通过独立可信渠道核对CA证书指纹和来源。只针对一次连接,可显式指定经过核对的CA文件:
curl --cacert <已核对的CA文件> <目标HTTPS地址>如果多个受管应用都需要信任同一个企业CA,可以按操作系统流程加入系统CA存储,但这会扩大信任范围,必须有变更记录和撤销方案。不要把目标站叶子证书、陌生论坛附件或聊天中收到的证书随意加入全局根信任。
第六步:检查是否经过HTTPS代理或检查设备
VPS环境变量、容器配置或企业网关可能让curl经过代理。代理如果终止并重新建立TLS连接,客户端看到的证书可能由企业CA签发;如果VPS没有信任该CA,就会报错误60。
env | grep -i proxy
curl -v <目标HTTPS地址>同时区分目标服务器证书和HTTPS代理自身证书。curl对代理TLS和目标站TLS使用不同的验证选项,不能用关闭目标站校验的方式掩盖代理证书问题。
代理环境下HTTP正常、HTTPS失败,还应检查CONNECT、SNI和证书替换链。可结合代理IP能开HTTP却打不开HTTPS的排查顺序继续定位。
为什么不应把-k写进脚本长期运行
-k或--insecure会让curl跳过正常的服务端证书验证。它可以用于受控诊断,例如确认网络连通和证书验证是否为唯一阻断点,但不应进入生产脚本、部署命令、健康检查或自动更新流程。
- 无法可靠确认远端是否为预期服务器;
- 证书过期、域名错误和中间人风险会被隐藏;
- 错误配置会从临时测试变成长期依赖;
- 后续证书轮换失败时缺少及时告警;
- 团队成员可能复制不安全参数到更多服务。
pip经过代理出现证书验证失败时也遵循相似原则,可查看pip的可信CA与代理证书处理,不要用关闭校验代替证书链修复。
修复后怎样验收
- 在不使用
-k的情况下重新运行原curl命令; - 确认目标域名、解析IP和证书名称一致;
- 确认系统时间正确,证书处于有效期内;
- 确认服务端发送完整链,curl能构建到可信CA;
- 确认没有未知环境变量替换CA文件或强制代理;
- 在容器、定时任务或systemd服务的真实运行环境中复测;
- 保存修复前后的错误、证书指纹和变更记录;
- 为证书到期、CA轮换和代理变更建立监控。
结论
VPS上的curl错误60应按“错误原文、系统时间、访问域名、服务端证书链、本机CA存储、内部CA和HTTPS代理”逐层处理。curl默认验证证书签名和域名,这是安全边界而不是多余障碍。找出信任链断在哪一层并修复,才比长期添加-k更安全、可维护。






