Kvm

無法通過虛擬分接頭介面將 vm 連接到 IPv6 網際網路

  • June 18, 2020

我無法通過主機上的虛擬分接設備將 vm 連接到 IPv6 網際網路。即,我無法 ping ipv6.google.com 或公共 IPv6 主機全域主介面地址。前任:

-bash-4.2$ ping6 ipv6.google.com
   PING ipv6.google.com(sea15s11-in-x0e.1e100.net) 56 data bytes
   From 2600:1f14:680:xxxx:66a3:79d5:6c1d:14c icmp_seq=1 Destination unreachable: Address unreachable
   From 2600:1f14:680:xxxx:66a3:79d5:6c1d:14c icmp_seq=2 Destination unreachable: Address unreachable
   From 2600:1f14:680:xxxx:66a3:79d5:6c1d:14c icmp_seq=3 Destination unreachable: Address unreachable
   ^C
   --- ipv6.google.com ping statistics ---
   4 packets transmitted, 0

received, +3 errors, 100% packet loss, time 3082ms

或主機的全域 ipv6 地址,我得到同樣的錯誤。

簡單拓撲:

  router -----(eth0)----- host ----(tap device)---- vm

主機上的鄰居發現似乎存在一些問題,當我從主機的分接端點 tcpdump 分接介面時,我收到了請求消息,但沒有返回任何內容:

[user ~]$ sudo tcpdump ip6 -vv -i tp-0gn-0000go-0    
tcpdump: listening on tp-0gn-0000go-0, link-type EN10MB (Ethernet), capture size 262144 bytes
   01:45:16.596378 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) 2600:1f14:680:xxxx:66a3:79d5:6c1d:14c > ff02::1:ff00:200e: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has sea15s11-in-x0e.1e100.net
         source link-address option (1), length 8 (1): 02:fc:80:d4:52:b6
           0x0000:  02fc 80d4 52b6
   01:45:17.610410 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) 2600:1f14:680:xxxx:66a3:79d5:6c1d:14c > ff02::1:ff00:200e: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has sea15s11-in-x0e.1e100.net
         source link-address option (1), length 8 (1): 02:fc:80:d4:52:b6
           0x0000:  02fc 80d4 52b6
   01:45:18.634402 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) 2600:1f14:680:xxxx:66a3:79d5:6c1d:14c > ff02::1:ff00:200e: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has sea15s11-in-x0e.1e100.net
         source link-address option (1), length 8 (1): 02:fc:80:d4:52:b6
           0x0000:  02fc 80d4 52b6

注意:我可以從主機 ping ipv6.google.com:

[user ~]$ ping6 ipv6.google.com
PING ipv6.google.com(sea15s11-in-x0e.1e100.net (2607:f8b0:400a:808::200e)) 56 data bytes
64 bytes from sea15s11-in-x0e.1e100.net (2607:f8b0:400a:808::200e): icmp_seq=1 ttl=39 time=9.93 ms
64 bytes from sea15s11-in-x0e.1e100.net (2607:f8b0:400a:808::200e): icmp_seq=2 ttl=39 time=10.1 ms
64 bytes from sea15s11-in-x0e.1e100.net (2607:f8b0:400a:808::200e): icmp_seq=3 ttl=39 time=10.1 ms

鄰居發現似乎存在問題。我不確定我是否面臨 DAD、NUD 或其他問題,或者可能根本不是鄰居發現問題?

我目前只有路由器ip -6 neigh show,但我對鄰居發現記憶體的印像只是一個記憶體,並且路由應該仍然是完整的並且可以發現(儘管這是我非常有限的理解)。也許我錯過了一些鄰居發現/廣告核心參數?

[user ~]$ ip -6 neigh show
fe80::460:a1ff:fec3:9cb6 dev eth0 lladdr 06:60:a1:c3:9c:b6 router STALE 

我有一種預感,我在net.ipv6這裡遺漏了一些核心參數,但我不確定從哪裡開始修改它們。任何建議都非常感謝。完整的網路設置資訊可以在下面找到。請注意,我手動配置了vm全域地址,因此它與主機非常相似,一個是:XXXb/128,一個是:XXXc/128。

虛擬機端點 - 介面:

-bash-4.2$ ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   link/ether 02:fc:80:d4:52:b6 brd ff:ff:ff:ff:ff:ff
   inet 169.254.18.177/30 brd 169.254.18.179 scope global eth0
      valid_lft forever preferred_lft forever
   inet6 2600:1f14:680:xxxx:66a3:79d5:6c1d:14c/128 scope global 
      valid_lft forever preferred_lft forever
   inet6 fe80::fc:80ff:fed4:52b6/64 scope link 
      valid_lft forever preferred_lft forever

和相關的VM路線:

-bash-4.2$ ip -6 r s
2600:1f14:680:6f00:66a3:79d5:6c1d:14c dev eth0  proto kernel  metric 256  pref medium
fe80::/64 dev eth1  proto kernel  metric 256  pref medium
fe80::/64 dev eth0  proto kernel  metric 256  pref medium
default dev eth0  metric 1024  pref medium

主機 - 分接頭和主界面如下所示:

[user ~]$ ip a s tp-0gn-0000go-0
2393: tp-0gn-0000go-0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   link/ether d2:d5:4e:f3:de:ab brd ff:ff:ff:ff:ff:ff
   inet 169.254.18.178/30 scope global tp-0gn-0000go-0
      valid_lft forever preferred_lft forever
   inet6 fe80::d0d5:4eff:fef3:deab/64 scope link 
      valid_lft forever preferred_lft forever
[user ~]$ ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
   link/ether 06:b6:f7:16:ac:04 brd ff:ff:ff:ff:ff:ff
   inet 172.30.255.4/28 brd 172.30.255.15 scope global dynamic eth0
      valid_lft 2994sec preferred_lft 2994sec
   inet6 2600:1f14:680:6f00:66a3:79d5:6c1d:14b/128 scope global dynamic 
      valid_lft 405sec preferred_lft 105sec
   inet6 fe80::4b6:f7ff:fe16:ac04/64 scope link 
      valid_lft forever preferred_lft forever

以及相關路線:

[user ~]$ ip -6 r s
2600:1f14:680:6f00:66a3:79d5:6c1d:14b dev eth0 proto kernel metric 256 expires 389sec pref medium
2600:1f14:680:6f00:66a3:79d5:6c1d:14c dev tp-0gn-0000go-0 metric 1024 pref medium
2600:1f14:680:6f00::/64 dev eth0 proto kernel metric 256 pref medium
unreachable 3ffe:ffff::/32 dev lo metric 1024 error 4294967183 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default via fe80::460:a1ff:fec3:9cb6 dev eth0 proto ra metric 1024 expires 1798sec hoplimit 64 pref medium

ip6tables 過濾器允許一切

[user ~]$ sudo ip6tables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

主機是 amazon-linux,類似於 centos/rhel/fedora, cat /etc/os-release

NAME ="Amazon Linux"
VERSION="2"
ID_LIKE="centos rhel fedora"

任何建議都非常感謝。如果我缺少任何必要的資訊或概念上的任何內容,請告訴我。提前致謝。


更新:另外我應該注意,在監聽主機的 eth0 並嘗試從 vm ping ipv6.google.com 時,我沒有收到任何 tcpdump 數據包。從第一個 tcpdump 中可以看出,數據包首先被發送到應該通過 eth0 路由的所有節點請求多播地址(基於本地路由表),但我從未看到數據包通過 tcpdump 通過 eth0。我目前有net.ipv6.conf.all.forwarding=1,net.ipv6.conf.all.accept_ra=2net.ipv6.conf.all.accept_ra_from_local=1.


更新#2:我看到了這篇文章。我添加net.ipv6.conf.all.proxy_ndp=1並添加了一個代理鄰居,ip -6 neigh add proxy <host eth0 global ip6 addr> dev <tap device>它允許我從 vm ping 主機的 eth0 全域地址。儘管我覺得我越來越近了,但從 vm 連接到 ipv6.google.com 仍然沒有運氣。


更新 #2.5:我認為之前的更新無關緊要。我認為問題的核心是虛擬機不知道任何路由器,因此它正在發送鄰居請求以獲取全域 ipv6 地址。我認為不應該是這樣,但這只是我的預感。我還沒有遇到一個很好的資源,它明確說明何時應該發送鄰居請求、路由器請求和回應要求。


更新#3:我取消了手動分配地址,並試圖讓 vm 與 DHCP 伺服器(這是在 EC2 vpc btw 中)進行通信以獲取它的地址。我在主機中添加了一個 DHCPv6 中繼,但似乎中繼消息正在發送到 DHCPv6 伺服器並且永遠不會返回。如果其他人感興趣,我很樂意發布有關此的更多資訊/tcpdump。

這是我認為錯誤的地方以及如何解決它。

虛擬機端

第一個問題是虛擬機上的這個:

default dev eth0  metric 1024  pref medium

這使得整個 Internet 上的 VM 路由堆棧都可以直接在eth0的連結上使用。因此,對於任何IPv6 目的地,它都會發送 NDP 請求,但沒有任何東西(包括主機)會回答它。

要解決此問題,VM 只需將主機用作路由器,並使用其本地連結地址。它可以簡單地在 VM 上手動配置:

ip -6 route delete default dev eth0
ip -6 route add default via fe80::d0d5:4eff:fef3:deab dev eth0

對於VM端就是這樣。

VM 上的備用設置(和主機的tp-0gn-0000go-0

如果您不想使用連結本地地址(例如:如果由於主機tp-0gn-0000go-0上的隨機 MAC 地址而可能在重新啟動時更改),則可以改用主機的全域 IP 地址通過在tp-0gn-0000go-0上複製它。

在主機上,還要​​在tp-0gn-0000go-0 上將其 IP 地址添加為 /128 (或者noprefixroute如果這不僅僅是一個 /128 的話):

ip -6 address add 2600:1f14:680:6f00:66a3:79d5:6c1d:14b/128 dev tp-0gn-0000go-0

在 VM 上,而不是上面:

ip -6 route delete default dev eth0
ip -6 route add 2600:1f14:680:6f00:66a3:79d5:6c1d:14b/128 dev eth0
ip -6 route add default via 2600:1f14:680:6f00:66a3:79d5:6c1d:14b dev eth0

主機端(在eth0上)

主機自己的路由器不知道虛擬機,因為虛擬機在主機的eth0端不存在。當來自 Internet 的數據包到達主機的路由器時,它將執行Neighbor Solicitation,但沒有任何響應,包括主機(當然,除非該路由器可以配置其他方式,這將簡化一切)。主機必須配置ND 代理才能實際響應此請求,以便最終將數據包發送到主機。

為此,請在主機上啟用eth0proxy_ndp添加**特定的 NDP 代理條目(僅proxy_ndp在介面上啟用時才有效):

sysctl -w net.ipv6.conf.eth0.proxy_ndp=1
ip -6 neighbour add proxy 2600:1f14:680:6f00:66a3:79d5:6c1d:14c dev eth0

(鄰居代理條目可以顯示ip neighbour show proxy和刪除,例如使用ip neighbour flush proxy。預設情況下不顯示ip neighbour或刪除ip neighbour flush all

主機現在將接收數據包2600:1f14:680:6f00:66a3:79d5:6c1d:14c並將其路由到其路由表中定義的 VM。


現在兩個方向都正確轉發:它應該可以工作。

我沒有嘗試使用路由器廣告守護radvd程序


更新:正如@uMdRupert 所提到的,無論何時啟動轉發(net.ipv6.conf.all.forwarding=1)如果由路由器廣告配置,主機上也需要此設置:

sysctl -w net.ipv6.conf.eth0.accept_ra=2

原因是預設情況下,Linux IPv6 路由器會忽略路由通告(我猜原因是:因為它已經被配置為路由器,所以無需更改此配置)。因此,只需在通過 Router Advertisements 接收其預設路由的主機上啟動 IPv6轉發proto ra [...] expires 1798sec(如在此類路由中所示),可能會在一段時間後失去此路由(或在更改配置後重新啟動)並變得無法訪問。這必須被否決,以便通過設置為 2仍然允許在eth0上接受此類 RA 。accept_ra

引用自:https://unix.stackexchange.com/questions/591743