【AWS】WAF v2で、特定のパスにアクセスできるIPを制限してみる

## 初めに
オークファンのライです。
一年ぶりの記事ですね！

この時期は、AWSがre:Inventを開催し、いろいろ新機能を発表し、記事を読むだけで一日終わりますねw
その中に、WAFに大きな[アップデート](https://aws.amazon.com/jp/blogs/aws/announcing-aws-managed-rules-for-aws-waf/)があり、AWS WAFはv2になりました。

早速WAFv2をやってみます
今回は `特定のパスにアクセスできるIPを制限してみる`

## 作ってみる
### IP set
![スクリーンショット 2019-12-05 17.32.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/7d7a2802-8662-7912-7518-8405c9fd65d8.png)

- IPを登録して作成する
- CIDR何個も登録した場合は、改行区切りで書く

### Rule Group
- `Rule Group` をいい感じに作ります
![スクリーンショット 2019-12-05 17.51.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/5376be3a-6391-0562-b2ba-d85c026854f6.png)

![スクリーンショット 2019-12-05 17.57.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/c846bd55-13fd-35e0-cf05-5314d9f44921.png)

- ルールはあとに作成するので、一旦パス
- キャパシティはとりあえず `100` にした
    - ※ 注意、あとに変更できない

![スクリーンショット 2019-12-05 17.58.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/c14ab6cb-5a91-2b57-cded-73f0cc0f9b49.png)

- ルールがまだ作ってないので、すきっぷ

![スクリーンショット 2019-12-05 17.58.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/7989784e-4d10-7d3b-d2af-0ad595181e4a.png)


- 作成する

### Rule
- ルールの作成
![スクリーンショット 2019-12-05 18.05.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/658a34b9-0cbe-ea37-e122-7ba3805766c6.png)
![スクリーンショット 2019-12-05 18.06.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/df748212-88d3-e90c-1257-d45c4e2dbf7d.png)
![スクリーンショット 2019-12-05 18.06.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/fc615474-d154-f049-f1c3-8005e61bdd5b.png)



- 最初は試しに、 `特定のIP` と `指定のパス(/test)` だとブロックするルールを作成し、検証する
    - 設定は画像に参考してください〜

![スクリーンショット 2019-12-06 12.59.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/b62b0823-200f-a1e5-d464-8bf882d77dd0.png)


- このルールのキャパシティは `3` ですね

![スクリーンショット 2019-12-06 13.01.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/ef1e8e70-32a0-b531-dfe5-159aa5d8b5d9.png)


- また試しにもう一個条件入れてみる
    - `Query` が `test` が入るとブロックする条件を追加する
- 現在のブロック条件は `指定したIPかつパスが/testかつQueryがtest` 入るリクエストですね

![スクリーンショット 2019-12-06 13.05.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/de9f8906-6909-d252-b6a2-26f150ac9dcd.png)


- キャパシティが `13` になった
    - 計算式が不明


### ACL
- ACLを作る
![スクリーンショット 2019-12-06 13.07.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/9f1b8561-8bdd-3333-2713-a01e13de4039.png)


- 別途で作ったALBとアタッチする
    - ALBの作り方は割愛させていただきます
![スクリーンショット 2019-12-06 13.17.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/14d348d8-8a1d-2a5d-8ce3-302f028e3e5e.png)


- 先程作ったルールクループを入れる

![スクリーンショット 2019-12-06 13.09.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/1cdb8c49-60b7-c976-d394-2b123cc845db.png)


- `100` キャパシティを消費した
- `Default Action` を `Allow` にする
![スクリーンショット 2019-12-06 13.10.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/1705a73f-43e8-44a8-1bd2-b0276ed88e03.png)


- ルールが１個しかないので、rule priority設定なし
![スクリーンショット 2019-12-06 13.11.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/6ce07ced-ce97-df15-b373-4a9554ff09f6.png)


- 確認し、作成する

## アクセスしてみる
- `http://{ALB_HOST}/` にアクセス
    - 制限されたIPだが、特定のパスではないので、ブロックしてない
![スクリーンショット 2019-12-06 13.23.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/b59c2a23-ceeb-e621-0caf-ea4bea8c0394.png)


- `http://{ALB_HOST}/test?test=1` にアクセスすると
    - 特定のパスにアクセスと、IP制限されたので、ブロックされた
![スクリーンショット 2019-12-06 13.23.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/a02d7eed-eb3c-ea21-5651-c768e853be16.png)



- 次は本番の `特定のパスにアクセスできるIPを制限してみる`

## 特定のパスにアクセスできるIPを制限してみる
- まあ、 `NOT` Statementを使えばいいよね
![スクリーンショット 2019-12-06 13.26.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/1ab7e98a-0596-376b-2dfd-d770f08c37e0.png)


- えっ、ちょっと待って、 `AND` Statementと併用できない
    - これで特定のパスだけ、特定のIPしかアクセスできないことを設定できない
- この場合、現在はJsonで自分が書くしかないみたい
    - 右上の `Rule JSON editor` をクリックする
    
![スクリーンショット 2019-12-06 13.34.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/9bf75690-e77a-f0f4-d3c0-464df53455b8.png)


- https://docs.aws.amazon.com/waf/latest/APIReference/API_CheckCapacity.html#API_CheckCapacity_RequestSyntax
- IPsetのARNはどこにも記載していない。。。
    - 自分でなんとなく指定するしかない
        - ちなみに、IPsetのページで `IPset ID` を確認することができる
    - `arn:aws:wafv2:ap-northeast-1:{AWSのアカウントID}:regional/ipset/{IPset Name}/{IPset ID}`

```json
{
  "Name": "test-rule2",
  "Priority": 0,
  "Statement": {
    "AndStatement": {
      "Statements": [
        {
          "NotStatement": {
            "Statement": {
              "IPSetReferenceStatement": {
                "ARN": "arn:aws:wafv2:ap-northeast-1:{AWSのアカウントID}:regional/ipset/{IPset Name}/{IPset ID}"
              }
            }
          }
        },
        {
          "ByteMatchStatement": {
            "SearchString": "/test2",
            "FieldToMatch": {
              "UriPath": {}
            },
            "PositionalConstraint": "STARTS_WITH",
            "TextTransformations": [
              {
                "Priority": 0,
                "Type": "NONE"
              }
            ]
          }
        }
      ]
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "test-rule2"
  }
}
```
- 保存して終了

![スクリーンショット 2019-12-06 13.43.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/4b3b783d-4096-9cac-ba6a-9ad36a30093c.png)

- `test-rule2` が作成できました
    - `test-rule2` を選択し、 `Edit` をクリックして修正画面に入る
- 何故か `"SearchString": "/test2"` のところが、勝手に `Buffer` に変更されている

![スクリーンショット 2019-12-06 13.41.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/9d9c969b-62e8-8a38-b6c0-2ee02372650c.png)

- とりあえず、テストしてみよう。。。


### アクセスしてみる
- 指定したIPで `http://{ALB_HOST}/test2` にアクセス
    - できました
![スクリーンショット 2019-12-06 13.48.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/beda14ea-6fa9-4124-1b23-88ba0ca260a1.png)


- 他のIPで `http://{ALB_HOST}/test2` にアクセス
    - ブロックされた
        - `Buffer` に変更されましたが、一応ブロックしてますね

![スクリーンショット 2019-12-06 13.49.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309401/3b5b2e5c-2da9-fa21-615c-ca70b0515dfe.png)



## 最後に
ACLごとのルールの数が緩和され、AWSマネージドルールグループも使えるWAFv2ですが、色々設定が便利になった反面、使いにくくなったところもありますね。

特に以下数点気になる事があります

- ルールグループやACL内にしかルールを定義できない
    - ルールを使い回す事ができない
- ルールグループのキャパシティが変更できない
    - 簡単に変更できるのも問題になるけどね
- GUIで簡単に複雑なルール条件を作ることができない
    - Json Editorの利用が必要
- WAFv2のJson Editorで作成したルールの中身を勝手に変更される
    - 正直、使いにくい
- 日本語のドキュメントが整っていない

現在はまだ使い勝手が悪いですが、
いつか上記のことを更新で改善されたら、今の旧WAFのACLをWAFv2に移行しようと思います