前回はS3バケットのデフォルト暗号化のパフォーマンス比較を紹介しました。 本当はこちらを先に紹介すべきでしたが、今回はS3の暗号化についてまとめてみました。
暗号化の種類
大きく分けてサーバ(Amazon S3)側とクライアント側に分かれます。
サーバ側の暗号化(Server Side Encryption: SSE)
サーバ(S3)に保管する際、つまりAWSのデータセンターにあるサーバのディスクに書き込まれる際にデータを暗号化します。データ格納時の暗号化とデータ取得時の復号をAWS側が管理してくれます。SSEの中でも三種類に分かれます。
- S3で管理されたキーによる暗号化 (SSE-S3)
- 暗号化キーの管理・ローテーション等をすべてAWSで管理してくれます
- KMS で管理されたキーによる暗号化 (SSE-KMS)
- 暗号化キーをKMSで管理します。KMSを利用することで、証跡(CloudTrail)を残せたり暗号化キーの権限を設定できたりします。ただし、KMSの利用には料金が発生しますし、S3操作が多いとKMSのリクエスト制限に達する可能性があります
- ユーザが用意したキーによる暗号化 (SSE-C)
- ユーザが用意した独自のキーで暗号化できます。自分で管理しなければならないデメリットはあるものの、鍵を自分で管理しなければならない要件では必要かと思います(どんな要件?)
クライアント側の暗号化(Client Side Encryption: CSE)
S3に格納する前にデータを暗号化します。暗号化に使用するキーはKMSやユーザが用意したものを利用できます。
デフォルト暗号化
従来では、S3バケットにファイルをアップロードする際は、暗号化オプションの指定が必要でした。また、暗号化していないファイルを拒否するバケットポリシーを設定する必要がありました。
デフォルト暗号化によって、アップロードする際の暗号化オプションの指定が不要になりました。また、バケットポリシーの設定が不要になります。
デフォルト暗号化で利用できる種類は SSE-S3 と SSE-KMS です。
AWS CLIで有効化するには以下のようにします。以下はSSE-S3による暗号化を有効化しています。
#!/bin/bash
bucket_name=$1
cat << EOF > ./config.json
{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
}
EOF
aws s3api put-bucket-encryption --bucket ${bucket_name} --server-side-encryption-configuration file://config.json
デフォルト暗号化を無効化する場合は以下のように実行します。
$ aws s3api delete-bucket-encryption --bucket ${bucket_name}
デフォルト暗号化におけるAthenaのテーブル定義による注意点
最近のアップデートで暗号化設定したS3バケットに対してAthenaからクエリ実行できるようになりました。
しかし、暗号化の種類によってはAhenaのテーブルプロパティ(has_encrypted_data
)の設定が必要になります。必要となるケースをリンク先より転載しました。
暗号化の種類 | Athena: テーブルデータからのリード | Athena: クエリ結果に対する読み書き | テーブルプロパティ has_encrypted_data=true が必要か |
---|---|---|---|
SSE-S3 | 可 | 可 | 不要 |
SSE-KMS | 可 | 可 | 不要 |
CSE-KMS | 可 | 可 | 必要 |
CSE-C | 不可 | 不可 | - |
SSE-C | 不可 | 不可 | - |
サーバサイドによる暗号化ではSSE-C以外はAthenaテーブルへの変更も不要です。
既存テーブルに対して has_encrypted_data=true
を有効化したい場合は ALTER TABLE SET TBLPROPERTIES文を実行してください。
既存S3オブジェクトの暗号化
デフォルト暗号化を設定する以前にS3オブジェクト(ファイル)が格納されている場合は暗号化されません。既存のファイルを暗号化するには以下のようにします。
$ aws s3 cp s3://${bucket_name} s3://${bucket_name} --recursive --sse
# 暗号化を無効化する場合
$ aws s3 cp s3://${bucket_name} s3://${bucket_name} --recursive
一つ一つのファイルに対してコピーしながら暗号化していくため、ファイル数に応じてCOPYリクエストが発生します。つまりは料金が発生します。もし膨大なファイル数に対して暗号化する際には、予めファイル数をCloudWatchのメトリクスで確認の上、いくらかかるのか試算されることをおすすめします。
最後に
S3の暗号化について紹介しました。暗号化に求められるセキュリティ要件に制約がなければ、SSE-S3によるデフォルト暗号化が最も無難でアプリケーション側の変更もなく、おすすめだと思います。