1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめてのアドベントカレンダーAdvent Calendar 2024

Day 17

NetFlow のデータを Fluentd・Prometheus・Grafanaで可視化する

Last updated at Posted at 2024-12-01

NetFlowのコレクタとしてFluentdを利用し、Prometheus・Grafanaを利用し可視化を行った際のメモ

モチベーション

  • オープンソースのソフトウェアを利用してNetFlowのデータを可視化したい

ということで、ネットワークシュミレータ上で動作を確認をしてみました

NetFlowとは

ざっくり

  • ネットワークのトラフィックの情報を監視・分析するための技術
  • 送信元IPアドレス、宛先IPアドレス、TCP/UDPポート番号(フローデータ)などの情報を収集
  • ネットワーク機器からフロー情報をフローコレクターに送信し監視・分析することができる

構成とアウトプットのイメージ

  • NetFlowの吐き出すネットワーク機器としてVyOSを利用

  • ネットワークシュミレータ上にUbuntuを設置してFlowコレクタとして利用
    image.png

  • 各ソフトウェアの役割は以下のイメージです
    image.png

  • 今回には Grafanaで以下のような簡単なグラフで可視化することを目標にしてます
    image.png

①環境準備

①-1 VyOSの準備

①-2 サーバ(Ubuntu)の準備

①-3 Fluentdの準備

Fluentdのインストール

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」に変更
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解決ができずに終わってしまうため)
    image.png

②-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の管理画面を開く

  • 「Graph」を選択し、Fluentdで設定した NetFlowのIPv4とIPv6が選択できることを確認する
    image.png

  • 「Graph」で定期的に取得したデータからグラフ表示されることを確認する
    image.png

②-5 Grafana で Prometheus のデータを表示する

  • ブラウザで「http://[サーバのアドレス]:3000/」にログインして Grafana の管理画面を開く
    • 初期ユーザとパスワードはともに「admin」です
  • Grafana と Prometheus の連携は他のサイトでもたくさん紹介されているため省略します。。。
  • 最終的には以下のようなグラフ表示が出せます
    image.png

最後に

Fluentd・Prometheus・Grafanaを利用してNetFlowデータの可視化まで確認できました
オープンソースのソフトウェアでここまでできるのはすごい
次は Telemetryもやってみたい

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?