CloudFrontディストリビューションオリジンアクセスコントロールの有効化について

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

今回は、Amazon CloudFrontディストリビューションでオリジンアクセスコントロール (OAC) が有効になっていない状態について、そのリスクと対策を解説します。

ポリシーの説明

Amazon CloudFront の Security Hub コントロール – AWS Security Hub

[CloudFront.13] CloudFront ディストリビューションでは、オリジンアクセスコントロールを有効にする必要があります

このコントロールは、Amazon S3 オリジンを使用する Amazon CloudFront ディストリビューションにオリジンアクセスコントロール (OAC) が設定されているかどうかをチェックします。OAC が CloudFront ディストリビューション用に設定されていない場合、コントロールは失敗します。

リスク

多くの場合、CloudFrontはAmazon S3バケットをオリジンとして使用し、静的コンテンツを配信します。しかし、CloudFrontディストリビューションとS3オリジン間のアクセス制御にオリジンアクセスコントロール (OAC) が適切に設定されていない場合、以下のような重大なセキュリティリスクが発生します。

  • S3バケットへの直接アクセスの許可: OAC(またはOAI)を設定しない場合、S3バケットへのアクセスは通常パブリックに設定されるか、バケットポリシーで特定のIPアドレスやVPCエンドポイントからのアクセスが許可されます。この状態では、CloudFrontを経由せずにS3バケットに直接アクセスされる可能性があり、コンテンツがCloudFrontのキャッシュやセキュリティ機能(WAFなど)を迂回して公開されてしまいます。
  • 不適切なコンテンツ公開のリスク: S3バケットへの直接アクセスが許可されていると、意図しないコンテンツが公開されたり、URLを推測されることで機密情報が露呈したりするリスクが高まります。また、バケットポリシーが不適切に設定されていると、不特定多数からの直接アクセスを許してしまい、悪用される可能性があります。
  • キャッシュ制御のバイパス: CloudFrontは、コンテンツのキャッシュによってパフォーマンスを向上させ、オリジンへの負荷を軽減します。S3への直接アクセスが許可されている場合、クライアントはCloudFrontのキャッシュをバイパスしてオリジンに直接リクエストを送信できるため、CloudFrontのメリット(パフォーマンス、コスト効率)が損なわれます
  • セキュリティ機能の迂回: CloudFrontの機能であるAWS WAF(ウェブアプリケーションファイアウォール)やAWS Shield(DDoS対策)は、CloudFrontを通過するトラフィックにのみ適用されます。S3バケットへの直接アクセスが可能な場合、これらのセキュリティ対策が迂回され、S3バケットが直接攻撃の対象となり、保護されなくなります。
  • アクセスログと監視の欠如: S3への直接アクセスが発生した場合、そのアクセスはCloudFrontのアクセスログには記録されません。S3バケット自身のアクセスログを有効にしていない場合、誰が、いつ、どのようにS3コンテンツに直接アクセスしたかを把握できず、セキュリティ監査やフォレンジック調査が困難になります。

対策

CloudFrontディストリビューションにオリジンアクセスコントロール (OAC) を有効にすることは、CloudFront経由でのみS3バケットのコンテンツへのアクセスを許可し、バケットへの直接アクセスを禁止するための最も推奨されるセキュリティベストプラクティスです。OACは、従来のオリジンアクセスアイデンティティ (OAI) に代わる、より強力で柔軟な機能を提供します。

  • OACの利用によるアクセス制限: OACは、CloudFrontディストリビューションとS3オリジン間の通信を暗号化し、CloudFrontからの署名付きリクエストのみをS3バケットが受け入れるように設定できます。これにより、CloudFrontディストリビューションを介してのみバケット内のコンテンツへのアクセスが許可され、バケットまたは別のディストリビューションからの直接アクセスが禁止されます
  • S3バケットポリシーの自動更新: OACはS3バケットポリシーと連携し、CloudFrontがS3にアクセスするために必要な権限を自動的に更新します。これにより、手動でのポリシー管理ミスを防ぎ、よりセキュアな設定を容易に実現できます。
  • すべてのS3バケットタイプへの対応: OACは、S3汎用バケット、S3ウェブサイトエンドポイント、およびS3バケットへのPrivateLinkエンドポイントなど、すべてのS3バケットタイプと互換性があります。
  • HTTPメソッドのサポート: OACは、GET だけでなく PUTPOST など、すべてのHTTPメソッドをサポートします。これにより、CloudFront経由でのS3へのファイルのアップロードなど、より複雑なワークフローも安全に実現できます。
  • CloudFront経由のセキュリティ強化: OACを有効にすることで、すべてのトラフィックがCloudFrontを経由することを強制し、AWS WAFやAWS ShieldなどのCloudFrontのセキュリティ機能を確実に適用できます。
  • 監視とログの統合: CloudFrontのアクセスログを通じて、すべてのコンテンツリクエストが記録されるため、アクセス状況の一元的な監視と分析が可能になります。

修復方法

AWSコンソールでの修復手順

AWSコンソールを使用して、CloudFrontディストリビューションにOACを設定します。

既存のディストリビューションにOACを設定する場合:

  1. CloudFrontサービスへ移動: AWSコンソールにログインし、Amazon CloudFront サービスを開きます。
  2. 対象のディストリビューションを選択: OACを設定したいCloudFrontディストリビューションを選択します。
  3. オリジンタブへ移動: ディストリビューションの詳細ページで、「オリジン」タブをクリックします。
  4. オリジンの編集: OACを適用したいS3オリジンを選択し、「編集」をクリックします。
  5. オリジンアクセスの設定:
    • S3 バケットアクセス」または「オリジンアクセス」セクションを見つけます。オプションで「オリジンアクセスコントロール設定 (推奨)」を選択します。ドロップダウンメニューから既存のOACを選択するか、「新しいコントロール設定を作成」をクリックします。
      • 新しいコントロール設定を作成する場合: 名前(例: my-s3-oac)を付け、「署名リクエスト (推奨)」が選択されていることを確認し、「作成」をクリックします。
      OACを選択した後、「バケットポリシー」セクションに「はい、バケットポリシーを更新します」というオプションが表示される場合、これを**チェックして「変更を保存」**してください。これにより、S3バケットポリシーにOACからのアクセスを許可する設定が自動的に追加されます。この自動更新はOACの非常に便利な機能です。
  1. 変更を保存: 設定を確認し、「変更を保存」をクリックします。

これで、CloudFrontディストリビューションはOACを使用してS3オリジンにアクセスし、S3バケットへの直接アクセスが拒否されるようになります。

Terraformでの修復手順

TerraformでCloudFrontディストリビューションにOACを設定するには、aws_cloudfront_origin_access_control リソースでOACを作成し、そのOACをaws_cloudfront_distribution のオリジンブロックで参照します。同時に、S3バケットポリシーも更新してOACからのアクセスを許可します。

# (例) CloudFrontのオリジンとなるS3バケット
resource "aws_s3_bucket" "my_cloudfront_origin_bucket" {
  bucket = "my-cloudfront-origin-bucket-unique-20250706" # グローバルで一意の名前に変更
  tags = {
    Name = "CloudFrontOriginBucket"
  }
}

# S3バケットをCloudFrontのウェブサイトホスティングとして設定しない場合(一般的な方法)
resource "aws_s3_bucket_acl" "my_cloudfront_origin_bucket_acl" {
  bucket = aws_s3_bucket.my_cloudfront_origin_bucket.id
  acl    = "private" # S3バケットへの直接アクセスを禁止
}

# CloudFront オリジンアクセスコントロール (OAC) の作成
resource "aws_cloudfront_origin_access_control" "s3_oac" {
  name                              = "MyS3OAC"
  description                       = "OAC for S3 origin"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always" # S3へのすべてのリクエストに署名
  signing_protocol                  = "sigv4"  # 署名プロトコル
}

# CloudFrontディストリビューション
resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name              = aws_s3_bucket.my_cloudfront_origin_bucket.bucket_regional_domain_name
    origin_id                = "S3-Origin"
    # OACを使用
    origin_access_control_id = aws_cloudfront_origin_access_control.s3_oac.id
  }

  enabled             = true
  is_ipv6_enabled     = true
  comment             = "CloudFront distribution for S3 bucket with OAC"
  default_root_object = "index.html"

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "S3-Origin"

    viewer_protocol_policy = "redirect-to-https" # HTTPSを強制
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400

    forwarded_values {
      query_string = false
      headers      = []
      cookies {
        forward = "none"
      }
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }

  tags = {
    Environment = "Production"
  }
}

# S3バケットポリシー (CloudFront OACからのアクセスを許可)
resource "aws_s3_bucket_policy" "allow_cloudfront_oac" {
  bucket = aws_s3_bucket.my_cloudfront_origin_bucket.id
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Sid       = "AllowCloudFrontOACAccess"
        Effect    = "Allow",
        Principal = {
          Service = "cloudfront.amazonaws.com"
        },
        Action    = "s3:GetObject", # または s3:ReadGetObject, s3:ListBucket など、必要なアクション
        Resource  = [
          "${aws_s3_bucket.my_cloudfront_origin_bucket.arn}/*",
          aws_s3_bucket.my_cloudfront_origin_bucket.arn
        ],
        Condition = {
          StringEquals = {
            "AWS:SourceArn" = aws_cloudfront_distribution.s3_distribution.arn
          }
        }
      }
    ]
  })
}

上記のTerraformコードでは、以下のリソースを使用しています。

  1. aws_cloudfront_origin_access_control: このリソースで新しいOACを作成します。signing_behavior = "always"signing_protocol = "sigv4" を設定し、CloudFrontからのすべてのリクエストに署名が要求されるようにします。
  2. aws_cloudfront_distribution: CloudFrontディストリビューションの origin ブロック内で、origin_access_control_id パラメータに作成したOACのIDを紐付けます。domain_name にはS3バケットのリージョナルエンドポイントを指定します(例: my-bucket.s3.us-east-1.amazonaws.com)。
  3. aws_s3_bucket_policy: S3バケットのポリシーを定義し、cloudfront.amazonaws.com サービスプリンシパルが、特定のCloudFrontディストリビューション(AWS:SourceArn 条件を使用)からS3オブジェクトへのs3:GetObjectアクションを実行することを許可します。これにより、OACからのアクセスのみが許可され、それ以外の直接アクセスは拒否されます。
  4. aws_s3_bucket_acl: S3バケットのACLをprivateに設定し、パブリックアクセスを明示的にブロックします。これはOAC/OAIを使用する際のベストプラクティスです。

my-cloudfront-origin-bucket-unique-20250706 などのプレースホルダーは、実際の環境に合わせて修正してください。

最後に

この記事では、CloudFrontディストリビューションにオリジンアクセスコントロール (OAC) を有効にすることの重要性について解説しました。OACは、S3オリジンのセキュリティを強化し、コンテンツ配信の信頼性と制御を向上させるための重要な機能です。S3バケットへの直接アクセスを効果的にブロックすることで、CloudFrontのセキュリティ機能とキャッシュ機能が最大限に活用されます。 貴社のCloudFrontディストリビューションでは、オリジンアクセスにOACが適切に設定されていますか?この機会にぜひ設定を確認・強化してみてください。 こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る