TT Lab
开始
学习 学习路径 课程

对象存储与 S3

生成预签名 URL 并验证

在 TT Lab 中继续学习

目标

通过创建、使用并让预签名 URL 过期,掌握这种不让字节经过应用服务器、只委托访问权限的方式。

为什么重要

由应用服务器中转用户文件下载的实现,在小规模时运行良好。问题出在 100 个 500MB 的视频被同时请求的时候:应用服务器要中转 50GB,工作进程被占满,带宽被应用服务器的规格限制,缓冲处理不当还会 OOM。预签名 URL 把这种结构彻底颠倒过来——应用只判断权限并生成一个只有几个字节的签名 URL,真正的传输直接发生在客户端与存储之间。在第 7 步把 URL 拆开来看,就能明白为什么这样是安全的:签名由密钥(secret key)生成,但密钥本身不在 URL 的任何位置。所以即使 URL 泄露,暴露的也只限于那个对象、那个操作和那个过期时间。

步骤

  1. 把 /opt/fixtures/s3/readme.txt 上传到 s3://lab-media/private/secret.txt。
  2. 不带签名执行 curl -o /dev/null -w '%{http_code}' http://127.0.0.1:9000/lab-media/private/secret.txt,并在 /root/ps/anon.txt 中写入 status=403。
  3. 用 /root/ps/presign.py 生成过期时间为 300 秒的预签名 GET URL,并以一行保存到 /root/ps/get_url.txt。URL 中必须有 X-Amz-Signature 和 X-Amz-Expires。
  4. 用该 URL 下载,生成 /root/ps/downloaded.txt。内容必须与原文件相同。
  5. 生成一个过期时间为 1 秒的 URL,等待 3 秒后再使用。在 /root/ps/expired.txt 中写入 status=403。
  6. 用过期时间为 300 秒的预签名 PUT URL,把 /opt/fixtures/s3/sales.csv 上传到 s3://lab-media/upload/direct.csv。用 aws --profile local s3api head-object 确认它已存在。
  7. 在 /root/ps/sig.md 中写一张 Markdown 表格。行标题是 X-Amz-Algorithm、X-Amz-Credential、X-Amz-Date、X-Amz-Expires、X-Amz-SignedHeaders、X-Amz-Signature 六个,每一行写出该参数的含义。文件中不得出现密钥的值。

参考

准备私有对象

把 /opt/fixtures/s3/readme.txt 上传到 s3://lab-media/private/secret.txt。

沿用上一项实验的存储桶,或新建一个。默认存储桶禁止匿名访问。

确认匿名访问被拒绝

不带签名执行 curl -o /dev/null -w '%{http_code}' http://127.0.0.1:9000/lab-media/private/secret.txt,并在 /root/ps/anon.txt 中写入 status=403。

不带签名,直接用 URL 访问试试。记录下状态码是什么。

生成预签名 GET URL

用 /root/ps/presign.py 生成过期时间为 300 秒的预签名 GET URL,并以一行保存到 /root/ps/get_url.txt。URL 中必须有 X-Amz-Signature 和 X-Amz-Expires。

同时指定过期时间。URL 上附带与签名相关的查询参数才算正常。

用预签名 URL 实际下载

用该 URL 下载,生成 /root/ps/downloaded.txt。内容必须与原文件相同。

不用引号括起来的话,shell 会把 & 符号解释为后台运行。

确认过期的 URL 被拒绝

生成一个过期时间为 1 秒的 URL,等待 3 秒后再使用。在 /root/ps/expired.txt 中写入 status=403。

把过期时间设得非常短,稍等一会儿再使用。记录下被拒绝的状态码。

用预签名 PUT 直接上传

用过期时间为 300 秒的预签名 PUT URL,把 /opt/fixtures/s3/sales.csv 上传到 s3://lab-media/upload/direct.csv。用 aws --profile local s3api head-object 确认它已存在。

由客户端直接上传到存储。关键在于不经过应用服务器。

分析签名要素

在 /root/ps/sig.md 中写一张 Markdown 表格。行标题是 X-Amz-Algorithm、X-Amz-Credential、X-Amz-Date、X-Amz-Expires、X-Amz-SignedHeaders、X-Amz-Signature 六个,每一行写出该参数的含义。文件中不得出现密钥的值。

把 URL 的查询参数拆开,写出每个参数分别是什么约束。确认 URL 中没有密钥。