この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
猫とアポロチョコと 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 の変更を行う必要がある点については、ご留意ください。