Fastly NGWAF の Advanced Rate Limiting 機能を使用する


Fastly の NGWAF の上位パッケージで利用可能な [Advanced rate limiting](https://docs.fastly.com/en/ngwaf/working-with-advanced-rate-limiting-rules) (ARL)の特徴と設定方法について説明します。

# 機能概要
指定した条件を満たすリクエストをカウントし、指定した閾値を超えるリクエストが発生した場合にブロックやログなどの指定された挙動を行います。

DDoS などの大規模なリクエストではなく、クレジットカードの有効性の確認やログイン試行など一般的に短時間に繰り返すことが考えづらいようなリクエストの繰り返しを制限するために利用します。

DDoS などの大規模なリクエストに対する Rate Limiting 機能である Edge Rate Limiting との違いについては [Fastly のふたつの Rate Limiting の機能について](https://qiita.com/AtsushiFukuda/items/d5dbf5183dbbdc43b6a1) をご確認下さい。


# 設定方法

それでは Advanced Rate Limiting 機能の設定方法を説明します。まずは NGWAF のコンソールから Advanced Rae Limiting を設定したい Site(workspace) を選択します。

対象の Site が表示されると、右上の Rules -> Site Rules -> Add site rule から Type: Rate limit をクリックすると以下の設定画面が表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128569/4ecd018a-c59f-4cd4-9f1e-5e9ad0beec3f.png)

# 設定項目
Advanced Rate Limiting を利用するためには以下の項目を設定します。

## Type
Rate limit を選択します。

## Conditions
カウントを行う条件を設定します。特定の Path や特定のリクエストメソッドなど、複数の条件を組み合わせて利用することが可能です。

利用方法はシンプルですが、より細かい設定を行いたい場合は [Defining rule conditions
](https://docs.fastly.com/en/ngwaf/defining-rule-conditions) をご参照下さい。

## Client Indetifier
Conditions にマッチしたリクエストをカウントする際に、何をベースにカウントを行うかを指定します。以下の項目から選択可能です。

- IP address(default)
- Request header value
- Cookie value
- Post parameter value
- IP address & request header value
- IP address & cookie value
- IP address & post parameter value
- Signal payload value

デフォルトでは IP アドレスをカウントしますが、特定のリクエストヘッダや Cookie の値をキーとしてをカウントしたり、IPアドレスとヘッダの値の組み合わせてでカウントを行うことも出来ます。

組み合わせを選択した場合は、指定条件のどちらかの値が変更になると別の Client Key としてカウントされます。
例えば IP address & request header value で Header Name に user-agent を選択すると、以下のリクエストは別々のクライアントとしてカウントされます。
リクエスト1 = IP Address x.x.x,x & user-agent: xxx
リクエスト2 = IP Address x.x.x,x & user-agent: yyy (同一IPから異なる User-Agentのリクエスト）


## Actions

閾値や閾値を超えた場合の動作を設定します。

### Tracking


Advanced Rate Limiting では指定条件に合致したリクエストに Signal を付与しますが、その Signal のことを Threshold シグナル と呼びます。ここでは Threshold シグナルと閾値を設定します。

なお、Threshold シグナルはひとつのレート制限ルールでのみ利用可能で、複数のレート制限ルールの Threshold シグナルとして使用することはできません。これは異なるルールで Threshold シグナルがカウントされ、意図しない制限が発生することを防ぐためです。


#### Threshold signal
Threshold シグナルを選択します。事前に Threshold signal を作成していない場合は Add signal をクリックして Threshold signal を新規に作成することが出来ます


#### Threshold
閾値を設定します。

- 検知期間: 1分 or 10分
- 閾値: 1 - 10,000

### Rate limiting

閾値を超えた場合の挙動を設定します。契約内容や実装環境により表示されないオプションなどもあります。

#### Action Type

- **Log**: ログを取得。ブロックは行いません
閾値を超えたリクエストには `Rate Limit` Signal が付与されます。
　
- **Block**: リクエストをブロック。ログも取得します
閾値を超えたリクエストには `Rate Limit` と `Blocked Request` Signal が付与されます。
　
- **Browser challenge**: Browser チャレンジを表示
[Browser challenge](https://docs.fastly.com/en/ngwaf/using-client-challenges) とは、クライアント側でアクションを実行させることで人によるアクセスを確認するものです。
Interactive(キャプチャ)もしくは Non-Interactive(JavaScript の簡単な処理)を選択することが出来ます。

#### Match type
Action type に Log や Block を選択した場合に、その対象となるリクエストを選択します。

- **Rule conditions**: この Advanced Rate Limiting のルールに指定した条件と同じリクエストを Action の対象とします
　
- **Other signal**: 指定した Signal を持つリクエストを Action の対象とします。
システムが自動的に付与する Attack Signal や Anormal Signal、もしくは自分で作成したカスタム signal からAction の対象となる Signal を選択します。カスタム signal を選択する場合は事前に Request Rule からカスタム Signal を作成しておく必要があります。
　
- **All requests**: すべてのリクエストを Action の対象とします


#### Duration
Action を有効にする期間を指定します。
期間は 5分から最大24時間まで選択可能です。

## Details
Status: ルールを有効にする場合は Enabled になっていることを確認して下さい
Description: ルールの説明を記載します

入力内容に問題がなければ `Create site rule` をクリックするとルールが作成されます。




# Data Storage
Advanced Rate Limiting に関連するリクエストの情報の収集は Signal ごとに以下のようになっています。

|Signal|Signal タイプ  |収集カテゴリー  |
|---|---|---|
|`Threshold signal`  |Informational  |グラフ情報のみ、リクエスト情報は取得しない  |
|`Rate limit`  |Anromaly  |サンプルとして一部のリクエスト情報を取得  |
|`Blocked Request`  |Anromaly  |サンプルとして一部のリクエスト情報を取得  |

各リクエストの数はグラフで確認可能ですが、すべてのリクエストの詳細情報が取得され、コンソールから確認出来るわけではありませんのでご注意ください。

# Rate limit ルールのサンプル
それでは実際にレートリミットを設定するサンプルをご紹介します。

## コメント追加にレートリミット

コメント機能にレートリミットを追加する設定のサンプルです。コメントの投稿を1分間に9回までに制限します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128569/c808ff6f-4f84-494d-ba07-b20baadcd87f.png)


このルールでは

Method: `POST`
Path: `/comments.php`

の条件に合致するリクエストに Threshold Signal として作成した `Comment Submission` シグナルを付与してリクエストをカウントします。

同じ IP アドレスからこのリクエストが1分間に10回記録された場合 Rate limit が発動します。(つまり9回しかコメント出来なくなります）

Action type には `Block`、Match Type には `Rule conditions` が指定されているので、カウントルールと同様に `/comments.php` に対する POST リクエストをブロックします。

ブロックは Duration に指定した 15分間継続します。


## クレジットカード番号の有効性確認へのレートリミット

無効なクレジットカード番号の有効性を確認するリクエストを繰り返しているユーザーにレートリミットを設定します。

先ほどの例と異なり、今回はレートリミットをカウントする条件（無効なカード番号の有効性確認リクエスト）と、閾値を超えた場合に制限する動作（カード番号の有効性を確認するリクエスト）が異なります。
そのため、以下の2つのルールが必要となります。

A.  Request ルール: カード番号の有効性確認を行うリクエストにカスタムシグナルを付与
B.  Rate limit ルール: 無効なカード番号の有効性確認リクエストを行ったIPアドレスに対するルール

まずは A の Request ルールから作成します。Site Rules から Type に Request を選択します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128569/806f4de2-0894-458b-9948-74dd92dd1e1a.png)

A のカード番号の有効性を確認するリクエストは `/checkout-payment.php` への `POST` リクエストとし、そのリクエストに `Credit Card Attempt` カスタムシグナルを付与します。

続いて B のレートリミットルールを設定します。Site Rules から新たに Rate limit ルールを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128569/c0e67dcd-c27f-4aa8-b6ce-1724b503b68e.png)

Conditions には A で作成した `Credit Card Attempt` が付与され、かつレスポンスが `401` だったものを条件とします。

Client Key にはデフォルトの `IP address`

Threshold Signal には Add signal から `Credit Card Failure` を作成して設定します。

10分以内に同じ IP アドレスから `Credit Card Failure`(Threshold signal) が5回記録されると、その IP (Client Key)からの `Credit card Attempt`(Action signal) がブロック(Action type) されます

ブロックは Duration で指定した 5分間継続されます。

# まとめ
Fastly NGWAF の Advanced Rate limiting 機能を活用することで、ユーザーや Bot からの過剰なアクセスを自動的に制限することが出来ます。機能の詳細や制約事項等については[Advanced rate limiting](https://docs.fastly.com/en/ngwaf/working-with-advanced-rate-limiting-rules) ごご参照ください。