指定のURLに対して、IP制限を実施するCloudFront用のWAF設定をCloudFormationでさくっと作ってみた

2019.11.15

突然肌寒くなりIaCしたい季節になってきました。AWS事業本部の梶原@新福岡オフィスです。
今回は特定のURI(パス)に対して、IP制限を実施する機会があったので、
特定のURI(パス)の条件に対して、許可したいIPアドレスを指定してIP制限を実施するWAF設定をイイ感じに作成する CloudFormationのtemplateを作成したので共有します。

ピンポイントで用途にハマれば、ちょっっっぴり難しいWAFの設定も、サクッとできるようにしていますのでぜひ使ってみて頂ければと思います

では、サクサクいきます。

作成するWAF の設定について

ACLの作成

新しいACLを作成する場合

テンプレートの入力パラメータでCreateWebACLYesを選択した場合、指定したデフォルトアクションのACLを作成後、以下で作成するルールを紐づけます。

既存のACLに紐づける場合

CreateWebACLでNoを選択した場合、ACLは作成されませんので、以下で作成するルールを手動で紐づけます。

ルールの作成

今回のWAF設定では許可と拒否の2つルールを作ります。

  1. URI が 指定した文字列条件 かつ アクセス元がIPアドレス は許可
  2. URI が 指定した文字列条件 かつ アクセス元がIPアドレス 以外は拒否

になります。

WCLに対して、上記2つのルールを合わせて設定すれば、わかりやすく許可、拒否できます。 また、ログ等でそれぞれのルールで一致した条件は抽出されますので、検証もやりやすいです。 ただ、WAFはルールに対して課金されますので、わかりやすさとコストとのトレードオフにはなるかと思いますが、デフォルトのルールを拒否もしくは許可にして、1つのルールでも対応可能ですのでご案内しておきます。

なお、今回のCloudFormationでは

  • 特定のURIは1~3つまで登録可能
  • IPアドレスは1~3つ(CIDR)で登録可能

としています。それ以上の対応が必要な場合は、手動で追加するか、templateを公開しておりますので、ご自由に編集ください。

URIの文字列条件の指定方法について

制限したいURIのPathにより、作成する文字列一致条件のルールをカスタマイズできます。 通常は、Contains(パスのどこかに含まれる), Exactly Mutch(完全一致)、Starts with(前方一致) くらいから選ぶかと思います パラメータ指定についてCloudFormationでのパラメータとしていますので、以下を参照して条件に合ったものを選択してください

Transformation, BASE64等の指定を実施されたい場合は、ご自由に編集してください。 詳細な指定条件は下記の公式ドキュメントに準拠します

AWS ドキュメント » AWS WAF » 開発者ガイド » AWS WAF » ウェブアクセスコントロールリスト (ウェブ ACL) の作成と設定 » 条件の使用 » 文字列一致条件の使用 https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/web-acl-string-conditions.html

Contains (CONTAINS)

  • 文字列が、指定したリクエスト部分内(URI)の任意の場所に存在する

Contains word (CONTAINS_WORD)

  • 単語が、指定したリクエスト部分内(URI)の任意の場所に存在する

Exactly matches (EXACTLY)

  • 文字列が指定したリクエスト部分(URI)の値と正確に一致します。

Starts with (STARTS_WITH)

  • 文字列が指定したリクエスト部分(URI)の先頭に存在する

Ends with (ENDS_WITH)

  • 文字列が指定したリクエスト部分(URI)の末尾に存在する

IPアドレスリスト

WAF ではIpSetsに許可したい複数のIpアドレスをCIDR形式で登録することができます。 今回作成するCloudFormationのテンプレートでは、入力された3つのCIDRを登録した1つのIpSetsを作成します。

IPV4のアドレスのみを受け付けますので、IPv6のアドレスを指定したい場合は、Typeの部分をIPV6に編集してください。 特にチェックをはいれていませんので、CIDR表記として認識できない値が入力されると作成時にエラーとなりますのでご注意ください

AWS ドキュメント » AWS WAF » 開発者ガイド » AWS WAF » ウェブアクセスコントロールリスト (ウェブ ACL) の作成と設定 » 条件の使用 » IP 一致条件の使用 https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/web-acl-ip-conditions.html

CloudFormationの実行

スタックの作成

いつものようにS3においてますので、AWSにログイン後、下記ボタンをポチっとするとCloudFomationのスタック画面に遷移しますので、内容を確認後、スタックの作成をしてください

https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/quickcreate?templateUrl=https://pub-devio-blog-qrgebosd.s3.amazonaws.com/template/cfn-waf-uri-ipsets-rule.yml&stackName=WAF-URI-IPset-Rule

入力パラメータについて

CreateWebACL

WebACLを作成する/しない Yes/No

WebACLDefaultAction

作成するWebACLのデフォルトアクションになります。

IPAddress1 ~ IPAddress3

IP制限で、許可したいIPアドレスを入力します。不要な項目は空白にしてください

MatchType1 ~ MatchType3

制限したいURIの文字列条件の指定方法を入力します1~3はそれぞれ同じ番号のURIに対応します。不要な項目は空白にしてください

URI1 ~ URI3

MatchTypeの条件で制限したいURI(文字列)を入力します。

入力パラメータ例

  • WebACLを作成する
  • WebACLのデフォルト条件はブロック
  • 許可したいIPアドレスは 192.168.1.1/32, 192.168.1.2/32, 192.168.1.3/32
  • 制限したいパスは
    • /aaa で開始されている
    • bbbを含む
    • /ccc.htmlと完全に一致

作成されたルールの確認

正常にスタックとリソースが作成されますと以下のようにWAFのACL, Ruleまた、各条件が作成されますので、意図したルールが作成されているか確認してください

Web ACL

AWS コンソール https://console.aws.amazon.com/wafv2/home?region=global#/webacls

Rule

https://console.aws.amazon.com/wafv2/home?region=global#/rules

許可Rule

拒否Rule 'does not originate from'を確認してください

作成されたRuleをWAF ACLに関連付ける

WebACLを作成しなかった場合などは、既存のACLに紐づけてください。

IPアドレスが一致する条件はallow, IPアドレスが一致しない条件はBlockで設定します。

※ほぼタイムラグ等がなく制限が反映されますので、使用中のWebACLに紐づける場合は検証環境等などで確認後に実施してください

作成されたWebACLをCloudFrontに紐づける

作成したWebACLを制限を実施したいCloudFrontのディストリビューションに紐づけます。

確認

許可したIPアドレス、また許可していないIPアドレス以外でアクセスを行い制限が実施されているか確認をお願いします。

まとめ

パス変更等あった場合も、同一のIPリストで3つくらいまではパスを指定できるようにしているので CloudFormationのテンプレートの入力パラメータを変更してスタック更新すればさくっとすむ感じにしてみました。

また、このテンプレートの注意点としては、WAFの課金体系は使用されるルールの数で課金されます。 このCloudFormationのテンプレートでは、特定のURLに対して、IPアドレスのリストに含む、含まないの2つルールが作成されるので 課金を節約する際は、最終デフォルトのRuleに応じて、関連づけるRuleを工夫してみてください。

ただ、個人的にはIP制限されているパスに関しては、拒否の割合(IPアドレスなど)が知りたい時が往々にしてある。 また、条件が増えた場合、わかりにくくなっていくので2つ設定することをお勧めしておきます。 (IP制限を検証する際もDefualtの条件に埋もれずにわかりやすいので)

テンプレート

参考情報

[小ネタ]AWS WAFを使って特定のURLにIP制限を設定する。

[小ネタ]AWS WAFを使って特定のURLにIP制限を設定する。

AWS WAF セキュリティオートメーション https://aws.amazon.com/jp/solutions/aws-waf-security-automations/

AWS ドキュメント » AWS CloudFormation » ユーザーガイド » テンプレートリファレンス » AWS リソースおよびプロパティタイプのリファレンス » WAF リソースタイプのリファレンス » AWS::WAF::WebACL https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-waf-webacl.html

AWS ドキュメント » AWS CloudFormation » ユーザーガイド » テンプレートリファレンス » AWS リソースおよびプロパティタイプのリファレンス » WAF リソースタイプのリファレンス » AWS::WAF::ByteMatchSet » AWS::WAF::ByteMatchSet ByteMatchTuple https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-waf-bytematchset-bytematchtuples.html#cfn-waf-bytematchset-bytematchtuples-positionalconstraint