web-dev-qa-db-ja.com

vethのネットワークレベルがarpに応答しない

私はvethで遊ぶことにしました:vethペアを作成し、一方の端からもう一方の端にpingを送信します。

$ ip link add type veth
$ ip addr add 192.168.99.1 dev veth4
$ ip addr add 192.168.99.2 dev veth5
$ ip link dev veth4 set up
$ ip link dev veth5 set up

確認しよう。

$ ip a

18: veth4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 6a:dc:02:5b:f0:f3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.99.1/24 scope global veth4
       valid_lft forever preferred_lft forever
19: veth5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 22:ec:d5:e8:7c:3e brd ff:ff:ff:ff:ff:ff
    inet 192.168.99.2/24 scope global veth5
       valid_lft forever preferred_lft forever

すべてが大丈夫のようです。次に、pingを実行してみます。

$ ping -I veth4 192.168.99.2
PING 192.168.99.2 (192.168.99.2) from 192.168.99.1 veth4: 56(84) bytes of data.
From 192.168.99.1 icmp_seq=1 Destination Host Unreachable
From 192.168.99.1 icmp_seq=2 Destination Host Unreachable
From 192.168.99.1 icmp_seq=3 Destination Host Unreachable


$ Sudo tshark -i veth5
Capturing on 'veth5'
l  1   0.000000 6a:dc:02:5b:f0:f3 -> Broadcast    ARP 42 Who has 192.168.99.2?  Tell 192.168.99.1
1   2   1.003206 6a:dc:02:5b:f0:f3 -> Broadcast    ARP 42 Who has 192.168.99.2?  Tell 192.168.99.1

したがって、veth5はarp要求を受信しますが、わざわざ応答することはありません。どうしたの?

4
nshy

これは非常に複雑で非常に古い質問であり、特にVETH、ネットワーク名前空間、ARP、ルートテーブル、NATなどのいくつかの異なる領域が関係しています。

私はこの問題への答えをOPだけでなく、そこにいる他の人たちのために追加しています。

多くの調査とテストを行った後、-vethペアは文字通り 2であるため、このように正確に使用できます個別のvirtualインターフェース。ただし、それらは virtual であるため、ARPテーブル/エントリに関していくつかの非常に奇妙な問題が発生します。この正確なシナリオ(作業に必要)に数週間取り組んだ後、私はこれを行う方法を正確に理解し、その過程で、ARP、NAT、およびルーティングについて、私が望んでいたよりも多くのことを学びました。

目的を正確に達成するには、次のように入力します(私の場合、Ubuntu 16.04)。注意test名前空間に入ると、bashを終了して、そこからのすべて(ルートテーブル、iptablesなど)を終了する必要があることに注意してください。ポイントオンはホストマシンとは異なります。私は通常、2つの端末を開きます。1つはホストに残り、もう1つはゲスト名前空間に残ります。

序文

# Tell the system we want to support IPv4 forwarding  
add/verify that the following is in `/etc/sysctl.conf`

`net.ipv4.ip_forward = 1`

# if it wasn't there, reparse syscrtl + restart networking
sysctl -p;
/etc/init.d/networking restart;

ホストの設定

# create a veth pair
ip link add name vHOST type veth peer name vGUEST

# choose a private MAC address and private IP address
ifconfig vHOST hw ether 02:1d:8d:dd:0c:61
ifconfig vHOST 10.11.0.1/24 up

# have to setup routes   FROM Host -> GUEST
ip route add 10.111.0.0/24 via 10.11.0.1 dev vHOST  # gateway

# have to explicitly assign what the MAC is for the vGUEST in the vHOST interface ARP table
arp -i vHOST -s 10.111.0.1 02:1d:8d:dd:0c:60 # vGUEST ip + mac address

# We must tell vHOST-vGUEST "tunnel", vHOST side that it's not a REAL bridge, so any ARP requests must be answered by vHOST
echo 1 > /proc/sys/net/ipv4/conf/vHOST/proxy_arp


# setup forwarding + NAT (so packets can come back)
iptables -A FORWARD -s 10.111.0.0/24 -o vHOST -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.111.0.1 -j SNAT --to 192.168.42.124

ゲストの設定

# create the "test" namespace, so we can verfiy settings
ip netns add test

# add vGUEST "interface" to the "test" namespace
ip link set vGUEST netns test

# enter the "test" namespace with a bash Shell
ip netns exec test bash

# choose a private MAC address and private IP address
ifconfig vGUEST hw ether 02:1d:8d:dd:0c:60
ifconfig vGUEST 10.111.0.1/24 up

# have to setup routes   FROM GUEST -> Host
ip route add default via 10.111.0.1 dev vGUEST   # gateway

# have to explicitly assign what the MAC is for the vHOST in the vGUEST interface ARP table
arp -i vGUEST -s 10.11.0.1 02:1d:8d:dd:0c:61 # vHOST ip + mac address

これで、GUEST/Hostは相互にpingを実行でき、vGUESTはマシンの外部でpingを実行できます。

特に、 multimac は、vethが1対1の関係である多対1の関係をサポートしているため、わずかに異なる方法でvethとまったく同じことを実行できます。

名前空間なしでこれをサポートするには、ポリシールーティングを使用する必要があります(これはネットワーク名前空間よりも少し複雑です) )

6
Nathan

Vethペアはこのようには使用されません。 vethペアは文字通りデバイスパイプであり、パイプパケットの一方の端がもう一方の端から出てきます。

私が提供できる最も単純な同義語は、ペアの半分がイーサネットデバイスであり、もう一方の端がデバイスが接続されているスイッチポートであると想像することです。ペアを2つの別個のデバイスとして扱うのではなく、プッシュ/プルするための2つの「端」を持つ1つのデバイスとして扱う必要があります。

4
Matthew Ife