Networking

無法從命名空間 ping 外部網路,可能後路由不起作用

  • January 17, 2020

我正在嘗試從網路命名空間內 ping 一個外部 ip(在本例中為 google)。

 ip netns add ns1
# Create v-eth1 and v-peer1: v-eth1 is in the host space whereas peer-1 is supposed to be in the ns
 ip link add v-eth1 type veth peer name v-peer1
# Move v-peer1 to ns
 ip link set v-peer1 netns ns1
# set v-eth1
 ip addr add 10.200.1.1/24 dev v-eth1
 ip link set v-eth1 up
# Set v-peer1 in the ns
 ip netns exec ns1 ip addr add 10.200.1.2/24 dev v-peer1
 ip netns exec ns1 ip link set v-peer1 up
# Set loopback interface in the ns
 ip netns exec ns1 ip link set lo up
# Add defaut route in the ns
 ip netns exec ns1 ip route add default via 10.200.1.1
# Set host routing tables
 iptables -t nat -A POSTROUTING -s 10.200.1.0/24 -j MASQUERADE
# Enable routing in the host
sysctl -w net.ipv4.ip_forward=1
#
 ip netns exec ns1 ping 8.8.8.8

由於某些原因,這在 virtualbox(在我的筆記型電腦上)的 VM 內執行良好,它在我的桌面(ubuntu 18.04)上執行,但它在我的筆記型電腦上的主機作業系統上不起作用(這也是 Ubuntu 18.04)。

我嘗試了traceroute,這就是我得到的:

在筆記型電腦上

筆記型電腦上的錯誤跟踪路由

在桌面上

在桌面上正確的 traceroute

你們中有人知道我應該調查什麼才能找到問題嗎?據我所知,我沒有設置防火牆(ufw 已禁用)

編輯:這就是我用 iptables-save -c 得到的:

# Generated by iptables-save v1.6.1 on Fri Jan 17 18:05:36 2020
*filter
:INPUT ACCEPT [3774:2079111]
:FORWARD DROP [5:420]
:OUTPUT ACCEPT [3053:308301]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
[16984:18361691] -A FORWARD -j DOCKER-USER
[16984:18361691] -A FORWARD -j DOCKER-ISOLATION-STAGE-1
[12139:18094316] -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -o docker0 -j DOCKER
[4761:260319] -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
[0:0] -A FORWARD -i docker0 -o docker0 -j ACCEPT
[0:0] -A FORWARD -o br-6a72e380ece6 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -o br-6a72e380ece6 -j DOCKER
[0:0] -A FORWARD -i br-6a72e380ece6 ! -o br-6a72e380ece6 -j ACCEPT
[0:0] -A FORWARD -i br-6a72e380ece6 -o br-6a72e380ece6 -j ACCEPT
[4761:260319] -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
[0:0] -A DOCKER-ISOLATION-STAGE-1 -i br-6a72e380ece6 ! -o br-6a72e380ece6 -j DOCKER-ISOLATION-STAGE-2
[16984:18361691] -A DOCKER-ISOLATION-STAGE-1 -j RETURN
[0:0] -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
[0:0] -A DOCKER-ISOLATION-STAGE-2 -o br-6a72e380ece6 -j DROP
[4761:260319] -A DOCKER-ISOLATION-STAGE-2 -j RETURN
[16984:18361691] -A DOCKER-USER -j RETURN
COMMIT
# Completed on Fri Jan 17 18:05:36 2020
# Generated by iptables-save v1.6.1 on Fri Jan 17 18:05:36 2020
*nat
:PREROUTING ACCEPT [406:111092]
:INPUT ACCEPT [9:703]
:OUTPUT ACCEPT [29:2283]
:POSTROUTING ACCEPT [28:2114]
:DOCKER - [0:0]
[253:19770] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
[0:0] -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
[4:249] -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
[0:0] -A POSTROUTING -s 172.18.0.0/16 ! -o br-6a72e380ece6 -j MASQUERADE
[1:169] -A POSTROUTING -s 10.200.1.0/24 -j MASQUERADE
[0:0] -A DOCKER -i docker0 -j RETURN
[0:0] -A DOCKER -i br-6a72e380ece6 -j RETURN
COMMIT
# Completed on Fri Jan 17 18:05:36 2020

你有 Docker,它本身會改變防火牆規則。我不知道這是否是因為 Docker,但是您將iptables的 filter/FORWARD 的預設策略設置為 DROP 以防止任何未明確允許的路由。

編輯:添加返回方向。

為了使您的實驗工作,這應該足夠了(包括還必須啟用的返回流量):

iptables -A FORWARD -i v-eth1 -j ACCEPT
iptables -A FORWARD -o v-eth1 -j ACCEPT

請注意,這些可以與到/從網際網路的介面相補充,但我沒有它的名字。

通常首選使用以下規則,讓狀態跟踪允許返回流量:conntrack,因此只需要關心初始流量。隨意嘗試。

iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i v-eth1 -j ACCEPT

作為旁注核心> = 4.7通常需要/允許更多設置以使conntrack助手(ftp …)正確/安全地工作,但這不是您的實驗所必需的(已處理ICMP)。此部落格中的一些資訊:安全使用 iptables 和連接跟踪助手

如果有疑問(例如與 Docker 的互動)-I,請確保在其他任何內容之前插入您的規則。請注意,重新啟動 Docker 可能會再次更改規則。現在您知道問題出在哪裡,您可以將其與引導和 Docker 集成。

您可能有興趣閱讀 Docker 關於其使用iptables的文件:Docker 和 iptables

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