
Cloudfront+ALB+S3+EC2+AWS WAFで海外IPからのアクセス時のみエラーページを表示する
お疲れ様です。MKです。
今回は、国内IPからのアクセスの場合はWebページを表示し、
海外IPからのアクセスの場合は、エラーページを表示させる方法が
AWSを使用すると意外と簡単にできたのでご紹介させていただきます。
リソースの用意
まず、AWSのコントロールパネルから必要なリソースの作成を行います。
今回は、Cloudfront+ALB+S3+EC2+AWS WAFの構成にて作成したいと思います。
CloudFrontを用意
通常の国内IPアドレスからのアクセスを流すのALB用と
海外IPアドレスからのアクセスを流すS3用の2つのオリジンを作成します。
設定はそれぞれ下記にて行います。
ALB用オリジンを作成
- オリジンドメイン
XXXX.ap-northeast-1.elb.amazonaws.com - プロトコル情報
HTTP のみ - HTTP ポート
80 - オリジンパス – オプション情報
空欄 - 名前
XXXX.ap-northeast-1.elb.amazonaws.com - カスタムヘッダーを追加 – オプション
なし - オリジンシールドを有効にする情報
いいえ - 追加設定
デフォルト設定

S3用オリジンを作成
- オリジンドメイン
XXXX.s3.ap-northeast-1.amazonaws.com - オリジンパス – オプション情報
空欄 - ・名前
XXXX.s3.ap-northeast-1.amazonaws.com - ・S3 バケットアクセス情報
Public - ・カスタムヘッダーを追加 – オプション
空欄 - ・オリジンシールドを有効にする情報
いいえ - ・追加設定
デフォルト設定

次に国内IPからのアクセスと海外IPからのアクセスを振り分けるための
ビヘイビアを作成します。
国内IPアクセス用ビヘイビアを用意
- パスパターン情報
デフォルト (*) - オリジンとオリジングループ
XXXX.ap-northeast-1.elb.amazonaws.com - オブジェクトを自動的に圧縮情報
Yes - ビューワープロトコルポリシー
HTTP and HTTPS - 許可された HTTP メソッド
GET, HEAD - ビューワーのアクセスを制限する
No - キャッシュキーとオリジンリクエスト
Legacy cache settings - ヘッダー
なし - クエリ文字列
なし - cookie
なし - オブジェクトキャッシュ
Use origin cache headers - レスポンスヘッダーポリシー – オプション
空欄 - 追加設定
関数の関連付け – オプション情報
ビューワーリクエスト
関連付けなし - ビューワーレスポンス
関連付けなし - オリジンリクエスト
関連付けなし - オリジンレスポンス
関連付けなし

海外IPからのアクセス用(エラーページ)ビヘイビアを用意
- パスパターン情報
forbidden.html - オリジンとオリジングループ
XXXX.s3.ap-northeast-1.amazonaws.com - オブジェクトを自動的に圧縮情報
Yes - ビューワープロトコルポリシー
HTTP and HTTPS - 許可された HTTP メソッド
GET, HEAD - ビューワーのアクセスを制限する
No - キャッシュキーとオリジンリクエスト
Legacy cache settings - ヘッダー
なし - クエリ文字列
なし - cookie
なし - オブジェクトキャッシュ
Use origin cache headers - レスポンスヘッダーポリシー – オプション
選択なし - 追加設定
関数の関連付け – オプション情報
ビューワーリクエスト
関連付けなし - ビューワーレスポンス
関連付けなし - オリジンリクエスト
関連付けなし - オリジンレスポンス
関連付けなし

これで、ビヘイビアの作成ができました。

次にCloudFront のカスタムエラーレスポンスにて、海外IPからのアクセス時のエラーページの設定をします。
海外IPからのアクセス時のエラーページを設定
- HTTP エラーコード
403: Forbidden - 最小 TTL のキャッシュエラー
300 - エラーレスポンスをカスタマイズ
はい - レスポンスページのパス
/forbidden.html - HTTP レスポンスコード
403: Forbidden
今度は、カスタムエラーレスポンスにて設定したエラーページを
S3バケットにアップロードします。
Amazon S3 > バケット > 対象バケット > エラーページ用ファイル(forbidden.html)を選択 > アップロード

アップロードしたforbidden.htmlの中身はこんな感じです。
<!DOCTYPE html>
<html>
<head>
<title>403</title>
<meta http-equiv="content-type" charset="utf-8">
</head>
<body>
<h1>403エラー</h1>
<p>海外IPの為、アクセスできません</p>
</body>
</html>
次にS3バケットのアクセス許可設定をしていきます。
Amazon S3 > バケット > 対象バケット > エラーページ用ファイル(forbidden.html)を選択 > アクセス許可
パブリックアクセスをすべて ブロックの☑を外して
バケットポリシーを下記に変更します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "", "Action": "s3:GetObject", "Resource": "バケット ARN/"
}
]
}

「アクセス許可の概要」が「公開」に変わりました。
最後にCloudFrontに国内IPからのアクセスのみを許可するAWS WAFを
設定して準備完了です。
※国内IPからのアクセスのみを許可するAWS WAFの設定方法に関しては
下記の記事をご参考ください
AWS WAFで海外IPからのアクセスを遮断する
AWS WAFで海外IPからのアクセスを遮断する
それでは、実際にアクセスをして結果を確認してみましょう。
●日本IPの場合
https://XXXX.cloudfront.net/

●海外IPの場合
https://XXXX.cloudfront.net/

同じURLへアクセスへアクセスしているにも関わらず
アクセス元IPアドレスの違いで表示されるページが変わることを確認できました。
今回は、単純に国内IPと海外IPで表示ページされるページを分けましたが
他にも設定の分け方次第で、色々と工夫をしてみるともっと面白いかと思います。
最後まで読んでいただき、誠にありがとうございました。
今後ともネットアシストをよろしくお願いいたします!