云计算百科
云计算领域专业知识百科平台

curl加-L后才报SSL证书错误:HTTPS重定向与目标站信任排查

入口地址能返回302,curl不加-L也不报错,一加-L却出现“SSL certificate problem”。别急着给入口换证书:请求可能已经跳到另一个HTTPS站点,失败的是下一段TLS。本文用两个独立CA的回环实验,把入口、Location和目标站拆开验证,不用关闭证书校验来换一个绿色退出码。

一、入口正常,不等于整段跳转正常

curl默认不跟随HTTP重定向;-L即–location,收到符合条件的3xx与Location后才继续请求。每次新建HTTPS连接,都要按对应URL做证书信任和名称校验。入口证书合格,不会给目标站发一张“免检通行证”。

先区分HTTP跳转与TLS证书链:前者串联请求地址,后者用于验证单次连接的证书。本文仅讨论无认证GET,不覆盖POST改写、浏览器脚本跳转,也不把页面子资源混合内容当重定向故障。

curl HTTPS重定向分层排查:入口、目标、策略与验收

二、先看第一跳,保留Location

先按实际请求方法执行,不要改成-I:HEAD与GET可能走不同路由。下面不带-L,只看第一跳,保存响应头,同时显示HTTP状态和待跳转URL。命令退出0且http=302,只证明当前传输完成,目标还没被访问。

curl -q –noproxy '*' –cacert root-a.pem \\
-sS -D first.headers -o /dev/null \\
-w 'http=%{http_code}\\nnext=%{redirect_url}\\n' \\
https://127.0.0.1:8443/start

示例依赖隔离夹具:8443为入口A,9443为目标B;root-a.pem、root-b.pem分别是经过确认的测试根,roots.pem包含二者。证书含回环IP的SAN,A的/start返回302指向B的/ok。请替换为自己的受控环境。

三、加-L后,证据要按跳数读

仍只信任A的根,再跟随跳转。这是故意保留的失败对照,不是生产验收命令。hops.headers按顺序保存收到的响应头,url_effective和num_redirects提供定位线索;TLS失败时,此前302和最后URL不代表内容已取回。

curl -q –noproxy '*' –cacert root-a.pem \\
-L –max-redirs 5 –connect-timeout 3 –max-time 15 \\
-sS -D hops.headers -o /dev/null \\
-w 'last=%{url_effective}\\nhops=%{num_redirects}\\n' \\
https://127.0.0.1:8443/start

本机curl 7.61.1、OpenSSL后端实测:不跟随时退出0;跟随到B时因缺B的信任根退出60。服务端事件显示A收到GET,B没有收到HTTP请求。这说明目标TLS校验失败发生在HTTP之前,而不是B返回了一个“证书错误页面”。

四、把目标站单独拿出来验证

从Location确定完整目标,包括协议、主机名、端口与路径,再直接请求它。目标的证书过期、名称不符、服务端漏发中间证书或客户端根库不同,都要在目标那一段排查。

curl -q –noproxy '*' –cacert root-b.pem \\
-sS -o /dev/null -w 'http=%{http_code}\\n' \\
https://127.0.0.1:9443/ok

这里换root-b.pem只是验证已知测试CA的B,不是“下载对端证书然后直接信任”。公网站点先修好服务端发链;私有PKI则经可信渠道核对根证书及授权范围。整条跳转需要的根放入经审批的CA包,不能把所有遇到的证书都追加进去。用-k绕过校验只会抹掉需要定位的证据。

五、限制HTTPS,不等于限制目标域名

–proto '=https'限制传输协议,–proto-redir '=https'限制重定向协议;等号表示仅允许指定集合。二者不会替你校验业务目标白名单,也不会让不可信证书变可信。本实验另设HTTPS到HTTP的跳转,受限命令在发出明文HTTP请求前失败。

显式设置–max-redirs 5可以阻止无限跳转,限制值应根据业务设计确定,不依赖文档中的默认次数。对于会携带认证信息的任务,不要为解决跳转错误顺手加–location-trusted;它会放宽跨目标发送凭据的限制。

六、脚本同时守住退出码和HTTP结果

下面只适用于预期最终返回200的GET探针。–fail让常见HTTP错误产生非零退出;仍单独检查预期状态,防止没有Location的302被当作完成。凭据不写进URL,响应头和错误文件按受限权限保存,分享前去掉Cookie、签名参数及业务信息。

#!/usr/bin/env bash
set -u
umask 077
if curl -q –noproxy '*' –cacert roots.pem \\
-L –max-redirs 5 –proto '=https' –proto-redir '=https' \\
–connect-timeout 3 –max-time 15 –fail -sS \\
-D hops.headers -o /dev/null \\
-w '%{http_code}\\n%{url_effective}\\n' \\
https://127.0.0.1:8443/start >result.txt 2>error.txt; then
rc=0
else
rc=$?
fi
(( rc == 0 )) || exit "$rc"
IFS= read -r code <result.txt || exit 1
[[ "$code" == 200 ]] || exit 1
printf '%s\\n' '传输与预期HTTP状态通过;另核对目标URL'

包装器没有通过管道掩盖curl状态。重定向或TLS失败、结果或错误文件打不开,均不能走成功分支;日志存储还需单独检查。它不代表业务内容正确,目标URL还须与批准的地址核对;写操作需业务专用探针,不能套用此脚本。

七、把失败分支整理成一张表

隔离场景实际结果下一步
只看A,不跟随 退出0、HTTP302 尚未验证B
跟随但只信任A 退出60,B无HTTP请求 核对目标发链与根库
信任A、B且允许HTTPS 退出0、最终200 继续核对URL与内容
跳转到HTTP 协议受限,退出1 纠正Location
循环超过设定次数 退出47 检查路由规则
目标返回503 –fail下退出22 转业务可用性排查

这些数字是本机curl实测的进程退出码,不是HTTP状态码。实验绑定随机回环端口,执行时替换正文端口;另覆盖日志写入失败和无Location的302。测试私钥与监听结束后销毁,未改系统信任库、DNS或生产配置,也不据此宣称生产网站已通过。

八、修完后按整条路径验收

  • 记录curl版本、TLS后端及实际CA包,区分第一跳与后续目标。
  • 第一跳和最终目标都保留证书校验,不使用-k作为修复。
  • 完整路径的Location、最终URL和业务预期一致,目标域名另行审查。
  • 错误根、HTTP降级、循环、业务503与日志失败均可阻断成功报告。
  • 最终200只是传输验收的一部分,还要确认返回内容,清理敏感诊断文件。

我会先问“究竟在哪一跳失败”,再问“哪张证书要换”。别让故障目标躲在Location后面。

参考资料:curl命令手册;curl证书验证说明;everything curl重定向章节。版本及默认行为以所用版本手册为准。

赞(0)
未经允许不得转载:网硕互联帮助中心 » curl加-L后才报SSL证书错误:HTTPS重定向与目标站信任排查
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!