外部インターフェイスへのローカルIPトラフィックを強制する


30

たとえば、必要に応じて構成できるいくつかのインターフェイスを持つマシンがあります。

  • eth1:192.168.1.1
  • eth2:192.168.2.2

これらのローカルアドレスの1つに送信されたすべてのトラフィックを、他のインターフェイスを介して転送したいと思います。たとえば、192.168.1.1のiperf、ftp、httpサーバーへのすべてのリクエストは、内部でルーティングされるだけでなく、eth2を介して転送される必要があります(外部ネットワークがeth1にパケットを再ルーティングします)。

iptables、ip routeなどのいくつかのコマンドを試してみましたが、何も機能しませんでした。

私が得ることができる最も近い行動は、

ip route change to 192.168.1.1/24 dev eth2

内部でルーティングされている192.168.1.1を除き、eth2ですべての192.168.1.xを送信します。その後、eth1で偽の192.168.1.2に向けられたすべてのトラフィックのNAT転送を行い、内部的に192.168.1.1に再ルーティングできますか?私は実際にiptablesで苦労していますが、それは私にとってあまりにも難しいです。

このセットアップの目標は、2台のPCを使用せずにインターフェイスドライバーのテストを行うことです。

私はLinuxを使用していますが、Windowsでそれを行う方法を知っていれば、それを購入します!

編集:

外部ネットワークは、eth1とeth2間の単なるクロスオーバーケーブルです。私のマシンにhttpサーバーがあるとします。ここで、同じマシンからこのサーバーにアクセスしたいのですが、TCP / IPトラフィックがこのeth1 / eth2ケーブルを通過するようにします。このためにインターフェイスをどのように構成すればよいですか?


インターフェイス1と2を介してすべてのトラフィックをミラーリングしたいが、別のルーターからのみインターフェイス2に戻すようにしたいと言っていますか?ネットワーク上でかなり奇妙なことをすることはできませんか?ミラーリングされたトラフィックをインターフェイス2からトラフィックをドロップしたばかりの別のシステムに転送してから、それを監視するか、仮想化ソフトウェアを使用してトラフィックをキャプチャする方が良いでしょうか?たぶん、説明に何かが欠けています。
バートシルバース

彼は、たとえばeth1のIPである192.168.1.1へのパケットを生成したいようです。しかし、Linuxスタックが完全に内部的にそのパケットを受信する代わりに、彼はパケットをeth2に強制的に送信することを望んでいます(外部からeth1に、次にLinuxスタックに配信されます)。これが可能かどうかはわかりません。ネットワーク層がアドレスが内部インターフェイスであることを検出すると、ルーティングテーブルを調べる理由はほとんどありません。他の誰かがよく知っているかもしれません。
PP。

回答:


14

応答パケットが表示されなかったため、caladonaの回答を拡張しました。この例では:

  1. 私のローカルPC上で私は、異なるサブネット上のNICのを持って、/ 24 192.168.1192.168.2 / 24
  2. 両方のサブネットにアクセスできる外部ルーター/ PCがあります。
  3. ローカルPCのNICを介して双方向トラフィックを送信したい。
  4. この構成では、サブネットごとに2つの未使用IPアドレスが必要です。

ローカルPCのiptableルートは、「偽の」IPへのSNATおよびDNAT発信トラフィックに設定されます。

iptables -t nat -A POSTROUTING -d 192.168.1.100 -s 192.168.2.0/24 -j SNAT --to-source      192.168.2.100
iptables -t nat -A PREROUTING  -d 192.168.1.100 -i eth0           -j DNAT --to-destination 192.168.1.1
iptables -t nat -A POSTROUTING -d 192.168.2.100 -s 192.168.1.0/24 -j SNAT --to-source      192.168.1.100
iptables -t nat -A PREROUTING  -d 192.168.2.100 -i eth1           -j DNAT --to-destination 192.168.2.1

ルールは次のことを行います。

  1. 送信パケットで192.168.2.1ソースを192.168.2.100に書き換えます
  2. 着信パケットで192.168.1.100宛先を192.168.1.1に書き換えます
  3. 送信パケットで192.168.1.1ソースを192.168.1.100に書き換えます
  4. 着信パケットで192.168.2.100宛先を192.168.2.1に書き換えます

要約すると、ローカルシステムは、アドレス192.168.1.100および192.168.2.100の「仮想」マシンと通信できるようになりました。

次に、ローカルPCで外部ルーターを使用して偽のIPに到達するように強制する必要があります。これを行うには、ルーターを経由してIPに直接ルートを作成します。宛先サブネットの反対側にパケットを強制することを確認したいと思います。

ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP 
ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP

最後に、これをすべて機能させるには、外部ルーターがローカルPC上の偽装IPに到達する方法を知る必要があります。システムでプロキシARPをオンにすることでシンを実行できます。

echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/proxy_arp
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

この設定により、ローカルPC上で偽のIPを実際のシステムとして扱うことができます。.1サブネットにデータを送信すると、パケットが.2インターフェイスから強制的に送信されます。.2サブネットにデータを送信すると、パケットが強制的に.1インターフェースから送信されます。

ping 192.168.1.100
ping 192.168.2.100

はるかに良い方法です!ARPを機能させるにはip_forwardも必要であることに注意してください。echo 1> / proc / sys / net / ipv4 / ip_forward
calandoa

28

Linuxで次のコードを使用して、「ループバック」モードの新しいデュアルポート10Gbpsカード、つまり1つのポートをもう1つのポートに直接接続してスループットをテストしました。これは、パケットを強制的に送信するためだけのブードゥー教です。しかし、そうしないと、Linuxはカーネルを介してトラフィックを短絡させるだけです(OPの質問です)。上記のケーシーの答えでは、外部ルーターが本当に必要かどうかはわかりませんが、以下は完全に自己完結型です。2つのインターフェイスはeth2とeth3です。

インターフェイスにIPを付与し、それらを別のネットワークに配置します。

ifconfig eth2 10.50.0.1/24
ifconfig eth3 10.50.1.1/24

次に、二重NATシナリオを設定します。2つの新しい偽のネットワークが他方に到達するために使用されます。途中で、NATを偽のネットワークに送信します。途中で、宛先を修正します。また、他のネットワークの場合も同様です。

# nat source IP 10.50.0.1 -> 10.60.0.1 when going to 10.60.1.1
iptables -t nat -A POSTROUTING -s 10.50.0.1 -d 10.60.1.1 -j SNAT --to-source 10.60.0.1

# nat inbound 10.60.0.1 -> 10.50.0.1
iptables -t nat -A PREROUTING -d 10.60.0.1 -j DNAT --to-destination 10.50.0.1

# nat source IP 10.50.1.1 -> 10.60.1.1 when going to 10.60.0.1
iptables -t nat -A POSTROUTING -s 10.50.1.1 -d 10.60.0.1 -j SNAT --to-source 10.60.1.1

# nat inbound 10.60.1.1 -> 10.50.1.1
iptables -t nat -A PREROUTING -d 10.60.1.1 -j DNAT --to-destination 10.50.1.1

次に、各偽のネットワークに到達する方法をシステムに伝え、arpエントリを事前入力します(必ずMACアドレスを置き換えてください。私のものは使用しないでください)。

ip route add 10.60.1.1 dev eth2
arp -i eth2 -s 10.60.1.1 00:1B:21:C1:F6:0F # eth3's mac address

ip route add 10.60.0.1 dev eth3 
arp -i eth3 -s 10.60.0.1 00:1B:21:C1:F6:0E # eth2's mac address

これは、実際にパケットをネットワークに送信するのに十分なほどLinuxをだます。例えば:

ping 10.60.1.1

eth2から出て、ソースIP 10.50.0.1は10.60.0.1にNATされ、eth3に入ると、宛先10.60.1.1は10.50.1.1にNATされます。そして、返信も同様の旅をします。

iperfを使用してスループットをテストします。正しいIPにバインドし、連絡しているIP(相手の偽のアドレス)を確認してください:

# server
./iperf -B 10.50.1.1 -s

# client: your destination is the other end's fake address
./iperf -B 10.50.0.1 -c 10.60.1.1 -t 60 -i 10

トラフィックが実際にワイヤに向かっていることを確認します。

tcpdump -nn -i eth2 -c 500

/ proc / interruptsを監視して、カードが使用されていることを完全に確認することもできます。

while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done

とにかく、私はこれを行う方法を探しているこの投稿を見つけました、Q&Aの人に感謝し、これが将来この投稿を見つける他の誰かに役立つことを願っています。


+1優れたソリューション-これは、ip-forwardingを有効にする必要さえありません!これがまさに今必要なものです(ループバックによる10GBテストの場合)。
ニルス

16

いつものように-私は少し遅れていますが-最近では、ネットワーク名前空間を使用してインターフェイスを分離し、ローカル転送を防止できます(およびiptablesをいじる:))。

名前空間を作成します(たとえば、rootとして必要な権限ですべて実行します):

ip netns add ns_server
ip netns add ns_client

インターフェイスのステータス/構成は、割り当てられたネームスペースのコンテキスト内でアクセスする必要があります。したがって、デフォルトのネームスペースのコンテキストで実行されるため、ネイキッドIPリンクを実行しても表示されません。名前空間内でコマンドを実行するには、次を使用します。

ip netns exec <namespace-name> <command>

プレフィックスとして。

次に、名前空間をインターフェイスに割り当て、構成を適用し、インターフェイスをセットアップします。

ip link set eth1 netns ns_server
ip netns exec ns_server ip addr add dev eth1 192.168.1.1/24
ip netns exec ns_server ip link set dev eth1 up
ip link set eth2 netns ns_client
ip netns exec ns_client ip addr add dev eth2 192.168.1.2/24
ip netns exec ns_client ip link set dev eth2 up

これで、ネームスペース内でアプリケーションを実行できます-iperfサーバーの実行

ip netns exec ns_server iperf -s -B 192.168.1.1

そしてクライアント:

ip netns exec ns_client iperf -c 192.168.1.1 -B 192.168.1.2

ネットワークスタック、インターフェース、ルーティング...全体が名前空間によって分離されているため、トラフィックは物理インターフェースを介して送信されるため、カーネルはトラフィック内で使用されるアドレスをローカル(利用可能な)インターフェースと一致させることができません。

実験が完了したら、名前空間を削除するだけです:

ip netns del <namespace-name>

インターフェイスはデフォルトのネームスペースに再割り当てされ、ネームスペース内で行われたすべての設定が消えます(たとえば、割り当てられたIPアドレスを削除する必要はありません)。


これは、提案されている二重ナットマジックよりもはるかに簡単であり、ネットワーク上の他のコンピューターからの調整を必要とせず、物理トポロジも想定していません。私の唯一の要求は、ルートを追加するコマンドを追加することです。
ハックル

2

OK、私はついに設定をセットアップすることに成功しました。

別の偽アドレスを使用して、この偽アドレスのルートをインターフェイス2に強制し、NAT / iptablesを使用して偽アドレスを実際のアドレス2に変換します。

私のセットアップは、実際にはIF1(インターフェイス1)とIF2の間でtelnetできる1つのルーターで構成されています

私のセットアップでは、FAKE_ADDRとIF1_ADDRは同じサブネット上にあります。

ifconfig $IF1 $IF1_ADDR netmask 255.255.255.0
ifconfig $IF2 $IF2_ADDR netmask 255.255.255.0

iptables -t nat -A PREROUTING -d $FAKE_ADDR -i $IF2 -j DNAT --to-destination $IF2_ADDR
iptables -t nat -A POSTROUTING -s $IF2_ADDR -d $IF1_ADDR/24 -j SNAT --to-source $FAKE_ADDR

route add $FAKE_ADDR gw $ROUTER_ADDR

そして、ルーター上で:

route add $FAKE_ADDR gw $IF2_ADDR

FAKE_ADDRに何かを送信すると、pktはIF1を介してルーターに転送され、IF2に再び転送され、FAKE_IPはIF2_ADDRに置き換えられます。パケットはサーバーによって処理され、結果はIF2_ADDRからIF1_ADDRに送り返され、FAKE_ADDRに置き換えられます。

たった1本のクロスケーブルでよりシンプルな構成を使用することも可能かもしれませんが、試していないので、実際のソリューションを提供したいと思います。


ルーターが$ FAKE_ADDRを$ IF2_ADDRに送信している場合、DNATルールは「-i $ IF1」ではなく「-i $ IF2」である必要はありませんか?
cmcginty

あなたは正しいケーシーです、修正は完了です。
カランドア

1

上記のThomasTannhäuserの答えはまさにその通りでした!

同様の状況がありました。2つのenetインターフェイスを備えた単一のマシンです。私の計画では、1つのインターフェースをサーバー(受信者)として使用し、もう1つのインターフェースをクライアント(送信者)として使用することでした。各インターフェイスはルーターに接続され、iperfはルーターを介してトラフィックを駆動し、スループット、PPS、遅延などを測定します。

残念ながら、iptablesのアプローチは直感的ではなく、問題を抱えていました。数時間イライラした後、私はこの攻撃計画を放棄しました。Thomasの提案に触発されて、私はLinux IP名前空間について少し宿題をし、このソリューションのシンプルさと優雅さに感謝し始めました。

以下は、この容量で機能するようにFedora FC26を設定するために使用した正確なコマンドのリストです。2つのインターフェイスはenp1s0とenp3s0です。ルーターには、アドレスが192.168.2.112と172.16.16.2の2つのインターフェイスがあります。各FC26 ENETコネクタは、対応するルーターインターフェイスに直接ケーブル接続されています。

# How to configure the IP Namespaces
ip netns add iperf-server
ip netns add iperf-client
ip link set enp1s0 netns iperf-server
ip link set enp3s0 netns iperf-client
ip netns exec iperf-server ip addr add dev enp1s0 192.168.2.139/20
ip netns exec iperf-client ip addr add dev enp3s0 172.16.16.2/24
ip netns exec iperf-client ip link set dev enp3s0 up
ip netns exec iperf-server ip link set dev enp1s0 up
ip netns exec iperf-server route add default gw 192.168.2.112
ip netns exec iperf-client route add default gw 172.16.16.1

# Test the interfaces and network using ping
ip netns exec iperf-client ping -c1 172.16.16.1
ip netns exec iperf-server ping -c1 192.168.2.112
ip netns exec iperf-server ping -c1 172.16.16.2
ip netns exec iperf-client ping -c1 192.168.2.139

# Start Iperf Server for UDP test
ip netns exec iperf-server iperf -u -s
# Run Client against Iperf server for UDP test
ip netns exec iperf-client iperf -u -c 192.168.2.139

0

Linuxボックスをルーター/ブリッジ/ゲートウェイ/ファイアウォールタイプのボックスにしたいようです。次のリソースが探しているものです。

Linuxルータープロジェクト

ルーターまたはファイアウォールのディストリビューションのリスト

Linux LiveCDルーター

Linux Journal-Linuxルーター

詳細情報に基づいて更新:

あなたが望むことをできるようになるとは思わない。OSは常に内部ルーティングテーブルを調べ、両方のIPアドレスをローカルで「参照」します。その後、OS内でトラフィックをルーティングし、ネットワークに送信しません。2台目のマシンまたは2台の仮想マシンが必要になります(Xenを確認してください)。


0

ここでは多くのことを行う必要があるため、正確さを完全に保証することはできませんが、元の質問は「自己送信」技術として知られているものを探しているようです。リンクされた検索は、トップリンク+さまざまなメーリングリスト、特に他のアプローチとの議論とパッチとして、最もよく維持されているカーネルパッチであると思うものを示しています。LKML。

iproute2の"ip netns"で行われるネットワーク名前空間も調べるべきだと思います。これには、追加のインターフェイスとルーティングマジックも必要になるため、他の回答の大規模なiptables hooplaほど複雑ではないかもしれません。

実装についてどのように、何を、どこで-誰かがこれらに有用な何かを見つけたらコメントは絶対に歓迎します。


0

この記事を確認してください。ここでは、NAT転送を使用してvirtualbox vmへのインターネットアクセスを有効にするための詳細な手順について説明します。

http://jackal777.wordpress.com/2012/02/13/virtualbox-host-only-networking-nat-for-internet-access/


これは理論的には質問に回答するかもしれませんが、回答の重要な部分をここに含め、参照用のリンクを提供することが望ましいでしょう
スコットパック

-1

IPV6で動作するようになった方法は次のとおりです

割り当てられた静的IP

/sbin/ifconfig eth1 inet6 add 2001:db8::1/127 
/sbin/ifconfig eth3 inet6 add 2001:db8::2/127 

「FAKE」アドレスへのホストのみのルートを設定します

ip -6 route add 2001:db8::2/128 dev eth1 metric 1
ip -6 route add 2001:db8::1/128 dev eth3 metric 1

隣接テーブルにデータを入力しました... arpのように

ip -6 neighbor add 2001:db8::1 lladdr 90:e2:ba:0d:75:e8 dev eth3 # eth1's mac address
ip -6 neighbor add 2001:db8::2 lladdr 90:e2:ba:0d:75:e9 dev eth1 # eth3's mac address

ip6tablesエントリを追加しました

ip6tables -t nat -A POSTROUTING -s 2001:db8::1 -d 2013::2 -j SNAT --to-source 2001:db8::1
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -j DNAT --to-destination 2001:db8::1
ip6tables -t nat -A POSTROUTING -s 2001:db8::2 -d 2013::1 -j SNAT --to-source 2001:db8::2
ip6tables -t nat -A PREROUTING -d 2001:db8::2 -j DNAT --to-destination 2001:db8::2

どのディストリビューションを使用していますか?前回チェックしたとき、カーネルにはIPv6用のNATテーブルがありません。
fukawi2
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.