エンジニアのはしがき

プログラミングの日々の知見を書き連ねているブログです

CloudFrontで配信しているサイトをWAFでIP制限する

f:id:tansantktk:20211023152616j:plain

こんばんは! CloudFrontとS3の静的ホスティングでのWebサイト配信って設定は面倒ですが、コストが安く大変重宝しています。

最近CloudFrontでさくっと検証できる環境を用意したかったのですが、セキュリティ的に社内IP以外からアクセスさせたくないなぁと思い、WAFで実装してみた結果を書き残していきます。

やりたいこと

  • S3で静的ホスティングし、CloudFrontで独自ドメイン配信しているWebサイトに対し、特定のIPからのみしかアクセスできないようにする
  • アクセス制限にはWAFを利用する

IP制限にはALBをCloudFrontの前に噛まして、ALBのセキュリティグループで制限するといったアプローチも考えられますが、今回はシンプル目の方法です。

前提条件

  • CloudFrontは既に作成されて稼働しているものとします

WAFのIPSetを用意する

まずはIPSetの画面にて「Create IP set」を押します。

f:id:tansantktk:20211012202442p:plain

IP setでは事前に制御対象とするPublicIPを定義します。 IP setの名前には任意の名前を付け、今回はCloudFrontに制限をかけたいのでRegionはGlobal(CloudFront)を指定します。

最後にIP addressesの部分にはアクセスを許可したいIPを指定します。

f:id:tansantktk:20211012202542p:plain

webACLを作成する

IPSetが作成できましたので、CloudFrontに適用するためのwebACLを作成する為、「Create web ACL」を押します。

f:id:tansantktk:20211012203130p:plain

webACLの基本設定

webACLのName, CloudWatch metric nameには任意の名前を付けてあげ、Resource typeは「CloudFront distributions」を指定します。

Associated AWS resourcesには適用するCloudFrontを追加してあげます。 入力できたら「Next」で次へ進みます。

f:id:tansantktk:20211012203138p:plain

webACLへのルール追加

次の画面ではwebACLに設定するルールを入力します。 先ほど自分で定義したIPSetを元にルールを作りたいので「Add rules」から「Add my own rules and rule groups」を選びましょう。

f:id:tansantktk:20211012203154p:plain

するとルールの詳細設定画面が出てきますので、Rule typeには「IP set」を指定し、Nameは任意の名前を入力、IP setには前のステップで作成したIP setを指定してあげましょう。

ActionはIPが一致した場合の処理内容です。今回は指定したIPであればアクセスを許可したいので「Allow」を選びます。

最後に「Add rule」を押してルールの追加は完了です。

f:id:tansantktk:20211012203209p:plain

f:id:tansantktk:20211012203215p:plain

ルールにそぐわないアクセスへの対応

「Default web ACL action for requests that don't match any rules」にはルールにそぐわないアクセスに対してのアクションを指定します。今回はここを「Block」に指定し、指定のIP以外はアクセスを禁じます。

指定できたら「Next」で次へ進みます。

f:id:tansantktk:20211012203222p:plain

各種項目を入力する

その後も各種設定値を入力する画面が出てきますので、要件に応じて指定をしていき、最後にwebACLの作成を実行します。(当記事では省略)

適用されたか確認する

さて、CloudFrontにIP制限が正しくできたか確認してみます。

今回は手っ取り早く確認したかったので、iPhoneを4G通信にしてブラウザからアクセスさせてみました。 (4G通信のPublicIPは前ステップでアクセス許可したIPとは異なっています)

f:id:tansantktk:20211012203228p:plain

無事WAFによりアクセスが拒否されました😊