giftee Tech Blog

ギフティの開発を支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信しています。

ベストプラクティスを活用して、“なんとなく”の AWS WAF を卒業する

こんにちは、エンジニアの chota60 です。開発組織を横断した課題と向き合う Platform Unit という組織に所属しています。 組織をまたがって活用される認証基盤の立ち上げから展開までを担当し、日夜ログイン機能と向き合っています。

この記事では、私がそんなログイン機能と向き合う中で得た WAF に関する知見を共有します。

この記事の目的

AWS には、 AWS Security Services Best Practices というドキュメントが存在します。このドキュメントの良さを紹介することで、AWS WAF と真っ向から向き合う人を増やすことがこの記事の目的です。

AWS Security Services Best Practices には、 AWS WAF Best Practices という AWS WAF 向けのベストプラクティスも載っており、今回はそれに助けられた話をします。

役立ててもらえそうな読者

この記事は、AWS WAF についてこんな思いを持っている人を対象にしています。

  • AWS WAF の基本的な概念や枠組みがわからない
  • ACL を設定したが、あやふやな設定で不安だ
  • ぜんぜんわからない。俺たちは雰囲気で WAF をやっている

WAF って…… 雰囲気でやっていいのか!(ダメだと思います)

アプリケーションレイヤーでいろんな攻撃から防御したい、そのためには WAF を入れるといいらしい!これは・・・?どうやるのが正解なんだ・・・・?と思いながら最初はやっていました。 雑に設定しても、必要な Managed Rule さえ入っていればある程度防御として機能してしまうためです。

そこでスタートラインとして紹介するのが、前述の AWS Security Services Best Practices です。 サポートケースや専属 TAM とのやりとりで情報共有を受けるまで知りませんでしたが、どうやら AWS 公式で管理されているベストプラクティス資料なようです(なぜドキュメントにリンクを載せてくれないのか)。 このドキュメントのうち、 Configuration に関するところ をなぞるだけでも非常に大きな示唆があります。

WAF の前提になる知識なども言語化されているので全部に目を通すことをお勧めしますが、ここでは Configuration に関するところに絞って紹介します。

Configuration に関する示唆

AWS WAF の Terminating Action と Default Action

WAF の ACL では、 Count や Block といった、そのルールに合致した時どんな対応を行うのかを決める設定があります。 このうち、 Allow や Block は Terminating Action と呼ばれ、最終的な対応を決定するものになります。 そして、 Default Action の設定はどのルールにも合致しなかったリクエストの処理を決定するものです。

これを意識しないと、誤った条件で設定してしまうことがあります。特に、 Allow Action は非常に曲者です。

例えば、下図のようにルールを設定したとします。

waf_acl_sample ACL の設定イメージ

この場合、不適切な接続元 IP からのリクエストは防げるのですが・・・(想定していない IP からのアクセスは Allow されず Default Action で Block される)、

waf_acl_block_ip Allow action のルールが適用されず Default Action で Block されてしまいます

Allow のルールが先に適用されてしまうので、後続の Block ルールで評価することなく、許可している IP からのリクエストはどんなものでも許可してしまう ことになります。

waf_acl_allow_ip_miss_configuration Allow のルールが適用され、他の Block Action のルールは評価されません

Default Action は、 1 つも Terminating Action が適用されていない場合 のみに適用されるため、たとえ Block を Default Action としていても、評価された Allow がそのリクエストに適用されてしまいます。

そのため、例えば接続元 IP に制限をかけたい場合、「接続元 IP が特定の値の場合 Allow するルール」で設定するよりも、「接続元 IP が特定の値の場合でない場合 Block するルール」の方が確実に防ぎたいリクエストを防げそうです。

waf_acl_block_only Block Action のルールでリクエストを制限することで、IP 以外のルールと両立できます

このように、Action はクセがある仕組みであるということを知っておくことが重要です。

適用したいルールたちを Top, Middle, Bottom で段階に分けて整理する

ACL で設定可能なルールは大雑把に分類しても多くのパターンがあります

  • リクエスト先の Path
  • リクエストヘッダーのパターン
  • 特定時間内のリクエスト数による制限
  • Managed Rule によるルール指定
    • たくさんのルール

などなど・・・

これらを一律に並べて、優先度をつけていくのは非常に大変です。そのため、このドキュメントで示唆されているのがそれぞれのルールを Top, Middle, Bottom の段階に分けることです。

こういうとっ散らかったものを・・・

barabara_rules 適用したい ACL のルールを無節操に選択していくととっ散らかってしまいがちです

このように、それぞれの Rule の特性ごとに分類するイメージです。実際の設定では、 Top, Middle, Bottom でそれぞれの Priority の次元を分けるような対応になると思います(例: Top は 1~9, Middle は 10~99 , Bottom は 100~999 など)。

matomari_rules Top, Middle, Bottom で段階を分けることで整理できます

このように、大枠から整理し見通しをよくすることで設定の方針決めだけでなく、運用していく中での見直しの際にも役立てることができます。

また、新規でルールを追加したい場合、どこの段階に入れるのかを検討することから考え始めることができます。これによって、設定先の前後のルールと抽象度のすり合わせから始めることができるので、具体的な 「設計」として「設定」を考えることが可能になります

例えば、上記の ACL の設定に IP 制限のルールを追加するとしたら、このように考えれば良いはずです。

matomari_adding_rule 整理されたルールのどこに当てはめるのが適切なのかを考えながら、新規のルールを追加できます

ベストプラクティスから思想を学び、設定を設計する

AWS WAF の設定には、最低限基本的な仕組みだけを知っておけば困ることはありません。 しかし、より使いこなすためには、なんとなく設定するのではなく意図を持って設計を行い、それを設定に反映させるという流れが必要です。

そして、使いこなしの例としてベストプラクティスがあるならば、それに則ることで先に仕組みの思想を学習してしまうという方法が有効です。下駄を履きましょう。 もちろん、ベストプラクティスをそのまま読むだけではさっぱりわからない部分も出てきますが、例があればそれに則ってドキュメントを読めば良くなります。

AWS Security Services Best Practices で記載されていることは、一見さらっとした概要しか書いていません。 この記事で紹介していない項目でも同様ですが、記載されていることと向き合って考えてみると、非常に示唆が含まれており学ぶところが多く、そういった意味でとても良質なドキュメントだと思っています。

その一方でなんと、公式のコンテンツでここまで有用にもかかわらず、全然 Star がありません!!!(2024/12/04 時点で 101 しかない) ここまでお読みのそこのあなた!ぜひ Star だけは押して帰ってください!お願いします!継続的にメンテされてくれると自分がとっても助かります。
それではー!