Security LakeにWAFのログを入れてAthenaでクエリしたい

# やりたいこと
Amazon Security Lakeが、AWS WAFのログサポートを2024年5月に開始しました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/05/amazon-security-lake-supports-logs-aws-waf/

WAFとSecurity Lakeを連携させて、お試しでAPI GWを建ててWAFと連携し、出てきたログをAthenaで見てみたいと思います。API GWなのは、一番楽そうだったからです。

# やってみる

## Security Lakeの作成
いつも使っているAWSアカウントでSecurity Lakeのコンソールに行って作成してみたところ、「別のAWSアカウントに委任する」という選択肢しか出てきませんでした。
そのため、別のAWSアカウントを指定しました。以下はその委任先のAWSアカウントでの作業です。

さて、委任先のAWSアカウントで再びSecurity Lakeのコンソールに行って、構築していきます。

ログとイベントソースの中にAWS WAFがデフォルトだと入っていなかったので、チェックして加えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/8f934dff-1000-7b55-3a79-a20c562f9455.png)

リージョンは、とりあえず東京のみにしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/4123d3f0-7110-2736-e6a5-244b92eca78d.png)

これ以外はデフォルトで作成。2分くらいで完了しました。

試しにAthenaで見たところ、WAFのテーブルも作成されていました。Glue DBとテーブルが勝手に用意されるみたいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/86eaf3c0-8e0d-394a-014b-bb1e57d04bd7.png)

## WAFとAPI GWの作成
WAFの設定と、WAFを使うための何かしらの口としてAPI GWを建てます。

まずはWAFのWeb ACLsを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/8321ac20-4ae1-d463-771a-135b77d33af2.png)

ルールは、AWSマネージドルールである`AWSManagedIPReputationList`を指定してみます。これは何でもOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/b8fa3b61-51b9-a2da-5d69-34342bedb95b.png)

:::note warn
Web ACLsにルールを付けないと、Security Lakeにログが溜まっていかなかったので注意。
:::

次にAPI GWを作成します。
とりあえず作って、ルート（/）配下にGETメソッドを作成、devステージを構築しました。
種類はREST APIで、GETメソッドの統合タイプはMockを使ってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/ba7a220f-c0aa-9a27-7217-40621dbab0b4.png)

そして、ステージからウェブACLに先ほど作成したWAFのルールを紐づけます。これで、API GWへのアクセスをWAFでチェックできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/c796fd2f-7af1-4ed9-2757-fb8ad5dbbdfc.png)

## Security LakeとWAFの統合を確認
ここまで実行すると、Security LakeでWAFにチェックを入れているので裏で勝手にSecurity LakeとWAFが統合されます。その統合は、WAFのルールの「Logging and metrics」タブで確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/4b3d8f7b-c47a-50fc-a1e1-c0fb2caf7a66.png)

:::note warn
上記のようにStatusが`Enabled`になっていたら統合されているのですが、私の場合は作って数分待っても`Disabled`だったので、一旦放置して約8時間後に確認したら`Enabled`となっていました。
:::

## テストアクセス
ここまででWAFとAPI GWが紐づけられ、かつWAFのログがSecurity Lakeで見られるようになっているはずです。
まずは、API GWにアクセスしてみて、WAFが動いていることを確認してみます。
API GWのステージの画面の「URL を呼び出す」に記載されているのが、このAPI GWのURLです。このアドレスに、ブラウザで何回かアクセスしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/84898a90-cd21-3316-8856-a11c7d9c0fff.png)

その後WAFのルールの画面を見てみると、Totalのところに件数が表示されています。これで、API GWへのアクセスをWAFでチェックできていることが分かりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/e342acc8-91f5-0657-7921-8806afa392fa.png)

## Athenaでログを確認
ここからはいよいよ、Athenaで見ていきます。
先ほどAPI GWに何回かアクセスしたので、そのログがSecurity Lakeに溜まって、Athenaで確認できるはずです。

以下のように、Athenaで確認することできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/1d084d33-6a3a-3506-11c4-83ea9ca41444.png)

:::note warn
API GWにアクセスしてからAthenaでログが見られるようになるまで、**3~5分ほどのライムラグ**がありました。
:::

また、GlueのコンソールでWAFのテーブルを見てみると、`Table format`がIcebergになっていました。特に指定はしていませんが、裏では勝手にIcebergテーブルにしてくれるようですね。Icebergならではのタイムトラベルクエリなどが使えて使い勝手が良さそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/92315ec5-a7a2-e5e3-6c25-2da6225eae71.png)

Icebergについては、以下のブログがとても分かりやすく詳しいのでご一読ください。

https://bering.hatenadiary.com/entry/2023/09/24/175953

## Athenaで同一IPからのログの件数をチェック
確認だけだとつまらないので、ありそうなユースケースをAthenaで調査してみます。
今回は、同一IPアドレスからの大量アクセスを調べてみます。

```SQL
SELECT accountid, region, 
       concat(http_request.url.hostname, http_request.url.path) AS url,
       http_request.http_headers[1].value AS ip,
       COUNT(*) AS count
FROM amazon_security_lake_glue_db_ap_northeast_1.amazon_security_lake_table_ap_northeast_1_waf_2_0
WHERE time_dt >= CURRENT_TIMESTAMP - INTERVAL '5' MINUTE  
  AND time_dt <= CURRENT_TIMESTAMP
GROUP BY accountid, region, concat(http_request.url.hostname, http_request.url.path), http_request.http_headers[1].value;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/84f3adc9-775c-5eaa-6aee-14cac252eecb.png)

5分前から現在までで、同一のAWSアカウントID、リージョン、対象のURL、IPアドレスの集計をしています。実際はcountが多い順に並び変えて調査することが多そうですね。

# おわりに
Security Lakeは有効にして紐づけるだけですぐAthenaで検索できるようになるので楽ですね。自前でS3にログを出力してそれをテーブル化して…ということをしなくてよいので、手軽にログ調査を始めるには良いサービスだなと思いました。
ただし、ログによっては量が多くなってコストが大きくなる可能性があるので注意してください。

https://aws.amazon.com/jp/security-lake/pricing/