AWS

AWS CloudFront 〜 ALB 〜 Webサーバ間で一連のアクセス制限を行う CFはIP制限 & ALBはCF経由のアクセスのみ許可 & サーバはALB経由のみ許可

以下のようなインフラ構成の各ポイントにおいて、それぞれ表題のアクセス制限をかけてみます。

CloudFront〜ALB〜Webサーバのインフラ構成図

【クライアント〜CloudFront間】

WAFを使用して社内IPのみ許可します。

アクセス制限はIPでの判定以外にもURLクエリに特定の文字が含まれているかで判定したり、リクエスト送信元の国で判定することが可能です。

【CloudFront〜ALB間】

外部からALBへ直接アクセスすることを禁止します。

HTTPヘッダにCloudFrontで設定したTokenもどきの文字列があるときのみ許可します。

【ALB〜Webサーバ(EC2)間】

外部からWebサーバへ直接アクセスすることを禁止します。

セキュリティグループでALB経由のアクセスのみ許可します。

スポンサーリンク

アクセス制限の設定手順

セキュリティグループの作成

EC2とALBにそれぞれ割り当てるセキュリティグループを作成します。
基本的な手順は、こちらのセキュリティグループの作成 を参考にしてください。

ALB用セキュリティグループの作成

HTTP80番ポートをソース0.0.0.0/0で作成します。

AWSマネジメントコンソールのインバウンドルール設定画面


EC2用セキュリティグループの作成

最初は戸惑うかもしれませんが、HTTP80番ポートのソースに上記で作成したALB用セキュリティグループ自体を指定します。

カスタムを選択するとセキュリティグループの候補が自動的に表示されます

AWSマネジメントコンソールのインバウンドルール設定画面

EC2の作成

最終的なアクセス先となるWebサーバを作成します。

基本的な手順は、こちらのEC2作成を参考にしてください。

当該手順の ステップ 6: セキュリティグループの設定 で、今回作成した、EC2用セキュリティグループ を割り当てください。

ALBの作成

ALB(アプリケーションロードバランサー)を作成します。

ベースとなるALBの作成

基本的な手順は、こちらのロードバランサー作成 を参考にしてください。

当該手順の セキュリティグループの割り当て で、今回作成したALB用のセキュリティグループを割り当てください。


リスナールールの設定

ALBにリスナールールを設定します。

左ペイン [ ロードバランサー ] → [ リスナータブ ] → [ ルールの表示/編集 ] をクリックします。

AWSマネジメントコンソールのロードバランサー設定画面


アクセス制限のルールを追加

次の画面で、画面上部の [ ] アイコン → [ ルールの挿入 ] をクリックします。

[ IF(すべてに一致) ] → [ 条件の追加 ] → [ HTTPヘッダー ] を選択し、header typeに X-Test-Token 、値に test1234 を入力します。

[ THEN ] → [ アクションの追加 ] → [ 転送先 ] を選択し、今回作成したEC2を選択します。

上記設定したら画面上部の [ 保存 ] ボタンを押します。

デフォルト動作の変更

次に、画面上部の [ えんぴつ ] アイコン → [ HTTP 80: デフォルトアクション ] の左の[ えんぴつ ] アイコン をクリックします。

[ THEN ] → [ 転送先 ] の [ ゴミ箱 ] アイコンクリック → [ アクションの追加 ] → [ 固定レスポンスを返す ] → [ レスポンスコード ] に 404 を入力します。

上記設定したら画面上部の [ 更新 ] ボタンを押します。


最終的に、以下のようになっていればOKです。

AWSマネジメントコンソールのリスナールール設定画面


WAFの作成

CloudFrontにIP制限をかけるWAFを作成します。

まずIP Setsを作成しそれをACLに割り当てる流れですすめます。

IP sets の作成

まずアクセスを許可するIPリストを定義します。

画面上部検索窓 [ WAF ] で検索 → 当該サービスをクリック → 左ペインの [ IP sets ] をクリック → プルダウンで [ Global(CloudFront)]を選択 → [ Create IP set ] をクリックします。

AWSマネジメントコンソールのWAF設定画面


次の画面で以下のように入力します。 [ IP addresses ] が複数ある場合は以下のように複数行に渡って入力します。

AWSマネジメントコンソールのWAF設定画面

Web ACLs の作成

IP Setsと同様に [ Global(CloudFront)]を選択、 [ Create web ACL ] をクリックします。

AWSマネジメントコンソールのWAF ACL設定画面
Describe web ACL and associate it to AWS resources
Web ACL details

以下のとおり設定します。

項目
Nametest-acl
CloudWatch metric nametest-acl
Resource typeCloudFront distributions
Region自動的に Global(CloudFront) が選択される
Associated AWS resources – optional

特になにも追加せずデフォルトのまま [ Next ] をクリックします。

Add rules and rule groups
Rules

Add my own rules and rule group を選択します。

AWSマネジメントコンソールのWAF ACL設定画面

次の画面で以下のとおり設定します。

Add my own rules and rule groups
Rule type

IP set を選択します。

Rule

Name に test-rule を入力します。

IP set

以下のとおり設定し [ Add rule ] をクリックします。

項目
IP set作成した test-ip-set を選択
IP address to use as the
originating address
Source IP address
ActionAllow

Default web ACL action for requests that don’t match any rules

[ Default action ] で Block を選択し [ Next ] をクリックします。

Set rule priority

test-rule にチェックを選択し [ Next ] クリックします。

Configure metrics

Amazon CloudWatch metrics と Request sampling options は、それぞれ利用するならば適宜チェックを入れ [ Next ] をクリックします。

CloudFront作成

最後にCloudFrontを作成します。

画面上部検索窓 [ CloudFront ] で検索 → 当該サービスをクリック → 左ペインの [ ディストリビューション ]  →  [ ディストリビューションを作成 ] をクリックします。

次画面で以下のとおりに設定し、画面下部の [ ディストリビューションを作成 ] をクリックします。明記していないものはデフォルトのままでOKです。

オリジン

項目備考
オリジンドメイン 作成したALBのドメイン自動で候補が表示されます
カスタムヘッダー
ヘッダ名
X-Test-Token[ ヘッダーを追加 ] をクリックして表示します
カスタムヘッダー
ヘッダ値
test1234[ ヘッダーを追加 ] をクリックして表示します

設定

項目備考
AWS WAF ウェブ ACLtest-acl作成したACLです。自動で候補が表示されます

テスト

これで構築完了したのでCurlコマンドで、それぞれのポイントにアクセスしてみます。

EC2へリクエスト

まずEC2への直接アクセスはタイムアウトとなります。

% curl -m 2 -w '%{http_code}\n' http://xxxxxxx.ap-northeast-1.compute.amazonaws.com 
000
curl: (28) Connection timed out after 2000 milliseconds
%

ALBへリクエスト

ALBへのアクセスはヘッダのX-Test-Token がない場合や、値が間違っている(今回は、test1234 以外)場合、404となります。

% curl -m 2 -w '%{http_code}\n' http://xxxxxxx.ap-northeast-1.elb.amazonaws.com/
Not Found404
% 
% curl -m 2 -w '%{http_code}\n' -H 'X-Test-Token:testoreore' http://xxxxxx.ap-northeast-1.elb.amazonaws.com/
Not Found404
%
% 
### ヘッダを正常に指定すればOK
% curl -m 2 -w '%{http_code}\n' -H 'X-Test-Token:test1234' http://xxxxxx.ap-northeast-1.elb.amazonaws.com/
Hello World.
200
%

CloudFrontへリクエスト

CloudFrontへのアクセスは許可IPではない場合、403でCloudFrontデフォルトのエラー画面が表示されます。

% curl -m 2 -w '%{http_code}\n' https://xxxxxx.cloudfront.net/ 

....

Generated by cloudfront (CloudFront)
Request ID: xxxxxxxxxyyyyyyyyyzzzzzzzz==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>403
%
% 
### 許可IPの端末からのリクエストであればOK. 成功レスポンス。
% curl -m 2 -w '%{http_code}\n' https://xxxxxx.cloudfront.net/ 
Hello World.
200
%

Tips

CloudFrontのIPレンジはこちらで確認できます。

のでALBのリスナールール(やWAF)を利用すればCloudFront〜ALB間はIP制限はできそう。
(Terraform ではこちらのタイプを使用することでIPレンジを取得できます。)

だがこのIPレンジが固定とは特に書いてないので変動があった場合、事故る可能性があるので、今回のような、ヘッダへのTokenもどきセットが無難でしょうか。。。

今回は以上です〜ノシ

参考

〃 ̄∇)ゞアリガトォーーーーーーーーーーーーーーー♪

AWS WAFV2でIPアドレス制限してみた
CloudFront専用のALBをリクエストルーティングで設定してみた
CloudFront エッジサーバーの場所と IP アドレス範囲
AWS WAF