読者です 読者をやめる 読者になる 読者になる

LGTM

Looks Good To Me

高速にnetflow を吐く

networking

最近 netflow コレクターをさわる機会が多く「コレクターをベンチマークしたい」と思っている. 「netflow v5 なら何 flow/s まで受けられる」「v9 ならこのくらい」など,性能限界を知っておきたい.

2016/02/20 追記: NetFlow-Generator

戦略

いくつか考えられる方法があって

  1. ネットワークデバイスのサンプリングレートを変え,多めにnetflow export する
  2. netflow データを用意し,高速に送信する

1 は実網に影響あるかもしれないためパス.2 の方法にする. netflow データの作り方もいくつか思いつく.

2-1. ネットワークデバイスが吐いたnetflow を再利用する
2-2. ウソデータをでっち上げる

ネットワークデバイスが吐いたnetflow を再利用する

nfdump というツールを利用する.

$ nfcapd -l . -p <ポート>

データが溜まるのを待つ.1M flowほどあれば十分だが,溜まるのに時間がかかる場合は-t <interval> オプションをつけておく. これはnetflow データを1 ファイルにまとめるため.(デフォルトでは5分でファイルローテートしてしまう)

1M flowも溜めるのは,netflow データストアによって重複netflow を無視する可能性があるため. なるべく重複レコードが少ないほうがよい.

実行すると nfcapd.201602180335 のようなファイルができ,

$ nfreplay -H <IP アドレス> -p <ポート> -r nfcapd.201602180335

のようにするとnetflow パケットを送信できる.デフォルトではnetflow v5 で,-v9 オプションをつけるとnetflow v9 になる.

OSX の場合は

Error sending data: No buffer space available

のようなエラーが出るかもしれない.手元ではLinuxからnetflow を吐き,ベンチマークした.

ウソデータをでっち上げる

nfdump に加え,flow-tools というツールを利用する.

$ nfcapd -l .

しておき,

$ flow-gen -n 1000000 -V 5 | flow-send 0/127.0.0.1/9995

すると各フィールドがシーケンシャルなnetflow データが作れる.

srcIP            dstIP            prot  srcPort  dstPort  octets      packets
0.0.0.0          255.255.0.0      17    0        65280    1           1
0.0.0.1          255.255.0.1      17    1        65281    2           2
0.0.0.2          255.255.0.2      17    2        65282    3           3
0.0.0.3          255.255.0.3      17    3        65283    4           4
0.0.0.4          255.255.0.4      17    4        65284    5           5
0.0.0.5          255.255.0.5      17    5        65285    6           6
0.0.0.6          255.255.0.6      17    6        65286    7           7
0.0.0.7          255.255.0.7      17    7        65287    8           8
0.0.0.8          255.255.0.8      17    8        65288    9           9
0.0.0.9          255.255.0.9      17    9        65289    10          10
0.0.0.10         255.255.0.10     17    10       65290    11          11
0.0.0.11         255.255.0.11     17    11       65291    12          12
0.0.0.12         255.255.0.12     17    12       65292    13          13
  • flow-gen が作るnetflow のタイムスタンプはエポックタイムで0 だが,nfcapd が一定時間シフトさせてしまう (バグの可能性ある)
  • flow-gen が作るnetflow は30 flow/pkt
    • MTU1500 ではこれが限界
    • 変更するオプションはなさそう

これをネットワークデバイスが吐いたnetflow を再利用する と同様にnfreplay すればよい. 手元のFE NIC 環境ではwire rate 出た.(およそ 250k flow/s)

さらにスピードを出す

250k flow/s も出れば十分すぎるが,さらにコレクターをいじめるためにtcpreplay をつかう. 前述のnfreplay 時にパケットキャプチャーしておき,

$ tcpreplay -t -i eth0 nfreplay.pcap

すれば1G NIC 環境でもwire rate 出た.(およそ 2.5M flow/s)

ちなみにdst IP アドレス,dst MAC アドレスを変えつつ送信してもwire rate 出る.

$ tcpreplay-edit -tC -i eth0 -D 0.0.0.0/0:<IP アドレス>/32 --enet-dmac <MAC アドレス> nfreplay.pcap

netmap を使えば10Gbps ちかく出る可能性 はあるが,やめてあげてください.コレクターが動くわけがない.

スピードを調整する

tcpreplay が便利なのは送信スピードを変えられること.

-x string, --multiplier=string
-p number, --pps=number
-M string, --mbps=string

オプションを使う.

課題

nfreplay を使った方法ではIPFIX,sflow を吐けない.対応しているのはnetflow v5/v9 のみ. 実パケットをキャプチャーし,tcpreplay で高速送信する方法ならOK.

2016/02/20 追記: NetFlow-Generator

NetFlow-Generator というのがあるよ」と教えてもらいました.

ウソデータをでっち上げる ときのflow-tools (のflow-gen) の代わりに使える.

  • タイムスタンプをいじれる
  • flow/pkt をいじれる
  • flow-gen → nfcapd でフローデータ保存 → nfreplay と同等のスループットで動く

柔軟でよさそう.

$ flowgen -h
Usage: flowgen [options] [flowrec-options] <collector>
 options:
   -n, --count <num>
   -p, --port <num>
   -V, --version <version>
   -f, --flowrec <# of flow records in packet>
   -d, --debug <debug level>
   -N, --nosend
   -h, --help
 flowrec-options:
   -w, --wait <wait time>
   -i, --interval <interval>
   --enginetype <engine type>
   --engineid <engine id>
   --srcaddr <src ip address>
   --dstaddr <dst ip address>
   --nexthop <nexthop ip address>
   --inputif <input IfIndex>
   --outputif <output IfIndex>
   --packets <# of packets>
   --octets <# of octets>
   --firstseen <first seen>
   --lastseen <last seen>
   --srcport <src port>
   --dstport <dst port>
   --tcpflags <tcp flags>
   --protocol <protocol number>
   --tos <tos value>
   --srcas <src AS#>
   --dstas <dst AS#>
   --srcmask <src subnet mask length>
   --dstmask <dst subnet mask length>

  Numbers can be expressed using the following meta characters:
    111      (static)
    111-222  (sequential)
    111:222  (random)
    100@70,200@20,300@10   (probabilistic)