外部から同じPC上の2つのネットワークカード間でIP接続を開始できますか?

外部から同じPC上の2つのネットワークカード間でIP接続を開始できますか?

Linuxコンピュータの2つのNICが外部ケーブルを使用して互いに直接接続されている場合は、そのケーブルを介して2つのNIC間のIP接続を開始できますか?

eth22つのNICとeth3IPアドレスを別々に設定しました。その後、テーブルからこれら2つのインターフェイスに関連するすべてのルールを削除しました。10.10.123.2/2410.10.123.3/24local

# ip rule
0:      from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 
# ip route show table local | grep -E "eth2|eth3"
# 

..そして接続が通過する必要がある規則と、接続が通過する必要がある規則をテーブルにmain追加しました。10.10.123.3eth210.10.123.2eth3

# ip route get 10.10.123.3
10.10.123.3 dev eth2  src 10.10.123.2 
    cache 
# ip route get 10.10.123.2
10.10.123.2 dev eth3  src 10.10.123.3 
    cache 
# 

10.10.123.2これで(ソースIPは)ICMP "エコー要求"メッセージを送信すると、10.10.123.3ARP要求メッセージが行に追加され、eth2インターフェイスがそれを受信することがわかりますが、Request who-has 10.10.123.2 tell 10.10.123.3何らかの理由で応答に対して何もしません。 。どんなアイデアがありますか?

答え1

パス操作なしで再試行しますが、

ip netns add not-me
ip link set eth2 netns not-me

これにより、デフォルトのネットワーク名前空間からeth2が削除され、表示されなくなります。回復: ip link set eth2 netns 1。新しい名前空間でコマンドを実行するには:ip netns exec not-me command....commandは、bash2番目の(ネストされた)シェルを開くことです。

答え2

これはスクリプトです。IPクロス私はこれをずっと前に書きましたが、まだ有効です。通常、カーネルによって区切られたパケットを「自分に」送信できるようにiptablesを設定します。それに基づいていますこの回答

#!/bin/bash
# posted in http://unix.stackexchange.com/a/275888/119298 by meuh
# see https://serverfault.com/q/127636/294707
#  cmcginty Apr 2 '10 and Steve Kehlet answered Sep 8 '11

usage(){
        echo "$0: usage:
 config interface1 interface2
 show
 test
 tcpdump
 undo
This script sets up an iptables address translation to allow packets
to circulate over an external loopback cable between two interfaces.
You need to be root. Example usage:
 $0 config eth0:1 eth1
 $0 test
" >&2
        exit 1
}

getmac(){
        $setdebug
        local interface=${1?'interface'}
        ip link show $interface |
        awk '/link\/ether/ { print $2 }'
}
getaddr(){
        $setdebug
        local interface=${1?'interface'}
        ip addr show $interface |
        awk '/ inet / { split($2,x,"/"); print x[1] }'
}
# return true if have name of 2 interfaces
haveconfig(){
        $setdebug
        [ -n "$if1" -a -n "$if2" ] &&
        ip link show "$if1" &&
        ip link show "$if2"
}
# set variables from $if1 and $if2
setup(){
        $setdebug
        if ! haveconfig >/dev/null
        then    haveconfig >&2
                echo "Start with 'config' and 2 valid interfaces" >&2
                usage
        fi
        realprefix=10.50
        fakeprefix=10.60
        real1=$realprefix.0.1
        fake1=$fakeprefix.0.1
        real2=$realprefix.1.1
        fake2=$fakeprefix.1.1
        mac1=$(getmac $if1)
        mac2=$(getmac $if2)
}
doconfig(){
        doifconfig
        doiptables
        doroute
        doarp
        echo "eg: ping $fake2"
}
# Give IPs to the interfaces, and put them on separate networks:
doifconfig(){
        $setdebug
        ifconfig $if1 $real1/24
        ifconfig $if2 $real2/24
}

# set up a double NAT scenario: two new fake networks used to reach the
# other. On the way out, source NAT to your fake network. On the way in,
# fix the destination. And vice versa for the other network:
doiptables(){
        $setdebug
        # nat source IP $real1 -> $fake1 when going to $fake2
        iptables -t nat -A POSTROUTING -s $real1 -d $fake2 -j SNAT --to-source $fake1
        # nat source IP $real2 -> $fake2 when going to $fake1
        iptables -t nat -A POSTROUTING -s $real2 -d $fake1 -j SNAT --to-source $fake2

        # nat inbound $fake1 -> $real1
        iptables -t nat -A PREROUTING -d $fake1 -j DNAT --to-destination $real1
        # nat inbound $fake2 -> $real2
        iptables -t nat -A PREROUTING -d $fake2 -j DNAT --to-destination $real2
}

# tell the system how to get to each fake network
doroute(){
        $setdebug
        ip route flush cache
        ip route add $fake2 dev $if1 src $real1
        ip route add $fake1 dev $if2 src $real2
}
# prepopulate the arp entries
doarp(){
        $setdebug
        ip neigh add $fake2 lladdr $mac2 dev $if1
        ip neigh add $fake1 lladdr $mac1 dev $if2
}
doshow(){
        $setdebug
        iptables -L -t nat -v -n -x
        ip route get $fake1
        ip route get $fake2
        arp -n
}
# undo all configuration
doundo(){
        iptables -F -t nat
        ip route del $fake2 dev $if1
        ip route del $fake1 dev $if2 
        ip route flush cache
        #arp -i $realif1 -d $fake2
        #arp -i $realif2 -d $fake1
        ip neigh del $fake2 lladdr $mac2 dev $if1
        ip neigh del $fake1 lladdr $mac1 dev $if2
        ip addr del $real1/24 dev $if1
        ip addr del $real2/24 dev $if2
}
# tcpdump of just the wanted packets, in case using nfs on interface
dotcpdump(){
        tcpdump -n -e -i fm1-gb1 ether src $mac1 or ether src $mac2 or ether dst $mac1 or ether dst $mac2
}
showpacketcounts(){
        echo -n "$1 "
        local realif=${1%:*}
        ifconfig "$realif" |
        awk '/packets/{printf "%s %-20s",$1,$2; if(/TX/)printf "\n"}'
}
showiptablescounts(){
        iptables -L -t nat -v -x |
        awk '       $3~/[SD]NAT/ { result = result " " $1 " " $3}
                END {print "iptables counts " result }'
}
showcounts(){
        showpacketcounts $if1
        showpacketcounts $if2
        showiptablescounts
}
showdiffs(){
        echo -e "==\n$old\n==\n$new" |
        awk '/^==/{ part++; i = 0; next }
                { inp[part][++i] = $0 }
        END { end = i; for(i = 1;i<=end;i++)print inp[1][i] "\n" inp[2][i] }'
}
# use netstat -l -t to see what services you could test
dotest(){
        old=$(showcounts)
        for ip in $fake1 $fake2
        do      ping -c 4 $ip # -W 1
                echo
                traceroute -M udp $ip # -m 2
                echo
                rpcinfo -p $ip | head -3
                echo
        done
        new=$(showcounts)
        showdiffs
}

# eg ping $fake2 goes out $if1, the source IP $real1 gets NATted to $fake1,
# and as it comes into $if2 the destination $fake2 gets NATted to $real2.
# And the reply takes a similar journey.

# to use iperf to test throughput. Bind to the correct IPs, and be certain
# which IP you're contacting (the other end's fake address):
# server
#./iperf -B $real2 -s
# client: your destination is the other end's fake address
#./iperf -B $real1 -c $fake2 -t 60 -i 10

setdebug= 
case $- in
*x*)        setdebug='set -x' ;; 
esac
PATH=$PATH:/sbin:/usr/sbin

# read saved config
CONFIGFILE=~/.ipcrossover
if [ -s $CONFIGFILE ]
then        source $CONFIGFILE
fi

while [ $# -gt 0 ]
do      cmd=$1; shift
        case $cmd in
        config) if [ $# -ge 2 ] && ip link show "$1" >/dev/null
                then    if1=$1
                        if2=$2
                        shift 2
                        echo "if1=$if1; if2=$if2" >$CONFIGFILE
                fi
                setup
                doconfig ;;
        show|test|undo|tcpdump)
                setup
                do$cmd ;;
        *)      usage ;;
        esac
done

使い方はかなり簡単です。

sudo ipcrossover config eth0 eth1
ping 10.60.0.1
ping 10.60.1.1
sudo ipcrossover test

eth0:1 eth1:1(これらのインターフェイスの既存のネットワークを中断したくない場合は、エイリアスを使用できます。)分解構成を使用してくださいsudo ipcrossover undo。動作方法は、最初のインターフェイスに新しいIPアドレス10.50.0.1と10.60.0.1を追加し、2番目のインターフェイスに10.50.1.1と10.60.1.1を追加し、スクリプトの動作設定に従うことです。

        realprefix=10.50
        fakeprefix=10.60
        real1=$realprefix.0.1
        fake1=$fakeprefix.0.1
        real2=$realprefix.1.1
        fake2=$fakeprefix.1.1

たとえば、ping $fake2インターフェイス$ if1のうち、ソースIP $ real1はNATから$ fake1に変換され、$ if2に入ると、ターゲットIP $ fake2は$ real2にNAT変換されます。答えも同様のプロセスを経ました。

スループットテストに使用するには、iperf正しいIPにバインドし、接続しているIP(相手の偽のアドレス)を確認してください。サーバーから./iperf -B $real2 -s。クライアントでは、宛先はもう一方の端にある偽のアドレスです ./iperf -B $real1 -c $fake2 -t 60 -i 10

ケーブルを抜いてPingが止まっていることを確認して、正しく機能していることを確認してください!ぜひお読みくださいリンクされた回答何が起こっているのか理解してください。

答え3

デフォルトでは、Linuxカーネルは、すべてのインターフェイスのすべてのインターフェイスから来るARPリクエストに応答します。この動作は時々望ましくない。

この動作を変更するには、いくつかのカーネルパラメータを変更する必要があります。

echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore 
echo 1 > /proc/sys/net/ipv4/conf/eth1/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/eth1/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_filter
echo 1 > /proc/sys/net/ipv4/conf/eth1/arp_filter

次のコマンドを使用して、マシンのすべてのインターフェイスに対してこの設定を変更することもできます。

echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore 
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter

これらのネットワークカーネルパラメータの意味を確認し、最後のコマンドが期待どおりに機能しない場合は、特定の要件に合わせて調整してください。

arp_ignore- 整数

ローカル宛先IPアドレスを解決する受信したARP要求に対する応答を送信するさまざまなモードを定義します。

  • 0 - (デフォルト):すべてのインターフェイスで設定されたすべてのローカル宛先IPアドレスに応答します。
  • 1 - 宛先IPアドレスが着信インターフェイスで設定されたローカルアドレスである場合にのみ応答します。
  • 2 - 宛先IPアドレスが着信インターフェイスで設定されたローカルアドレスであり、両方が送信者のIPアドレスとそのインターフェイスの同じサブネットに属している場合にのみ応答します。
  • 3 - スコープホストを使用して設定されたローカルアドレスには応答せず、グローバルアドレスとリンクアドレスの確認にのみ応答します。
  • 4-7 - 予約済み
  • 8 - すべてのローカルアドレスに返信しないでください。

{interface}からARP要求を受信すると、conf / {all、interface} / arp_ignoreの最大値を使用します。

arp_announce- 整数

インターフェイスから送信されたARP要求のIPパケットからローカルソースIPアドレスを宣伝するためのさまざまな制限レベルを定義します。

  • 0 - (デフォルト) すべてのインターフェイスに設定されたローカルアドレスを使用します。
  • 1 - そのインターフェイスの宛先サブネットにないローカルアドレスを使用しないでください。このモードは、このインターフェイスを介して接続できるターゲットホストが、ARP要求の送信元IPアドレスが着信インターフェイスに設定されている論理ネットワークの一部である必要がある場合に便利です。要求を生​​成すると、宛先IPを含むすべてのサブネットが解決され、送信元アドレスがそのサブネットから来る場合は送信元アドレスが保持されます。そのサブネットがない場合は、レベル2の規則に従ってソースアドレスを選択します。
  • 2 - 常にターゲットに最適なローカルアドレスを使用してください。このモードでは、IPパケットの送信元アドレスを無視し、宛先ホストと通信するために好ましいローカルアドレスを選択しようとします。これらのローカルアドレスは、宛先IPアドレスを含むすべてのサブネットのプライマリIPアドレスへの送信インターフェイスを確認することによって選択されます。適切なローカルアドレスが見つからない場合は、発信元のIPアドレスに関係なく、要求への応答を受け取ることを望み、発信インターフェイスまたは他のすべてのインターフェイスの最初のローカルアドレスを選択します。

conf/{all,interface}/arp_announce で最大値を使用してください。

制限レベルを上げると解決された宛先から回答を受ける機会が増え、制限レベルを下げると有効な発信者情報をより多く知らせることができます。

arp_filter- ブール値

  • 1 - 同じサブネットに複数のネットワークインターフェイスがあり、カーネルがARP IPからそのインターフェイスにパケットをルーティングするかどうかに応じて、各インターフェイスに対してARPに応答できます(したがってソースベースのソースを使用する必要があります)。動作するようにルーティング)。つまり、arp要求に応答するカード(通常1枚)を制御できます。

  • 0 - (デフォルト)カーネルは他のインターフェイスのアドレスを使用してarp要求に応答できます。これは間違っているように見えるかもしれませんが、成功したコミュニケーションの可能性を高めるので、しばしば意味があります。 IP アドレスは、特定のインターフェイスではなく Linux のホスト全体が所有します。この動作は、ロードバランシングなどのより複雑な設定でのみ問題を引き起こします。

conf/{all,interface}/arp_filter の 1 つ以上が TRUE に設定されている場合は、インターフェイスの arp_filter が有効になり、それ以外の場合は無効になります。

より多くの関連ネットワークパラメータを表示できます。https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

答え4

私はこれを行うためにLinuxネットワークネームスペースを使います。私はns1ポートの1つに別々の名前空間を作成し、これを 。

名前空間にインターフェイスを追加し、eth1IPアドレスを割り当てました192.168.2.1/24。また、ns1ネームスペース内からネームスペースに入ってくるすべてのネットワークトラフィックが次を使用するように強制しますeth1

ip route add default dev eth1

その後、まだルートネームスペース内の192.168.1.1/24他のイーサネットポートにIPアドレスを割り当てました。また、ルートネームスペースのネームスペースにパスをeth0追加しました。ns1

ip route add 192.168.2.0/24 dev eth0

これで、192.168.2.1から192.168.1.1にpingを送信でき、その逆も可能です。 eth0とeth1の間のケーブルを外し、パケットフローが停止していることを確認してください。

iperf を使用して帯域幅を確認して、ケーブルを使用していることを確認することもできます。名前空間内でns1iperfサーバーを実行します。

iperf -s -f m -i 5

ルートネームスペースでiperfクライアントを実行します。

iperf -c 192.168.2.1 -t 60

関連情報