NetFlowのコレクタとしてFluentdを利用し、Prometheus・Grafanaを利用し可視化を行った際のメモ
モチベーション
- オープンソースのソフトウェアを利用してNetFlowのデータを可視化したい
ということで、ネットワークシュミレータ上で動作を確認をしてみました
NetFlowとは
ざっくり
- ネットワークのトラフィックの情報を監視・分析するための技術
- 送信元IPアドレス、宛先IPアドレス、TCP/UDPポート番号(フローデータ)などの情報を収集
- ネットワーク機器からフロー情報をフローコレクターに送信し監視・分析することができる
構成とアウトプットのイメージ
-
NetFlowの吐き出すネットワーク機器としてVyOSを利用
①環境準備
①-1 VyOSの準備
- 以下のサイトを参考にVyOSのイメージ作成
①-2 サーバ(Ubuntu)の準備
- 以下のサイトを参考にサーバのイメージ作成
- https://www.eve-ng.net/index.php/documentation/howtos/howto-create-own-linux-host-image/
- 「How to create own custom Linux host for EVE:」の部分からUbuntuをインストール
- 今回は Ubuntuの22.04の Serverをインストール。インストールは Ubuntu Server (minimized) にして最小限の環境を構築
- インストール中に聞かれるSSHサーバは設定
- IPアドレスを以下のサイトを参考に設定
- コンソールでログインできるように以下のサイトを参考に設定
①-3 Fluentdの準備
Fluentdのインストール
- 事前に以下内容を設定
- Fluentdのインストール
- root ユーザで、以下を実施
Fluentdのインストール(Ubuntu 22.04 Jammy)
curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-jammy-fluent-package5-lts.sh | sh
systemctl start fluentd.service
systemctl status fluentd.service
- 以下のサイトを参考にしてます
Fluentdのプラグインのインストール
Fluentdで、NetFlow取得したり、データを整形したり、Prometheusと連携するためにプラグインをインストールする
Fluentdの各プラグインのインストール
apt install make g++ ruby-dev ruby-bundler
/opt/fluent/bin/fluent-gem install fluent-plugin-netflow
/opt/fluent/bin/fluent-gem install fluent-plugin-rewrite-tag-filter
/opt/fluent/bin/fluent-gem install fluent-plugin-prometheus
①-4 Prometheusの準備
Prometheusのインストール
- Prometheusのインストール
- root ユーザで、以下を実施
Prometheusのインストール
apt -y install prometheus prometheus-node-exporter
systemctl enable prometheus prometheus-node-exporter
①-5 Grafanaの準備
Grafanaのインストール
- Grafanaのインストール
- root ユーザで、以下を実施
Grafanaのインストール
wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | tee -a /etc/apt/sources.list.d/grafana.list
apt update
apt -y install grafana
- Grafanaの設定変更
- ローカル環境なので https ではなく http でログインできるように変更
- 「/etc/grafana/grafana.ini」内の「;protocol = http」を「protocol = http」に変更
- ローカル環境なので https ではなく http でログインできるように変更
Grafanaのインストール
root@ubuntsu-netflow:/etc/grafana# diff grafana.ini grafana.ini.org
32c32
< protocol = http
---
> ;protocol = http
root@ubuntsu-netflow:/etc/grafana#
② NetFlowデータ取得と可視化
②-1 VyOSからNetFlowのFlowデータを送信する
コンフィグ設定
- eth0 に PCと接続するIFとしてIP設定(IPv4/IPv6)
- eth3 は Flowコレクタとなるサーバに送信するIFとして設定
- NetFlowは eth0 のIFのトラフィックを監視して 「10.0.0.1」の FlowコレクへNetFlowデータを送信
VyOS設定内容
set interfaces ethernet eth0 address '192.168.1.254/24'
set interfaces ethernet eth0 address '2001:db8:1::254/64'
set interfaces ethernet eth3 address '10.0.0.254/24'
set system flow-accounting interface 'eth0'
set system flow-accounting netflow engine-id '0'
set system flow-accounting netflow server 10.0.0.1 port '4739'
set system flow-accounting netflow timeout expiry-interval '60'
set system flow-accounting netflow timeout max-active-life '60'
set system flow-accounting netflow version '9'
set system host-name 'vyos-netflow'
NetFlowが動作しているか確認する
- フロー対象となるトラフィックを出すためPCからVyOSのIFにPINGを打ち続ける
- VyOSの eth3 をパケットキャプチャして定期的にFlowデータが送信されていることを確認する
- サーバ側はIPアドレスだけ事前に設定(VyOSからのFlowデータ送信前にARP解決ができずに終わってしまうため)
②-2 Fluentd でNetFlowのFlowデータを受信する
コンフィグ設定
- 「/etc/fluent/fluentd.conf」を編集する
- 事前にオリジナルのデータをコピーしておく
- cp -p /etc/fluent/fluentd.conf /etc/fluent/fluentd.conf.org
- 「/etc/fluent/fluentd.conf」を編集
fluentd.conf 設定内容
# NetFlowデータを取得
<source>
@type netflow
tag netflow.event
port 4739
</source>
# デバッグ用に出力
<match **>
@type stdout
</match>
- 設定内容を反映させるため fluentd をリスタート
- systemctl restart fluentd.service
- PCとVyOS間でIPv4とIPv6でPINGを打ち続けて Flowデータをだす
- ログを tail してFlowデータをFluentdで受信していることを確認する
- tail -f /var/log/fluent/fluentd.log
- IPv4とIPv6でそれぞれのテンプレートのフォーマットで受信を確認できます
fluentd.log でFlowデータ受信した内容
▼IPv4
2024-xx-xx 16:11:42.000000000 +0900 netflow.event: {"version":"9","flow_seq_num":"2","flowset_id":"1024","flowEndMilliseconds":"2024-xx-xxT07:11:42.132Z","flowStartMilliseconds":"2024-xx-xxT07:10:33.039Z","in_bytes":5880,"in_pkts":70,"ip_protocol_version":4,"input_snmp":2,"output_snmp":0,"direction":0,"flows":0,"ipv4_src_addr":"192.168.1.1","ipv4_dst_addr":"192.168.1.254","l4_src_port":0,"l4_dst_port":2048,"src_tos":0,"tcp_flags":0,"protocol":1,"in_src_mac":"00:50:79:66:68:b9","in_dst_mac":"50:1f:38:00:b7:00","src_vlan":0,"host":"10.0.0.254"}
▼IPv6
2024-xx-xx 16:11:58.000000000 +0900 netflow.event: {"version":"9","flow_seq_num":"3","flowset_id":"2048","flowEndMilliseconds":"2024-xx-xxT07:11:58.068Z","flowStartMilliseconds":"2024-xx-xxT07:10:48.722Z","in_bytes":7280,"in_pkts":70,"ip_protocol_version":6,"input_snmp":2,"output_snmp":0,"direction":0,"flows":0,"ipv6_src_addr":"2001:db8:1::1","ipv6_dst_addr":"2001:db8:1::254","src_tos":0,"l4_src_port":0,"l4_dst_port":0,"tcp_flags":0,"protocol":58,"in_src_mac":"00:50:79:66:68:b9","in_dst_mac":"50:1f:38:00:b7:00","src_vlan":0,"host":"10.0.0.254"}
②-3 Prometheus で Fluentd の NetFlowデータを取得する設定を行う
Prometheus側の設定
- 「/etc/prometheus/prometheus.yml」を編集する
- 事前にオリジナルのデータをコピーしておく
- cp -p /etc/prometheus/prometheus.yml /etc/prometheus/prometheus.yml.org
- 「/etc/prometheus/prometheus.ymlを編集
prometheus.yml 設定内容
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
external_labels:
monitor: 'example'
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
rule_files:
scrape_configs:
- job_name: fluentd
static_configs:
- targets: ['localhost:24231']
- 設定内容を反映させるため Prometheus をリスタート
- systemctl restart prometheus.service
Fluentd側の設定
- 再度「/etc/fluent/fluentd.conf」を編集する
- IPv4・IPv6で受信データ「in_bytes」をキーにする
- 事前に取得したログからラベルを設定し、必要な物以外はコメントアウト
- 以下の内容に変更し設定内容を反映させるため fluentd をリスタート
- systemctl restart fluentd.service
fluentd.conf 設定内容
fluentd.conf 設定内容
#-----------------------
# Prometheus用
#-----------------------
<source>
@type prometheus
@id in_prometheus
bind "0.0.0.0"
port 24231
metrics_path "/metrics"
</source>
#-----------------------
# NetFlow用
#-----------------------
# NetFlowデータを取得
<source>
@type netflow
tag netflow.event
port 4739
</source>
## デバッグ用に出力
#<match **>
# @type stdout
#</match>
# IPv4とIPv6にデータ分ける
<match netflow.event>
@type copy
<store>
@type rewrite_tag_filter
<rule>
key ipv4_src_addr
pattern /(.*)/
tag netflow.ipv4
</rule>
</store>
<store>
@type rewrite_tag_filter
<rule>
key ipv6_src_addr
pattern /(.*)/
tag netflow.ipv6
</rule>
</store>
</match>
# IPv4用にPrometheusに出力するデータを決める、受信バイト数(in_bytes)をkeyにする、不要なラベルはコメントアウト
<filter netflow.ipv4>
@type prometheus
<metric>
name netflow_ipv4_in_byte
desc NetFlow IPv4 Traffic input byte
type counter
key in_bytes
<labels>
#version ${version}
#flow_seq_num ${flow_seq_num}
#flowset_id ${flowset_id}
#flowEndMilliseconds ${flowEndMilliseconds}
#flowStartMilliseconds ${flowStartMilliseconds}
#in_pkts ${in_pkts}
#ip_protocol_version ${ip_protocol_version}
input_snmp ${input_snmp}
#output_snmp ${output_snmp}
#direction ${direction}
#flows ${flows}
ipv4_src_addr ${ipv4_src_addr}
ipv4_dst_addr ${ipv4_dst_addr}
l4_src_port ${l4_src_port}
l4_dst_port ${l4_dst_port}
#src_tos ${src_tos}
#tcp_flags ${tcp_flags}
protocol ${protocol}
#in_src_mac ${in_src_mac}
#in_dst_mac ${in_dst_mac}
#src_vlan ${src_vlan}
hostip ${host}
</labels>
</metric>
</filter>
<match netflow.ipv4>
#@type stdout
@type null
</match>
# IPv6用にPrometheusに出力するデータを決める、受信バイト数(in_bytes)をkeyにする、不要なラベルはコメントアウト
<filter netflow.ipv6>
@type prometheus
<metric>
name netflow_ipv6_in_byte
desc NetFlow IPv6 Traffic input byte
type counter
key in_bytes
<labels>
#version ${version}
#flow_seq_num ${flow_seq_num}
#flowset_id ${flowset_id}
#flowEndMilliseconds ${flowEndMilliseconds}
#flowStartMilliseconds ${flowStartMilliseconds}
#in_pkts ${in_pkts}
#ip_protocol_version ${ip_protocol_version}
input_snmp ${input_snmp}
#output_snmp ${output_snmp}
#direction ${direction}
#flows ${flows}
ipv6_src_addr ${ipv6_src_addr}
ipv6_dst_addr ${ipv6_dst_addr}
#src_tos ${src_tos}
l4_src_port ${l4_src_port}
l4_dst_port ${l4_dst_port}
#tcp_flags ${tcp_flags}
protocol ${protocol}
#in_src_mac ${in_src_mac}
#in_dst_mac ${in_dst_mac}
#src_vlan ${src_vlan}
hostip ${host}
</labels>
</metric>
</filter>
<match netflow.ipv6>
#@type stdout
@type null
</match>
②-4 Prometheus で確認を行う
-
ブラウザで「http://[サーバのアドレス]:9090/」にログインして Prometheusの管理画面を開く
②-5 Grafana で Prometheus のデータを表示する
- ブラウザで「http://[サーバのアドレス]:3000/」にログインして Grafana の管理画面を開く
- 初期ユーザとパスワードはともに「admin」です
- Grafana と Prometheus の連携は他のサイトでもたくさん紹介されているため省略します。。。
- 最終的には以下のようなグラフ表示が出せます
最後に
Fluentd・Prometheus・Grafanaを利用してNetFlowデータの可視化まで確認できました
オープンソースのソフトウェアでここまでできるのはすごい
次は Telemetryもやってみたい