1

既知のトラフィックを(libpcapを使用して)NICからキャプチャし、テストしようとしているアプリケーションにフィードする必要があるテストツールを作成しています。

私がセットアップしようとしているのは、Webサーバー(この場合はlighttpd)と、同じマシン上で分離されたテストネットワーク上で実行されているクライアント(curl)です。スクリプトはセットアップ全体を駆動します。目標は、クライアントの数と、各クライアントがWebサーバーからダウンロードするファイルのセットを指定できるようにすることです。

私の最初のアプローチは、単にループバック(lo)インターフェイスを使用することでした... 127.0.0.1でWebサーバーを実行し、クライアントにファイルをフェッチさせhttp://127.0.0.1、loインターフェイスでlibpcapベースのツールを実行します。これは、ループバックインターフェイスが実際のイーサネットインターフェイスをエミュレートしないという事実を除けば、問題なく機能します。それに関する主な問題は、パケットがすべて一貫性のないサイズであるということです... 32kバイト以上で、いくらかランダムです... loでMTUを下げることもできません(まあ、できますが、効果はありません!)。

また、実際のインターフェイス(eth0)で実行しようとしましたが、内部Webサーバーと通信する内部Webクライアントであるため、トラフィックがインターフェイスを離れることはなく、libpcapはそれを認識しません。

それで私はtun/tapに目を向けました。私はsocatを使用して2つのtunインターフェイスをtcp接続でバインドしたので、実際には次のようになりました。

10.0.1.1/24 <-> tun0 <-socat-> tcp connection <-socat-> tun1 <-> 10.0.2.1/24

これは本当に素晴らしい解決策のようです...tun/ tapデバイスは実際のイーサネットデバイスをエミュレートするので、Webサーバーをtun0(10.0.1.1)で実行し、キャプチャツールをtun0で実行して、クライアントをtun1(10.0.2.1)にバインドできます。 )... tcを使用して、このトラフィックにシェーピングルールを適用し、Linuxボックス内に仮想WANを作成することもできます...しかし、それは機能しません...

これが私が使用したsocatコマンドです:

$ socat -d TCP-LISTEN:11443,reuseaddr TUN:10.0.1.1/24,up &
$ socat TCP:127.0.0.1:11443 TUN:10.0.2.1/24,up &

これにより、それぞれのIPアドレスを持つ2つのtunインターフェイス(tun0および)が生成されます。tun1

を実行するping -I tun1 10.0.1.1と応答がありませんが、iを実行するとtcpdump -n -i tun0、ICMPエコー要求が反対側に到達し、応答の兆候が戻ってこないことがわかります。

# tcpdump -i tun0 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 65535 bytes
16:49:16.772718 IP 10.0.2.1 > 10.0.1.1: ICMP echo request, id 4062, seq 5, length 64
<--- insert sound of crickets here (chirp, chirp)

それで、私は明らかな何かを見逃していますか、それともこれは間違ったアプローチですか?他に試すことができるものはありますか(たとえば、2つの物理インターフェイス、eth0とeth1 ???)。

最も簡単な方法は、2台のマシンを使用することですが、このすべてが自己完結型である必要があるため、他の依存関係なしに、1台のマシンですべてのスクリプトと自動化を行うことができます...

アップデート:

2つのsocatをtcp接続で接続する必要はありません。これを行うことは可能です(そして私にとっては望ましいことです)。

socat TUN:10.0.1.1/24,up TUN:10.0.2.1/24,up &

同じ問題がまだ存在します...

4

1 に答える 1

0

OK、Linuxネットワーク名前空間(netns)を使用した解決策を見つけました。ここにそれを使用する方法についての役立つ記事があります:http ://code.google.com/p/coreemu/wiki/Namespaces

これは私が私のセットアップのためにしたことです...

まず、COREをダウンロードしてインストールします:http://cs.itd.nrl.navy.mil/work/core/index.php

次に、次のスクリプトを実行します。

#!/bin/sh

core-cleanup.sh > /dev/null 2>&1
ip link set vbridge down > /dev/null 2>&1
brctl delbr vbridge > /dev/null 2>&1

# create a server node namespace container - node 0
vnoded -c /tmp/n0.ctl -l /tmp/n0.log -p /tmp/n0.pid > /dev/null
# create a virtual Ethernet (veth) pair, installing one end into node 0
ip link add name veth0 type veth peer name n0.0
ip link set n0.0 netns `cat /tmp/n0.pid`
vcmd -c /tmp/n0.ctl -- ip link set n0.0 name eth0
vcmd -c /tmp/n0.ctl -- ifconfig eth0 10.0.0.1/24 up

# start web server on node 0
vcmd -I -c /tmp/n0.ctl -- lighttpd -f /etc/lighttpd/lighttpd.conf

# create client node namespace container - node 1
vnoded -c /tmp/n1.ctl -l /tmp/n1.log -p /tmp/n1.pid > /dev/null
# create a virtual Ethernet (veth) pair, installing one end into node 1
ip link add name veth1 type veth peer name n1.0
ip link set n1.0 netns `cat /tmp/n1.pid`
vcmd -c /tmp/n1.ctl -- ip link set n1.0 name eth0
vcmd -c /tmp/n1.ctl -- ifconfig eth0 10.0.0.2/24 up

# bridge together nodes using the other end of each veth pair
brctl addbr vbridge
brctl setfd vbridge 0
brctl addif vbridge veth0
brctl addif vbridge veth1
ip link set veth0 up
ip link set veth1 up
ip link set vbridge up

これにより、基本的にLinuxホスト(この場合はノード0とノード1)に2つの仮想/分離/名前間隔のネットワークがセットアップされます。Webサーバーはノード0で起動されます。

ここで行う必要があるのは、ノード1でcurlを実行することだけです。

vcmd -c /tmp/n1.ctl -- curl --output /dev/null http://10.0.0.1

そして、tcpdumpでトラフィックを監視します。

tcpdump -s 1514 -i veth0 -n

これは非常にうまく機能しているようです...まだ実験中ですが、私の問題は解決するようです。

于 2012-10-03T03:47:32.383 に答える