CloudFront+S3 で署名付き URL を用いたコンテンツアクセスをしてみた 2023
はじめに
猫とアポロチョコと Systems Manager が好きな m.hayakawa です。
TLS 1.2 未満での AWS API エンドポイントへの接続が2023年6月28日以降、不可能になります。
TLS 1.2 がすべての AWS API エンドポイントへの接続に必要な最小バージョンになります | Amazon Web Services ブログ
今後 Transport Layer Security (TLS) の技術の進化と規制基準に対応するため、すべての AWS サービス API エンドポイントの TLS 構成において、最小バージョンを TLS 1.2 に更新する予定です。この更新は、2023 年 6 月 28 日までにすべての AWS リージョンで、すべての AWS API で TLS バージョン 1.0 と 1.1 が使用できなくなることを意味します。
そのため、TLS 1.0 や TLS 1.1 プロトコルを用いて S3 へアクセスを行うクライアントについて、更新が必要になります。
しかしながら、S3 へアクセスするクライアントが TLS 1.2 以上に対応できない場合があります。
回避策として CloudFront を通じて S3 にアクセスすることで、TLS 1.0 や TLS 1.1 のクライアントでも対応ができるといった記事がありましたので、今回は署名付き URL を用いた方法で検証をしてみます。
古い TLS を使用するお客様が S3 バケットにアクセスできるようにする | AWS re:Post
Amazon CloudFront では、CloudFront ディストリビューションと Amazon S3 の間で使用されている TLS プロトコルからお客様を抽象化することで、古い TLS バージョンを使用できます。
なお、Origin Access Control を用いる方法については、下記のブログが参考になります。
[NEW] CloudFrontからS3への新たなアクセス制御方法としてOrigin Access Control (OAC)が発表されました! | DevelopersIO
やってみた
キーペアを作成する
ここでは CloudShell を用いて、OpenSSL を用いてキーペアを作成します。
CloudShell には OpenSSL がインストールされていないため、インストールします。
$ sudo yum -y install openssl
その後、秘密鍵を作成し、その秘密鍵から公開鍵を作成します。
$ mkdir key $ cd key $ openssl genrsa -out tls12test.private.pem 2048 $ openssl rsa -pubout -in tls12test.private.pem -out tls12test.pub.pem $ ls tls12test.private.pem tls12test.pub.pem
キーペアは任意の S3 バケットに保存しておきます。
$ aws s3 sync . s3://<キーペア保存バケット>
CloudFront にパブリックキーを登録
CloudFront コンソールからパブリックキーを開き、パブリックキーを作成します。
キーにはtls12test.pub.pem
の内容を転記します。
キーグループの作成
CloudFront コンソールからキーグループを作成します。
以下の画面の通り、設定します。
S3 バケットを作成する
デフォルト設定で S3 バケットを作成します。
アクセスの検証用に、test_picture.png をバケットにアップロードしておきます。
test_picture.png
CloudFront ディストリビューションを作成する
CloudFront コンソールへ移動し、ディストリビューションの作成ボタンを押下します。
オリジンを先ほど作成した S3 にします。
CloudFront の署名付きリクエストを有効にする
オリジンアクセスをOrigin access control settings (recommended)
にします。
「コントロール設定を作成」ボタンを押下し、署名動作に署名リクエスト (推奨)
を選択し、「作成」ボタンを押下します。
デフォルトのキャッシュビヘイビアにて、ビューワーのアクセスを制限するをYes
、信頼された認可タイプをTrusted key groups (recommended)
、キーグループを先ほど作成したキーグループにします。
最後に「ディストリビューションを作成」ボタンを押下します。
S3 バケットポリシーを更新する
ディストリビューションの作成後に、バケットポリシーの更新を促す画面が出ますので、それに従い、手動でバケットポリシーを更新します。
生成されるバケットポリシーの内容としては、CloudFront サービスからのアクセスで、特定のCloudFront ディストリビューションからの GetObject アクションの許可がされているといったものとなります。
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::cloudfront-tls12-test/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::<AccountID>:distribution/<DistributionID>" } } } ] }
CloudFront の事前署名付き URL を使用してオブジェクトにアクセスする
試しに、下記の URL でオリジンの S3 にアクセスをしてみますが、失敗しました。
$ curl https://<DistributionDomain>.cloudfront.net/test_picture.png <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>SAMPLE</RequestId><HostId>sample</HostId></Error>
では、CloudShell で署名付き URL を発行します。
$ aws cloudfront sign \ --url https://<DistributionDomain>.cloudfront.net/test_picture.png \ --key-pair-id <KeyPairID> \ --private-key file://./tls12test.private.pem \ --date-less-than $((`date "+%s"` + 86400))
動作チェック
取得した署名付き URL へアクセスします。
アクセスできました!
留意点
この対応を行う場合、S3 へのアクセスについては、S3 の URL ではなく、CloudFront の URL か、代替ドメインを使用する必要があります。
そのため、クライアント側でアクセス先の URL の変更を行う必要がある点については、ご留意ください。