TT Lab
はじめる
学ぶ 学習パス コース

オブジェクトストレージとS3

署名付きURLを生成して検証する

TT Labで続きを見る

目標

署名付きURLを作り、使ってみて、期限切れにしてみながら、バイトをアプリサーバーに通さず、アクセス権限だけを委任する方式を手に馴染ませます。

なぜ重要なのか

ユーザーのファイルのダウンロードをアプリサーバーが中継する実装は、小規模ではうまく動きます。問題は、500MBの動画100個が同時にリクエストされたときです。アプリサーバーが50GBを中継しながら、ワーカーがふさがり、帯域幅がアプリサーバーのスペックに閉じ込められ、バッファリングを間違えるとOOMが起きます。署名付きURLは、この構造をひっくり返します。アプリは権限を判断して、数バイトの署名付きURLだけを作り、実際の転送は、クライアントとストレージの間で直接行われます。ステップ7でURLを分解してみると、なぜこれが安全なのかが見えてきます。署名はシークレットキーで作られていますが、シークレットキー自体は、URLのどこにもありません。そのため、URLが漏れても、そのオブジェクト、その操作、その有効期限までしか露出しません。

ステップ

  1. s3://lab-media/private/secret.txtに、/opt/fixtures/s3/readme.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に1行で保存してください。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の6つで、各行にそのパラメーターの意味を書きます。ファイルにシークレットキーの値が入っていてはいけません。

参考

非公開オブジェクトを用意する

s3://lab-media/private/secret.txtに、/opt/fixtures/s3/readme.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に1行で保存してください。URLにX-Amz-SignatureとX-Amz-Expiresが含まれている必要があります。

有効期限を一緒に指定します。URLに、署名に関するクエリパラメーターが付いていれば正常です。

署名付きURLで実際にダウンロードしてみる

そのURLでダウンロードして、/root/ps/downloaded.txtを作成してください。元と内容が同じである必要があります。

引用符で囲まないと、シェルがアンパサンドをバックグラウンド実行と解釈します。

期限切れの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の6つで、各行にそのパラメーターの意味を書きます。ファイルにシークレットキーの値が入っていてはいけません。

URLのクエリパラメーターを分解して、それぞれがどんな制約かを書きます。シークレットキーがURLにないことを確認してください。