はじめに

AWS上にあるWebサイトなどにIP制限をかけたい場合、AWS WAFを使用することで制限をかけることができます

これはAWSの公式ページをはじめ、検索するとたくさんの記事が出てきます
https://repost.aws/ja/knowledge-center/waf-allow-my-ip-block-other-ip

今回自分もWAFを使用したIP制限を実装することになったのですが、単純なIP制限であってもルールの書き方や適用順序について色々考えることがありました

この記事ではAWS WAFのコンポーネントや機能について解説した後、IP制限の定義方法を2パターン紹介します
そして、この2パターンの挙動の違いについても補足していきます

前提知識:WAFのコンポーネントや機能について

まずは、今回の記事を読むにあたって最低限必要な前提知識を整理します

Web ACLとルール

まずAWS WAFでは、WAF本体のことを「Web ACL」と呼んでいます
このWeb ACLに対して、複数のルールのセットである「ルールグループ」をアタッチすることができます

実際の設定としては、以下のようにWeb ACLに優先度を設定した複数のルールグループをぶら下げていきます

そしてルールグループの中には、複数のルールを追加することができます

また、WAFのルールグループには大きく分けて4つの種類があります

  • ユーザー独自のルールグループ
    • ユーザーが独自にルールを作成して管理する
  • AWS マネージドルールチームが作成して管理するマネージドルールグループ
    • AWSがAWS WAF用にあらかじめ作成してくれているルールグループ
  • AWS Marketplace 販売者がお客様に代わって作成、管理するマネージドルールグループ
    • Marketplaceでサードパーティの企業などが販売しているルールグループ
  • 他のサービスが所有および管理するルールグループ
    • Firewall Manager または Shield Advancedで管理しているルール

参考:https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-rule-groups.html

この4種類のルールをあれこれ組み合わせることで、要件に合ったWAFのルールを設定していきます

AWS WAF用のマネージドルールも結構充実していますので、1,2つ目のルールグループを使うことで大体の要件を満たすことができると思います
3,4つ目は特殊な要件やAWS環境によって適宜カスタマイズするようなイメージで良いと思います

ルールアクションとルールステートメント

WAFのルールを作る時には、ルールアクションとルールステートメントを使います

ルールアクションにはAllow、Block、Count、CAPTCHAand Challengeの4種類があり、定義された条件に一致した時の処理を定義します
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-rule-action.html

ルールステートメントはアクションを適用するリクエストの条件のことで、IPアドレスやヘッダーなどのコンポーネントと、AND, OR, NOTの論理演算子を組み合わせて定義します
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-rule-statements.html

以下が、実際のルールアクションとルールステートメントの詳細画面です

デフォルトアクション

ルールグループそれぞれにおいて定義するルールアクション以外に、Web ACLのデフォルトアクションというものがあります
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/web-acl-default-action.html

これは、設定したルールがどれも適用されなかったトラフィックに対する処理を定義するもので、AllowかBlockが選択できます

デフォルトアクションをAllowにしておくと、「定義したルールで検査した結果、特に異常がなければOK」という挙動をします
逆にデフォルトアクションをBlockにしておくと、「基本全てのトラフィックは拒否、ルールで検査した結果OKになればアクセス許可」という挙動をします

イメージとしては、Allowの場合はブラックリスト形式のルール、Blockの場合はホワイトリスト形式のルールと思ってもらうと良いと思います

IPsets

ルールステートメントの中でIPアドレスのリストを使用したい場合には、WAFのIPsetsという機能を使用します
IPsetsは名前の通りIPアドレスのリストで、WAFのルールで使用するIPアドレスを管理することができます

ステートメントの中でIPsetsを使用することで、とある企業や拠点で使用しているIPアドレスに対して特定のルールを指定することができます

IP制限ルールの作り方

では実際にIPアドレスを制限する方法を記載していきます
ルールの定義の仕方として2パターンが考えられますが、挙動が微妙に変わってきます

パターン別に挙動の違いも合わせて説明していきます

パターン①:IPsetsに含まれているアドレスだけを許可、デフォルトアクションはBlock

これは一番シンプル、かつ最初に思いつくルールの書き方だと思います

以下のようなルールを定義し、Web ACLのデフォルトアクションをBlockにしておきます

このルールのメリットとしては、ルールが直感的でわかりやすいという点が挙げられると思います
ただこのルールを使用するときに気をつけて欲しいのは、Web ACLの中でのルールの適用順序です

例えば、以下のようなルールグループ設定をしたとします

Web ACLのルールグループ、およびルールグループ内の各ルールには以下のような決まりがあります

ウェブリクエストと照合してウェブ ACL AWS WAF またはルールグループを評価する場合、優先順位が最も低いものから順に、一致するものが見つかって評価を終了するか、すべてのルールを使い果たすまで、ルールを評価します。
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/web-acl-processing-order.html

上記の例で考えると、優先度0のIP制限のルールip_restriction_ruleに一致した瞬間にWAFの処理が終了します

今回ルールに一致する条件というのは、「許可しているIPアドレスで接続してきた場合」です
つまり、許可したIPで接続した場合はip_restriction_ruleだけ適用されて処理が終了、優先度1, 2, 3のマネージドルールが適用されません

ざっくり言ってしまうと、「IPアドレスさえ正しければOK!」というルールになります

これが良いかどうかは要件次第ですが、もしも許可したIPを持ったユーザーが何らかの悪意を持ってアクセスしてきた場合には対処しようがありません
ゼロトラストの考え方に則ると完全にアンチパターンです

パターン②:IPsetsに含まれていないアドレスをブロック、デフォルトアクションはAllow

このパターンは少し理解しにくいですが、「IPsetsに含まれてないIPアドレスからのトラフィックを全てブロックする」というルールです

以下のようなルールを定義し、Web ACLのデフォルトアクションをAllowにしておきます

パターン①との違いを考えるとルールの適用順序が関係してきますので、先ほどと同じルール設定の例で考えてみます

この例は、優先度0のIP制限のルールip_restriction_ruleに一致した瞬間にWAFの処理が終了します

今回だと、ルールに一致する条件というのは「許可していないIPアドレスで接続してきた場合」です
つまり、許可したIPで接続した場合はip_restriction_ruleが適用されず、そのまま優先度1, 2, 3のマネージドルールも適用されます

ざっくり言ってしまうと、「IPアドレスが正しくても他のルールでチェックしますよ!」というルールになります

もしも許可したIPを持つユーザーが何らかの悪意を持ってアクセスした場合であっても、他のルールで弾くという実装も可能です

まとめ

以上、IP制限ルールの2パターンについて解説しました
ゼロトラストの考え方に則ったルール設計になりますので、特に要件がなければパターン②にした方が良いと思っています

このブログが誰かの助けになれば幸いです