n本目です.
最初に書き始めたはずなのに,気が付いたら別の記事を何本もあげてしまっていました.
前回何も自己紹介していませんでしたが,私は現在大学院でセキュリティ系の研究に携わっていまして,中でもパケットやIDSに触れる機会が多いです.
今回はその中で扱っているTcpreplay
というツールのインストール方法について紹介します.
これもまた詰まりどころが多く,私は導入に2日かかりました...
Tcpreplay
とは
Tcpreplay
は,あらかじめキャプチャしたネットワークトラフィックを書き換えたり再送信したりするためのフリーのオープンソースユーティリティ群です.
引用元:Tcpreplay - pcap ファイルの書き換えと再送信ユーティリティ
というとても便利なツールです.
私も研究で通信の再送信やフラグメント化に使っています.
上記のリンクのように非公式ですが日本語版のサイトも整っており,活用する上ではあまりハマるところはないかと思います.
今回の課題
本記事ではタイトルに記載した方法について紹介します.
が,その前にそこに至った経緯について軽く述べます.
私は結局はTcpreplay
を実際にインストールしたわけですが,私が使用していた環境にはなんと初めからTcpreplay
がインストールされていました.
ラッキーと思い早速研究に取り掛かったわけですね.
研究でTcpreplay
を使用する流れとしては,まず,対象のpcapファイルをフラグメント化した後に再送信します.
フラグメント化については,以下のサイトに詳しく載っているのでもし気になった方は見てみて下さい.
参照:MTUとフラグメント
ここでも一応簡単に説明すると,TCP/IP通信はパケットと呼ばれる単位で行われていますが,ネットワークによって通過できるパケットサイズに上限があるわけですね.
その上限を上回るサイズのパケットがそのネットワークを通るためにはあらかじめ,分割してあげる必要があり,この作業をフラグメント化と呼びます.
Tcpreplay
にはこのフラグメント化を行ってくれるコマンドも備えています.
$ tcprewrite --fragroute=frag.cfg --infile=input.pcap --outfile=output.pcap
以上のコマンドを打つことで,input.pcap
をフラグメント化したoutput.pcap
が出力されます.
ちなみに,frag.cfg
は分割サイズを設定するファイルで,コマンドを実行するディレクトリ内に自分で作成する必要があります.
例として,1400バイトで分割したければ,
iP_frag 1400
とします.
参照:tcprewrite
ということで,私も以上の設定でtcprewrite
を実行しました...
$ tcprewrite --fragroute=frag.cfg --infile=test.pcap --outfile=test.pcap
/usr/local/bin/tcprewrite: illegal option -- fragroute
tcprewrite (tcprewrite) - Rewrite the packets in a pcap file.
Usage: tcprewrite [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
-r, --portmap=str Rewrite TCP/UDP ports
-s, --seed=num Randomize src/dst IPv4/v6 addresses w/ given seed
-N, --pnat=str Rewrite IPv4/v6 addresses using pseudo-NAT
-S, --srcipmap=str Rewrite source IPv4/v6 addresses using pseudo-NAT
-D, --dstipmap=str Rewrite destination IPv4/v6 addresses using pseudo-NAT
-e, --endpoints=str Rewrite IP addresses to be between two endpoints
--tcp-sequence=num Change TCP Sequence (and ACK) numbers /w given seed
-b, --skipbroadcast Skip rewriting broadcast/multicast IPv4/v6 addresses
-C, --fixcsum Force recalculation of IPv4/TCP/UDP header checksums
-m, --mtu=num Override default MTU length (1500 bytes)
--mtu-trunc Truncate packets larger then specified MTU
-E, --efcs Remove Ethernet checksums (FCS) from end of frames
--ttl=str Modify the IPv4/v6 TTL/Hop Limit
--tos=num Set the IPv4 TOS/DiffServ/ECN byte
--tclass=num Set the IPv6 Traffic Class byte
--flowlabel=num Set the IPv6 Flow Label
-F, --fixlen=str Pad or truncate packet data to match header length
--fuzz-seed=num Fuzz 1 in X packets. Edit bytes, length, or emulate packet drop
--fuzz-factor=num Set the Fuzz 1 in X packet ratio (default 1 in 8 packets)
--skipl2broadcast Skip rewriting broadcast/multicast Layer 2 addresses
--dlt=str Override output DLT encapsulation
--enet-dmac=str Override destination ethernet MAC addresses
--enet-smac=str Override source ethernet MAC addresses
--enet-subsmac=str Substitute MAC addresses
--enet-mac-seed=num Randomize MAC addresses
--enet-mac-seed-keep-bytes=num Randomize MAC addresses
--enet-vlan=str Specify ethernet 802.1q VLAN tag mode
--enet-vlan-tag=num Specify the new ethernet 802.1q VLAN tag value
--enet-vlan-cfi=num Specify the ethernet 802.1q VLAN CFI value
--enet-vlan-pri=num Specify the ethernet 802.1q VLAN priority
--hdlc-control=num Specify HDLC control value
--hdlc-address=num Specify HDLC address
--user-dlt=num Set output file DLT type
--user-dlink=str Rewrite Data-Link layer with user specified data
-i, --infile=str Input pcap file to be processed
-o, --outfile=str Output pcap file
-c, --cachefile=str Split traffic via tcpprep cache file
-v, --verbose Print decoded packets via tcpdump to STDOUT
-A, --decode=str Arguments passed to tcpdump decoder
--skip-soft-errors Skip writing packets with soft errors
-V, --version Print version information
-h, --less-help Display less usage information and exit
-H, --help display extended usage information and exit
-!, --more-help extended usage information passed thru pager
--save-opts[=arg] save the option state to a config file
--load-opts=str load options from a config file
Options are specified by doubled hyphens and their name or by a single
hyphen and the flag character.
Please send bug reports to: <tcpreplay-users@lists.sourceforge.net>
あれ?
上手くいかない.
どうやら--fragroute
というオプションが認識されてないようです.
バージョンを確認してみると,
$ tcprewrite -V
tcprewrite version: 4.3.4 (build git:v4.3.4)
Copyright 2013-2018 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta
Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net>
The entire Tcpreplay Suite is licensed under the GPLv3
Cache file supported: 04
Not compiled with libdnet.
Compiled against libpcap: 1.9.1
64 bit packet counters: enabled
Verbose printing via tcpdump: enabled
Fragroute engine: disabled
なるほど.
Fragroute engine
というものがdisabeled
になっていますね.
これが原因のようです.
では,解決策はというとこのようなページを見つけました.
細かいところはよくわかりませんが,libdnet
をインストールすれば良いようです.
確かに上記のバージョン情報でもNot compiled with libdnet.
と出ています.
ここで大事なのは先にlibdnet
をインストールした後にTcpreplay
をインストールすることです.
私は試しにこの状態のままlibdnet
をインストールしてみましたがやっぱり上手くいきませんでした.
libdnet
のインストール
本来であればapt-get
を使うことで簡単にインストールできますが,先程のサイトにはapt-get
を使わずにコンパイル&インストールしろと書いてあるので従います.
ちなみに真剣にダウンロード
→コンパイル
→インストール
の手順を踏んだのはこれが初めてだったので,少し丁寧に説明します.
ソースコードをダウンロード
まずは対象のサイトからソースコードをダウンロードします.
今回は以下のサイトからlibdnet
のソースコードをダウンロードしました.
コマンドラインからダウンロードしたければwget
を使います.
$ wget http://prdownloads.sourceforge.net/libdnet/libdnet-1.11.tar.gz
...
2021-05-16 16:02:32 (608 KB/s) - ‘libdnet-1.11.tar.gz’ saved [446233/446233]
これで対象のURLからファイルをダウンロードできます.
もし,URLが分からなければwebサイト上で右クリック
→リンクのアドレスをコピー
とし,どこかに貼り付けることでわかります.
今回のサイトで行うと
http://prdownloads.sourceforge.net/libdnet/libdnet-1.11.tar.gz?download
このようなリンクが出てきます.
最後の?download
が余計なので,消す必要がありますね.
ソースコードを解凍
次にダウンロードしたファイルを以下のようにして解凍します.
$ tar -xzvf libdnet-1.11.tar.gz
解凍方法は対象のファイルによって異なります.
以下の記事がとても分かりやすくまとめてあります.
configure
次にインストール先の環境に合わせた設定を行います.
と言っても以下のコマンドで自動でやってくれますが...
$ cd libdnet-1.11 # 回答したフォルダに移動
$ ./configure
実はこのタイミングで様々な設定をすることが出来ます.
一つ例を挙げると,
$./configure --prefix=$HOME/ # インストール先をホームディレクト以下に変更
このように--prefix
を使うとインストール先を指定することが出来ます.
make
ここは私の理解不足もあり詳しく説明できませんが,以下のコマンドを打つだけです.
$ make
make install
最後にインストールです.
以下のコマンドでインストールできます.
$ sudo make install
configureでインストール先を自分のホームディレクトリ以下にしていた場合,sudo
は必要ないかもしれません(所有者による).
何はともあれこれでインストールの完了です.
$ wget
$ tar
$ cd
$ ./configure
$ make
$ sudo make install
とりあえずはこの流れさえ押さえていれば大丈夫だと思います.
TCPReplay
のインストール
ここからやっと,TCPReplay
のインストール方法を説明します.
apt-get install
を使ったインストール方法もありますが,私の環境だとどうしてもfragroute
が有効化されなかったので,地道にビルドします.
流れはlibdnet
の時と同じなのでまとめて書いてしまいます.
$ sudo apt install build-essential libpcap-dev #1
$ wget https://github.com/appneta/tcpreplay/releases/download/v4.3.4/tcpreplay-4.3.4.tar.gz
$ tar -zxvf tcpreplay-4.3.4.tar.gz
$ cd tcpreplay-4.3.4
$ ./configure
$ make
$ sudo ln -s /usr/local/lib/libdnet.1 /usr/lib/x86_64-linux-gnu/libdnet.1 #2
$ sudo make install
#1
ではTCPReplay
のコンパイルに必要なパッケージをインストールしています.
#2
はlibdnet
のシンボリックリンクを作成しています.
TCPReplay
がlibdnet
の場所を上手く認識できるようにするためでしょうか.
環境によっては必要ないかもしれませんが,sudo make install
後にtcpreplay -V
としても以下のようなエラーが出る場合,#2
を実行することで解決するかもしれません.
$ tcpreplay -V
tcpreplay: error while loading shared libraries: libdnet.1: cannot open shared object file: No such file or directory
参照
私も同じエラーが出ました.
そして,以上の記事を見つけました.
しかし,解決策を知ってから実際に解決するまで,半日もの時間を費やしてしまったのです.
1
とl
この違いわかりますか?
そう!
左がいち
で右がえる
です.
では,#2
のln
はどちらでしょう.
そう,えるえぬ
ですね.
ではでは,libdnet.1
は...
私はずっとえる
だと思ってました.
しかし,正解はいち
です.
そう.
私はこの勘違いのせいで半日を無駄に過ごしました...
気を付けましょう.
インストール完了!!
はい.
では,インストールできたか確認してみましょう.
$ tcpreplay -V
Warning: May need to run as root to get access to all network interfaces.
tcpreplay version: 4.3.4 (build git:v4.3.4)
Copyright 2013-2018 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta
Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net>
The entire Tcpreplay Suite is licensed under the GPLv3
Cache file supported: 04
Compiled against libdnet: 1.11
Compiled against libpcap: 1.9.1
64 bit packet counters: enabled
Verbose printing via tcpdump: enabled
Packet editing: disabled
Fragroute engine: enabled
Injection method: PF_PACKET send()
Not compiled with netmap
無事に出来たみたいです.
Fragroute engine
もしっかり有効化されていますね.
まとめ
1
とl
には気を付けよう.