使用curl上传文件至S3存储桶的脚本运行失败,应如何排查问题?
你的脚本存在以下几处问题:
- 签名逻辑和标识不匹配:你在Authorization头标注了
AWS4-HMAC-SHA256(AWS签名版本4),但实际构造stringToSign的逻辑是旧的签名版本2的规则,两者完全不兼容导致签名校验失败。如果要使用SigV2,需要将Authorization头的前缀修改为AWS;如果要使用官方更推荐的SigV4(新区域默认仅支持SigV4),需要重写签名构造逻辑,补充区域、服务标识、ISO 8601格式的时间戳等必填参数。 - 签名算法不匹配:SigV2签名要求使用SHA1算法生成摘要,你的脚本错误使用了SHA256算法,会直接导致签名无效。
- MIME类型填写错误:
contentType的正确值是text/plain,你写的text/plaintext属于无效MIME类型,会导致签名校验不通过、S3元数据识别错误。 - S3对象键路径错误:你直接将本地文件的绝对路径
$HOME/Documents/test.txt作为S3对象键拼接进了resource和请求URL,最终请求的S3资源路径会包含本地目录结构,如果你要上传到存储桶根目录下的test.txt,需要单独定义S3对象键变量,比如s3_obj="test.txt",再用这个变量拼接路径。 - 区域适配缺失:如果你的存储桶不在us-east-1默认区域,Host头和请求URL需要补充区域标识,格式为
${bucket}.s3.${region}.amazonaws.com,否则会请求到错误的区域返回400/404错误。
以下是适配SigV2的修正脚本示例(仅适用于支持SigV2的旧区域):
file=$HOME/Documents/test.txt bucket=my-s3bucket # 单独定义S3对象键,不要用本地绝对路径 s3_obj="test.txt" resource="/${bucket}/${s3_obj}" # 修正MIME类型 contentType="text/plain" dateValue=`date -R` stringToSign="PUT ${contentType} ${dateValue} ${resource}" s3Key=你的访问密钥AK s3Secret=你的访问密钥SK # 修正为SigV2要求的SHA1算法 signature=`echo -en "${stringToSign}" | openssl sha1 -hmac "${s3Secret}" -binary | base64` curl -X PUT -T "${file}" \ -H "Host: ${bucket}.s3.amazonaws.com" \ -H "Date: ${dateValue}" \ -H "Content-Type: ${contentType}" \ # 修改为SigV2对应的Authorization前缀 -H "Authorization: AWS ${s3Key}:${signature}" \ https://${bucket}.s3.amazonaws.com/${s3_obj}
内容的提问来源于stack exchange,提问作者listout
相关产品推荐
相关产品推荐

