メインコンテンツまでスキップ

AWS WAFのチューニング手法

本記事の位置づけ

この記事は、AWS WAFを最初からBlockで入れて事故らせないためのチューニング手順を整理するものなのだ。

AWS Managed Rulesの選定、WCU計算、Countでの観測、誤検知調整、scope-down statement、label match、本番Block移行までを扱う。特定環境の完成設定ではなく、Web ACLを設計・調整するときに確認する観点の記録である。

WCUやManaged Rulesの内容は変更される可能性がある。導入前には、AWS WAFコンソール、ListAvailableManagedRuleGroupsDescribeManagedRuleGroup、公式ドキュメントで確認する。

結論

AWS WAFのチューニングでは、最初から全量ログや全ルール詳細を読む必要はないのだ。

実務では、次の順番で進める。

  1. 保護対象のアプリケーション特性を整理する。
  2. 必要なAWS Managed Rulesを選ぶ。
  3. WCUを計算する。
  4. まずCountで導入する。
  5. ログ、メトリクス、sampled requestsで検知状況を見る。
  6. 誤検知を個別ルール単位で調整する。
  7. scope-down statementやlabel matchで対象を絞る。
  8. ビジネスロジック上の妥当性を確認する。
  9. 問題ないルールからBlockへ移す。

重要なのは、「誤検知したルールを外す」ことではない。

より正確には、「誤検知した個別ルールをCount継続にし、最小範囲の例外に調整する」なのだ。

AWS Managed Rulesの全体像

AWS Managed Rulesは、AWSが管理するルールグループなのだ。

Web ACLに追加するだけで、一般的なWeb攻撃、既知の悪性入力、OSやアプリケーション固有の攻撃、IP reputation、Bot、アカウント不正利用、DDoSなどに対する防御を導入できる。

ただし、Managed Rulesは万能ではない。

アプリケーションの仕様を知らないままBlockすると、正常な業務通信を止める可能性がある。

そのため、初期導入ではCountで観測するのだ。

現在のAWS Managed Rules一覧

以下は、AWS公式ドキュメントに掲載されているAWS Managed Rulesの整理なのだ。

WCUは変更される可能性がある。

導入前には、AWS WAFコンソール、ListAvailableManagedRuleGroupsDescribeManagedRuleGroupで確認する。

Baseline rule groups

Rule GroupVendorNameNameWCU用途
Core rule setAWSAWSManagedRulesCommonRuleSet700OWASP Top 10を含む一般的なWeb攻撃、異常リクエスト対策
Admin protectionAWSAWSManagedRulesAdminProtectionRuleSet100管理画面や管理用パスへの外部アクセス対策
Known bad inputsAWSAWSManagedRulesKnownBadInputsRuleSet200既知の悪性入力、脆弱性探索、攻撃パターン対策

Use-case specific rule groups

Rule GroupVendorNameNameWCU用途
SQL databaseAWSAWSManagedRulesSQLiRuleSet200SQLインジェクション対策
Linux operating systemAWSAWSManagedRulesLinuxRuleSet200Linux固有のLFI、コマンド実行、ファイル参照系攻撃対策
POSIX operating systemAWSAWSManagedRulesUnixRuleSet100POSIX系OSのLFI、パストラバーサル、シェルコマンド系攻撃対策
Windows operating systemAWSAWSManagedRulesWindowsRuleSet200Windows、PowerShell、Windows固有パスなどへの攻撃対策
PHP applicationAWSAWSManagedRulesPHPRuleSet100PHP関数悪用、PHPアプリケーション固有の攻撃対策
WordPress applicationAWSAWSManagedRulesWordPressRuleSet100WordPress本体、管理パス、既知のWordPress攻撃対策

IP reputation rule groups

Rule GroupVendorNameNameWCU用途
Amazon IP reputation listAWSAWSManagedRulesAmazonIpReputationList25Amazonの脅威インテリジェンスに基づく悪性IP対策
Anonymous IP listAWSAWSManagedRulesAnonymousIpList50Tor、VPN、プロキシ、ホスティング事業者IPなどの匿名化通信対策

Intelligent threat mitigation rule groups

Rule GroupVendorNameNameWCU用途注意
Bot ControlAWSAWSManagedRulesBotControlRuleSet50Bot分類、スクレイピング、悪性Bot、Targeted Bot対策追加料金あり
Fraud Control account takeover preventionAWSAWSManagedRulesATPRuleSet50ログイン試行、漏えい認証情報、アカウント乗っ取り対策追加料金あり。ログインエンドポイント設定が必要
Fraud Control account creation fraud preventionAWSAWSManagedRulesACFPRuleSet50不正なアカウント作成、量産登録、漏えい認証情報対策追加料金あり。登録エンドポイント設定が必要
Anti-DDoSAWSAWSManagedRulesAntiDDoSRuleSet50DDoS参加リクエストの検知、Challenge、ラベル付け追加料金あり

マネージドルールの選定フロー

Managed Rulesは、全部入れるものではない。

アプリケーションの特性に合わせて選ぶのだ。

実務上の選定順は次の通りなのだ。

  1. まずBaselineを検討する。
  2. 次にアプリケーション技術に応じたUse-case specificを選ぶ。
  3. 外部公開サービスならIP reputationを検討する。
  4. Botや不正ログインが課題ならIntelligent threat mitigationを検討する。
  5. WCUと費用を確認する。
  6. Countで導入する。

まず検討する基本セット

一般的な外部公開Webアプリケーションなら、最初の候補は次なのだ。

優先度Rule Group理由
AWSManagedRulesCommonRuleSet一般的なWeb攻撃を広く見るため
AWSManagedRulesKnownBadInputsRuleSet明らかに悪性の入力を拾うため
AWSManagedRulesSQLiRuleSetSQLを使うアプリでは重要なため
AWSManagedRulesAmazonIpReputationList悪性IPや探索元を減らすため
AWSManagedRulesAnonymousIpList匿名化通信やホスティング元からの攻撃を減らすため

この構成のWCUは次の通りなのだ。

Rule GroupWCU
AWSManagedRulesCommonRuleSet700
AWSManagedRulesKnownBadInputsRuleSet200
AWSManagedRulesSQLiRuleSet200
AWSManagedRulesAmazonIpReputationList25
AWSManagedRulesAnonymousIpList50
合計1,175

この構成は、初期導入のたたき台として使いやすい。

ただし、必ずCountで始めるのだ。

技術スタック別の追加候補

アプリケーションの技術スタックが分かっている場合は、次を追加候補にする。

条件追加候補
Linux上で動作しているAWSManagedRulesLinuxRuleSet
POSIX系OS全般を想定するAWSManagedRulesUnixRuleSet
Windows ServerやIISを使うAWSManagedRulesWindowsRuleSet
PHPを使うAWSManagedRulesPHPRuleSet
WordPressを使うAWSManagedRulesWordPressRuleSet
ログイン機能が重要AWSManagedRulesATPRuleSet
会員登録が重要AWSManagedRulesACFPRuleSet
Botやスクレイピングが課題AWSManagedRulesBotControlRuleSet
DDoS対策をWAFでも強化したいAWSManagedRulesAntiDDoSRuleSet

WordPressの場合は、単体ではなく次の組み合わせを検討するのだ。

Rule GroupWCU
AWSManagedRulesCommonRuleSet700
AWSManagedRulesKnownBadInputsRuleSet200
AWSManagedRulesSQLiRuleSet200
AWSManagedRulesPHPRuleSet100
AWSManagedRulesWordPressRuleSet100
AWSManagedRulesAmazonIpReputationList25
合計1,325

WCUの考え方

WCUは、Web ACL capacity unitの略なのだ。

AWS WAFがWeb ACL内のルールを評価するための容量である。

WCUは通信量ではない。

WCUはルール数そのものでもない。

Web ACLにはWCU上限がある。

現在のAWS WAFでは、Web ACLの最大WCUは公式ドキュメント上で5,000 WCUとして説明されているのだ。

ただし、アカウント、リージョン、機能、時期によって制約や表示が変わる可能性がある。

導入前には必ず実際のコンソールまたはAPIで確認するのだ。

WCU計算の基本

WCU計算は単純なのだ。

Web ACLに追加するRule GroupとカスタムルールのWCUを合算する。

例は次の通りである。

構成WCU
CommonRuleSet700
KnownBadInputsRuleSet200
SQLiRuleSet200
AmazonIpReputationList25
AnonymousIpList50
カスタムIP allow rule1
カスタムrate-based rule2以上
合計1,178以上

scope-down statementを追加すると、その条件分のWCUが加算される場合がある。

label match ruleを追加した場合も、追加ルール分のWCUが必要なのだ。

したがって、Managed Rulesの合計だけでなく、例外制御用の余力も残す。

WCU設計の目安

WCUは、上限いっぱいまで詰め込まない方がよいのだ。

理由は3つある。

  1. 誤検知調整用のカスタムルールを追加するため。
  2. label matchによる後続制御を追加するため。
  3. 将来のManaged Rules追加やバージョン変更に備えるため。

目安は次の通りなのだ。

状態判断
1,500 WCU未満余裕が大きい
1,500から3,000 WCU標準的な構成なら扱いやすい
3,000から4,500 WCU追加ルールの余力を意識する
4,500 WCU超ルール分割、Web ACL分離、設計見直しを検討する

構成例

一般的なWebアプリ

Rule GroupWCU
AWSManagedRulesCommonRuleSet700
AWSManagedRulesKnownBadInputsRuleSet200
AWSManagedRulesSQLiRuleSet200
AWSManagedRulesAmazonIpReputationList25
AWSManagedRulesAnonymousIpList50
合計1,175

まずはこの構成をCountで導入するのだ。

管理画面を持つWebアプリ

Rule GroupWCU
AWSManagedRulesCommonRuleSet700
AWSManagedRulesAdminProtectionRuleSet100
AWSManagedRulesKnownBadInputsRuleSet200
AWSManagedRulesSQLiRuleSet200
AWSManagedRulesAmazonIpReputationList25
合計1,225

管理画面のパスが正規に外部公開されている場合は、Admin protectionの誤検知に注意するのだ。

WordPress

Rule GroupWCU
AWSManagedRulesCommonRuleSet700
AWSManagedRulesKnownBadInputsRuleSet200
AWSManagedRulesSQLiRuleSet200
AWSManagedRulesPHPRuleSet100
AWSManagedRulesWordPressRuleSet100
AWSManagedRulesAmazonIpReputationList25
合計1,325

WordPressでは、プラグインや管理画面の仕様による誤検知を確認するのだ。

ログイン不正対策を重視するWebアプリ

Rule GroupWCU
AWSManagedRulesCommonRuleSet700
AWSManagedRulesKnownBadInputsRuleSet200
AWSManagedRulesSQLiRuleSet200
AWSManagedRulesATPRuleSet50
AWSManagedRulesAmazonIpReputationList25
合計1,175

ATPはログインエンドポイントの設定が必要なのだ。

CloudFrontではレスポンス検査も考慮する。

会員登録不正を重視するWebアプリ

Rule GroupWCU
AWSManagedRulesCommonRuleSet700
AWSManagedRulesKnownBadInputsRuleSet200
AWSManagedRulesSQLiRuleSet200
AWSManagedRulesACFPRuleSet50
AWSManagedRulesAmazonIpReputationList25
合計1,175

ACFPは登録ページとアカウント作成エンドポイントの設定が必要なのだ。

Countモードでのチューニング全体像

Countモードでのチューニングは、次の流れで進めるのだ。

最初に見るべきものは、全量アクセスログではない。

見るべきものは、Countされたリクエストなのだ。

Countで確認する観点

Countされたリクエストは、次の観点で確認する。

観点確認内容
Rule GroupどのManaged Rule Groupに一致したか
Rule nameどの個別ルールに一致したか
ActionCount、Block、Captcha、Challengeなど
terminatingRuleId最終的にどのルールが効いたか
labels後続のlabel matchで使えるか
URI特定画面やAPIに偏っているか
HTTP methodGET、POST、PUT、DELETEなどが想定どおりか
query string業務上あり得る値か
request body入力フォーム、JSON、XML、GraphQLなどの仕様に合うか
headersUser-Agent、Content-Type、X-Forwarded-Forなどが想定どおりか
source IP一般利用者、社内、監視、Bot、攻撃元のどれに近いか
country想定利用地域と合っているか
user agentブラウザ、Bot、監視、スキャナのどれに近いか
frequency単発か、継続的か、大量発生か
business eventログイン、検索、申込、決済、アップロードなど重要操作か

sampled requestsは初期確認に便利なのだ。

ただし、sampled requestsは全件ではない。

最終判断にはAWS WAFログを使う。

誤検知の分類

Countされたリクエストは、次のように分類するのだ。

分類判断対応
明らかな攻撃業務上あり得ない文字列、探索、スキャンBlock候補
正常通信業務機能として必要例外化候補
監視通信外形監視、脆弱性診断、社内監視送信元やパスで条件付き許可
Bot通信検索エンジン、提携先、スクレイパーBot種別ごとに判断
判断保留仕様確認が必要Count継続
高リスクだが必要業務上必要だが攻撃にも似るscope-down、label match、追加認証、レート制限を検討

誤検知が見つかった場合でも、Rule Group全体を無効化するのは避けます。

まずは個別ルール単位で調整します。

ビジネスロジックが不確かな場合の確認ポイント

WAFログだけでは、正常通信か攻撃かを判断できないことがあります。

その場合は、Blockへ移す前に次を確認します。

確認ポイント内容
画面・APIの用途そのURIが何の業務機能か
利用者一般顧客、社内利用者、管理者、外部連携先のどれか
入力仕様特殊文字、HTML、SQL風文字列、JSON、XMLを許容するか
入力長長文、Base64、ファイル名、URL、スクリプト断片を許容するか
Content-Typeapplication/jsonmultipart/form-datatext/plainなどが仕様どおりか
認証状態未認証、ログイン済み、管理者権限のどれか
業務影響Blockした場合に申込、決済、ログイン、登録が止まるか
代替経路WAFで止めてもアプリ側で安全に処理できるか
アプリ側検証サーバ側で入力検証、認可、CSRF対策、SQL対策があるか
監視・診断社内監視、外形監視、脆弱性診断の通信ではないか
過去実績過去にも同じ入力が正常に使われていたか
件数傾向少数の正常利用か、大量の機械的通信か
失敗率対象リクエストがアプリ側で成功しているか失敗しているか
利用時間帯営業時間、バッチ時間、キャンペーン期間に偏るか
問い合わせ利用者問い合わせや業務部門からの申告があるか

この確認が取れない場合、原則として即Blockにはしません。

まずCount継続にします。

次に、影響範囲を絞った例外または段階的Blockを検討します。

Blockへ移してよい目安

次の条件を満たすほど、Blockへ移しやすくなります。

条件判断
一定期間、正常通信への一致がないBlockへ移しやすい
一致内容が明らかに攻撃Blockへ移しやすい
アプリ担当者が業務上不要と確認したBlockへ移しやすい
対象URIが公開不要な管理系パスBlockへ移しやすい
同一送信元から大量発生しているBlock、rate limit、Challengeを検討
誤検知が特定パスだけ例外化後にBlock
誤検知が広範囲Count継続または設計見直し
業務仕様が不明Count継続
決済、申込、ログインに関係する追加確認後に段階移行

観測期間は、システムの利用サイクルに合わせます。

最低でも、平日と休日を含めます。

月次処理、給与日、請求日、キャンペーン、繁忙期がある場合は、その期間も確認します。

個別ルールをCountに残す

Managed Rule Groupの中で、一部のルールだけが誤検知を起こすことがあります。

この場合は、該当ルールだけをCountに残します。

他のルールはBlockへ移せます。

例です。

状況悪い対応良い対応
CommonRuleSetの一部だけ誤検知CommonRuleSet全体を外す該当個別ルールだけCount継続
SQLiRuleSetが検索画面で誤検知SQLiRuleSet全体を外す検索画面だけscope-downで調整
AnonymousIpListが社内VPNを検知AnonymousIpList全体を外す社内IPだけ条件付き許可
WordPress管理画面で誤検知WordPressRuleSet全体を外す管理者IP、認証状態、URIで限定調整

scope-down statementの使い方

scope-down statementは、Managed Rule Groupの評価対象を絞るために使います。

使いどころは次です。

用途
特定パスだけ対象にする/loginだけATP対象
特定パスだけ対象外にする/api/searchだけSQLi誤検知を回避
特定メソッドだけ対象にするPOSTだけ検査
特定Content-Typeだけ対象にするJSON APIだけ検査
特定IPを除外する社内監視IPだけ除外
特定Hostだけ対象にする管理用サブドメインだけAdmin protection対象

除外範囲は狭くします。

広い除外は、防御効果を大きく削ります。

label matchの使い方

AWS Managed Rulesは、リクエストにlabelを付与します。

label matchを使うと、Managed Rulesの検知結果を後続ルールで再利用できます。

使い方の例です。

用途
検知だけ先に行うManaged Rule GroupをCountにしてlabelを見る
後続でBlockする特定labelかつ特定URIだけBlock
後続でChallengeするBot系labelにChallengeを適用
例外を細かく作る特定labelかつ社内IP以外をBlock
誤検知を避ける特定labelでも正規APIだけ許可

label matchは柔軟です。

ただし、条件が複雑になりやすいです。

設定理由を必ず記録します。

本番移行の進め方

CountからBlockへ移すときは、影響が小さいものから進めます。

  1. 明らかな攻撃だけをBlockにする。
  2. 正常通信への一致がないルールをBlockにする。
  3. 誤検知がある個別ルールはCountに残す。
  4. scope-down statementで対象を絞る。
  5. label matchで後続制御する。
  6. 重要機能の4xx増加を監視する。
  7. 問い合わせや業務影響を確認する。
  8. 問題があれば該当ルールだけCountへ戻す。

本番移行では、戻し方を事前に決めます。

WAFのBlock化は、アプリケーション変更と同じように変更管理します。

よくある失敗

Rule Group全体を外す

一部のルールで誤検知が出ただけなのに、Rule Group全体を外すケースがあります。

防御範囲を大きく落とします。

個別ルールのCount化を先に検討します。

sampled requestsだけで判断する

sampled requestsは全件ではありません。

傾向を見るには便利です。

最終判断にはログを使います。

例外条件を広くしすぎる

パス全体、IP全体、Host全体を広く除外すると、防御対象が薄くなります。

URI、メソッド、IP、ヘッダ、labelを組み合わせて狭くします。

Countのまま放置する

Countは観測のための状態です。

恒久的にCountのままにすると、防御にはなりません。

定期的に棚卸しします。

ビジネス仕様を確認せずBlockする

WAFログだけでは正常通信か判断できない場合があります。

ログイン、申込、決済、会員登録、検索、ファイルアップロードは特に慎重に扱います。

運用で記録すべきこと

最低限、次を記録します。

項目内容
日付変更した日
対象Web ACLどのWeb ACLを変更したか
対象Rule GroupどのManaged Rule Groupを変更したか
対象個別ルールどの個別ルールをCount継続またはBlockにしたか
変更内容Count、Block、Challenge、Captcha、例外条件など
理由誤検知、攻撃確認、業務要件など
根拠ログ判断に使ったログ、メトリクス、sampled requests
業務確認誰に何を確認したか
WCU影響追加・削除後のWCU
戻し方問題発生時に戻す設定

Managed RulesはAWS側で更新されます。

そのため、過去の判断理由を残すことが重要です。

実務チェックリスト

導入前

  • 保護対象のCloudFront、ALB、API Gateway、AppSyncなどを確認した。
  • Web ACLのscopeを確認した。
  • アプリケーションの主要機能を確認した。
  • ログイン、申込、決済、検索、アップロードの有無を確認した。
  • 技術スタックを確認した。
  • 必要なManaged Rulesを選定した。
  • WCUを計算した。
  • 追加料金が発生するRule Groupを確認した。
  • ログ出力先を決めた。

Count期間中

  • Countイベントをルール別に集計した。
  • CountイベントをURI別に集計した。
  • Countイベントを送信元別に集計した。
  • 重要機能への一致を確認した。
  • 誤検知候補を分類した。
  • アプリ担当者に仕様確認した。
  • 監視通信や診断通信を識別した。
  • 個別ルールのCount継続を設定した。
  • scope-down statementを検討した。
  • label matchを検討した。

Block移行前

  • 正常通信への一致がないことを確認した。
  • 業務上必要な入力ではないことを確認した。
  • 重要機能への影響がないことを確認した。
  • 例外条件が最小範囲であることを確認した。
  • 4xx増加を監視できることを確認した。
  • 問い合わせ増加を検知できることを確認した。
  • ロールバック手順を決めた。
  • 変更記録を残した。

出典

まとめ

AWS WAFのチューニングは、ルールを大量に読む作業ではない。

保護対象の業務仕様を整理し、必要なManaged Rulesを選び、WCUを計算し、Countで実通信を観測する作業なのだ。

誤検知があれば、Rule Group全体を外すのではなく、個別ルール、scope-down statement、label matchで最小範囲に調整する。

ビジネスロジックが不確かな場合は、業務仕様、入力仕様、認証状態、重要機能への影響、アプリ側検証、過去実績を確認する。

確認が取れないものは、原則としてCount継続にする。

問題ないものから段階的にBlockへ移す。

この進め方なら、業務影響を抑えながらAWS WAFの防御効果を高められるのだ。