1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ログ保存用S3バケットポリシーの記載のばらつきと修正例について

Posted at

はじめに

本稿では、各マネージドサービスで S3 にログを保存する際の S3バケットポリシー について記載します。

各種マネージドサービスで S3バケット にログを保存する際、S3バケットポリシーというアクセス権限の設定が必要になります。この S3バケットポリシー ですが、AWS のユーザーガイドで、記載のばらつきが見られます。

▼S3バケットポリシーの記載のばらつき内容

  • S3バケットポリシーで、Resource への Condition 設定の有無がサービスによって異なり、
    ポリシーの設定に一貫性がない点

  • 2023年4月にS3バケットのアクセスコントロールリスト(以下、ACL)が
    デフォルトで無効化される仕様変更があったが、
    一部のマネージドサービスでは ACL に関するポリシーが残っている点


ACL に関するポリシーがS3バケットポリシーに残っていても、運用上は大きな問題ありません。 しかし、ポリシー内の Resource 設定に対して、アクセスの条件を指定する Condition は設定が望ましいものになります。Condition を設定することで、必要なアクセス権限をより細かく絞り込めるため、セキュリティを強化できます。

以上の背景から、本稿では、以下のマネージドサービスのログ保存に関するS3バケットポリシーを見直し、修正例をご提案していきたいと思います。

▼見直し対象のS3バケットポリシー

  • VPCフローログ用
  • DNSクエリログ用
  • Application Load Balancer(ALB)アクセスログ用
  • WAFv2ログ用
  • Global Acceleratorログ用

S3バケットポリシーでのバケットACLの無効化について

前述の、S3バケットでのデフォルトACL無効化について記載します。

2023年4月28日から、S3の新規バケットについて、以下のセキュリティベストプラクティスがデフォルトで適用になりました。

  • S3パブリックアクセスブロック:デフォルトで有効化
  • S3アクセスコントロールリスト:デフォルトで無効化

20230428-AWS広報-Amazon S3が新規バケットすべてに2つのセキュリティベストプラクティスをデフォルトで適用開始.png

S3アクセスコントロールリスト(ACL)がデフォルトで無効化された件については、S3ユーザーガイドの以下に記載されています。

S3 オブジェクト所有権は、Amazon S3 バケットレベルの設定で、バケットにアップロードされたオブジェクトの所有権を制御し、アクセスコントロールリスト (ACL) を有効または無効にするのに使用できます。デフォルトでは、オブジェクト所有権は[バケット所有者の強制] 設定に設定され、すべての ACL は無効になっています。ACL が無効になっている場合、バケット所有者はバケット内のすべてのオブジェクトを所有し、アクセス管理ポリシーのみを使用してデータへのアクセスを管理します。

ACLがデフォルトで無効化になったことにより、S3バケットポリシーが、ユーザーガイドの記載に比べて簡略化できるようになっています。

それでは、次の節から、各マネージドサービスのS3バケットポリシーを見直していきましょう。

※なお、本投稿で説明するS3バケットポリシーは動作を確認しておりますが、
 ご利用にあたっては、皆様の環境でご確認の上ご利用ください。

1. VPCフローログ用S3バケットポリシー

1.1 VPCユーザーガイドに記載のS3バケットポリシー

VPCユーザーガイドに記載のS3バケットポリシーは以下の通りです。

▼VPCフローログ用S3バケットポリシー
出典:VPCユーザーガイド > フローログのための Amazon S3 バケットのアクセス許可
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "123456789012",
                    "s3:x-amz-acl": "bucket-owner-full-control"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:logs:us-east-1:123456789012:*"
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "123456789012"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:logs:us-east-1:123456789012:*"
                }
            }
        }
    ]
}

上記のうち、"s3:x-amz-acl": "bucket-owner-full-control""Action": "s3:GetBucketAcl" については、S3バケットのACLデフォルト無効化により、ポリシーに記載しなくてもS3バケットにログ出力はできるようになっています。
記載が残っていても問題はありませんが、ポリシーをすっきりさせることができます。

1.2 見直したS3バケットポリシー

以下は、必要なアクションである "Action": "s3:PutObject" だけに絞った例です。
このS3バケットポリシーで、ログ出力ができることを確認しています。

▼VPCフローログ用S3バケットポリシーの見直し例
{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Sid": "AWSLogDeliveryWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::${S3_LOGS_VPC}/*/AWSLogs/${AWS_ACCOUNT}/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "${AWS_ACCOUNT}"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:logs:${AWS_REGION}:${AWS_ACCOUNT}:*"
        }
      }
    }
  ]
}

${...} の部分は変数です。環境に合わせて適宜置き換えてください。

1.3 "aws:SourceAccount" 条件キーと "aws:SourceArn" 条件キーの設定について

なお、 "aws:SourceAccount" 条件キーと "aws:SourceArn" 条件キーの両方を設定することについて、AWSのページでは一見矛盾した記載があります。

まず、VPCフローログ用のS3バケットポリシーについて記載されたページでは、以下の記載があります。ここでは、両方を設定することが良い、と記載されています。

aws:SourceAccount および aws:SourceArn 条件キーを使用して、混乱した使節の問題から保護することもベストプラクティスです。ソースアカウントはフローログの所有者であり、ソース ARN は、ログサービスのワイルドカード (*) ARN です。


一方、また別のページですが、 "aws:SourceAccount" 条件キーと "aws:SourceArn" 条件キーの両方を設定することについて、以下のページに、"aws:SourceArn" 条件キーが設定されていれば、"aws:SourceAccount" 条件キーは不要という記載もあります。

aws:SourceArn
このキーを使用して、サービス間リクエストを行っているリソースの Amazon リソースネーム (ARN) を、ポリシーで指定した ARN と比較します。ただし、このリクエストが AWS サービスプリンシパルによって実行された場合に限定されます。
ソースの ARN にアカウント ID が含まれている場合は、aws:SourceArn で aws:SourceAccount を使用する必要はありません。


上記の記述から、機能的には、"aws:SourceArn" 条件キーが設定されていれば良いと判断できます。ですが、ソースの ARN にアカウント ID が含まれている場合は と記載がある通り、逆に "aws:SourceArn" に アカウント ID が含まれていない場合がある、ということになります。

マネージドサービスによってユーザーガイドの記載状況が異なるのですが、AWS Systems Manager のユーザーガイドに、"aws:SourceArn" にアカウント ID が含まれないケースがあることについて、以下の通りわかりやすく記載されています。

リソースポリシーで aws:SourceArn および aws:SourceAccount のグローバル条件コンテキストキーを使用して、AWS Systems Manager が別のサービスに付与する許可をそのリソースに制限することをお勧めします。aws:SourceArn 値に、S3 バケットの Amazon リソースネーム (ARN) などのアカウント ID が含まれていない場合は、アクセス許可を制限するために、両方のグローバル条件コンテキストキーを使用する必要があります。


そのため本稿では、"aws:SourceAccount" 条件キーと "aws:SourceArn" 条件キーの両方を設定するようにしています。

2. DNSクエリログ用S3バケットポリシー

2.1 Route 53 デベロッパーガイドに記載のS3バケットポリシー

Route 53 デベロッパーガイド では、以下の記載があります。

自分が所有するアカウント内に S3 バケットがある場合、
必要なアクセス許可がバケットポリシーに自動的に追加されます。

クエリログ設定時に自動で設定される S3バケットポリシー は、2025年11月14時点では以下の形式でした。

▼DNSクエリログ用S3バケットポリシー
クエリログ設定時に自動で作成される S3バケットポリシーの形式
{
    "Version": "2012-10-17",
    "Id": "AWSLogDeliveryWrite20150319",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite1",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::${S3_BUCKET}/${S3_PREFIX}/AWSLogs/${AWS_ACCOUNT}/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "${AWS_ACCOUNT}",
                    "s3:x-amz-acl": "bucket-owner-full-control"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:logs:${AWS_REGION}:${AWS_ACCOUNT}:*"
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryAclCheck1",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::${S3_BUCKET}",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "${AWS_ACCOUNT}"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:logs:${AWS_REGION}:${AWS_ACCOUNT}:*"
                }
            }
        }
    ]
}

上記のうち、"Action": "s3:GetBucketAcl" については、S3バケットのACLデフォルト無効化により、ポリシーに記載しなくてもS3バケットにログ出力はできるようになっています。

2.2 見直したS3バケットポリシー

以下は、必要なアクションである "Action": "s3:PutObject" だけに絞った例です。
このS3バケットポリシーで、ログ出力ができることを確認しています。

▼DNSクエリログ用S3バケットポリシーの見直し例
{
  "Version":"2012-10-17",
  "Id": "CrossAccountAccess",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::${S3_LOGS_DNS}/*/AWSLogs/${AWS_ACCOUNT}/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "${AWS_ACCOUNT}"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:logs:${AWS_REGION}:${AWS_ACCOUNT}:*"
        }
      }
    }
  ]
}

${...} の部分は変数です。環境に合わせて適宜置き換えてください。

3. ALBログ用S3バケットポリシー

3.1 ALBユーザーガイドに記載のS3バケットポリシー

Application Load Balancer ユーザーガイド に記載のS3バケットポリシーは以下の通りです。

▼ALBログ用S3バケットポリシー
出典:Application Load Balancer ユーザーガイド > Application Load Balancer のアクセスログを有効にする > ステップ 2: S3 バケットにポリシーをアタッチする
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "logdelivery.elasticloadbalancing.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/prefix/AWSLogs/123456789012/*"
    }
  ]
}

こちらのポリシーは、Actionは最小限で必要なものに絞られていますが、Resouce に対する Condition が設定されていませんでした。

3.2 見直したS3バケットポリシー

そこで、見直した例が以下のバケットポリシーになります。

▼ALBログ用S3バケットポリシーの見直し例
{
  "Version":"2012-10-17",                                
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "logdelivery.elasticloadbalancing.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::${S3_BUCKET_FOR_ALB}/*/AWSLogs/${AWS_ACCOUNT}/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "${AWS_ACCOUNT}"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:elasticloadbalancing:${AWS_REGION}:${AWS_ACCOUNT}:loadbalancer/*"
        }
      }
    }
  ]
}

${...} の部分は変数です。環境に合わせて適宜置き換えてください。

4. WAFv2ログ用S3バケットポリシー

4.1 WAF デベロッパーガイドに記載のS3バケットポリシー

WAF デベロッパーガイド に記載のS3バケットポリシーは以下の通りです。

▼WAFv2ログ用S3バケットポリシー
出典:WAF デベロッパーガイド > Amazon Simple Storage Service バケットへの保護パック (ウェブ ACL) トラフィックログの送信 > Amazon S3 にログを発行するために必須のアクセス許可
{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Sid": "AWSLogDeliveryWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::aws-waf-logs-amzn-s3-demo-destination-bucket-suffix/AWSLogs/123456789012/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control",
          "aws:SourceAccount": ["123456789012"]
        },
        "ArnLike": {
        "aws:SourceArn": ["arn:aws:logs:us-east-2:123456789012:*"]
        }
      }
    },
    {
      "Sid": "AWSLogDeliveryAclCheck",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::aws-waf-logs-amzn-s3-demo-destination-bucket-suffix",
      "Condition": {
        "StringEquals": {
        "aws:SourceAccount": ["123456789012"]
        },
        "ArnLike": {
        "aws:SourceArn": ["arn:aws:logs:us-east-2:123456789012:*"]
        }
      }
    }
  ]
}

上記のうち、"s3:x-amz-acl": "bucket-owner-full-control""Action": "s3:GetBucketAcl" については、VPCフローログ用のポリシーの箇所で記載した通り、S3バケットのACLデフォルト無効化により、ポリシーに記載しなくてもS3バケットにログ出力はできるようになっています。
記載が残っていても問題はありませんが、ポリシーをすっきりさせることができます。

4.2 見直したS3バケットポリシー

以下は、必要なアクションである "Action": "s3:PutObject" だけに絞った例です。
このS3バケットポリシーで、ログ出力ができることを確認しています。

▼WAFv2ログ用S3バケットポリシーの見直し例
{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Sid": "AWSLogDeliveryWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::${S3_LOGS_WAF}/*/AWSLogs/${AWS_ACCOUNT}/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "${AWS_ACCOUNT}"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:logs:${AWS_REGION}:${AWS_ACCOUNT}:*"
        }
      }
    }
  ]
}

${...} の部分は変数です。環境に合わせて適宜置き換えてください。

5. Global Acceleratorログ用S3バケットポリシー

5.1 Global Accelerator開発者ガイドに記載のS3バケットポリシー

AWS Global Accelerator 開発者ガイド に記載のS3バケットポリシーは以下の通りです。

▼Global Acceleratorログ用S3バケットポリシー
出典:AWS Global Accelerator 開発者ガイド > AWS Global Accelerator フローログの設定と使用 > フローログを Amazon S3 に発行する
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {"Service": "delivery.logs.amazonaws.com"},
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::bucket_name/optional_folder/AWSLogs/account_id/*",
            "Condition": {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}}
        },
        {
            "Sid": "AWSLogDeliveryAclCheck",
            "Effect": "Allow",
            "Principal": {"Service": "delivery.logs.amazonaws.com"},
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::bucket_name"
        }
    ]
}

5.2 見直したS3バケットポリシー

こちらのS3バケットポリシーも他と同様です。"Action": "s3:GetBucketAcl" を削除し、Resouce に対する Condition を設定しました。

なお、Global Acceleratorはグローバルサービスで、実体は us-west-2リージョン で稼働しています。そのため、リージョンは us-west-2 固定にします。

▼Global Acceleratorログ用S3バケットポリシーの見直し例
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AWSLogDeliveryWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::${S3_BUCKET_FOR_GA}/*/AWSLogs/${AWS_ACCOUNT}/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "${AWS_ACCOUNT}"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:logs:us-west-2:${AWS_ACCOUNT}:*"
        }
      }
    }
  ]
}

${...} の部分は変数です。環境に合わせて適宜置き換えてください。

まとめ

本稿では、S3バケットポリシーについてまとめました。
AWSでは、マネージドサービスによってユーザーガイドの記載粒度にばらつきが見られることがあります。他にも気になる点が出てきましたら、また内容をまとめてご紹介したいと思います。

この投稿が皆様のご参考になれば幸いです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?