ALBへのアクセスをCloudFront経由のみに制限してみた
以前、
パブリックなALBからプライベートなEC2にアクセスしてみた
という記事を書いた際、
CloudFrontを合わせて、CloudFront経由のアクセスのみ許可し、EC2、ALBの直接アクセスは禁止するということもできる
と記載したので、今回はその方法を紹介します。
構成図

・EC2はプライベートサブネットに設置
・EC2へのアクセス制限はセキュリティグループで実施
・ALBはパブリックサブネットに配置
・ALBへのアクセス制限はリスナールールで実施
・CloudFrontのオリジンにALBを指定
前提
・VPCは10.0.0.0/16で作成済み
・プライベートサブネットは10.0.10.0/24で作成済み
・パブリックサブネットは10.0.1.0/24と10.0.2.0/24で作成済み
EC2作成~ALB作成
パブリックなALBからプライベートなEC2にアクセスしてみた
を参考に構築してください。
なお、最終的に表示されるページがApacheのデフォルトページでもよければ、SSMセッションマネージャーでEC2に接続するための作業は不要です。
CloudFront作成
まずはCloudFrontコンソールに移動しましょう。

「CloudFrontディストリビューションを作成」をクリックします。

オリジンにALBを指定します。

カスタムヘッダーを追加します。
ヘッダー名、値は任意の文字列を入力します。
今回はテストなので適当ですが、本番環境では推測されにくい文字列がよいと思います。

その他の設定はデフォルトのままにしておき、「ディストリビューションを作成」をクリックします。

作成直後は「デプロイ」状態となりますが、しばらくすると利用可能になります。


この状態でアクセスすると、Apacheのデフォルトページが表示されます。

CloudFrontの設定は以上でOKです。
ALBのリスナールール編集
続いてALB側の設定を変更しますが、その前に現時点でALBのDNS名でアクセスしてみましょう。
こちらでもApacheのデフォルトページが表示されるはずです。
リスナールールを変更することで、これが表示されないようにしていきます。

ALBの「リスナー」タブから「ルールの表示/編集」をクリックします。

新しいルールを追加します。

IFで「HTTPヘッダー」を選択し、CloudFront作成時に指定したキーと値を入力してチェックアイコンをクリックします。
THENで「転送先」を選択し、ALBのターゲットグループを選択してチェックアイコンをクリックします。

この状態でいったん「保存」をクリックします。

続けてデフォルトルールを編集します。

THENを一度削除します。

「アクションの追加」から「固定レスポンスを返す」を選択します。

任意のレスポンスコードと文章を入力して、チェックアイコンをクリックします。

これで「更新」をクリックします。

以上でリスナールールを変更できたので、元の画面に戻って確認してみましょう。

ALBのDNS名でアクセスしてみると、503が返ってきました。
CloudFrontを経由していないため、デフォルトルールに設定した503が返ってきたというわけです。

それではCloudFront経由でアクセスしてみましょう。
こちらはApacheのページが表示されました。
ヘッダールールが一致しているので追加したリスナールールによりEC2インスタンスにルーティングされています。

EC2インスタンスはプライベートサブネットに設置したため、もちろんインターネットからの直接アクセスはできません。

これで、CloudFront経由以外のアクセスは禁止することができました!
まとめ
今回はALBへのアクセスをCloudFront経由のみに制限してみました。
簡単にまとめると以下の設定を行うことで実現しました。
・CloudFront - ALB間はヘッダーとリスナールールで制限
・ALB - EC2間はセキュリティグループで制限
通信面で見ると、ユーザー - CloudFront間はHTTPSですが、CloudFront - ALB間はHTTPのままなので、ALBまでをHTTPSにする方法も今度紹介したいと思います。
今回の内容がどなたかの参考になれば幸いです。
後片付け
以下を削除しておきましょう。その他、EC2用のIAMロールやVPCも不要であれば削除してください。
・EC2インスタンス
・ALB
・CloudFront
参考資料
・パブリックなALBからプライベートなEC2にアクセスしてみた
・Application Load Balancers へのアクセスを制限する
Discussion