CloudFrontとEC2を直接つないでWAFでIP制限する

目次

CloudFront と EC2 を 直接 つないで WAF でIP制限します。
普通は取らない構成ですが、興味があったので自分用のEC2ひとつを実験台にしてやってみました。

概要

メインの内容はEC2とCloudFrontを直接つなぐことです。
結論から言うと、EC2のパブリックIPv4 DNSをCloudFrontのオリジンドメイン名に指定することで実現できます。

ここからは東京リージョンで作業します。

EC2 準備

インスタンス起動

以下のようにEC2を起動しました。

  1. Amazon Linux 2 - 64ビット (x86)
  2. t3.micro ( 無料枠ある方は t2.micro でも )
  3. セキュリティグループ名cloudfront-ec2とし、2つルールを追加
    • SSH・マイIP
    • HTTP・Anywhere-IPv4(任意の場所)
  4. 任意のキーペア指定

他の項目はデフォルトのままです。
EC2が野ざらしになるのですが、ここの修正は最後にやります。

Webサーバーインストール

適当なWebページが開けるようにApache2.4をインストールしておきます。
SSHして以下を実行します。

sudo yum -y update
sudo yum -y upgrade
sudo yum -y install httpd
sudo systemctl start httpd

# サービスが自動起動するように設定する
sudo systemctl enable httpd

# Apacheのバージョン確認
httpd -v
# Server version: Apache/2.4.52 ()
# Server built:   Dec 30 2021 21:40:08

http://{インスタンスのパブリックIPv4 DNS}にアクセスして、Apacheのテストページが表示されればOKです。
※http://でアクセスします。

CloudFront 準備

以下のように作成しました。

  1. オリジンドメイン:EC2のパブリックIPv4 DNS
  2. プロトコル:HTTPのみ
  3. ビューワープロトコルポリシー:HTTP and HTTPS
  4. 許可された HTTP メソッド:GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
  5. Cache policy and origin request policy (recommended) を選択
  6. キャッシュポリシー:CachingOptimized

他はデフォルトのままです。
ちなみに「AWS WAF ウェブ ACL - オプション」は後で設定します。

(私みたいな)せっかちな人は気をつけて。
CloudFrontはすぐに使えるようになりません。
作成後にディストリビューション一覧を見ると、最終変更日が「デプロイ」になっているかもしれません。
「有効」になるまで待ちませう。

CloudFrontが有効になったら、https://{CloudFrontのドメイン名}でブラウザからアクセスしてみます。
※HTTPSでアクセスします。

Apacheのテストページが表示されればOKです。

Apacheのデフォルトページ

WAF でIP制限

IPセット定義

最後にWAFを使ってホワイトリスト形式でIP制限します。
ここでは自分のIPのみ許可するようにしてみます。

  1. WAFのホームへアクセス
  2. サイドメニューからIP setクリック
  3. Create IP setの左隣のプルダウンからGlobal (CloudFront)を選択してCreate IP set
  4. IP set name:適宜入力(例:developer-ipset)
  5. Region:Global (CloudFront)
  6. IP version:IPv4
  7. IP addresses:アクセスを許可したいIPを入力(例:自宅のIP/32)
IP setsの登録

Web ACL作成

作成したIPセットを使ってWebACLを作成します。

  1. サイドメニューから「Web ACLs」クリック
  2. プルダウンからGlobal (CloudFront)を選択してCreate web ACL
  3. 先にフォームの上から4番目のResource type → CloudFront distributions
  4. Resorce:適宜入力(例:developer-web-acl)
  5. CloudWatch metric name:リソースと同じ
  6. Associated AWS resources で Add AWS resources
  7. 先ほど作成したCloudFrontを選択して Add して Next
  8. Add Rules から Add my own rules and rule groups を選択
  9. IP set を選択
  10. Rule:適宜入力(例:allow-ipset)
  11. IP set:先ほど作成したIPセットを選択
  12. Source IP Address・Allowを選択してAdd rule
  13. Default action:Block して Next
  14. Set rule priorityはデフォルトのままで
  15. Configure metricsはデフォルトのままで
  16. Review and create web ACLで内容を確認してCreate web ACL
Web ACLs登録

CloudFront との紐づけを確認

CloudFrontのディストリビューション詳細の 一般 → 設定 で
WAFのWebACLが適用されているのがわかります。
これで準備ができたので、CloudFront経由でEC2にアクセスして確認しましょう。

これで当初の目的が達成できました。
次に、EC2のアクセス制御をしていきます。

WAFが適用されているのを確認(おまけ)

さっきからずっとアクセスできていたので、WAFがちゃんと機能しているかわかりにくいですね。
そこで、先ほどWEbACLで定義したIPセットのアクションをBlockに変更してみます。

WebACL で
 → 作成したACL
 → Rulesタブ
 → 該当のIPセット
 → 右上のEdit
 → Action を BlockにしてSave

自分のIPをブロックしたので、再びアクセスすると「403」エラーでアクセスできなくなりました。

403 Forbiddens

WAFがちゃんと機能していることがわかりました。
BlockしたのをAllowに戻しておきましょう。

EC2のアクセス制御

具体的にすることは
CloudFrontにカスタムヘッダーを追加し、Apache側でカスタムヘッダーが確認できたらアクセスを許可
するように設定します。

CloudFrontにカスタムヘッダー追加

CloudFrontのディストリビューション詳細を開き、オリジンタブから該当のオリジンを編集します。
カスタムヘッダーのキーと値は内緒です。
あとで使うので忘れないでください。

カスタムヘッダー追加

Apacheのバーチャルホストの設定を追加

既存の設定ファイルはそのままにして、以下のような内容で/etc/httpd/conf.d/vhost.confを作成します。
作成済みの方は、一番上に追加します。
2.2では書き方が違うかもしれないので注意です。

<VirtualHost *:80>
  <Location '/'>
    SetEnvIf カスタムヘッダ "カスタムヘッダの値" ALLOW_ACCESS
    Require all denied
    Require env ALLOW_ACCESS
  </Location>
</VirtualHost>

Apacheの設定ファイルに大事な値を直書きしていますが今回はこれで。
設定ファイルを変更したら、Apacheを再起動します。

sudo service httpd restart

アクセス確認

Forbiddens
Test Page

まとめ

CloudFrontのオリジンドメイン名にEC2のパブリックIPv4 DNSを指定して、直接つなげることができました。

最後までお読みいただきありがとうございました。
参考になれば幸いです。