외부에서 동일한 PC에 있는 두 개의 네트워크 카드 간에 IP 연결을 시작할 수 있습니까?

외부에서 동일한 PC에 있는 두 개의 네트워크 카드 간에 IP 연결을 시작할 수 있습니까?

Linux 컴퓨터의 두 NIC가 외부 케이블을 사용하여 서로 직접 연결된 경우 해당 케이블을 통해 두 NIC 간의 IP 연결을 시작할 수 있습니까?

eth2두 개의 NIC 와 eth3IP 주소를 별도로 구성했습니다 . 그런 다음 테이블에서 이 두 인터페이스와 관련된 모든 규칙을 제거했습니다.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는 bash두 번째(중첩된) 셸을 여는 것일 수 있습니다.

답변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을 추가하고 두 번째 인터페이스에 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.

케이블을 뽑고 핑이 멈추는지 확인하여 제대로 작동하는지 확인하세요! 꼭 읽어주세요연결된 답변무슨 일이 일어나고 있는지 이해하세요.

답변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 중 하나 이상이 TRUE로 설정되면 인터페이스의 arp_filter가 활성화되고, 그렇지 않으면 비활성화됩니다.

더 많은 관련 네트워크 매개변수를 볼 수 있습니다.https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

답변4

저는 이 작업을 수행하기 위해 Linux 네트워크 네임스페이스를 사용합니다. 나는 ns1포트 중 하나에 대해 별도의 네임스페이스를 만들고 이를 .

네임스페이스에 인터페이스를 추가 eth1하고 IP 주소를 할당했습니다 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

관련 정보