Closed6

pmacct/nfacctってなんやねん

harrythecodeharrythecode

pmacctとは

以下のPDFが分かりやすいです。一言で言うと「色んな形式のネットワーク通信を色んな形式のアウトプットに出力できる」軽量なツール。しかも開発者が一人で10年以上メンテナンスを続けているという、信頼と実績が高いもの。

http://www.pmacct.net/plucente_janog36_v0.2-jp.pdf

harrythecodeharrythecode

本編

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サーバーなどのサードパーティツールへのデータインジェクションに適しています。
脚注
  1. デーモンとは、UNIX系OSでメインメモリ上に常駐して特定の機能を提供するプログラム (IT用語辞典より) ↩︎

  2. ネットワーク通信を効率よく監視、分析する為に生み出された技術。こちらも参考になります。 ↩︎

  3. https://labs.gree.jp/blog/2014/08/11078/#:~:text=BMPとは,結果を表示します。 ↩︎

harrythecodeharrythecode

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経由で収集したデータをエクスポートします。 このプラグインはデフォルトでコンパイルされています。

harrythecodeharrythecode

理解したこと

「pmacct」のやっていることは「Daemon」でINPUTを受け取って「Plugin」でOUTPUTを形成する。その形式は用途に合わせて色々変えれる。

疑問だったこと

Q1. pmacctのConfigはどうやって設定するの

A1. "CONFIG-KEYS"に全てが載ってる。

例えば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
      

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」です。

  1. 以下の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
  1. docker build -t custom-pmacct .
  2. docker run -d --rm --name pmacct custom-pmacct
  3. 新規ターミナル上でコンテナ内に入って作業 (1): docker exec -it pmacct bash
  • pmacctd -P nfprobe
  1. 新規ターミナル上でコンテナ内に入って作業 (2): docker exec -it pmacct bash
  • nfacctd -r 10 -P print
  1. 新規ターミナル上でコンテナ内に入って作業 (3): docker exec -it pmacct bash
  • flow-gen -V5 | flow-send 0/127.0.0.1/2100
  1. しばらく待つと以下のようなアウトプットが確認できます。
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
脚注
  1. NetFlowのダミーデータをflow-toolsで生成する為、あえて古いバージョンのUbuntu 18.04 (Bionic)を使用しています。本番環境では利用しないように注意してください。 ↩︎

harrythecodeharrythecode

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で使えないパラメータも環境によってはあるので、その場合は使えないものは除外した上で試しましょう。(大抵コマンド実行時の初期メッセージに何が使えないかの記載あり。)

https://github.com/pmacct/pmacct/issues/212

このスクラップは2023/06/16にクローズされました