GNU/Linux >> Linux の 問題 >  >> Linux

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

解決策 1:

Linux で次のコマンドを使用して、新しいデュアルポート 10Gbps カードのスループットを「ループバック」モード (つまり、一方のポートをもう一方のポートに直接接続) でテストすることに成功しました。これはすべて、パケットをネットワークから強制的に送信するためのちょっとしたブードゥーですが、そうしないと、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 担当者に感謝します。将来この投稿を見つけた他の人に役立つことを願っています。

解決策 2:

いつものように-少し遅れています-しかし、最近では、ネットワーク名前空間を使用してインターフェースを分離し、ローカル転送を防ぐことができます(および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 アドレスを削除する必要はありません)。

解決策 3:

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

<オール>
  • 私のローカル PC には、異なるサブネット 192.168.1/24 に NIC があります。 、192.168.2/24
  • 両方のサブネットにアクセスできる外部ルーター/PC があります。
  • ローカル PC の NIC を介して双方向トラフィックを送信したい
  • 構成には、サブネットごとに 2 つの未使用の IP アドレスが必要です。
  • ローカル PC の iptable ルートは SNAT に設定され、DNAT 発信トラフィックは「偽の」IP に送信されます。

    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
    

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

    <オール>
  • 発信パケットのソース 192.168.2.1 を 192.168.2.100 に書き換える
  • 着信パケットの宛先 192.168.1.100 を 192.168.1.1 に書き換える
  • 発信パケットのソース 192.168.1.1 を 192.168.1.100 に書き換える
  • 着信パケットの宛先 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
    

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

    ping 192.168.1.100
    ping 192.168.2.100
    

    解決策 4:

    わかりました、ようやく構成のセットアップに成功しました。

    このアイデアは、別の偽のアドレスを使用して、この偽のアドレスのルートをインターフェイス 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 本のクロスオーバー ケーブルだけで、より単純な構成を使用することは可能かもしれませんが、試していないので、実際の解決策を提供することを好みます。


    Linux
    1. Python:Linux でローカル インターフェイス/IP アドレスのデフォルト ゲートウェイを取得する

    2. Linux で特定のインターフェイスを介してマルチキャスト パケットを送信する方法

    3. wget を強制的にタイムアウトにする

    1. 6tcpdumpネットワークトラフィックフィルターオプション

    2. USB トラフィックをダンプする方法は?

    3. インターフェイス経由のネットワーク トラフィック量を監視する

    1. Awkの外部変数?

    2. ScpへのSftpインターフェース?

    3. proc のみを使用してローカル ネットワーク インターフェイス アドレスを取得しますか?