ちょっと話題の記事

[アップデート] root ユーザー作業が不要に!Amazon CloudFront で署名付き URL/Cookie 向け公開鍵を IAM ユーザー権限で管理できるようになりました。

アカウント管理者の皆さま、おつかれさまでした!
2020.10.23

本日のアップデートで Amazon CloudFront の署名付き URL および署名付き Cookie に対する公開鍵の管理を、IAM ユーザー権限で行えるようになりました!

IAM ユーザー権限による公開鍵管理が可能に

従来、CloudFront で署名付き URL および 署名付き Cookie を利用する場合、「CloudFront のキーペア」を作成する必要がありました。このキーペアの作成は AWS アカウントの root ユーザーしか行うことが出来ません。そのため必要になった際にアカウント管理者に連絡しキーペアを作成してもらう、っといった手間が必要でした。

今回のアップデートにより署名付き URL または 署名付き Cookie の署名者として、従来の 「AWS アカウント」に加えて「信頼されたキーグループ(Trusted Key Group)」が追加されました。信頼されたキーグループは通常の IAM 権限によって管理が可能ですので、root ユーザーを利用する必要がなくなりました。

今後は信頼されたキーグループを推奨

公式ガイドでは以下の理由から、信頼されたキーグループの利用を推奨しています。

  • AWS のベストプラクティスでは必要がない場合、root ユーザーを利用しないことが推奨されている
  • 信頼されたキーグループは、CloudFront API 管理ができることでキーのローテーションなどを自動化できる
    • アプリケーションを保護するためにも、キーペアの定期的なローテーションをお勧めします
  • IAM ユーザーやグループでの権限コントロールが可能(root ユーザーには IAM ポリシーが適用できないため、権限や条件を制限することはできない)
  • 信頼されたキーグループごとに5つのキー、ディストリビューションごとに最大4つのキーグループを関連付けできるため、使用方法と管理方法がより柔軟に設定できる
    • CloudFront キーペアの場合、アカウントごとに 2 つまで

やってみる

それでは早速やってみましょう。今回の検証では Administrator 権限のユーザーで作業しています。

信頼されたキーグループのキーペアを作成

CloudFront の署名付き URL または署名付き Cookie の作成に使用する各署名者は、公開鍵と秘密鍵のペアを持っている必要があります。作成するキーペアは次の要件を満たしている必要があります。

  • SSH-2RSA キーペア
  • base64 エンコードされた PEM 形式
  • 1024、2048、または 4096 ビットのキーペア

キーペアの作成

公式ガイドを参考に以下の手順で公開鍵と秘密鍵のペアを作成します。上記の要件を満たしているならば、その他の作成方法でも構いません。

$ openssl genrsa -out private_key.pem 2048

$ openssl rsa -pubout -in private_key.pem -out public_key.pem

公開鍵を CloudFront にアップロード

次に公開鍵を CloudFront にアップロードします。CloudFront メニューから [Key management] - [Public keys] を開き、[Add public key] をクリックします。

[Key name] に任意の名前を入力し、[Key value] に公開鍵の内容を貼り付け、[Add]します。-----BEGIN PUBLIC KEY----------END PUBLIC KEY----- も含める形で貼り付けてください。これらを省略した場合 com.amazonaws.services.cloudfront.model.InvalidArgumentException のエラーになりました。

公開鍵を CloudFront キーグループに追加

次にアップロードした公開鍵を CloudFront キーグループに追加します。CloudFront メニューから [Key management] - [Key groups] を開き、[Create key group] をクリックします。

[Key group name] に任意のグループ名を入力し、[Public keys] から先程登録した公開鍵を選択し [Add] し、さいごに [Create key group] をクリックします。

これでキーグループの作成は完了です

ディストリビューションに署名者の追加

保護する CloudFront ディストリビューションを開き、[Behaviors] タブを選択します。署名付き URL または署名付き Cookie で保護するパスパターンを選択し、[Edit] を開きます。

[Restrict Viewer Access(Use Signed URLs or Signed Cookies)] で Yes を選択すると、信頼されたキー(Trusted Key)の設定メニューが表示されます。[Trusted Key Groups or Trusted Signer] で Trusted Key Groups を選択し、[Trusted Key Groups] から先程作成したキーグループを選択し [Add] し、Edit を終了します。

※ この設定を行うと署名付き URL または署名付き Cookie のないリクエストは拒否されますので、既存のパスパターンに設定する際はご注意ください

これで準備は完了です!

アクセス確認

まず、何も指定せずにリクエストしてみます。

$ curl http://dju74f8c9avbq.cloudfront.net/index.html
<?xml version="1.0" encoding="UTF-8"?><Error><Code>MissingKey</Code><Message>Missing Key-Pair-Id query parameter or cookie value</Message></Error>

想定どおりアクセスできません。次に署名付き URL を使ってリクエストしてみます。AWS CLI の場合 aws cloudfront sign コマンドで署名付き URL を発行できます。以下の例では日本時間 2020年10月23日 19時30分 まで利用可能な署名付き URL になります。

$ aws cloudfront sign --url https://dju74f8c9avbq.cloudfront.net/index.html \
   --key-pair-id KVFXXXXXXXXX \
   --private-key file://private_key.pem \
   --date-less-than 2020-10-23T19:30:00+09:00 \
   
https://dju74f8c9avbq.cloudfront.net/index.html?Expires=1603449000&Signature=s3buZdu5oYsOGltCQBI9rO37X7sHRIZ0f~ny3EuBFVPCAb9UDKuN61qyUj107kUdtPSo60cTPcw6rJIxjpACvgDYTGD4h5e05JvcHfg4XL2t~HwGvbQRHGD5hcujKJ7Nff1P2rzIi7k8f5zClzPtL7CrF-bfG75cdBP3gofYQowo8cBgygFNTd1Gxdxoh54PTzmoCr3rEh-h7Cvidt-P8LlrSie8Ae92100LTAXtbF45hbnTQoaD3xusyvLXLtf0U4NXP~Ep3ftDbCEUGxvb~ymydMxa8dnd72O3vcS1FbHt9P9CIK6kbAOZoqmSmwFwstpu380qmGkbTzo36hu2XQ__&Key-Pair-Id=KVFXXXXXXXXX

署名付き URL でリクエストしてみます。

$ date
2020年 10月23日 金曜日 19時29分42秒 JST

$ curl "https://dju74f8c9avbq.cloudfront.net/index.html?Expires=1603449000&Signature=s3buZdu5oYsOGltCQBI9rO37X7sHRIZ0f~ny3EuBFVPCAb9UDKuN61qyUj107kUdtPSo60cTPcw6rJIxjpACvgDYTGD4h5e05JvcHfg4XL2t~HwGvbQRHGD5hcujKJ7Nff1P2rzIi7k8f5zClzPtL7CrF-bfG75cdBP3gofYQowo8cBgygFNTd1Gxdxoh54PTzmoCr3rEh-h7Cvidt-P8LlrSie8Ae92100LTAXtbF45hbnTQoaD3xusyvLXLtf0U4NXP~Ep3ftDbCEUGxvb~ymydMxa8dnd72O3vcS1FbHt9P9CIK6kbAOZoqmSmwFwstpu380qmGkbTzo36hu2XQ__&Key-Pair-Id=KVFXXXXXXXXX"

Hello! Classmethod!!

Hello! Classmethod!! が正常に表示されました。次に期限切れまで待ったのちリクエストしてみます。

$ date
2020年 10月23日 金曜日 19時30分10秒 JST

$ curl "https://dju74f8c9avbq.cloudfront.net/index.html?Expires=1603449000&Signature=s3buZdu5oYsOGltCQBI9rO37X7sHRIZ0f~ny3EuBFVPCAb9UDKuN61qyUj107kUdtPSo60cTPcw6rJIxjpACvgDYTGD4h5e05JvcHfg4XL2t~HwGvbQRHGD5hcujKJ7Nff1P2rzIi7k8f5zClzPtL7CrF-bfG75cdBP3gofYQowo8cBgygFNTd1Gxdxoh54PTzmoCr3rEh-h7Cvidt-P8LlrSie8Ae92100LTAXtbF45hbnTQoaD3xusyvLXLtf0U4NXP~Ep3ftDbCEUGxvb~ymydMxa8dnd72O3vcS1FbHt9P9CIK6kbAOZoqmSmwFwstpu380qmGkbTzo36hu2XQ__&Key-Pair-Id=KVFXXXXXXXXX"
<?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><Message>Access denied</Message></Error>

想定どおりアクセスできなくなりましたね!検証は以上です。

さいごに

これまで CloudFront の署名付き URL および署名付き Cookie の利用には AWS アカウントの root ユーザー作業が必要でしたが、今後は信頼されたキーグループの利用が推奨となります。root ユーザーによる運用手順は早々に見直していただくのが良いかと思います!

また IAM 権限によりキー管理できるようになりましたので、アプリケーション保護の観点からもキーのローテーション運用も自動化するのが良さそうですね。

以上!大阪オフィスの丸毛(@marumo1981)でした!