Splunk で NetworkX を使った分析と可視化が出来るってよ


# はじめに

以前、[グラフ・ネットワークをSplunkで作る](https://qiita.com/maroon/items/38be94ac6b3fb765274c)をご紹介しましたが、もっとすごい可視化ツールが出たということで試してみました。　本格的に NetworkX を使ったネットワーク可視化がお手軽に利用できるようになります。

# ツールの紹介

3D Graph Network Topology Visualization
https://splunkbase.splunk.com/app/4611/#/details　


まずはどんなことが出来るかイメージをみてください。

![networkx.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/d375749d-85ed-289e-c1f7-7d2a59cb2625.gif)

こんなかっこいいグラフが SPLだけで描けます。

また、Networkx を使った分析により、接続が多いノードを抽出したり、全体に影響度が高いノードを抽出するなども計算してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/3d9b84d5-3b55-a769-b4ff-85e52cf028cd.png)


利用するためには Splunk (Enterprise or Cloud) 環境に以下のAppを追加します。
・　Splunk's Machine Learning Toolkit (MLTK)
・　Python for Scientific Computing Libraries 2.0 or later
・　3D Graph Network Topology Visualization

(*) MLTK App には、Global Permission を与える必要があります。 
 

# 使い方

一番シンプルに可視化だけしたいなら、 src , dest , 接続有無　の３つのフィールドがデータにあれば大丈夫です。

```:sample
| inputlookup firewall_traffic.csv 
| head 1000
| stats count by src_ip dst_ip
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/b149f593-e1b1-64b1-6286-24a3856627e2.png)

視覚エフェクトで 「3D Graph Network Topology Viz」 を選択すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/cba874c9-4627-5ce4-3a48-cdf21d1eefb9.png)

めちゃめちゃ簡単！！

フォーマットで Use 3D にすると 3D 表示にもなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/e22a2da7-8f97-3551-5aa3-fbe75f448d35.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/fee9726c-a5d5-23d6-fcee-402aa4c17bab.png)


ノード（球）の大きさやエッジ（辺）の太さ、またカラーを変えたかったら、オプションもあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/87ba6760-25e9-6127-2f52-c0090e1f971a.png)

```
| inputlookup firewall_traffic.csv 
| head 1000
| stats count by src_ip dst_ip
| eval weight_src= 'count'
| eval weight_dest= 'count'
| eval color_src = "#00FF33"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/6f08a6a1-0bac-d2c2-63e4-b7ff3ad783f4.png)



# さらに使いこなす！

これだけでも、ネットワークの可視化が簡単にできて便利なのですが、このAppのすごいところはさらにまだあります。

App の中身をみてみると、いくつかの python コードがおいてあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/de557b45-1a05-3215-3f45-ab73548c5990.png)

これらは networkxを使った、MLTKから呼び出しができるアルゴリズムになっております。

### 用意されているアルゴリズムや機能　（要注意：個人調査）

私がチェックした限りでは以下のアルゴリズムや機能が用意されてました。

**1) GraphCentrality　( compute オプション）**
- degree_centrality
- betweenness_centrality
- eigenvector_centrality
- cluster_coefficient

**2) GraphConnectedComponents**
- weakly_connected_components

**3)  GraphLabelPropagation**
- label_propagation_communities

**4) MinimumSpanningTree**
- minimum_spanning_tree

それぞれの機能については、私も詳しくないので他のサイトでご確認頂くこととして、その中の一部について使ってみたいと思います。
使い方は、MLTK の fitコマンド に続いて上記のアルゴリズムを指定し、src / dest を引数にします。GraphCentrality アルゴリズムについては、computeオプションで、いくつかのアルゴリズムを指定できます。（複数指定も可能）


### 接続数の多いノードを探す (degree_centerality) 

```
| inputlookup firewall_traffic.csv 
| head 1000
| stats count by src_ip dst_ip
| fit GraphCentrality src_ip dst_ip compute="degree_centrality" 
| stats max(degree_centrality) as degree_centrality by src_ip
| sort - degree_centrality
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/90368136-e155-7fc7-c5eb-099d5cd582d4.png)


上記の結果、109.197.174.142 が最も接続数が多いという結果になりました。

本当にそうか、可視化グラフで確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/b0dee2ec-af84-e3e8-561f-c7dcd77db47d.png)

グラフには、明らかなに接続数が多い円がありますが、その中心をマウスオーバーすると、 "109.197.174.142" となっており、同じ結果がえられました。

このようにはっきりしていれば、グラフからわかりますが、２つ目以降だとわかりづらいですよね。その場合計算してくれたものがわかると嬉しいですね。

### 一番多い中継地点となっているノード (between_centrality)

今度は分かりやすいように少しデータ量を減らしてみます。

```
| inputlookup firewall_traffic.csv 
| head 100
| rename src_ip as src dst_ip as dest
| stats count by src dest
| fit GraphCentrality src dest compute="betweenness_centrality"
| sort - betweenness_centrality
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/67d6b2bf-1eb7-32e6-af8b-b9617a26a4b6.png)

src が 73,147,88,91 が一番大きい値になりました。グラフでも確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/71dffbc7-3592-60d8-15f5-4ff9002c2558.png)

確かに一番中継している数が多いノードのように見えます。

### ネットワークにとって重要なノード (eigenvector_centrality) 

数学的な詳しいことは分かりませんが、固有ベクトルの中心性が重要度をはかるファクターのようで、この eigenvector_centrality がそれを計算してくれます。

データ量を下に戻して計算してみます。

```
| inputlookup firewall_traffic.csv 
| inputlookup firewall_traffic.csv 
| head 1000
| rename src_ip as src dst_ip as dest
| stats count by src dest
| fit GraphCentrality src dest compute="eigenvector_centrality"
| stats max(eigenvector_centrality) as eigenvector_centrality by src 
| sort - eigenvector_centrality
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/c0d3d852-14b3-2c97-74d9-7b93d5962445.png)

109.197.174.142 が一番重要と出ました。また１番が突出してて、４番以降は0というのも面白い結果です。

# 最後に

ノード数が大きくなると計算するために、CPU / Memoryに負荷がかかります。そのためサーバースペックにも依存してしまいますが、大きいデータを分析するためにはDLTKを使うことで解決できるかもです。 そこでは GPUを使った計算の分散や、Spark GraphX を使った分散機能が利用できるとのことです。
詳細は、参考Blogをご覧ください。

# 参考Blog

Chasing a Hidden Gem: Graph Analytics with Splunk’s Machine Learning Toolkit
https://www.splunk.com/en_us/blog/machine-learning/chasing-a-hidden-gem-graph-analytics-with-splunk-s-machine-learning-toolkit.html

Understanding and Baselining Network Behaviour using Machine Learning - Part I
https://www.splunk.com/en_us/blog/machine-learning/understanding-and-baselining-network-behaviour-using-machine-learning-part-i.html

Understanding and Baselining Network Behaviour using Machine Learning - Part II
https://www.splunk.com/en_us/blog/machine-learning/understanding-and-baselining-network-behaviour-using-machine-learning-part-ii.html