すべてのユーザーが読み取り/書き込みを実行できるS3バケットポリシーの変更手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、S3バケットのパブリックアクセス設定に関するセキュリティポリシーについて解説します。

ポリシーの説明
Amazon S3 の Security Hub コントロール – AWS Security Hub
このコントロールは、Amazon S3 汎用バケットがバケットレベルでパブリックアクセスをブロックするかどうかをチェックします。次の設定のいずれかが
false
に設定されている場合、コントロールは失敗します。
このポリシーは、S3バケットがインターネットから誰でもアクセスできないようにすることを求めています。パブリックアクセスを許可すると、機密データが漏洩したり、不正なアップロードや削除が行われたりするリスクが高まります。S3バケットには様々なデータが保存されるため、厳格なアクセス制御が必要です。
修復方法
AWSコンソールでの修正手順
- Amazon S3 > 対象バケットを選択し、アクセス許可をクリック
- ブロックパブリックアクセス(バケット限定)で「編集」をクリック

3. パブリックアクセスをすべてブロックにチェックを入れ、「変更の保存」をクリック

Terraformでの修復手順
S3バケットのセキュアな設定を実装するTerraformコードを作成します。
# S3バケットの基本設定
resource "aws_s3_bucket" "secure_bucket" {
bucket = "secure-bucket-${data.aws_caller_identity.current.account_id}"
# 重要:バケットを削除する前に内容の確認が必要
force_destroy = false
tags = {
Environment = "Production"
Security = "High"
}
}
# 重要: パブリックアクセスをすべてブロック
resource "aws_s3_bucket_public_access_block" "secure_bucket" {
bucket = aws_s3_bucket.secure_bucket.id
# すべてのパブリックアクセスをブロック
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# バケットのバージョニングを有効化
resource "aws_s3_bucket_versioning" "secure_bucket" {
bucket = aws_s3_bucket.secure_bucket.id
versioning_configuration {
status = "Enabled"
}
}
# サーバーサイド暗号化の設定
resource "aws_s3_bucket_server_side_encryption_configuration" "secure_bucket" {
bucket = aws_s3_bucket.secure_bucket.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
# 安全なバケットポリシーの設定
resource "aws_s3_bucket_policy" "secure_bucket" {
bucket = aws_s3_bucket.secure_bucket.id
# パブリックアクセスブロックが適用されるのを待つ
depends_on = [aws_s3_bucket_public_access_block.secure_bucket]
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "SecureTransportOnly"
Effect = "Deny"
Principal = "*"
Action = "s3:*"
Resource = [
aws_s3_bucket.secure_bucket.arn,
"${aws_s3_bucket.secure_bucket.arn}/*"
]
Condition = {
Bool = {
"aws:SecureTransport" = "false"
}
}
},
{
Sid = "AllowSpecificRoleAccess"
Effect = "Allow"
Principal = {
AWS = [
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.allowed_role_name}"
]
}
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
]
Resource = [
aws_s3_bucket.secure_bucket.arn,
"${aws_s3_bucket.secure_bucket.arn}/*"
]
}
]
})
}
# アクセスログの保存先バケット
resource "aws_s3_bucket" "log_bucket" {
bucket = "access-logs-${data.aws_caller_identity.current.account_id}"
}
# ログバケットのパブリックアクセスブロック
resource "aws_s3_bucket_public_access_block" "log_bucket" {
bucket = aws_s3_bucket.log_bucket.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# メインバケットのログ記録設定
resource "aws_s3_bucket_logging" "secure_bucket" {
bucket = aws_s3_bucket.secure_bucket.id
target_bucket = aws_s3_bucket.log_bucket.id
target_prefix = "s3-access-logs/"
}
# 現在のAWSアカウントIDの取得
data "aws_caller_identity" "current" {}
# 変数定義
variable "allowed_role_name" {
type = string
description = "Name of the IAM role allowed to access the bucket"
}
# 出力
output "bucket_name" {
value = aws_s3_bucket.secure_bucket.id
description = "The name of the secure S3 bucket"
}
output "bucket_arn" {
value = aws_s3_bucket.secure_bucket.arn
description = "The ARN of the secure S3 bucket"
}
重要な修正ポイントと実装手順を説明します:
- パブリックアクセスのブロック(最重要):
resource "aws_s3_bucket_public_access_block" "secure_bucket" {
bucket = aws_s3_bucket.secure_bucket.id
block_public_acls = true # パブリックACLをブロック
block_public_policy = true # パブリックポリシーをブロック
ignore_public_acls = true # パブリックACLを無視
restrict_public_buckets = true # パブリックバケットを制限
}
aws_s3_bucket_public_access_block
リソースの4つの属性 (block_public_acls
,block_public_policy
,ignore_public_acls
,restrict_public_buckets
) をすべてtrue
に設定することが、このポリシーに準拠するための最も重要な設定です。これにより、ACLやバケットポリシーによる意図しない公開を防ぎます。
2. 安全なバケットポリシーの実装:
- Terraformコード内の
aws_s3_bucket_policy
リソースでは、HTTPS通信 (aws:SecureTransport
=false
をDeny) を強制し、指定したIAMロール (var.allowed_role_name
から生成したARN) のみにアクセスを許可 (AllowSpecificRoleAccess
) するポリシーを設定しています。パブリックアクセスブロック設定と併用することで、よりセキュアになります。
3. 暗号化の設定:
# サーバーサイド暗号化の設定
resource "aws_s3_bucket_server_side_encryption_configuration" "secure_bucket" {
# ... (省略) ...
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
aws_s3_bucket_server_side_encryption_configuration
リソースで、デフォルトのサーバーサイド暗号化 (SSE-S3) を有効にしています。
4. ログ記録の有効化:
# メインバケットのログ記録設定
resource "aws_s3_bucket_logging" "secure_bucket" {
# ... (省略) ...
target_bucket = aws_s3_bucket.log_bucket.id # ログ専用バケット
target_prefix = "s3-access-logs/"
}
aws_s3_bucket_logging
リソースで、別の安全なバケット (aws_s3_bucket.log_bucket
) へのアクセスログ記録を設定しています。
適用手順:
- 変数の設定:
# terraform.tfvars
allowed_role_name = "your-specific-role-name"
2. Terraformの実行:
terraform init
terraform plan
terraform apply
最後に
今回は、S3バケットのパブリックアクセス設定について解説しました。パブリックアクセスを許可すると、データ漏洩や不正アクセスのリスクが高まります。必ずパブリックアクセスをブロックし、厳格なアクセス制御を実施してください。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。
運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。
最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。