CloudFrontの地理的制限によるコンテンツアクセス制御

目次

概要

グローバルに配信するWebコンテンツに対して、特定の国からのアクセスを制限したいケースがあります。たとえば、コンプライアンス要件やライセンス上の理由から、特定の国のユーザーにはコンテンツを配信できない場合です。

Amazon CloudFrontの地理的制限(Geo-Restriction)機能を使用すると、CloudFrontのエッジロケーションレベルで国単位のアクセス制御を実現できます。さらに、S3バケットへの直接アクセスを防ぐためにOAC(Origin Access Control)を併用することで、CloudFrontを経由しないアクセスをブロックし、地理的制限を確実に適用できます。

本記事では、CloudFrontの地理的制限の仕組みと、OACによるオリジン保護を組み合わせたコンテンツアクセス制御について解説します。

CloudFrontの地理的制限とオリジンアクセスコントロール(OAC)を組み合わせたアクセス制御の全体像を示す図(ユーザー→CloudFrontエッジロケーション→S3の流れで、許可国からのリクエストは通過し、拒否リストの国からのリクエストはエッジロケーションで403を返す構成)
CloudFrontの地理的制限とオリジンアクセスコントロール(OAC)を組み合わせたアクセス制御の全体像を示す図(ユーザー→CloudFrontエッジロケーション→S3の流れで、許可国からのリクエストは通過し、拒否リストの国からのリクエストはエッジロケーションで403を返す構成)
クラウドおさる

国ごとに配信を止める CloudFront の地理的制限と、その制限を裏口から迂回させないための OAC を、あわせて確かめる記事でござる。表門だけ固めても裏口が開いていては意味がない、というお話でござるな。

この記事のメリット

  • CloudFrontの地理的制限の仕組みと許可リスト・拒否リストの使い分けを理解できる
  • OACによるS3バケット保護の重要性と設定方法を把握できる(レガシーのOAIとの違いも整理できる)
  • S3バケットポリシーによる国別制限やRoute 53の地理的ルーティングでは不十分な理由を理解できる
  • CloudFrontの地理的制限とOACを組み合わせた実践的な設定手順を体験できる
  • SCS試験で「国別コンテンツ制限」を問われた際に正確に判断できるようになる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。

クラウドおさる

基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

CloudFrontの地理的制限とは

CloudFrontの地理的制限は、ディストリビューション単位で特定の国からのアクセスを許可または拒否する機能です。CloudFrontは、リクエスト元のIPアドレスから国を判定し、設定に基づいてアクセスを制御します。

国の判定にはMaxMind社のGeoIPデータベースが使用されます。IPアドレスと国の対応は定期的に更新されますが、100%の精度ではない点に留意が必要です。

地理的制限が適用された場合、拒否対象の国からのリクエストにはHTTPステータスコード 403(Forbidden) が返されます。

許可リストと拒否リストの使い分け

地理的制限には2つのアプローチがあります。

アプローチ設定方法ユースケース
許可リスト(Allowlist)アクセスを許可する国を指定し、それ以外はすべて拒否配信先が限定されている場合(例: 日本国内のみに配信)
拒否リスト(Denylist)アクセスを拒否する国を指定し、それ以外はすべて許可大部分の国には配信し、一部の国のみブロックしたい場合

許可リストは「ホワイトリスト型」のため、指定し忘れた国からのアクセスはすべて拒否されます。一方、拒否リストは「ブラックリスト型」のため、指定し忘れた国からのアクセスは許可されます。要件に応じて適切なアプローチを選択することが重要です。

クラウドおさる

許可リストは書き忘れた国が締め出され、拒否リストは書き忘れた国が素通りするのでござる。猿山の長老会も、入山を許す群れを名簿に書くか、断る群れを書くかで、名簿漏れの意味が真逆になるのでござるな。

オリジンアクセスコントロール(OAC)によるオリジン保護

CloudFrontの地理的制限を有効にしても、S3バケットに直接アクセスされると制限が適用されません。S3のバケットURLに直接アクセスすれば、CloudFrontを経由しないため地理的制限を迂回できてしまいます。

これを防ぐために、OAC(Origin Access Control)を使用してS3バケットへのアクセスをCloudFrontディストリビューション経由のみに制限します。

OACの仕組みは以下の通りです。

  • CloudFrontがオリジンへのリクエストにSigV4署名を付ける
  • S3バケットポリシーで、サービスプリンシパル cloudfront.amazonaws.com からのアクセスだけを許可する
  • さらに AWS:SourceArn 条件で、特定のディストリビューションからのリクエストに限定する
  • S3バケットのパブリックアクセスはブロックする
  • ユーザーはCloudFrontのドメイン名を通じてのみコンテンツにアクセスできる
項目OAI(レガシー)OAC(現行)
バケットポリシーのプリンシパルarn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <ID>サービスプリンシパル cloudfront.amazonaws.com
ディストリビューション単位の限定OAIごとに分けるAWS:SourceArn 条件で指定
SSE-KMS で暗号化したオブジェクト非対応対応
現在のコンソール新規ディストリビューション作成画面では選べない既定で有効(推奨)
OACによるアクセス制御の仕組み(S3バケットへの直接アクセスは拒否され、CloudFront経由のアクセスのみが許可される構成図)
OACによるアクセス制御の仕組み(S3バケットへの直接アクセスは拒否され、CloudFront経由のアクセスのみが許可される構成図)

OAIは引き続き既存のディストリビューションで利用できますが、AWSはOACの使用を推奨しています。現在のディストリビューション作成ウィザードにはOAIを選ぶ項目自体がありません。

クラウドおさる

地理的制限をかけても、S3 のバケット URL に直接来られたら CloudFront を通らず制限は効かないのでござる。だから OAC で、バケットへの入口を CloudFront 経由だけに絞るのでござるぞ。

他のアプローチが不十分な理由

国別のアクセス制限を実現する手段として、以下のアプローチが考えられますが、それぞれに制約があります。

S3バケットポリシーによる国別制限

S3バケットポリシーの条件キーには、リクエスト元の国を直接判定する仕組みがありません。aws:SourceIp 条件キーでIPアドレス範囲を指定することは可能ですが、国単位でのIPアドレス範囲は膨大かつ変動するため、実用的ではありません。

さらに、CloudFront経由でS3にアクセスする場合、S3が受け取るリクエスト元のIPアドレスはCloudFrontエッジロケーションのIPアドレスであり、エンドユーザーのIPアドレスではありません。そのため、S3バケットポリシーの aws:SourceIp でエンドユーザーの国を判定すること自体が不可能です。

Route 53の地理的位置ルーティング

Route 53の地理的位置ルーティングを使用すると、DNSレベルで特定の国からのリクエストを異なるエンドポイントに誘導できます。しかし、この方法には以下の制約があります。

  • DNS解決の迂回: ユーザーがCloudFrontディストリビューションのIPアドレスを直接指定してアクセスすると、Route 53のDNSルーティングを迂回できる
  • DNSキャッシュの問題: DNSレコードのTTL期間中は、ルーティング変更が反映されない場合がある

これらの理由から、CloudFrontの地理的制限とOACの組み合わせが、国別アクセス制御の実装として適切な方法です。

フリーランス案件
クラウドおさる
クラウドキャリアフリーランス

AWS の実務経験があるなら、単価を上げにいく

AWS に特化したフリーランスエージェントです。以下は取り扱い案件の一例です。設計・SRE・セキュリティ・生成 AI の領域で、専門を掛け合わせるほど単価が上がります。

横にスクロールできます。掲載時点の情報のため、募集が終了している場合があります。条件の近い案件をご紹介しますので、お気軽にご相談ください。

実践

ここでは、S3バケットをオリジンとするCloudFrontディストリビューションに地理的制限を設定し、特定の国からのアクセスを拒否する構成を作成します。また、OACによってS3バケットへの直接アクセスをブロックし、CloudFront経由でのみコンテンツにアクセスできるようにします。

前提条件

  • リージョン: ap-northeast-1(東京)
  • 以下のリソースが作成済みであること
リソース種別リソース名用途
S3バケットgeo-restriction-lab-<アカウントID>コンテンツ配信用オリジン

S3バケットにはテスト用のHTMLファイル(index.html)がアップロード済みであることを前提とします。

手順1: S3バケットのパブリックアクセスをブロックする

まず、S3バケットへの直接アクセスをブロックし、CloudFront経由のみでアクセスできるようにします。

  • AWSマネジメントコンソールにログインし、右上のリージョンが「アジアパシフィック(東京) ap-northeast-1」であることを確認します。
  • 上部の検索バーに S3 と入力し、表示された「S3」を選択します。
  • バケット一覧からバケット(geo-restriction-lab-<アカウントID>)をクリックします。
  • 「アクセス許可」タブを選択します。
  • 「ブロックパブリックアクセス(バケット設定)」セクションの「編集」をクリックします。
  • 「パブリックアクセスをすべてブロック」にチェックを入れます。
  • 「変更の保存」をクリックし、確認ダイアログに 確認 と入力して保存します。
S3バケットのブロックパブリックアクセス設定画面 ── 「パブリックアクセスをすべてブロック」が有効になっている状態
S3バケットのブロックパブリックアクセス設定画面 ── 「パブリックアクセスをすべてブロック」が有効になっている状態

手順2: CloudFrontディストリビューションを作成する

  • 上部の検索バーに CloudFront と入力し、表示された「CloudFront」を選択します。
  • 「ディストリビューションを作成」をクリックすると、6ステップのウィザード(Choose a plan / Get started / Specify origin / Enable security / Get TLS certificate / Review and create)が開きます。

ステップ1: Choose a plan

料金体系を選びます。定額のプラン(Flat-rate plans)と従量課金(Pay as you go)のどちらかを選択します。

  • 検証目的では「Pay as you go」を選び、「Choose pay-as-you-go」をクリックします
CloudFrontディストリビューション作成のプラン選択画面 ── Pay as you go を選択した状態
CloudFrontディストリビューション作成のプラン選択画面 ── Pay as you go を選択した状態

Flat-rate plans を選ぶと、トラフィックの有無にかかわらず月額の定額料金が発生します。検証用のディストリビューションでは従量課金を選びます。

ステップ2: Get started

  • Distribution name: geo-restriction-lab
  • Distribution type: 「Single website or app」(デフォルト)
  • ドメインの項目は空のままにします(CloudFrontのデフォルトドメインを使います)
  • 「Next」をクリックします

ステップ3: Specify origin

  • Origin type: 「Amazon S3」を選択します
  • S3 origin: geo-restriction-lab-<アカウントID>.s3.ap-northeast-1.amazonaws.com を入力します(「Browse S3」からバケットを選ぶこともできます)
  • 「Allow private S3 bucket access to CloudFront – Recommended」にチェックが入っていることを確認します。これがOACの設定で、CloudFrontがS3バケットポリシーを自動的に更新します
  • 「オリジン設定」「Cache settings」は推奨設定(Use recommended …)のままにします
  • 「Next」をクリックします
CloudFrontディストリビューション作成のオリジン指定画面 ── S3オリジンとOACの設定
CloudFrontディストリビューション作成のオリジン指定画面 ── S3オリジンとOACの設定

ステップ4: Enable security

  • 「セキュリティ保護を有効にしないでください」を選択します(AWS WAF は使いません)
  • 「Next」をクリックします

ここで「セキュリティ保護を有効にする」を選ぶと AWS WAF のウェブ ACL が作成され、月額の利用料が発生します。

ステップ5: Review and create

  • Billing が「Pay-as-you-go ($0/month)」、Grant CloudFront access to origin が「Yes」になっていることを確認します
  • 「Create distribution」をクリックします

ディストリビューションが作成されると、詳細画面にディストリビューションドメイン名(dxxxxxxxxxxxxx.cloudfront.net)が表示されます。デプロイが完了するまで数分かかります。

CloudFrontディストリビューション作成完了画面 ── ディストリビューションドメイン名が表示されている状態
CloudFrontディストリビューション作成完了画面 ── ディストリビューションドメイン名が表示されている状態

デフォルトルートオブジェクトの設定

現在の作成ウィザードにはデフォルトルートオブジェクトの入力欄がないため、作成後に設定します。

  • ディストリビューションの詳細画面で「一般」タブを選択します
  • 「設定」セクションの「編集」をクリックします
  • 「デフォルトルートオブジェクト」に index.html を入力して保存します

これで https://<ディストリビューションドメイン名>/ にアクセスしたときに index.html が返るようになります。

手順3: S3バケットポリシーを確認する

手順2で「Allow private S3 bucket access to CloudFront」を有効にしたため、S3バケットポリシーにOACを許可するポリシーが自動的に設定されています。

  • S3コンソールに移動し、バケット(geo-restriction-lab-<アカウントID>)の「アクセス許可」タブを選択します。
  • 「バケットポリシー」セクションで、以下のようなポリシーが設定されていることを確認します。
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::geo-restriction-lab-<アカウントID>/*",
            "Condition": {
                "ArnLike": {
                    "AWS:SourceArn": "arn:aws:cloudfront::<アカウントID>:distribution/<ディストリビューションID>"
                }
            }
        }
    ]
}

プリンシパルがIAMユーザーではなくサービスプリンシパル cloudfront.amazonaws.com になっており、AWS:SourceArn 条件で「このディストリビューションからのリクエストであること」まで絞り込まれています。これがOACのポリシーです。

S3バケットポリシー画面 ── OACを許可するポリシーが設定されている状態
S3バケットポリシー画面 ── OACを許可するポリシーが設定されている状態
クラウドおさる

自動で入ったバケットポリシーは、プリンシパルが cloudfront.amazonaws.com で、AWS:SourceArn でこのディストリビューションに絞られているのでござる。どの CloudFront でもよいわけではない、という点が OAC の要でござるな。

手順4: CloudFrontに地理的制限を設定する

  • CloudFrontコンソールに移動し、手順2で作成したディストリビューションをクリックします。
  • 「セキュリティ」タブを選択します。
  • 一番下の「CloudFront geographic restrictions」は折りたたまれています。見出しをクリックして展開し、「Edit」をクリックします。
  • 以下を設定します。
  • Restriction type: 「Block list」を選択(「No restrictions」「Allow list」「Block list」の3択)
  • 国: 「Select countries」のプルダウンから拒否する国を選びます(例: テスト用に日本以外の任意の国を追加)
CloudFront地理的制限の編集画面 ── Block list を選択し、拒否する国を指定した状態
CloudFront地理的制限の編集画面 ── Block list を選択し、拒否する国を指定した状態
  • 「変更を保存」をクリックします。
  • ディストリビューションのステータスが「デプロイ中」に変わります。デプロイが完了するまで数分待ちます。

手順5: アクセスの動作を確認する

CloudFront経由のアクセス確認

  • ブラウザで CloudFrontのディストリビューションドメイン名(https://dxxxxxxxxxxxx.cloudfront.net)にアクセスします。
  • 日本からのアクセスが拒否リストに含まれていなければ、index.html の内容が正常に表示されます。
ブラウザでCloudFrontドメインにアクセスした結果 ── index.htmlの内容が正常に表示されている状態
ブラウザでCloudFrontドメインにアクセスした結果 ── index.htmlの内容が正常に表示されている状態

S3バケットへの直接アクセス確認

  • ブラウザでS3バケットのURLに直接アクセスします。
  • https://geo-restriction-lab-<アカウントID>.s3.ap-northeast-1.amazonaws.com/index.html
  • OACによるバケットポリシー制限により、403 AccessDenied エラーが返されることを確認します。
S3バケットURLに直接アクセスした結果 ── 403 AccessDenied エラーが表示されている状態
S3バケットURLに直接アクセスした結果 ── 403 AccessDenied エラーが表示されている状態

これにより、S3バケットに直接アクセスしてCloudFrontの地理的制限を迂回することが不可能であることを確認できます。ブラウザではXMLのエラーレスポンスがそのまま表示されます。

地理的制限による拒否の確認

拒否リストに指定した国からアクセスした場合、CloudFrontは以下のようなエラーレスポンスを返します。

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
</Error>

HTTPステータスコード403とともに、CloudFrontのエッジロケーションでリクエストが拒否されます。オリジンのS3バケットにはリクエストが到達しません。

CloudFrontの地理的制限はエッジロケーションで処理されるため、オリジンに負荷をかけることなく不要なトラフィックを遮断できます。

クラウドおさる

国別に配信を止めたいとき、バケットポリシーの aws:SourceIp や Route 53 の地理的位置ルーティングと取り違えないか、が問われる観点でござる。エッジで止める地理的制限と、迂回を塞ぐ OAC の組み合わせで答えるのでござるな。

まとめ

  • CloudFrontの地理的制限は、エッジロケーションレベルで国単位のアクセス制御を行う機能で、許可リストと拒否リストの2つのアプローチがある
  • 国の判定にはMaxMind社のGeoIPデータベースが使用され、リクエスト元のIPアドレスから自動的に判定される
  • OACを使用してS3バケットへのアクセスをCloudFront経由のみに制限することで、地理的制限の迂回を防止できる。バケットポリシーはサービスプリンシパル cloudfront.amazonaws.com と AWS:SourceArn 条件で構成される
  • S3バケットポリシーの aws:SourceIp による国別制限は、CloudFront経由のアクセスではエンドユーザーのIPアドレスを取得できないため不適切
  • Route 53の地理的位置ルーティングは、IPアドレス直接指定による迂回が可能なため単独では不十分
  • CloudFrontの地理的制限 + OAC の組み合わせが、国別コンテンツ制限の推奨アーキテクチャ(OAIはレガシーで、現在の作成ウィザードでは選択できない)

参照先

フリーランス案件
クラウドおさる
クラウドキャリアフリーランス

AWS の実務経験があるなら、単価を上げにいく

AWS に特化したフリーランスエージェントです。以下は取り扱い案件の一例です。設計・SRE・セキュリティ・生成 AI の領域で、専門を掛け合わせるほど単価が上がります。

横にスクロールできます。掲載時点の情報のため、募集が終了している場合があります。条件の近い案件をご紹介しますので、お気軽にご相談ください。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次