AWS WAFを有効活用するための導入と運用のポイント

# 初めに
Webシステムにおいて非機能要件の中でもセキュリティは非常に重要なポイントとなります。
不特定多数の人がアクセスできる環境では様々な種類の攻撃が行われ、それにより情報漏洩をはじめとした各種被害によりビジネス損失を発生させてしまうことになりかねません。
こういった事態を避けるために複数のセキュリティ対策により総合的にセキュリティ強度を上げることが有効であり、その中の1つとしてWAF（Web Application Firewall）が存在します。
WAFはオンプレミス・クラウド問わず多くのシステムで利用されており、また最近ではクレジットカード業界のセキュリティ基準であるPCIDSSのv4.0においてWAFの利用が明示されるなど高いセキュリティを担保するために必須のコンポーネントと考えられています。

この記事では私が業務で触れる機会の多いAWS WAFについて有効活用するための導入と運用のポイントについて解説します。

# 前提

## WAFの位置付けについて
WAFを利用するにあたりまず理解すべきことは、WAFはアプリケーションのセキュリティに対して根本的な対応を行うものではない、という点です。
アプリケーションセキュリティはアプリケーション自体の中で担保するのが基本的な考え方であり、WAFはあくまでその脆弱性をついて攻撃された場合の被害を軽減するためのものです。
これは2011年にIPAが発行した「Web Application Firewall 読本 改訂第2版」でも言われている通りです。

## AWS WAFについて
AWS WAFはAWSのマネージドサービスの1つでその名の通りWAF機能を提供するサービスです。
私が感じるAWS WAFの長所は以下の通りです。

- AWS製/3rdParty製のマネージドルールが充実している
- 用途ごとに新たなWAFを個別に作れる
- 料金が安価である
- AWSサービスとの連携が容易である

<br>
それぞれの長所について以下簡単に補足します。

### AWS製/3rdParty製のマネージドルールが充実している
AWS WAFでは各種検知ルールをまとめたマネージドルールグループというものをAWSもしくはAWS Marketplace 販売者が提供しています。更にAWSが提供しているマネージドルールグループについては追加費用無しで利用することができます。
ユーザ自身が適切なルールを全て作成してWAFに適用するのは現実的ではないので、マネージドルールグループが充実していることはWAFを利用する上で非常に重要なポイントと考えています。

### 用途ごとに新たなWAFを個別に作れる
AWS WAFはAmazon CloudFrontやApplication Load Balancer(ALB)、Amazon API Gateway等にアタッチして利用することができます。
WAFはこれらアタッチする対象リソース毎に個別に作成が可能なので、例えば1つのシステムの中でALBを3つ作成した場合、WAF(WebACL)を別々に3つ作成して利用することができます。これによりWAFの中で定義するルールをシンプルにすることや、システムを拡張する際に既存のWAFに手を加えることなく対応が可能です。
これが可能なのはこの次に記載する長所である料金の安さにも起因しています。

### 料金が安価である
AWS WAFは使い方にもよりますが月額数千円～利用できるためWebシステム構築時には必ず利用する、という方針を採用しやすいのが特徴です。
WAFをアタッチするAWSリソース単位に作成していくとその分料金は発生しますがそれでも低額ですので、保守性や設計のシンプルさなどを優先して構成を考えることができるというのが実際にシステムを作る際にありがたいポイントです。

### AWSサービスとの連携が容易である
これは当然のことですがAWSサービス同士ですので、アタッチする対象のALBやAPI Gateway等との連携や、ログ保管を行うCloudwatch LogsやS3、監視のためのCloudwatch Alarmなど各種AWSサービスと組み合わせることが非常に容易です。


# WAF導入から運用までの流れ
AWS WAFに限らずWAFを導入し運用する際、組織によって詳細は異なりますが凡そ以下のような流れで行うことが多いのではないかと思います。

| No | 工程 | 実施内容の例 |
| ---- | ---- | ---- | 
| 1 | 要件定義 | ・非機能要件（主にセキュリティ要件）を明確にし、その中でWAFに期待することを整理にする <br> ・システム構成の中のどこにWAFを配置するか決定する| 
| 2 | 設計 | ・非機能要件の中のWAFで対応すべき事項について、具体的な対応方法を検討する <br> ・WAFの運用方法（検知時のシステム面・運用面の動き方/検知ルールの見直し方針など）を明確にする <br> ・WAF導入初期時点で設定すべきルールを明確にする <br> ・WAFに関連するテストの方針を整理する <br> ・WAF構築に必要な各種設定内容を整理する| 
| 3 | 構築 | ・設計工程の内容に従って実際にWAFを設定する | 
| 4 | テスト | ・WAF単体のテストとして、正常系（検知ルールに抵触しない通信を実行してその通信が許可されること）及び異常系（検知ルールに抵触する通信を実行してその通信が遮断やカウント等想定する挙動となること）を確認する <br> ・アプリケーションレイヤまで含んだ結合テストやシステムテストの一環として、アプリケーションの正常な利用時に誤検知が多発しないことを確認する <br> ・セキュリティテストの一環として、WAFの検知ルールに含まれる不正通信が発生した際に想定する挙動となることを確認する| 
| 5 | 移行 | ・移行後に実際の業務通信に対してWAFが適切に動作していること（主に誤検知と思われる挙動が多発していないこと）を確認する | 
| 6 | 保守運用 | ・予め定めた運用方針に則って運用を実施する <br> ・世の中のWebセキュリティの状況を考慮してWAFの役割の見直しを行う | 

次の章では上記各項目についてAWS WAFを利用する際にどのようなポイントがあるのかを解説します。

# AWS WAFの導入・運用で考慮すべきポイント

## 1. 要件定義
要件定義の工程では非機能要件を明確にして、主にその中のセキュリティ要件についてどの要件をWAFで対応するのかを整理することになります。
AWS WAFではAWSやAWS Marketplace 販売者から検知ルールをひとまとめにしたマネージドルールグループというものが提供されています。
そもそもAWS WAFを用いることで満たせるセキュリティ要件としてどういったものがあるのかを明確にしたいという場合にはこれらを確認することから始めるのがおすすめです。

AWSが提供するマネージドルールグループの情報↓
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups-list.html

また、マネージドルールグループ以外にWebシステム全般でよく使われるAWS WAFの機能としては以下のようなものがあります。

* 送信元IPアドレスによる制御
* 送信元IPアドレスによるレートリミット制御
* 送信元の国/場所による制御
* ホストヘッダによる制御

1点目については、クライアントIPアドレスを限定してホワイトリストもしくはブラックリスト方式で通信の制御ができるというものです。
例えばシステムの管理者用サイト等で特定の送信元IPアドレスからしか正当な通信が来ないケースや、開発環境等で関係者以外に環境を開放したくない場合にはIPアドレスによる制御を利用することで実現できます。

2点目は、1つの送信元IPアドレスから特定時間当たり（*)に閾値を超過するリクエストが発生した場合にそのIPアドレスからの通信を拒否するというものです。
これはセキュリティ対策という観点でももちろん使えますが、簡易的にバックエンドの負荷を考慮した流量制御を行いたいというユースケースで利用を検討することもあるかと思います。

*. 従来時間間隔は5分で固定されていましたが2024/3にアップデートがあり2024/4現在、1分・2分・5分・10分の中選択が可能になっています。
https://aws.amazon.com/jp/about-aws/whats-new/2024/03/aws-waf-rate-based-rules-configurable-time-windows/

3点目はリクエストを行っているクライアントが存在する国や場所を識別してそれに基づいて通信可否を制御するというものです。
例えば日本国内のユーザに限定してサービスを提供したい場合にはホワイトリスト形式で日本のみを許可することでそれ以外の国・場所からの通信を拒否することができます。
なお、国・場所を識別する精度は99.8%(*)ですので誤検知のリスクがあるということは導入前の時点で認識しておくことが必要です。

*. 以下サイトの記載を参照。
https://aws.amazon.com/jp/waf/faqs/

4点目はHTTPヘッダ内のホストヘッダの値が適切な場合のみ通信を許可するという制御です。
アプリケーションをエンドユーザが使用する場合、通常はホストヘッダにそのサイトのFQDNが含まれることになると思いますが、想定外（攻撃やその前段階など）通信において例えばALBにカスタムドメインを割り振って利用している構成において、ALBに対してカスタムドメインを使わずALBが使用しているパブリックIPアドレスを直接指定して通信を行ってくるケースがあります。実際にALBのアクセスログなどを確認してみるとそういった通信がそれなりの頻度で行われていることがわかるかと思います。
そういった攻撃への対策としてホストヘッダが適切でない通信をWAFの検知対象とするユースケースも考えられます。

上記の通りWAFのルールを検討する際にはマネージドルールグループとカスタムのルールを組み合わせて要件を満たせるように考えていきます。

これらを踏まえて、非機能要件の中でWAFで何を実現するのかということを明確にしていきます。

## 2. 設計
設計の工程について、まずWAFの設計としては構築を行うための設計と運用設計の2種類を行う必要があります。
WAFにおいては特に後者の運用設計が重要になると私は考えています。

### AWS WAF構築のための設計ポイント

* WAF（WebACL）の分割に関する検討
* 採用するマネージドルールグループの選定
* 送信元IPアドレス制御/国・場所別制御等のカスタムルールの具体的な内容の検討
* WAFが攻撃と判断した通信に対する扱いの検討

1点目のWAF(WebACL）の分割に関する検討について、前述した通りAWS WAFの長所の1つとして、用途ごとに新たなWAFを個別に作ることが可能な点があります。
これにより、WAFの中で利用するルールをシンプルにして、かつ拡張時に既存のWAFに手を加えることなく対応が可能というメリットを享受することができます。
そのため私が所属する組織では基本的にALBやAPI GatewayといったAWSのリソースそれぞれ（AWSサービス単位でまとめることなく、AWSリソース単位に）個別のWAFを作成・アタッチすることが多いです。
もちろんコストを最小限に抑えるなどの理由で1つのWAF（WebACL）を複数のAWSリソースで利用するという方式にすることもあり得ると思いますが、この部分が設計ポイントであることを認識して検討するということが重要だと考えます。

2点目について、要件定義の項目で記載したマネージドルールグループの中で具体的にどのルールグループが今回のシステムにマッチしているのか、どのルールグループを使うことで非機能要件を満たすことができるのかを検討して選定します。
なお、ルールグループは複数選択することが可能なため、要件にマッチするものは全て選択するということが可能です。但しルールグループの用途を考慮せずとにかく全てのルールグループを利用する設定とした場合には無駄なコストが発生することに加え、誤検知リスクが高まり適切なWAF運用を行う妨げになりますので、WAFの初期導入の時点で100%正しいと言い切れなくても妥当と思われるルールグループを選択することは必要だと考えます。

3点目について、要件定義の項目で記載したカスタムのルールを組み合わせて正当な通信のみをバックエンドに送るよう設計していきます。
送信元IPアドレスの制御や国・場所別制御に関して、プロジェクトの要件定義・設計工程内で通信要件を一覧形式でまとめていくことが多いかと思いますのでその中で明示することで抜け漏れなく構築に取り込むことができるかと思います。また、この制御は環境（本番環境・開発環境など）ごとにあるべき内容が異なるケースがあります。例えば本番環境は世界中の任意の送信元から通信を受け付けたいが、開発環境については関係者のみの限られた通信のみを許可したいといったケース等が該当します。そのためAWS WAFの設計も一部環境ごとに差異が出る可能性がある点を考慮して設計の取り込みが必要です。

最後4点目について、AWS WAFではルールに合致した通信についてAllow/Count/Block/CAPTCHAおよびChallenge、の4種類のいずれかの処理を行います。この中では特に攻撃を検知した際使われる可能性が高いであろうCountとBlockについて使い分けを記載します。
まずそれぞれの処理内容は以下の通りです。

> Block ： 通信に対してHTTPステータスコード403(Forbidden)でレスポンスして終了させる。バックエンドに対して通信を送らない。正当な通信を攻撃と誤検知して通信を止めてしまいユーザがアプリケーションを利用できないリスクが存在する。

> Count : AWS WAFの中で件数をカウントするのみで通信を止めることは無い。但し通信を許可することもないのでこのルールに該当したということでバックエンドに通信が送られるということもない（後段のルールの中でAllowに該当した場合のみバックエンドに通信が送られる）。攻撃を受けてもその攻撃を止めることはできず被害が発生するリスクが存在する。

多くのプロジェクトにおいて非機能要件を整理した時点でBlock/Countのいずれを用いるか明言しているケースは少なく、プロジェクトによっては単純に「アプリケーションレイヤの攻撃を検知・防御する」といった抽象的な表現のみとなっている場合もあるかと思います。
その場合に何を基準にBlock/Countを採用するかですが、まずはビジネス観点で判断をするべきであると考えます。
具体的には誤検知により正当なユーザがアプリケーションを利用できないリスクを全く許容できないビジネスにおいてはBlockモードを採用することは困難ですし、逆に扱うデータの秘匿度が非常に高いなどで誤検知だとしても攻撃の可能性のある通信は排除したいという場合にはBlockモードが推奨となります。
そのうえで、極力誤検知のリスクを下げつつ攻撃と思われる通信を排除するために以下のような流れで進めることが選択肢の1つとして考えられます。

1. WAF導入の構築時点ではCountモードで設定を実施する
1. アプリケーションを実際に動かすテスト（ITやSTなど）でWAFの検知状況を確認、どの程度誤検知がされているかの精査とそれに対するチューニングを実施する
1. Countモードのままリリースを行い、実通信に対してWAFの検知状況を確認、どの程度誤検知がされているかの精査とそれに対するチューニングを実施する
1. 1～3カ月程度の期間状況確認とチューニングを行い、誤検知リスクが許容できる程度まで低下したと判断された後Blockモードへの移行を実施する

なお、上記2・3で行う誤検知がされているかの精査及びチューニングについて、詳細を確認するためにはアプリケーションのログを確認する必要があることや、誤検知の原因がアプリケーション側に起因しているケースも存在するため、インフラエンジニアがWAF導入を推進する場合であってもそのシステムを担当するアプリケーションエンジニアと協力して対応が必要です。


### 運用設計のための設計ポイント

* 検知時の動き方の検討
* 検知ルールの見直し方針の策定
* WAFログの収集・活用方法の検討

1点目について、WAFで攻撃と思われる通信を検知した際に運用としてどのように動いていくべきかを予め決める必要があります。これは前述したCountモード/Blockモードのどちらで検知した場合なのかによって変わることになります。
Blockモードの場合は悪意ある通信をアプリケーションに到達させることなく除外できているので急いで対応することは基本的には無いと考えられますが、但し突然Blockする通信が大量に現れた場合には様々な手法で攻撃されている可能性やその中の一部の攻撃がBlockされずにアプリケーションに到達しているリスクを考慮して調査などの対応を行う必要があるかもしれません。
逆にCountモードの場合は攻撃の可能性のある通信を遮断していないので、対象の通信が正当なものだったかどうかの確認は速やかに行わなければならないケースが多いのではないでしょうか。
いずれにせよWAFでの検知数は閾値を設けてチェックを行い、閾値を超過した場合にはアラート通知等の手段を用いて運用担当者がその状況を把握、その後アプリケーション担当者含めて調査対応ができるよう運用設計が必要です。
AWS WAFではCloudwatchメトリクスにWAFのCount/Block件数が収集されますのでEC2のCPU使用率など各種メトリクス監視と同様にWAFの検知数の監視も行うことが可能です。

2点目の検知ルール見直し方針の策定について、システムリリース後にアプリケーションをアップデートしていく中でWAFに求められる役割が変化したり、アップデートによって追加された通信に対してWAFが誤検知してしまうといったケースもあり得ます。そのため保守運用フェーズにおいてWAFの検知ルールをどう見直していくべきかの方針を運用設計の段階で考えておく必要があります。
また、AWS WAFのマネージドルールグループに関する検知ルールの見直しという観点では、ルールグループのバージョンアップ対応というものがあります。
多くのマネージドルールグループにはバージョンが存在し、そのバージョンを自動的に更新する運用とするか、手動で更新する運用とするかを検討する必要があります。また新しいバージョンへの変更運用をいつ行うべきかについては通知を受け取ることも可能ですので、こういった設定を適切に行うことで「気づいたらバージョンが変更されていた」という事態を避けることができます。
マネージドルールグループのバージョンに関して詳細は以下をご参照ください。

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

3点目について、AWS WAFではAmazon S3、Amazon Cloudwatch Logs、もしくはAmazon Data Firehoseにログを出力することが可能です。どこにログを出力するかはシステム全体のログ管理の中で検討すれば問題ないと思いますが、適切な保守運用のために基本的にはログの出力は有効にしておくべきだと考えます。
また、ログ出力にあたって以下2点のポイントは特に意識すべきです。

- ログの大量出力が想定されるケースでは必要なログのみにフィルタリングを行う
- ログ取得後、どのように活用するかを検討し必要に応じてそのためのツール等の整備を行う

1つ目のポイントはログが大量に出力されることでコストに影響することと、あまりに大量の無駄なデータが出てしまうと適切な分析が難しくなるなどの観点からのポイントです。
2つ目のポイントはログの取得目的としてただ取っておくのではなくそれを活用して調査等に役立てることが想定されるので、設計の段階でどういった活用を行うのか具体的なシーンを想定してツールの整備の要否検討等を行うことが望ましいと考えています。
例えばCloudatch Logsにログを格納する場合であればCloudwatch Logs Insightsを利用することで多くのユースケースに対応することができますし、S3に格納する場合はAmazon Athenaを使って検索可能な状態にすることができます。それ以外に、より高度な分析が行いたい場合、AWSではGitHub上で SIEM on Amazon OpenSearch ServiceというOSSのSIEMソリューションが提供されています。WAFログだけでなく様々なログを用いてセキュリティに関する総合的な分析が行えるツールですので、高いセキュリティを実現したいシステムではこういったソリューションも検討に入れてみても良いかもしれないです。

https://github.com/aws-samples/siem-on-amazon-opensearch-service/blob/main/README_ja.md

### その他
構築に向けた設計及び運用設計以外に設計工程の中で対応すべき事項としてWAFのテストに関する方針整理があります。
特にマネージドルールグループを採用している場合、その中で使用している全ルールについてのテストを行うことは現実的には難しいです。そのため、WAF構築時点ではある程度サンプリングしてテストを行ったうえで、ITやST工程の中でWAFの検知状況の確認も観点の1つに含めることが望ましいと考えています。
特にピーク時を想定した負荷テストや、様々なバリエーションでのテストなどを通して実際にアプリケーションが使われる状態を模してどの程度WAFが検知するのかを見極めてチューニングしていくことが必要なので、設計工程の中でどのテスト項目にWAFの状態確認も盛り込んでいくのかを検討しておくことが必要だと考えます。

また、その他個別の話になりますがWAFのアタッチ先としてALBを利用する場合、設計工程で決めるべきポイントとして「WAFのフェールオープンを有効にするかどうか」という点があります。
フェールオープンとはWAFが一時的な不具合等により処理できない状態になった場合にWAFでの通信チェックを行わずバックエンドに通信を送ることを指します。
フェールオープンを有効にするとWAFが使えない状態であってもアプリケーションを利用し続けることが可能です、但しWAFが機能している時と比較して悪意ある通信がアプリケーションに到達するリスクが高い状態となります。
逆にフェールオープンを無効にするとセキュリティレベルを維持することは可能ですがWAFが使えない時間帯は正当な通信も含めてアプリケーションが利用できなくなるためビジネス機会の損失につながるリスクがあります。
フェールオープンを有効・無効のいずれにするかは扱うシステムの特性を踏まえて組織として判断することになりますが、ALBの場合にはフェールオープンについて検討する必要がある、ということは認識して設計を行うべきです。

ここまで設計工程で考えるべきポイントを解説してきました。WAFを有効に活用するためには設計工程までで決めるべき「何のリスクに対してどうWAFで防ぐのか」を決めることが重要であると考えています。

## 3. 構築
設計工程で定めた内容に従って構築を行っていきます。
構築の方法はマネジメントコンソールを用いてGUIで行う方法やAWS CloudFormation、AWS CDKを用いる方法等各組織で構築方法に関するポリシーが存在するかと思いますのでAWS WAFについてもそれに従い構築を行うことが可能です。

AWS CloudFormationでAWS WAFの構築を行う際に私が所属するチームで行っている工夫として、CloudFormationテンプレートを個別のWAFごとに分割するという点があります。
WAFのルールはテスト時のチューニングや保守運用フェーズでのルール見直し、IPアドレス制御を行っている場合には接続元IPアドレスの追加時など変更されることがあります。その頻度はALB等WAFをアタッチするAWSリソースよりも多くなる可能性が高いので、AWS WAFを作成するCloudFormationスタックは独立して作成することを意識しています。ライフサイクルによってCloudFormtaionスタックを分割するという点についてはCloudFormationのベストプラクティスでも記載されている通りです。<br>

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/best-practices.html#organizingstacks


## 4. テスト
テストの段階では設計工程で定めた内容に従ってWAF単独のテスト及びアプリケーションを実際に動かしてのテストを行っていきます。
ポイントとして、特にIT・STの段階ではアプリケーション側が多くのテストケースを消化していくことになりますので、WAFの初期設定やチューニングがおかしいことで誤検知（通信遮断）が多発してテストの消化に影響が出ることは避ける必要があります。
その対策として設計段階で利用するルールを適正と思われるものに絞っていくことと、最終的にBlockモードで運用するケースでも最初はCountモードにして検出状況を確認するなどの工夫が考えられます。

## 5. 移行
移行の段階でWAFの設定を変更するケースとしては、例えば移行直前までは関係者からのアクセスのみを許可するためにIPアドレスによる制限を加えていて、移行する際にその制限を解除するといったものが考えられます。
その際、CloudFormation等のIaCを用いて実施していれば特に問題は無いかと思いますが、マネジメントコンソールを用いて行う場合にはフォールバックのリスクを想定して、IPアドレス制限のルールを削除するのではなく、対象のWAF（WebACL)からそのルールを外す対応にすることでフォールバック時にも迅速にIPアドレス制限の再設定が可能になります。

また、移行直後からしばらくの期間はサーバのCPU/メモリ使用率等のリソース状態と同様にWAFの検出状況のチェックも必要になります。移行計画を立てる際にはこの部分も観測の観点に含めるようにすることが望ましいと考えます。


## 6. 保守運用
保守運用フェーズではWAFの検出実績の管理や検出時の具体的な対応、更に検出状況を踏まえたルール見直しといった活動を行っていくことになります。
更にAWS WAFの特徴として、随時WAFの機能アップデートが行われますので、新機能を定期的にチェックする機会を設けてその機能を自分たちのシステムに適用すべきか検討する活動も有意義だと思います。


# まとめ
この記事の中ではAWS WAFの導入から運用まで有効活用するためのポイントを説明しました。
AWS WAFはそれ単体でも低価格であり機能も充実していることから利用しやすいサービスであることに加え、AWSの他サービスとの連携が非常に容易ですのでAWS上でWebシステムを開発する場合にはデフォルトで利用することができるものであると考えています。
Webシステムのセキュリティを担保するにあたりWAFを利用することはほぼ必須なのではないかと思いますので、AWS WAFを用いてセキュアなWebシステムを実現して頂ければと思います。


# 参考資料

IPA Web Application Firewall 読本

https://www.ipa.go.jp/archive/security/vuln/waf.html

AWS公式ホームページおよび公式ドキュメント

https://aws.amazon.com/jp/waf/

https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-rule-action.html

https://d1.awsstatic.com/webinars/jp/pdf/services/20200324_AWS_BlackBelt_AWS_WAF_Update.pdf

https://aws.amazon.com/jp/waf/faqs/

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/best-practices.html#organizingstacks

https://aws.amazon.com/jp/about-aws/whats-new/2024/03/aws-waf-rate-based-rules-configurable-time-windows/