linux命名空間中的IP轉發
我目前正在嘗試在 Linux 下使用網路命名空間來模擬網路。我已經設置了節點並連接了它們,它們可以相互ping通,一次一跳。但我真的很難嘗試啟用 IP 轉發。
我使用的是 Ubuntu Server 21.04,我係統上的網路由 systemd-networkd 控制。systemd 的版本是 247.3-3ubuntu3.4。
net.ipv6.conf.all.forwarding
並且net.ipv4.ip_forward
已經啟用。由於使用了networkd,因此必須在配置文件中另外啟用轉發。對於我的命名空間之一,如下所示:/etc/systemd/network/router1i.network:
[Match] Name=router1i [Network] IPForward=yes
和 /etc/systemd/network/router1i2.network:
[Match] Name=router1i2 [Network] IPForward=yes
那些 (
router1i
和router1i2
) 都是 veth 介面,也是命名空間中僅有的 2 個介面。如果我
ip -6 route get to fe80::1:0:200 iif router1i2
在命名空間中使用命令,我會得到正確的答案fe80::1:0:200 from :: dev router1i2 proto kernel metric 256 iif router1i2 pref medium
,因為路由不涉及轉發。如果我使用類似的命令ip -6 route get to fe80::1:0:200 iif router1i
,從另一個界面開始,答案突然是RNETLINK answers: Network is unreachable
。顯然,未啟用轉發。我已經嘗試通過
networkctl reconfigure router1i
在命名空間中使用來進行網路更新,但它說Failed to reconfigure network interface router1i: No such device or address
. 這很奇怪,因為當我使用 時networkctl status router1i
,它會正確列出所有資訊。完全重新載入 usingnetworkctl reload
也已經嘗試過,並且沒有任何改變。老實說,我幾乎無計可施。我什至不一定需要讓它與網路一起工作。任何想法或解決方法將不勝感激。
編輯:
正如 dirkt 建議的那樣,我現在已經用唯一本地地址交換了連結本地地址。根據 的輸出,現在可以正確選擇路線
ip -6 route get
。但我仍然無法ping通其他網路介面。我將在下面添加詳細資訊,因為老實說我找不到錯誤。介面配置:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group`default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 6: router1i@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether be:fc:8e:30:e4:18 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fd00:0:0:1000::1/64 scope global valid_lft forever preferred_lft forever inet6 fe80::bcfc:8eff:fe30:e418/64 scope link valid_lft forever preferred_lft forever 8: router1i2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether d6:3f:e9:9a:93:f3 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fd00:0:0:1001::1/63 scope global valid_lft forever preferred_lft forever inet6 fe80::d43f:e9ff:fe9a:93f3/64 scope link valid_lft forever preferred_lft forever
IPv6 路由表:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip -6 route fd00:0:0:1000::/64 dev router1i proto kernel metric 256 pref medium fd00:0:0:1000::/63 dev router1i2 proto kernel metric 256 pref medium fe80::/64 dev router1i proto kernel metric 256 pref medium fe80::/64 dev router1i2 proto kernel metric 256 pref medium default via fd00:0:0:1001::2 dev router1i2 metric 1024 pref medium
輸出
ip netconf
:ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip netconf inet lo forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet router1i forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet router1i2 forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet all forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet default forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet6 lo forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet6 router1i forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet6 router1i2 forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet6 all forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off inet6 default forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
這現在可以正常工作:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip -6 route get to fd00:0:0:1001::2 iif router1i fd00:0:0:1001::2 from :: dev router1i2 proto kernel metric 256 iif router1i pref medium
但是當我嘗試從 router1i 實際 ping 該地址時,它說:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ping6 fd00:0:0:1001::2 -I router1i ping6: connect: Network is unreachable
轉發已開啟,選擇了正確的路由,為什麼還是不行呢?
編輯2:
我讓它工作了!感謝所有試圖提供幫助的人。
顯然我誤判了 ping 與 -I 選項的作用。這讓我感到困惑,而我的經驗不足也無濟於事……最後,我發現缺少的最後一塊是外部命名空間中的一條錯誤路線,阻礙了它響應 ping。我應該早點找到那種方式,但我對轉發問題太著迷了……
所以無論如何,再次感謝,祝你有美好的一天!
fe80::/10
是連結本地地址。我認為這些是不可路由的(儘管可能有一些技巧可以使它們可路由,但我從未嘗試過)。如果您想使用 IPv6 路由,請不要使用這些;相反,除了連結本地地址(通常是自動配置的)之外,還為您的介面分配唯一本地地址(ULA,範圍)。
fc00::/7
您還可以
ip -6 route get from ... to ...
用於調試。
ip route add ...
在玩耍時照常設置路線。請記住,需要在數據包路徑上的所有節點(或者在您的情況下,命名空間)上設置路由,而不僅僅是在“轉發”節點上(忘記這一點是初學者的典型錯誤)。
如果您不通過嘗試 ping“從介面到介面”(我假設使用
-I
)而使您的生活變得困難,那麼這項工作會更容易。設置三個命名空間 A、B、C。用 veth pair 連接 A 和 B,用 veth pair 連接 B 和 C。在所有四個網路介面上放置 ULA 地址(使用正確的子網,A/B 一個子網,B/C 一個子網)。在 A 和 C 上設置預設路由(通過相應的 B 介面)。在 B 中啟用轉發。然後,在 A 中,嘗試 ping B 中近介面上的地址,然後是 B 中“遠”介面上的地址,然後是 C。只需使用 plain
ping <addr>
。查看它在哪裡停止工作(如果它不能直接工作)。要調試,請
tcpdump
在所有四個介面上的四個終端中執行。在網路命名空間中執行一個xterm
(或多個),這使得調試和設置變得更加容易。如果它仍然不起作用,請提出一個新問題,包括您進行上述設置的所有命令,包括有效的 ping,對於不起作用的 ping,包括 tcpdump 輸出。(每個問答的遠端調試是一個 PITA)。