curl访问HTTPS报47 Too many redirects:重定向循环与max-redirs排查

访问 HTTPS 下载入口,curl 加上 -L 后反而报"curl: (47) Maximum (2) redirects followed"。这时先别换证书,更别加 -k。47 指向重定向次数上限:可能是入口来回兜圈,也可能只是正常链条超过了你设置的预算。下面用隔离实验,把跳转、TLS 验证和最终文件验收拆开。

一、先分清 302、47 和证书错误

HTTP 302 是响应状态;curl 47 是客户端退出码,两者不是同一套编号。单次请求收到 302,curl 默认不跟随,传输可以正常结束且退出 0。启用 -L 后才沿 Location 继续;达到 --max-redirs 允许的次数,再需要跳转时会失败。

退出 0 不代表拿到文件,47 也不证明循环。三次正常跳转遇到上限 2 同样失败:问路超预算,不等于被指回原地。

现象 先查什么 不能据此断言
302,curl 退出 0 是否启用 -L,Location 是否合理 正文是目标文件
curl 退出 47 跳转链、次数、重复 URL 一定循环或证书过期
curl 退出 60 失败目标的证书、信任与名称 增加跳转次数可以修好

二、固定环境,先看第一跳

本次回环实验使用 curl 7.61.1、OpenSSL 1.1.1k FIPS,限定 TLS 1.2、HTTP/1.1;临时证书私钥用完销毁,未改生产配置。先记录版本,不照搬新版默认值。

bash 复制代码
curl -V
openssl version

下面保留默认"不跟随",保存第一跳响应头和正文。example.com 是文档占位,并不保证提供这些路径;需要替换成有权限访问的真实入口。实验执行器则通过回环映射和临时授权 CA 重放同样命令。

bash 复制代码
curl -q --noproxy '*' --http1.1 \
  --connect-timeout 3 --max-time 10 \
  -sS -D first.headers -o first.body \
  -w 'http=%{http_code} redirects=%{num_redirects}\n' \
  https://example.com/start

-q 必须作为 curl 的首个参数,它跳过默认配置文件,但不会清空环境变量。这里用 --noproxy '*' 明确直连;企业网络若必须走代理,应改成自己的授权配置,不能照搬绕过。命令未关闭证书验证,生产私有 CA 仅添加经管理员确认的 --cacert 文件。

三、跟随跳转,同时限制协议和次数

先设小预算诊断,不要一开始就无限跟随。两项协议限制分别约束初始 URL 和重定向目标;仅限制第一跳,不能代替检查 Location。实验入口 /start 经 /middle 到 /final,共两次跳转,预算 2 恰好成功。

bash 复制代码
curl -q --noproxy '*' --http1.1 \
  --proto '=https' --proto-redir '=https' \
  -L --max-redirs 2 --connect-timeout 3 --max-time 10 \
  -sS -D chain.headers -o candidate.body \
  -w 'http=%{http_code} redirects=%{num_redirects}\n' \
  https://example.com/start

-D 保存跳转链上的多组响应头,不能只看最后一组。-w 打印最终观察到的 HTTP 码与已跟随次数;出错时 HTTP 码可能只是最近一跳,不代表最终文件成功。candidate.body 只是候选输出,绝不能直接覆盖正式产物。

图为独立概念卡,非时序;次数须给数值,如上例 2。HTTPS 验证保持开启。DM-Fox 辅助生成,已复核。

四、怎样确认是循环,而不只是链太长

按顺序整理"当前 URL → Location"。相对路径基于当前 URL 解析,再比较协议、主机、端口、路径和查询参数。重复终点或反复转换规则才是循环证据,两次 302 还不足以定性。

常见原因是应用误读代理信息生成另一种协议地址,或两层规则反复增删末尾斜杠。修复实际生成 Location 的那层;转发头只接受可信代理,不能信任任意客户端头。

无 Cookie 也可能反复回登录页,先确认认证契约。公开 Location、Cookie、Authorization 和签名参数前须脱敏,原始证据按权限保管。

五、回环正反例说明了什么

实验记录请求路径、退出码和响应头,分别测试长链、循环、降级及错误 CA;不凭一行 verify 0 放行。

隔离样本 实际结果 边界
两跳,预算 2 退出 0,最终 200,正文 OK 仍需业务验收
三跳,预算 2;或自循环 均退出 47 同码不能区分二者
预算 0,入口要跳转 退出 47 0 不是无限制
跳向 HTTP,限定 HTTPS 本机构建退出 1 不要移除协议限制当修复
目标 HTTPS 不受信任 退出 60 不是跳转次数问题

这是回环实测,未覆盖浏览器、全部 TLS 后端或生产单点登录。跨主机须重审授权,不盲加 --location-trusted 转发凭据。

六、成功文件最后再替换

下面只接受最终 200 和精确字节 OK 加换行,适合演示"失败保留旧文件"。真实下载须换成独立可信来源的摘要、签名或业务解析规则,不是机械寻找 OK 字样。临时文件与目标在同一目录,验证完成后再 mv。

bash 复制代码
set -eu
url='https://example.com/start'
tmp=$(mktemp './download.XXXXXX')
trap 'rm -f "$tmp"' EXIT
if code=$(curl -q --noproxy '*' --http1.1 \
  --proto '=https' --proto-redir '=https' \
  -L --max-redirs 2 --connect-timeout 3 --max-time 10 \
  -sS -f -o "$tmp" -w '%{http_code}' "$url"); then
  [ "$code" = 200 ] || exit 1
  python3 - "$tmp" <<'PY'
import sys
from pathlib import Path
if Path(sys.argv[1]).read_bytes() != b'OK\n':
    raise SystemExit(1)
PY
  mv -- "$tmp" result.txt
else
  rc=$?
  exit "$rc"
fi

我重放了正常链、循环、错误正文、空正文、HTTP 500 和错误 CA;成功时替换结果,其他情况保持旧文件,并清除临时下载。-f 负责部分 HTTP 错误,不负责证明 200 的内容正确;跳转失败也可能已经写入部分数据,所以必须检查 curl 退出码。

七、哪些做法不算修复

单纯把次数改大只能处理经确认合理的长链,不能修循环。--max-redirs -1 表示不限制次数,诊断时不建议使用;--max-time 限制总时间,但时间预算不替代次数预算。也不要加 -k,让真正的目标证书问题藏到下一层。

HEAD 与 GET 可能走不同规则,不能代替下载验收;调试输出须脱敏。修复后原入口重测,直达最终地址不证明入口恢复。

八、收尾验收清单与参考

  • 记录 curl/TLS 后端版本,明确代理、CA、入口和协议预算。
  • 保存并脱敏每一跳 Location,区分长链与重复循环。
  • 每个 HTTPS 目标保持证书验证,禁止无条件转发凭据。
  • 确认最终状态、内容、退出码;失败不覆盖旧文件。
  • 修复后从原入口重测,回收实验监听、临时证书和私钥。

参考资料:

相关推荐
9624563 小时前
一次 Dell PowerEdge R750xs 启动故障复盘:从 iDRAC 带外管理到 Linux 多内核回退与 initramfs 重建
linux·运维·服务器
Zevalin爱灰灰3 小时前
Linux入门第一部分(Ubuntu入门篇) 第二章 浅尝Ubuntu(二)
linux·嵌入式·1024程序员节
北京中科新远科技4 小时前
高速接口兼容排查实战:OSFP、QSFP112与QSFP56如何逐层验证
linux·运维·网络
Ruiery4 小时前
Linux 6.6内核 CPU 深度解析(零):x86 内核引导协议 — 从 bootloader 到 main()
linux·运维·服务器
Ruiery4 小时前
Linux 6.6内核 CPU 深度解析(十六):x86 保护机制 — 从 ring 到页表的权限防线
linux·运维·服务器
qetfw4 小时前
Linux 文件清理:find、mtime 与安全传参验证
linux·shell·1024程序员节
可乐_不渴5 小时前
【Linux】 项目自动化构建工具makefile&& 版本管理Git&&第一个程序
linux·git·自动化·1024程序员节
西安同步电子6 小时前
时统卡驱动踩坑:Windows 和 Linux 下时间同步的底层差异
linux·stm32·单片机
虚无的纽扣6 小时前
【Linux】线程互斥:多线程改同一个变量,到底会出什么问题
linux·服务器·1024程序员节