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

HTTPS下CURL请求报403错误排查(GoDaddy跨主机场景)

问题描述

场景

从独立IP主机的子域名yyy.xxx.com(sendfeed.php)向另一IP主机的主域名xxx.com(receivefeed.php)发起POST请求,receivefeed.php收到参数后需发送邮件。本地及自有生产服务器运行正常,但在GoDaddy服务器上出现异常。

代码实现

function curl2($url, $urlencoded)
{
    $options = null;
    $headers = false;
   
    $cacert='/home/ooo/public_html/cacert.pem';
    
    $vbh = fopen('php://temp', 'w+');

    session_write_close();

    /* Initialise curl request object */
    $curl=curl_init();
    if (parse_url($url, PHP_URL_SCHEME)=='https') {
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($curl, CURLOPT_CAINFO, $cacert);
    }
    /* Define standard options */    

    curl_setopt($curl, CURLOPT_POST, true);           
    curl_setopt($curl, CURLOPT_POSTFIELDS, $urlencoded); 
    curl_setopt($curl, CURLOPT_URL, trim($url));
    curl_setopt($curl, CURLOPT_AUTOREFERER, true);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($curl, CURLOPT_FAILONERROR, true);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLINFO_HEADER_OUT, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
    curl_setopt($curl, CURLOPT_TIMEOUT, 60);
    curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36');
    curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
    curl_setopt($curl, CURLOPT_ENCODING, '');
    curl_setopt($curl, CURLOPT_VERBOSE, true);
    curl_setopt($curl, CURLOPT_NOPROGRESS, true);
    curl_setopt($curl, CURLOPT_STDERR, $vbh);
    /* Assign runtime parameters as options */
    if (isset($options) && is_array($options)) {
        foreach ($options as $param => $value) {
            curl_setopt($curl, $param, $value);
        }
    }
    if ($headers && is_array($headers)) {
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    }
    /* Execute the request and store responses */
    $res=(object)array(
        'response'  =>  curl_exec($curl),
        'info'      =>  (object)curl_getinfo($curl),
        'errors'    =>  curl_error($curl)
    );       
    rewind($vbh);
    $res->verbose=stream_get_contents($vbh);
    fclose($vbh);
    curl_close($curl);
    return $res;
}

$vars = array(
    'act'=>$_GET['act']
);
$urlencoded = http_build_query($vars);   
$res=curl2("https://www.example.com/test/receivefeed.php",$urlencoded);
print_r($res->verbose);

错误响应(Verbose日志)

Trying xxx.xxx.xxx.108:443...
Connected to www.example.com (xxx.xxx.xxx.108) port 443 (#0)
ALPN: offers h2
ALPN: offers http/1.1
CAfile: /home/ooo/public_html/cacert.pem
CApath: none
SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
ALPN: server accepted h2
Server certificate:
subject: CN=example.com
start date: Apr 6 13:34:23 2023 GMT
expire date: Apr 6 13:34:23 2024 GMT
subjectAltName: host "www.example.com" matched cert's "www.example.com"
issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
SSL certificate verify ok.
Using HTTP2, server supports multiplexing
Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
h2h3 [:method: POST]
h2h3 [:path: /test/receivefeed.php]
h2h3 [:scheme: https]
h2h3 [:authority: www.example.com]
h2h3 [user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36]
h2h3 [accept: /]
h2h3 [accept-encoding: deflate, gzip]
h2h3 [content-length: 5]
h2h3 [content-type: application/x-www-form-urlencoded]
Using Stream ID: 1 (easy handle 0x2cefdd0)

POST /test/receivefeed.php HTTP/2 Host: www.example.com user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 accept: / accept-encoding: deflate, gzip content-length: 5 content-type: application/x-www-form-urlencoded

We are completely uploaded and fine
old SSL session ID is stale, removing
Connection state changed (MAX_CONCURRENT_STREAMS == 128)! < HTTP/2 403 < server: nginx < date: Mon, 29 May 2023 12:48:39 GMT <
content-type: text/html < x-sucuri-id: 11008 < x-xss-protection: 1; mode=block < x-frame-options: SAMEORIGIN < x-content-type-options: nosniff < content-security-policy: upgrade-insecure-requests; <
x-sucuri-block: FBP007
The requested URL returned error: 403

当前问题

  • HTTPS请求返回403,响应含x-sucuri-block: FBP007标识
  • HTTP请求返回200,但GoDaddy会将80端口请求重定向到443并转为GET,导致POST参数丢失

解决方案

1. 处理Sucuri防火墙拦截

x-sucuri-block: FBP007是Sucuri防火墙的拦截规则,针对自动化流量或异常请求触发:

  • 登录目标服务器的Sucuri控制台,将GoDaddy服务器的IP加入白名单
  • 调整Sucuri防火墙规则,允许来自yyy.xxx.com的POST请求

2. 优化CURL请求参数

调整请求特征,避免被防火墙识别为异常流量:

  • 添加Referer头,模拟正常浏览器跳转:
    curl_setopt($curl, CURLOPT_REFERER, 'https://yyy.xxx.com/sendfeed.php');
    
  • 强制使用HTTP/1.1(部分防火墙对HTTP/2的兼容性处理存在问题):
    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    
  • 指定明确的编码类型,替代空值配置:
    curl_setopt($curl, CURLOPT_ENCODING, 'gzip, deflate');
    

3. 修复HTTP重定向丢失POST参数问题

若需使用HTTP请求,配置CURL保留重定向后的POST方法:

curl_setopt($curl, CURLOPT_POSTREDIR, 3); // 3表示所有重定向均保留POST方法

注:该参数需PHP 5.3.2+及CURL 7.19.1+版本支持

4. 修正SSL证书验证配置

当前代码禁用了SSL证书验证,存在安全风险且易被防火墙标记:

  • 确保cacert.pem路径正确且为最新版本
  • 启用SSL证书验证:
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 11:24:55