toto_1212

技術のログをツラツラ書きます。自分用ですが参考にしていただけたら嬉しいです。間違ってたらドンドン突っ込んでください。

【CloudFront】署名付きURL(Signed URL)をOpenSSLで作成

署名付きURLとはCloudFront経由のコンテンツへのアクセス元を限定したり、公開期限を指定したり、セキュアにプライペートなコンテンツを公開する機能です。


署名付き URL の概要 - Amazon CloudFront

実現するにはCloudFrontキーを作成し、作成したポリシーをエンコードし、更に署名化し、URLとそれらいくつかの情報をくっつけてアクセスするためのURLを作成します。
エンコード/署名にはいくつか方法があり、perlPHPC#、.NET、JAVA、OpenSSL等があります。今回はSDKが使えなくてもOpenSSLで簡単に出来るのでその方法を書きたいと思います。

署名付きURLには2通りの種類があり、1つのオブジェクトへの制限・停止する日時を指定できる「既定ポリシー」と1つ以上のオブジェクトへの制限・停止する日時・アクセスできるIPを制限できる「カスタムポリシー」があります。
今回は接続元も制限できるカスタムポリシーで制限をかけてみます。

・テスト用webサイト構築するためテスト用のインスタンスにwebサーバを立てる。

・純粋にEC2へ直接アクセスし、webページが表示されることを確認する。
f:id:toatoshi:20141201233508j:plain

・CloudFrontを受け入れるセキュリティグループを作成し作成したインスタンスに適用する。
 CloudFrontのエッジサーバが利用するIPレンジが決まっているので、そのIPアドレスを設定する。

CloudFront エッジサーバーの場所と IP アドレス範囲 - Amazon CloudFront

・CloudFrontのディストリビューションを作成し、オリジンをテスト用インスタンスに向ける。

・CloudfrontのDomainNameでアクセスし、webページが表示されることを確認する。
f:id:toatoshi:20141202000057j:plain

・managementコンソールのSecurity CredentialsよりCloudFront Key Pairsにて鍵を生成し、private key ファイルをダウンロードするf:id:toatoshi:20141202085002j:plain

・作成したCloudFrontのBehaviors設定からSignedURLを有効にするためRestrict Viewer Access
 YESにする(作成済みのもでも設定可能)
 別アカウントのCloudfrontキーを利用する場合はTrusted SignersをSpecify Accountsにし
 対象のアカウント番号を入力する。
f:id:toatoshi:20141201233939j:plain

・ポリシーが設定されていないため、制限がかかっていて閲覧できないことを確認する。
f:id:toatoshi:20141202000432j:plain

・OpenSSLがインストールされているサーバを用意する。
 EC2でもオンプレのどちらでもよいが、この手順ではAmazonLinuxを使っている。

・ダウンロードしたprivate keyを用意したサーバの/tmpへアップロードする。

・/tmpにpolicyという名前でポリシーを記載したファイルを作成する。

☆今回のポリシーは、対象サイトへの接続は自宅のグローバルIPのみとし、
 2014/11/30 23:00:00まで接続可能とする。
 接続できる時間(DareLessThan)の記載は必須項目となり、時間はUnixTimeでの記載となる
 UnixTimeへの変換はUNIXTIME相互変換ツール - konisimpleを使うと楽チン。

#サンプルポリシー
{
"Statement": [{
"Resource":"http://xxxxxxxxxxxxxx.cloudfront.net/*",
"Condition":{
"IpAddress":{"AWS:SourceIp":"xxx.xxx.xxx.xxx/32"},
"DateLessThan":{"AWS:EpochTime":1417356000}
}
}]
}

・policyをBase64エンコードする

$ cat policy | openssl base64 | tr '+=/' '-_~'

☆返り値
eyAKICAgIlN0YXRlbWVudCI6IFt7IAogICAgICAiUmVzb3VyY2UiOiJodHRwOi8v
ZDIyMGR6dWl3ZHF3OXouY2xvdWRmcm9udC5uZXQvKiIsIAogICAgICAiQ29uZGl0
aW9uIjp7IAogICAgICAgICAiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjEy
MS4xMDIuMTcuMjMyLzMyIn0sIAogICAgICAgICAiRGF0ZUxlc3NUaGFuIjp7IkFX
UzpFcG9jaFRpbWUiOjE0MTczNTYwMDB9CiAgICAgIH0gCiAgIH1dIAp9Cg__

・policyを署名に変換する

$ cat policy | openssl sha1 -sign pk-APKAJKTNETSYZLRR5RJQ.pem | openssl base64 | tr '+=/' '-_~'

ZkE9khCVW70dZqe-IjsJnALOnoR1jEOLXjLXp04Nr4~oca8OQHxOAK02u1lF6Gex
OmRz3uF7naMOQz8rap8xg-MnY0ZUOgcKt~EgmC4DI6DRsGh6gaWzE5r5eOsj29Nb
zyPPGYWGx-MKgncKdSI23-7rFUOlPkAoxyFxmxZ8K~3QfjCNJHAUtwBYUVdAU3~P
37roKM1CE1QLT4do4bJpHY5eR0KFu8t0WvvqYKg1O5P5K0K27FNul~Peb~NKALmN
ggVufjVqIashKhJAh66MImEsJ~nIvk2~fzmTe1Pzt29e8JwPrwnjQkblFvIHbrLz
Ae2CDPrCqTYJAXmCLlY-jA__

・出力された情報を利用してURLを生成する

1️⃣1. 対象のサイトURLを記載(ワイルドカード可能)
  2. ?
  3. クエリ文字列パラメータ(ある場合)&
  4. Policy= ポリシーステートメント(←・policyをBase64エンコードするで生成したもの)
  5. &Signature= ハッシュ化および署名されたバージョンのポリシーステートメント(← ・policyを署名に変換するで生成したもの)
  6. &Key-Pair-Id= 作成したCloudFront キーペア ID

1 + 2 + 3 + 4 + 5 + 6のようにしてURLを作成する。

http://d220dzuiwdqw9z.cloudfront.net/?&Policy=eyAKICAgIlN0YXRlbWVudCI6IFt7IAogICAgICAiUmVzb3VyY2UiOiJodHRwOi8vZDIyMGR6dWl3ZHF3OXouY2xvdWRmcm9udC5uZXQvKiIsIAogICAgICAiQ29uZGl0aW9uIjp7IAogICAgICAgICAiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjEyMS4xMDIuMTcuMjMyLzMyIn0sIAogICAgICAgICAiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MTczNTYwMDB9CiAgICAgIH0gCiAgIH1dIAp9Cg__&Signature=ZkE9khCVW70dZqe-IjsJnALOnoR1jEOLXjLXp04Nr4~oca8OQHxOAK02u1lF6GexOmRz3uF7naMOQz8rap8xg-MnY0ZUOgcKt~EgmC4DI6DRsGh6gaWzE5r5eOsj29NbzyPPGYWGx-MKgncKdSI23-7rFUOlPkAoxyFxmxZ8K~3QfjCNJHAUtwBYUVdAU3~P37roKM1CE1QLT4do4bJpHY5eR0KFu8t0WvvqYKg1O5P5K0K27FNul~Peb~NKALmNggVufjVqIashKhJAh66MImEsJ~nIvk2~fzmTe1Pzt29e8JwPrwnjQkblFvIHbrLzAe2CDPrCqTYJAXmCLlY-jA__&Key-Pair-Id=APKAJKTNETSYZLRR5RJQ

・作成したURLでアクセスし、閲覧できることを確認する。
f:id:toatoshi:20141202000555j:plain

・設定した時間を過ぎたらアクセス出来ないことを確認する。
f:id:toatoshi:20141202000629j:plain

参考URL


署名付き URL の概要 - Amazon CloudFront


カスタムポリシーを使用して署名付き URL を作成する - Amazon CloudFront


Linux コマンドおよび OpenSSL を使用して Base64 エンコードおよび暗号化を行う - Amazon CloudFront