pmacct/nfacctってなんやねん
本スクラップの目的
pmacctを理解しつつ、全然Quickstartじゃない以下の文章を噛み砕いて理解していく。
pmacctとは
以下のPDFが分かりやすいです。一言で言うと「色んな形式のネットワーク通信を色んな形式のアウトプットに出力できる」軽量なツール。しかも開発者が一人で10年以上メンテナンスを続けているという、信頼と実績が高いもの。
本編
Daemon
pmacctには以下の実行可能なプログラム(Daemon[1])が存在します。
Daemon | 説明 |
---|---|
pmacctd | libpcapベースの統計デーモン。1つまたは複数のインタフェースからパケットをキャプチャします。コレクターとしての役割だけでなく、NetFlow、IPFIX、sFlowプロトコル[2]を通じて統計をエクスポートすることもできます。 |
nfacctd | NetFlow / IPFIX統計デーモン。1つまたは複数のインタフェース(IPv4とIPv6)でNetFlow v5 / v9とIPFIXパケットを待ちます。コレクターとしての役割だけでなく、3番目のパーティーコレクターにレプリケートすることもできます。 |
sfacctd | sFlow統計デーモン。1つまたは複数のインタフェース(IPv4とIPv6の両方)でsFlowパケットv2、v4、v5を待ちます。コレクターとしての役割だけでなく、3番目のパーティーコレクターにレプリケートすることもできます。 |
uacctd | Linux Netlink NFLOG統計デーモン。NFLOGのマルチキャストグループを利用してパケットをキャプチャするもので、Linuxでのみ動作します。コレクターとして機能するだけでなく、このデーモンは、NetFlow、IPFIX、sFlowを介して NetFlow、IPFIX、sFlowの各プロトコルで統計情報を出力することができます。 |
pmtelemetryd | スタンドアロン型ストリーミング・テレメトリー・コレクター・デーモン。TCPまたはUDPポートにバインドされたテレメトリーデータをリッスンし、リアルタイムでログを記録します。または設定されたバックエンドに一定時間間隔でダンプします。 |
pmbgpd | スタンドアロンBGPコレクターデーモン:パッシブiBGPまたはeBGPネイバーとして動作し eBGPネイバーとして動作し、ピアごとのRIBを維持します。をリアルタイムで記録し、設定したバックエンドに一定時間間隔でBGPデータをダンプすることが バックエンドにリアルタイムでログを記録することができます。 |
pmbmpd | スタンドアロンBMPコレクターデーモン。設定済みのバックエンドにリアルタイムでロギングしたり、一定時間間隔でBMP/BGP[3]データをダンプすることができます。 |
pmacct | コマンドライン pmacct クライアント; メモリテーブルプラグインからデータを取得することができます。メモリテーブルプラグインからデータを取得することができます; データに対してクエリーを実行したり データの一括取得が可能。出力はフォーマットされた CSV または JSON フォーマットです。RRDtoolのようなサードパーティツールへのデータインジェクションに適しています。GnuplotやSNMPサーバーなどのサードパーティツールへのデータインジェクションに適しています。 |
Plugin
pmacctには様々な形式のアウトプットを提供するために以下のプラグインを用意しています。
memory: データはメモリテーブルに保存され、pmacct コマンドラインクライアントツール 'pmacct' から取得することができます。このプラグインはプッシュモデルも実装しており、サードパーティツールにデータを簡単に注入することができます。このプラグインはプロトタイピングや概念実証(大量のトラフィックを発生させない)、小規模/自作環境向けに推奨されており、デフォルトでコンパイルされています。
mysql: MySQL/MariaDBが動作している環境では、データの保存に使用することができます。このプラグインは --enable-mysql スイッチを使ってコンパイルすることができます。
pgsql: PostgreSQLが動作している環境であれば、データ保存に使用できる。 このプラグインは --enable-pgsql スイッチを使ってコンパイルすることができます。
sqlite3: SQLite 3.x または BerkeleyDB 5.x (SQLite API でコンパイルされたもの) がインストールされていれば、データストレージとして使うことができます。このプラグインは --enable-sqlite3 スイッチを使ってコンパイルすることができる。
print: データを一定間隔でフラットファイルや標準出力にタブ区切り、CSV、JSON 形式で出力します。このプラグインはデフォルトでコンパイルされている。
amqp: データはAMQPプロトコルを実行するRabbitMQブローカーに送られ、コンシューマーアプリケーションやツールに配信されます。一般的なコンシューマは、ElasticSearch、InfluxDB、Druid、ClickHouseです。このプラグインは --enable-rabbitmq スイッチを使用してコンパイルすることができます。
kafka:データはKafkaブローカーに送信され、コンシューマーアプリケーションやツールに配信されます。一般的なコンシューマは、ElasticSearch、InfluxDB、Druid、ClickHouseです。このプラグインは、--enable-kafkaスイッチを使用してコンパイルすることができます。
tee: nfacctdとsfacctdのデーモンのみに適用されます。NetFlow/IPFIX/sFlowデータ用の機能豊富なパケットレプリケータです。このプラグインはデフォルトでコンパイルされています。
nfprobe: pmacctd と uacctd デーモンのみに適用されます。NetFlow v5/v9 または IPFIX を介して収集されたデータをエクスポートします。このプラグインは、デフォルトでコンパイルされています。
sfprobe: pmacctd と uacctd デーモンのみに適用されます。sFlow v5経由で収集したデータをエクスポートします。 このプラグインはデフォルトでコンパイルされています。
理解したこと
「pmacct」のやっていることは「Daemon」でINPUTを受け取って「Plugin」でOUTPUTを形成する。その形式は用途に合わせて色々変えれる。
疑問だったこと
Q1. pmacctのConfigはどうやって設定するの
"CONFIG-KEYS"に全てが載ってる。
A1.例えばpmacctd
プログラムの場合、pmacctd -h
のヘルプと見比べながら、どのオプションを有効化するのかを引数で渡すかファイルにして渡すかの2択。別デーモンもコマンドを変えてヘルプを見ながら同様に行う。
例えば以下のコマンドとConfigファイルは同一。
-
pmacctd -D -c src_host,dst_host -i eth0 -P mysql src net 10.0.0.0/16
-
pmacctd -f pmacctd.conf
- pmacctd.conf
! コメントは!で書ける daemonize: true plugins: mysql aggregate: src_host, dst_host pcap_interface: eth0 pcap_filter: src net 10.0.0.0/16
- pmacctd.conf
Q2. Pluginの横に[in]のような書き方がされてるんだけど
A2. プラグインには任意の名前がつけられ、それに応じた値を各々与えることが可能
以下の場合、memory[in], memory[out]
用の設定を同一ファイルにて行うことが可能です。
!
daemonize: true
plugins: memory[in], memory[out]
aggregate[in]: dst_host
aggregate[out]: src_host
aggregate_filter[in]: dst net 192.168.0.0/16
aggregate_filter[out]: src net 192.168.0.0/16
imt_path[in]: /tmp/pmacct_in.pipe
imt_path[out]: /tmp/pmacct_out.pipe
!
Q3. ローカルで簡単に試せる環境は作れないの?
A3. Linux環境にpmacctパッケージをインストールすると気軽に試せます
試した環境は「Mac M1 - Docker Desktop」です。
- 以下のDockerfileファイルを作成 [1]
# https://github.com/linuxserver/docker-baseimage-ubuntu/pkgs/container/baseimage-ubuntu
FROM ghcr.io/linuxserver/baseimage-ubuntu:bionic
# https://ubuntu.com/blog/we-reduced-our-docker-images-by-60-with-no-install-recommends
RUN \
echo "=== install dependencies" && \
apt-get update && \
apt-get install -y --no-install-recommends \
pmacct \
flow-tools
docker build -t custom-pmacct .
docker run -d --rm --name pmacct custom-pmacct
- 新規ターミナル上でコンテナ内に入って作業 (1):
docker exec -it pmacct bash
pmacctd -P nfprobe
- 新規ターミナル上でコンテナ内に入って作業 (2):
docker exec -it pmacct bash
nfacctd -r 10 -P print
- 新規ターミナル上でコンテナ内に入って作業 (3):
docker exec -it pmacct bash
flow-gen -V5 | flow-send 0/127.0.0.1/2100
- しばらく待つと以下のようなアウトプットが確認できます。
0.0.3.222 991 991
0.0.3.223 992 992
0.0.3.224 993 993
0.0.3.225 994 994
0.0.3.226 995 995
0.0.3.227 996 996
0.0.3.228 997 997
0.0.3.229 998 998
0.0.3.230 999 999
0.0.3.231 1000 1000
INFO ( default_print/print ): *** Purging cache - START (PID: 313) ***
INFO ( default_print/print ): *** Purging cache - END (PID: 313, QN: 0/0, ET: 0) ***
Q4. pmacctd (nfprobe) と nfacctd (kafka) が別々のマシン上で動いて別IPを持ってる場合はどうすれば良い?
A4. pmacctd側のreceiverを設定します。
- pmacctd (Plugin: nfprobe)
- nfacctd (Plugin: kafka)
の上記設定の場合、pmacctd側でnfacctdのIPまたはHostnameをnfprobe_receiver
で設定します。
plugins: nfprobe
nfprobe_receiver: 192.168.1.100:2100
するとpmacctdが起動した際に以下のメッセージを確認可能です。後はnfacctd側できちんとデータが送られてきてることを確認してください。届いてない場合は、Firewall等の設定を見直してください。
INFO ( default_nfprobe/nfprobe ): Exporting flows to [192.168.1.100]:2100
Q5. Q4のport 2100はUDP or TCP?
A5. パケットを観測する限りUDPで送ってる模様。
正確に理解するにはソースコードを別途読み込む必要がありますが、一応パケット上ではUDPが使われてデータ転送されてます。
root@localhost:/# tcpdump -nnn -i any host 192.168.1.2
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
19:56:28.514279 eth0 Out IP 192.168.1.1.32948 > 192.168.1.2.2100: UDP, length 420
19:56:28.514322 eth0 Out IP 192.168.1.1.32948 > 192.168.1.2.2100: UDP, length 364
-
NetFlowのダミーデータをflow-toolsで生成する為、あえて古いバージョンのUbuntu 18.04 (Bionic)を使用しています。本番環境では利用しないように注意してください。 ↩︎
Aggregate (-c) オプションの値
データを集計して集約(Aggregate)できるpmacct。
Daemonごとに-a
オプションをつけると具体的な説明が表示されます。
pmacctd -a
Promiscuous Mode Accounting Daemon, pmacctd 1.7.6-git (RELEASE)
L2
cos : Ethernet CoS, 802.1P
etype : Ethernet Ethertype
src_mac : Source MAC address
dst_mac : Destination MAC address
vlan : Ethernet VLAN, 802.1Q
$ nfacctd -a
NetFlow Accounting Daemon, nfacctd 1.7.8-git (20221231-1 (723b0cb2))
L2
cos : Ethernet CoS, 802.1P
etype : Ethernet Ethertype
src_mac : Source MAC address
dst_mac : Destination MAC address
vlan : Ethernet VLAN, 802.1Q
in_vlan : Input Ethernet VLAN, 802.1Q
out_vlan : Output Ethernet VLAN, 802.1Q
デバッグオプションが便利
引数で-d
を渡すか、設定ファイルにdebug: true
を入れて使います (Ref)
$ nfacctd -d -P print
DEBUG ( default/core ): Received NetFlow/IPFIX packet from [192.168.1.5:39820] version [9] seqno [296]
DEBUG ( default/core ): Processing NetFlow/IPFIX flowset [1024] from [192.168.1.5:39820] seqno [296]
DEBUG ( default/core ): Discarded NetFlow v9/IPFIX packet (R: unknown template 1024 [192.168.1.5:0])
...
DEBUG ( default/core ): Processing NetFlow/IPFIX flowset [0] from [192.168.1.5:54462] seqno [361]
DEBUG ( default/core ): NfV9 agent : 192.168.1.2:0
DEBUG ( default/core ): NfV9 template type : flow
DEBUG ( default/core ): NfV9 template ID : 2049
DEBUG ( default/core ): -------------------------------------------------------------
DEBUG ( default/core ): | pen | field type | offset | size |
DEBUG ( default/core ): | 0 | last switched [21 ] | 0 | 4 |
DEBUG ( default/core ): | 0 | first switched [22 ] | 4 | 4 |
DEBUG ( default/core ): | 0 | in bytes [1 ] | 8 | 8 |
DEBUG ( default/core ): | 0 | in packets [2 ] | 16 | 8 |
DEBUG ( default/core ): | 0 | ip version [60 ] | 24 | 1 |
DEBUG ( default/core ): | 0 | input snmp [10 ] | 25 | 4 |
DEBUG ( default/core ): | 0 | output snmp [14 ] | 29 | 4 |
DEBUG ( default/core ): | 0 | direction [61 ] | 33 | 1 |
DEBUG ( default/core ): | 0 | IPv6 src addr [27 ] | 34 | 16 |
DEBUG ( default/core ): | 0 | IPv6 dst addr [28 ] | 50 | 16 |
DEBUG ( default/core ): | 0 | tos [5 ] | 66 | 1 |
DEBUG ( default/core ): | 0 | L4 src port [7 ] | 67 | 2 |
DEBUG ( default/core ): | 0 | L4 dst port [11 ] | 69 | 2 |
DEBUG ( default/core ): | 0 | tcp flags [6 ] | 71 | 1 |
DEBUG ( default/core ): | 0 | L4 protocol [4 ] | 72 | 1 |
DEBUG ( default/core ): -------------------------------------------------------------
DEBUG ( default/core ): Netflow V9/IPFIX record size : 73
ちなみに上記のエラーメッセージはテンプレートが生成されるまでしばらく出続けますが、期待通りの動作なので気にせず気長に待ちましょう。ただ aggregationで使えないパラメータも環境によってはあるので、その場合は使えないものは除外した上で試しましょう。(大抵コマンド実行時の初期メッセージに何が使えないかの記載あり。)