更新

更新

我在使用 Hypriot OS 时遇到了一个非常奇怪的情况。

网络配置:

+--------+  +------+-----+------+  +---------------------+  +-------+
+ laptop +--+ eth0 + br0 + eth1 +--+ router @ 10.98.76.1 +--+ tower +
+--------+  +------+-----+------+  +---------------------+  +-------+
                         |
                         +-------+     +----------------------+
                         + wlan0 +-----+ router @ 192.168.0.1 +
                         +-------+     +----------------------+

我实际上是想让 Raspberry Pi 充当我的笔记本电脑和路由器之间的中间人。我将 eth0 和 eth1 连接到启动时创建的网桥 (br0)。eth0、eth1 和 br0 都在名为“foo”的网络命名空间内。wlan0 是默认命名空间中的主要竞争者——docker 目前已禁用,而它通常会在默认命名空间中创建一个 docker0 网桥。

我将 eth0 和 eth1 推送到不同的网络命名空间,以确保 wlan0 可以运行 ssh 客户端,并且仅有的wlan0 正在运行所述客户端——我不希望硬连线接口在任何条件下使用 ssh 客户端。

我正在使用“device-init.yaml”(设备初始化的一部分)来启动我的网络配置脚本。

我的网络配置脚本如下:

# Create a new namespace for the ethernet devices
ip netns add foo

# Create the bridge in the foo namespace and bring it up
ip netns exec foo ip link add name br0 type bridge
ip netns exec foo ip link set dev br0 up

# Bring down the ethernet devices
ip link set dev eth0 down
ip link set dev eth1 down

# Move the eth0/eth1 devices to the foo namespace
ip link set dev eth0 netns foo
ip link set dev eth1 netns foo

# Add the eth0/eth1 devices to the bridge
ip netns exec foo ip link set dev eth0 master br0
ip netns exec foo ip link set dev eth1 master br0

# Enable promiscuous mode
ip netns exec foo ip link set eth0 promisc on
ip netns exec foo ip link set eth1 promisc on

# Bring up the adapters within the foo namespace
ip netns exec foo ip link set dev lo up
ip netns exec foo ip link set dev eth0 up
ip netns exec foo ip link set dev eth1 up

# List the devices for posterity
netnsout=$(ip netns exec foo ip a)

echo "- Done running ip commands. Result: $netnsout"

启动完成后,我可以从我的塔式机箱 ping 我的笔记本电脑,也可以从我的笔记本电脑 ping 我的塔式机箱,没有任何问题。我还可以毫无问题地在我的笔记本电脑上获取 IP 地址——网桥运行正常,允许流量通过。

问题:我无法在 eth1、eth0 或 br0 上运行 dhclient 并从 Raspberry Pi 访问网络内的任何实体。

我运行的用于获取 eth1 上的 IP 地址的代码:

$ ip netns exec foo dhclient eth1

运行dhclient后的结果:

$ ip netns exec foo ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:e0:4c:36:1e:fb brd ff:ff:ff:ff:ff:ff
    inet6 fe80::60fc:16ff:fe9a:2e26/64 scope link
       valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether b8:27:eb:9e:8d:63 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::ba27:ebff:fe9e:8d63/64 scope link
       valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether 00:e0:4c:36:1e:fb brd ff:ff:ff:ff:ff:ff
    inet 10.98.76.11/24 brd 10.98.76.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::2e0:4cff:fe36:1efb/64 scope link
       valid_lft forever preferred_lft forever

eth1 配置了适当的 IP 地址。

如果我随后 ping 任何内容,则会收到“目标主机无法访问”的消息:

$ ip netns exec foo ping 10.98.76.1 (or .44 for laptop, .55 for tower)

另外,目前我无法通过 wlan0 进行外部访问。我可以访问无线路由器和无线网络上的其他机器,但似乎无法向外访问互联网。

作为参考,这里有更多详细信息:arp 表:

$ ip netns exec foo arp
Address        HWtype  HWaddress      Flags Mask  Iface
10.98.76.1             (incomplete)               eth1

路线:

$ ip netns exec foo ip route show all
default via 10.98.76.1 dev eth1
10.98.76.0/24 dev eth1  proto kernel  scope link  src 10.98.76.11

然后我把桥倒塌了:

$ ip netns exec foo ip link set dev br0 down
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
2: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 00:e0:4c:36:1e:fb brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether b8:27:eb:9e:8d:63 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::ba27:ebff:fe9e:8d63/64 scope link
       valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether 00:e0:4c:36:1e:fb brd ff:ff:ff:ff:ff:ff
    inet 10.98.76.11/24 brd 10.98.76.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::2e0:4cff:fe36:1efb/64 scope link
       valid_lft forever preferred_lft forever

但是当我尝试 ping 路由器或塔时,仍然收到“目标主机无法访问”的消息。此时,由于桥接器已关闭,我显然无法通过笔记本电脑执行任何操作。

如果我删除网桥,我就可以按预期 ping 网络上的所有内容:

$ ip netns exec foo ip link delete dev br0
PING 10.98.76.1 (10.98.76.1) 56(84) bytes of data.
64 bytes from 10.98.76.1: icmp_seq=1 ttl=127 time=1.71 ms
64 bytes from 10.98.76.1: icmp_seq=2 ttl=127 time=0.894 ms
64 bytes from 10.98.76.1: icmp_seq=3 ttl=127 time=0.873 ms

这时我被难住了。同样的设置在 Raspbian 上可以工作,但在 Hypriot 上却不行。以下 gitter看起来和我的情况几乎一模一样,但是我有重复的设备:https://gitter.im/hypriot/talk/archives/2016/06/02

我尝试过其他没有结果的方法: - 关闭 eth0 和 eth1 promisc - 打开 br0 promisc - 在 /etc/netns/foo/resolv.conf 中创建自定义 resolv.conf - arping(见下文)

$ ip netns exec foo arping -A -I eth1 10.98.76.11
ARPING 10.98.76.11
Timeout
Timeout
Timeout
Timeout
Timeout

我的主要目标是让 Raspberry Pi 上的 eth1 与我的笔记本电脑使用相同的 IP 和 MAC。在这样做的同时,它仍然应该将流量传递到我的笔记本电脑,并尊重我的笔记本电脑可能有的任何 dhcp 请求等。我最终将尝试在我的 Raspberry Pi 和塔之间设置一个 vpn 隧道,并且仍然需要数据包来实现它通过将 Raspberry Pi 插入我的笔记本电脑,但这需要在桥接器/设备正常工作后才能实现。

重申一下:这在 Raspbian 上工作,这才是真正让我困惑的地方。如果需要更多信息,例如运行服务(除了 Hypriot 的默认设置外,没有其他信息,当然我确实禁用了 docker),请告诉我。

更新

根据以下回答维贝尔我能够修复这个一开始无法解决的问题。我不知道它在 Raspbian 上是如何/为什么工作的,因为它真的不应该工作。

我将在下面发布解决方法/正确的做事方法,以防对未来的溢出有用:

# Ensure the traffic we send to the laptop goes through the right device
ip netns exec foo route add 10.98.76.44 dev eth0

# Enable forwarding on both devices
ip netns exec foo sysctl net.ipv4.conf.eth0.forwarding=1
ip netns exec foo sysctl net.ipv4.conf.eth1.forwarding=1

# Enable arp proxying on both devices
ip netns exec foo sysctl net.ipv4.conf.eth0.proxy_arp=1
ip netns exec foo sysctl net.ipv4.conf.eth1.proxy_arp=1

# Reload
ip netns exec foo sysctl --system

# Flush arp
ip netns exec foo -s -s neigh flush all

# Aggressively flush arp (the one above would do it, but this seems to be quick and thorough):
ip netns exec foo ip link set arp off dev eth0
ip netns exec foo ip link set arp off dev eth1
ip netns exec foo ip link set arp on dev eth0
ip netns exec foo ip link set arp on dev eth1

一旦运行上述操作,我就可以毫无问题地访问/访问网络上的所有设备。

答案1

一旦接口成为网桥的成员,您就不能为接口本身分配 IP 地址,而需要为网桥设置地址。桥接 STP 指南

相关内容