Azure Log Analytics / Microsoft Sentinel で IP アドレスに国情報を付与する

> 2024.4.9 更新

Azure KQL 側で、標準関数が提供されました。こちらの記事は古いものになります。

https://qiita.com/hisnakad/items/2ea55bcd904ccbda7ef1


# 1. はじめに
Azure 環境で診断ログ（監査ログ）を Log Analytics / Microsoft Sentinel で監視することが多いと思いますが、接続元の国情報を調査したい、といったニーズがありましたので、方法をご紹介したいと思います。

# 2. 想定とするリソース
Azure 環境において、外部からアクセスするリソースとしては以下のリソースが考えられます。

- Azure Front Door
- Azure Application Gateway / アクセスログ
- Azure Web Application Firewall
- Azure Firewall
- Azure アクティビティログ
- Azure AD サインインログ

2022.11 現在、残念ながら接続元の国情報はフィールドとして付与されておりません。

- [[参考] Azure Front Door のアクセスログフォーマット](https://learn.microsoft.com/en-us/azure/frontdoor/standard-premium/how-to-logs)
- [[参考] Azure Application Gateway アクセスログフォーマット](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/web-application-firewall-logs#access-log)
- [[参考] Azure Application Gateway / Web Application Firewall ログフォーマット](
https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/web-application-firewall-logs#firewall-log)

# 3. 実現方法 - KQL を用いて外部 DB にルックアップする！
構成のイメージを以下ご紹介します。
やり方は簡単で KQL (Kusto Query)で備わっている外部 DB ルックアップ関数を用いて、IP のフィールド情報に対してマッチングする国情報を付与することが出来るようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/50709509-c200-c1c9-fcdb-a408ae1f58c4.png)

参照先となる Maxmind Geolite2 Free Geolocation Dataはダウンロードして、Github や Azure Storage に格納し、自己管理で更新することをお勧めします。

https://dev.maxmind.com/geoip/geolite2-free-geolocation-data


# 4. クエリー例
今回、2015/4/21 に作成された古いデータですが、テスト用途に以下の公開レポジトリデータに対して lookup するクエリー例となっています。最新の Maxmind GeoLite2 Geolocation でクエリーをかけたい場合は、ご自分で用意することをお勧めします。

https://github.com/datasets/geoip2-ipv4

**[2024/3/7]** 2024.3 の最新 Maxmind GeoLite2 Country DB を抽出してみました。

https://github.com/hisashin0728/geolite2ipv4country

Target URL を以下に変更して試してみてください。
```
https://raw.githubusercontent.com/hisashin0728/geolite2ipv4country/main/geolite2-ipv4.csv
```
# 4.1 Azure Activity Log に対する国情報検出例
※project でフィルタしているフィールドについてはサンプルなので、適時カスタマイズ下さい。

```sql
let IP_Data = external_data(network:string,geoname_id:long,continent_code:string,continent_name:string ,country_iso_code:string,country_name:string,is_anonymous_proxy:bool,is_satellite_provider:bool)
    ['https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv'];
AzureActivity 
| where isnotempty(CallerIpAddress)
| evaluate ipv4_lookup(IP_Data, CallerIpAddress, network, return_unmatched = true)
| project TimeGenerated, Caller, CallerIpAddress, CategoryValue,OperationNameValue,ResourceProviderValue,ActivityStatusValue,ResourceGroup,continent_name,country_name
```
クエリー結果サンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/94cdc441-7963-f9e4-aac4-250c062a9a67.png)


# 4.2 Azure Application Gateway アクセスログに対する国情報検出例
※project でフィルタしているフィールドについてはサンプルなので、適時カスタマイズ下さい。

```sql
let IP_Data = external_data(network:string,geoname_id:long,continent_code:string,continent_name:string ,country_iso_code:string,country_name:string,is_anonymous_proxy:bool,is_satellite_provider:bool)
    ['https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv'];
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayAccessLog"
| evaluate ipv4_lookup(IP_Data, clientIP_s, network, return_unmatched = true)
| project TimeGenerated, Category, requestUri_s, userAgent_s, httpMethod_s, instanceId_s, clientIP_s, host_s, requestQuery_s, httpStatus_d, originalRequestUriWithArgs_s, country_name
```
クエリー結果サンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/0be6ce44-bfd1-84fe-4795-eedd41898394.png)


# 4.3 Azure Application Gateway / Azure WAF ログに対する国情報検出例
※project でフィルタしているフィールドについてはサンプルなので、適時カスタマイズ下さい。

```sql
let IP_Data = external_data(network:string,geoname_id:long,continent_code:string,continent_name:string ,country_iso_code:string,country_name:string,is_anonymous_proxy:bool,is_satellite_provider:bool)
    ['https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv'];
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| evaluate ipv4_lookup(IP_Data, tostring(clientIp_s), network, return_unmatched = true)
| project TimeGenerated, Category, requestUri_s, Message, ruleId_s, hostname_s, policyScope_s, continent_name, country_name
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/5fce020b-c90d-d42f-f113-0edd99b2904a.png)

# 5. まとめ
Azure では送信元の国情報のフィールドをログとして出していないようなので、LogAnalytics ワークスペースの活用、および Micorosoft Sentinel の活用例として作ってみました。本記事がどなたかの参考になれば幸いです。

＊本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。

# 6.参考情報
https://dev.classmethod.jp/articles/geolite2-python/