You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CURLOPT_SSL_VERIFYHOST提示Let's Encrypt证书过期问题排查

解决cURL设置CURLOPT_SSL_VERIFYHOST=2时Let's Encrypt证书域名路径请求报错问题

问题概述

当设置CURLOPT_SSL_VERIFYHOST=2后,使用cURL请求带路径/参数的Let's Encrypt签发证书的域名时,会返回错误:SSL certificate problem: certificate has expired。但直接请求根域名无异常,且证书链检测显示有效;同时使用CloudFlare或亚马逊签发证书的域名无此问题。

核心原因

这是由于系统中旧的Let's Encrypt根证书(DST Root CA X3)过期后,部分版本的cURL在处理带路径的请求时,证书链验证逻辑出现偏差,错误优先选择了过期的根证书进行验证;而根域名请求的证书链处理逻辑不同,避开了该问题。

可行解决方案

  • 更新系统根证书库:确保系统根证书为最新状态,移除过期的DST Root CA X3,保留有效的ISRG Root X1证书。
    • Debian/Ubuntu系统执行:sudo apt update && sudo apt install ca-certificates
    • RHEL/CentOS系统执行:sudo yum update ca-certificates
  • 手动指定CA证书文件:通过CURLOPT_CAINFO参数指定包含ISRG Root X1的CA证书路径,强制cURL使用有效证书链验证:
    curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/ca-certificates.crt'); // 替换为系统实际CA证书路径
    
  • 升级cURL版本:将cURL升级到7.79.0及以上版本,新版本修复了证书链选择逻辑,会优先使用有效的ISRG Root X1证书。

测试代码复现

<?php
$testUrls = [
    'https://letsencrypt.org', // 根域名请求正常
    'https://letsencrypt.org/docs/', // 带路径请求报错
    'https://cloudflare.com', // CloudFlare证书域名正常
    'https://aws.amazon.com' // 亚马逊证书域名正常
];

foreach ($testUrls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    $response = curl_exec($ch);
    
    if (curl_errno($ch)) {
        echo "URL: $url\nError: " . curl_error($ch) . "\n\n";
    } else {
        echo "URL: $url\nRequest succeeded\n\n";
    }
    curl_close($ch);
}
?>

内容的提问来源于stack exchange,提问作者user3934058

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:35:27