Cloudflare Logpush を Splunk Cloud Platform にプッシュ

## やっていること
ある組織からインターネットへの通信を [Cloudflare Gateway](https://www.cloudflare.com/ja-jp/products/zero-trust/gateway/) で管理し、その [ログ](https://developers.cloudflare.com/cloudflare-one/insights/logs/gateway-logs/) を、[Splunk Cloud Platform](https://www.splunk.com/ja_jp/products/splunk-cloud-platform.html)で可視化。


## 構成

```mermaid
graph LR
  nw1([My Network]) --> Router --Magic WAN / IPSec--> gw((Gateway))
  nw2([My Network]) --> Local_DNS_Forwarder --DNS DoH DoT--> gw((Gateway))
  nw3([My Network]) --> Local_HTTP_Proxy --HTTP CONNECT--> gw((Gateway))
  cl1(My Device + WARP)-- WARP / WireGuard --> gw((Gateway))
  cl2(My Device) -- DNS DoH DoT --> gw((Gateway))
  cl3(My Device) -- HTTP CONNECT --> gw((Gateway))
  gw((Gateway))-->in((Internet))
  gw((Gateway))-->sp[(Splunk Cloud)]
  style gw fill:#F48120,color:#fff
  style sp fill:#60AB31,color:#fff
  style in fill:#ffff00
```

今回は [Magic WAN](https://developers.cloudflare.com/magic-wan/) を使った [IPSec](https://developers.cloudflare.com/magic-wan/reference/tunnels/#ipsec-tunnels) 接続で試した。

## 環境
### Splunk Cloud Platform

+ 無料トライアル版 15日... → [Splunk Cloud Platform](https://www.splunk.com/ja_jp/products/splunk-cloud-platform.html)
+ Cloudflare テンプレート → [Cloudflare App for Splunk](https://splunkbase.splunk.com/app/4501)
対応中のログ一覧 (↑の Details タブに記載)

|Log Type|Source Type|
|-|-|
|HTTP Request (WAF や CDN など)|cloudflare:json|
|Gateway Network logs|cloudflare:network|
|Gateway HTTP logs|cloudflare:http|
|Gateway DNS logs|cloudflare:dns|
|Access requests logs|cloudflare:access|
|CASB Findings logs|cloudflare:casb|
|Audit logs|cloudflare:audit|

今回の対象は下記3つ。
+ `cloudflare:network`, 各デバイスからの IP/TCP/UDP/TLS 通信（Stateful Firewall）
+ `cloudflare:http`, 各デバイスからの HTTP/HTTPS 通信（Forward Proxy）
+ `cloudflare:dns`, 各デバイスからの DNS 通信（Full Resolver）

#### Splunk Cloud の申込みと Cloudflare App の追加

+ [Splunk Cloud Platform の開始](https://www.splunk.com/ja_jp/resources/videos/splunk-cloud-registration.html)
+ [Cloudflare App for Splunk](https://splunkbase.splunk.com/app/4501) のインストール
Apps > Find More Apps
![Screenshot 2023-07-02 at 1.07.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/5cf00430-9099-e5ea-2a65-33a9778167ff.png)
![Screenshot 2023-07-02 at 1.07.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/acaebd1f-4461-b48d-0352-f47edee19ab4.png)

`cloudflare` を入れて Cloudflare App for Splunk を見つける
`Install` (↑はインストール後のため Open App になっている)

#### Index の追加
+ Settings > Indexes > New Index
![Screenshot 2023-07-01 at 18.25.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/3ed299bd-606b-23a0-c855-ddaeaa1d255a.png)
![Screenshot 2023-06-29 at 9.34.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/91a71679-60dc-132b-dfba-14e9656351d3.png)

Index name: cloudflare
Index Data Type: Events
Max raw data size: 適当 (0 MB)
Serchable retention (days): 適当 (30 Days)

>`Index name`
> App の各マクロはデフォルトで `cloudflare` を参照しているので、それに合わせている。別の名前にする際はマクロ `cloudflare_zt_index` が参照するIndex名も変える。


#### Data Inputs の追加

##### HTTP Event Collector (HEC)
+ Settings > Data Inputs > HTTP Event Collector > + Add New
![Screenshot 2023-06-29 at 9.37.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/1a821fe2-8cb8-56e2-b938-a6e96f6a1f5d.png)
![Screenshot 2023-07-01 at 9.52.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/c435ca15-f35c-3455-30b7-60fa1cad491b.png)


Source type > Select > cloudflare:network
Index > cloudflare

>`Source type` は Automatic でもいいかも


##### HTTP と DNS も同じように追加

Source type > Select > cloudflare:http
Index > cloudflare

Source type > Select > cloudflare:dns
Index > cloudflare

+ 各コレクターの `Token Value` は後ほど Cloudflare ダッシュボードで入力する
![Screenshot 2023-07-01 at 18.08.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/3e993024-11ec-0cfe-6afa-6899bd03a414.png)

#### Source Types の編集

+ Settings > Source Types
`Show only popular` のチェックを外す
search `cloudflare`
![Screenshot 2023-07-01 at 18.53.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/0d65f2b6-b9b2-b239-5316-27e8cc7910f2.png)
+ それぞれの Source Type で [Regex Expression を編集](https://developers.cloudflare.com/fundamentals/data-products/analytics-integrations/splunk/#task-1---install-and-configure-the-cloudflare-app-for-splunk)
Pattern:
`([\r\n]+)\{\"\w+\"`
を
`([\r\n]+)`

<details><summary>Splunk の解説</summary>

* Specifies a regex that determines how the raw text stream is broken into initial events, before line merging takes place.
*This sets SHOULD_LINEMERGE = false and LINE_BREAKER to the user-provided regular expression.
* Defaults to ([\r\n]+), meaning data is broken into an event for each line, delimited by any number of carriage return or newline characters.
* The regex must contain a capturing group -- a pair of parentheses which defines an identified subcomponent of the match.
* Wherever the regex matches, Splunk considers the start of the first capturing group to be the end of the previous event, and considers the end of the first capturing group to be the start of the next event.
* The contents of the first capturing group are discarded, and will not be present in any event. You are telling Splunk that this text comes between lines.
</details>



### Cloudflare
#### Logpush (Account)

+ 分析とログ > Logs > Logpush ジョブを追加する > Gateway network
![Screenshot 2023-07-01 at 9.37.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/17b74317-9dc7-d70d-568b-b9702d9f690e.png)
+ すべてのフィールドを選択 (とりあえず全部。パフォーマンスへの悪影響はない。後で取捨できる)
![Screenshot 2023-07-01 at 9.37.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/61a6ec34-1a0e-4d8a-a3cc-7028cf88c199.png)
+ プッシュ先は Splunk
![Screenshot 2023-07-01 at 9.38.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/cb9ee057-0477-c8ec-c8cb-4462b43250bc.png)
+ Splunk HEC の接続情報を入力
![Screenshot 2023-07-01 at 9.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/d21cc588-e2f3-91e0-a1ef-e76535776193.png)
+ 証明書のエラーが出たら、skip verify は `はい` に。
![Screenshot 2023-07-01 at 9.54.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/90e42fe1-dfc9-bb70-b04a-8e0ed16ad662.png)
+ 設定内容

|項目|設定値|補足|
|-|-|-|
|Splunk raw HTTP イベント コレクタのURL|\<Splunk Cloud Platform管理ダッシュボードのホスト名>:8088/services/collector/raw|Settings > Data Inputs >HTTP Event Collector > Global Settings にポート番号あり ![Screenshot 2023-07-01 at 20.59.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/a4e78f63-b619-c74a-926e-42002583ca1e.png)|
|チャネルID|GUIDジェネレータなどで自作|[ジェネレータ](https://www.guidgenerator.com/) や `python -c 'import uuid; print(uuid.uuid4())'` |
|認証トークン|Splunk%20<トークンの値>|トークンは HTTP Event Collector から見れる。`Splunk%20`を頭に。|
|ソースタイプ|cloudflare:network|タイプごとに個別の Logpush ジョブを作成|
|Insecure skip verify|はい|HEC が検査不合格の証明書を使っていたので true|


<details><summary>作成したジョブの確認や変更は <a href ="https://developers.cloudflare.com/logs/get-started/enable-destinations/splunk/#manage-via-api">API</a> で</summary>

```
curl -Ls "https://api.cloudflare.com/client/v4/accounts/$ACCOUNTID/logpush/jobs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: $CTYPE" | jq '.result[]|select (.destination_conf|startswith("splunk"))'

{
  "id": 258376,
  "dataset": "gateway_network",
  "frequency": "high",
  "kind": "",
  "enabled": true,
  "name": null,
  "logpull_options": "fields=AccountID,Action,Datetime,DestinationIP,DestinationPort,DetectedProtocol,DeviceID,DeviceName,Email,OverrideIP,OverridePort,PolicyID,PolicyName,SNI,SessionID,SourceIP,SourceInternalIP,SourcePort,Transport,UserID&timestamps=rfc3339&CVE-2021-44228=false",
  "destination_conf": "splunk://***.splunkcloud.com:8088/services/collector/raw?channel=***&header_Authorization=Splunk%20***&sourcetype=cloudflare:network&insecure-skip-verify=true",
  "last_complete": "2023-07-01T12:02:55Z",
  "last_error": null,
  "error_message": null,
  "time_created": "2023-07-01T00:54:41Z"
}
```
</details>

+ プッシュ !!!
![Screenshot 2023-07-01 at 9.54.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/cc019cee-228d-53ff-7e60-d865fbc1a08d.png)

<details><summary>所有権チャレンジの探し方 @ Splunk</summary>

`index=cloudflare | spath filename | search filename="*"`
![Screenshot 2023-07-01 at 22.03.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/20ee7944-653f-0395-14f3-222883814f5f.png)
</details>

##### HTTP と DNS も同じように追加
+ チャネルID
+ 認証トークン
+ ソースタイプ

が別。後は共通。

## 動作確認

+ Apps > Cloudflare App for Splunk
![Screenshot 2023-07-01 at 9.55.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/486201b2-a733-f45c-3549-2f9b9b8b18be.png)

+ Zero Trust > Cloudflare - Zero Trust - Gateway
![Screenshot 2023-07-01 at 9.55.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/6e9008e2-1e7c-707c-79a0-4a26953813bb.png)

+ HTTP (各デバイスからの HTTP/HTTPS 通信)
![Screenshot 2023-07-01 at 22.08.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/36b101a6-7411-2637-3f8e-9dc04b468283.png)
![Screenshot 2023-07-01 at 22.08.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/2a4117b2-40d8-801b-b869-d0c5e5743e39.png)

+ Network (各デバイスからの IP 通信)
→ デフォルトとは違う、カスタマイズ後の表示。理由は後述。
![Screenshot 2023-07-01 at 15.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/f0e0f2c7-3859-da2c-91c7-e2c1fab6e312.png)

+ DNS (各デバイスからの DNS 通信)
![Screenshot 2023-07-01 at 22.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/1e07cc9d-4bb0-e879-fdf3-ffa481219f24.png)
![Screenshot 2023-07-01 at 22.13.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/4daf389a-0b4f-50ea-d77f-e0af1cd7447b.png)

## カスタマイズ

`Network` はデフォルトでは思うような表示とならなかった。
下記のようにホスト名で表示され、実際にブロックしていたポート宛の通信が Blocked にあらわれていない。

![Screenshot 2023-07-01 at 12.17.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/032cca18-2ec2-32b1-67e6-f956402a22a0.png)

### ソースの編集

+ Apps > Manage Apps
![Screenshot 2023-07-01 at 15.16.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/e4a01d70-5dc4-0004-7411-5cb298417891.png)

+ Search `cloudflare` > View objects
![Screenshot 2023-07-01 at 13.10.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/9af108e9-d06c-8828-9301-dfe20b867053.png)

+ Search `gateway` > dashboard_cloudflare_zero_trust_gateway
![Screenshot 2023-07-01 at 22.23.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/4ffeb7a7-6c49-ce99-da27-ac896faf28cf.png)

+ XML の当該部分を編集
SNI でフィルタしているため TLS 接続以外が表示されなかった。
宛先IP を基準にするよう編集。
![Screenshot 2023-07-01 at 22.28.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/ae2c36fa-1e41-93a8-15a5-e8517131cd6a.png)

<details><summary>パッチ</summary>

```
--- Splunk.Cloudflare.app.origin.txt	2023-07-01 12:49:07
+++ Splunk.Cloudflare.app.origin.txt.new	2023-07-01 15:28:54
@@ -13,7 +13,7 @@
     <query>search ResolverDecision="*block*"</query>
   </search>
   <search id="network_base_search">
-    <query>`cloudflare_zt_index` sourcetype="cloudflare:network" SNI!="" | where isnotnull(SNI) | fields *</query>
+    <query>`cloudflare_zt_index` sourcetype="cloudflare:network" DestinationIP!="" | where isnotnull(DestinationIP) | fields *</query>
     <earliest>$earliest$</earliest>
     <latest>$latest$</latest>
     <sampleRatio>1</sampleRatio>
@@ -266,7 +266,7 @@
         <title>Click to Drilldown</title>
         <search base="network_base_search">
           <query>search action="*allow*" |stats count as Requests by
-                        SNI | rename SNI as Domain |sort - Requests</query>
+                        DestinationIP | rename DestinationIP as Destination |sort - Requests</query>
         </search>
         <option name="count">5</option>
         <option name="drilldown">row</option>
@@ -274,7 +274,7 @@
         <option name="totalsRow">false</option>
         <option name="wrap">true</option>
         <drilldown>
-          <set token="allow_network_domain">$row.Domain$</set>
+          <set token="allow_network_domain">$row.Destination$</set>
           <set token="allow_network_domain_hidden"></set>
         </drilldown>
       </table>
@@ -285,14 +285,14 @@
         <title>Click to Drilldown</title>
         <search base="network_base_search">
           <query>search action="*block*" |stats count as Requests by
-                        SNI | rename SNI as Domain|sort - Requests</query>
+                        DestinationIP | rename DestinationIP as Destination|sort - Requests</query>
         </search>
         <option name="count">5</option>
         <option name="drilldown">row</option>
         <option name="percentagesRow">false</option>
         <option name="totalsRow">false</option>
         <drilldown>
-          <set token="block_network_domain">$row.Domain$</set>
+          <set token="block_network_domain">$row.Destination$</set>
           <set token="block_network_domain_hidden"></set>
         </drilldown>
       </table>
@@ -304,7 +304,7 @@
       <table>
         <search base="network_base_search">
           <query>search action="*allow*"
-                        SNI="$allow_network_domain$"| table
+                        DestinationIP="$allow_network_domain$"| table
                         Action,DestinationIP,DestinationPort,DeviceName,Email,OverrideIP,OverridePort,PolicyName,SNI,SourceIP,SourceInternalIP,SourcePort,Transport
                     </query>
         </search>
@@ -319,7 +319,7 @@
       <table>
         <search base="network_base_search">
           <query>search action="*block*"
-                        SNI="$block_network_domain$"| table
+                        DestinationIP="$block_network_domain$"| table
                         Action,DestinationIP,DestinationPort,DeviceName,Email,OverrideIP,OverridePort,PolicyName,SNI,SourceIP,SourceInternalIP,SourcePort,Transport</query>
         </search>
         <option name="count">5</option>
```
</details>

## トラブルシューティング

Splunk 素人なので遠回りしてるかもしれないが、やったことは下記。

+ なんか表示されない。
![Screenshot 2023-06-29 at 12.01.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/d3c6d774-98db-887d-ca22-68f5e61ff695.png)
+ マウスホバーで出てくる虫眼鏡 (Open in Search) をクリック
![Screenshot 2023-07-01 at 23.49.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/96c897d6-8529-006e-5614-e62284fd8a93.png)
+ マッチするログが出てくるところまで、絞り込みを緩める
![Screenshot 2023-07-01 at 23.49.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/d52e83d9-75f3-b25c-493a-ad18b7aed45b.png)
+ 出てきたログの中身から、どこのフィルタで漏れているか調べる
![Screenshot 2023-07-01 at 23.46.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/2dedd1da-ec53-7cf9-12ac-6e0d05379339.png)
この場合はログの sourucetype = `cloudflare.html` ということで、フィルタ条件の `cloudflare.http` とマッチしない。Logpush 設定のタイポだったので、直した。

## 感想
### いい点

公開 Web App に対するパフォーマンスやセキュリティの[ログ](https://developers.cloudflare.com/fundamentals/data-products/analytics-integrations/splunk/#task-3---view-the-dashboards)も同じように取れるので、
![Screenshot 2023-07-02 at 0.06.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/080262c5-a36a-e70a-2f8e-a2a5903a40b7.png)


+ 組織ネットワークからの、インターネットへの接続
例）マルウェアに感染したサーバーの外向けの活動

+ 組織ネットワークへの、インターネットからの接続
例）公開サービスの脆弱性を利用したサーバーへの攻撃

という、2方向の情報のやり取りを

+ Cloudflare で一括制御し、Splunk で一括監視

と一元化できるのは、効率がいい。

下図の
+ 1、2 両方とも
+ 双方向に管理

できるので、アタックサーフェスってやつを減らせるんじゃないだろか。

```mermaid
graph LR
  nw1([My Network]) --> gw((Gateway))
  gw((Gateway)) -.-> nw1([My Network])
  in2((Internet)) --1.外発Request IN--> rp((WAF)) --> nw1([My Network])
  nw1([My Network]) -.-> rp((WAF)) -.2.Response OUT.->in2((Internet))
  gw((Gateway))--1.自発Request OUT-->in1((Internet))
  in1((Internet)) -.2.Response IN.-> gw((Gateway))
  gw((Gateway))-->sp[(Splunk Cloud)]
  rp((WAF/CDN))-->sp[(Splunk Cloud)]
  style gw fill:#F48120,color:#fff
  style rp fill:#F48120,color:#fff
  style sp fill:#60AB31,color:#fff
  style in1 fill:#ffff00
  style in2 fill:#ffff00
```


### 悪い点
悪い点というか、Gateway の部分は Logpush の項目自体は豊富なので、さらに役立つアナリティクス画面が作れると思う。HTTP Request のように Gateway の方も今後の機能拡張を期待。

ただ、カスタマイズの例を書いたように、Cloudflare App を利用者側でカスタマイズできそうなので、バージョンアップを待たずに、用途に応じて柔軟にセルフサーブできるのは良いと感じる。

Splunk Cloud Platform が欲しくなった。。。

## 余談

余談だが、Cloudflare のプラットフォームを使う利点は、[Innovating at the Edge](https://www.cloudflare.com/network-edge/) にあると思う。

上の絵では表現できないが、
たとえば、

+ WAF/CDN に関しては、利用者や攻撃者（ユーザーの属する ISP）に近い PoP でサービスを提供
+ Gateway に関しては、利用者（My Network の属する ISP）に近い PoP でサービスを提供

できる。

言い換えると、

+ あなたの Web App を加速、保護する機能はサービス利用者の目の前で稼働
+ 組織の Internet 利用を加速、保護する機能は組織ユーザーの目の前で稼働

するよう、地球上にプロダクトをデプロイしてる。

そもそも、パフォーマンスとセキュリティを両立するのが目的なので、そういう作りになっている。
会社の考えがプロダクトに影響。
[The Network is The Computer ™](https://blog.cloudflare.com/the-network-is-the-computer/) や [Supercloud](https://blog.cloudflare.com/welcome-to-the-supercloud-and-developer-week-2022/)。


## リンク
https://www.splunk.com/ja_jp/products/splunk-cloud-platform.html
https://splunkbase.splunk.com/app/4501
https://developers.cloudflare.com/fundamentals/data-products/analytics-integrations/splunk/
https://developers.cloudflare.com/logs/get-started/enable-destinations/splunk/