![如何在 Linux 上使用虚拟接口和网桥创建虚拟局域网?](https://linux22.com/image/1535636/%E5%A6%82%E4%BD%95%E5%9C%A8%20Linux%20%E4%B8%8A%E4%BD%BF%E7%94%A8%E8%99%9A%E6%8B%9F%E6%8E%A5%E5%8F%A3%E5%92%8C%E7%BD%91%E6%A1%A5%E5%88%9B%E5%BB%BA%E8%99%9A%E6%8B%9F%E5%B1%80%E5%9F%9F%E7%BD%91%EF%BC%9F.png)
我想在 Linux 上创建一个 LAN 来运行一些实验。这主要是学习练习,所以我不想使用真正的以太网接口或类似的东西。看起来我可以创建虚拟接口并将它们连接到桥接接口来执行此操作。每个虚拟接口都是 LAN 上的一个端点,而桥接器将充当以太网交换机。以下是我创建 LAN 的方式:
ip link add dummy1 type dummy
ip link add dummy2 type dummy
ip link add br0 type bridge
ip link set dummy1 arp on
ip link set dummy2 arp on
ip link set dev dummy1 master br0
ip link set dev dummy2 master br0
ip address add 10.0.2.1/24 broadcast + dev br0
ip address add 10.0.2.2/24 broadcast + dev dummy1
ip address add 10.0.2.3/24 broadcast + dev dummy2
ip link set dummy1 up
ip link set dummy2 up
ip link set br0 up
我可以看到链接已打开(谷歌搜索显示预计为“状态未知”):
$ ip link
...
6: dummy1: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether fa:b9:0e:8e:a7:1f brd ff:ff:ff:ff:ff:ff
7: dummy2: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether 7a:5d:8e:2b:76:d6 brd ff:ff:ff:ff:ff:ff
8: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 7a:5d:8e:2b:76:d6 brd ff:ff:ff:ff:ff:ff
并且地址是预期的。但是ping
和arping
不起作用。换句话说,以下任何一项都不会报告响应:
ping -I dummy1 10.0.2.3
arping -I dummy1 10.0.2.3
ping -I dummy2 10.0.2.2
arping -I dummy2 10.0.2.2
在虚拟接口上运行 wireshark 会显示ping
并arping
生成数据包,但仅此而已。
看起来网桥知道 MAC 地址:
$ brctl showmacs br0
port no mac addr is local? ageing timer
2 7a:5d:8e:2b:76:d6 yes 0.00
2 7a:5d:8e:2b:76:d6 yes 0.00
1 fa:b9:0e:8e:a7:1f yes 0.00
1 fa:b9:0e:8e:a7:1f yes 0.00
然而,我不认为这座桥正在转发帧dummy1
,dummy2
反之亦然。
我应该怎么做才能使网桥转发帧,或者除了使用虚拟接口之外,还有其他方法可以虚拟地构建这个 LAN 吗?
答案1
虚拟接口之所以被称为“虚拟”,是因为它们实际上并不工作。它们的唯一用途(我知道的)是允许长期应用程序绑定到它们,这样您就可以移动它们并将它们桥接到其他接口而不会中断应用程序。
您将无法使用虚拟接口构建虚拟局域网。
相反,使用网络命名空间作为不同计算机(“主机”)的替代,并通过虚拟以太网链路(veth 对)连接它们。
这样,您就可以构建任意复杂的 LAN。以任意方式桥接它们、进行转发和 NAT、设置复杂的路由等。
作为起点,下面是我用来创建网络命名空间的脚本,该脚本通过 veth-pair 连接到主命名空间,并在此命名空间中创建一个 xterm。以 root 身份运行,并将 USERNAME 替换为您的用户名:
#!/bin/bash
# Setup network namespace with veth pair, start xterm in it
# nsterm ns0 veth0 10.0.0 yellow 24
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
NS=${1:-ns0}
DEV=${2:-veth0}
DEV_A=${DEV}a
DEV_B=${DEV}b
ADDR=${3-:10.0.0}
ADDR_A=${ADDR}.254
ADDR_B=${ADDR}.1
MASK=${5:-24}
COL=${4:-yellow}
# echo ns=$NS dev=$DEV col=$COL mask=$MASK
ip netns add $NS
ip link add $DEV_A type veth peer name $DEV_B netns $NS
ip addr add $ADDR_A/$MASK dev $DEV_A
ip link set ${DEV}a up
ip netns exec $NS ip addr add $ADDR_B/$MASK dev $DEV_B
ip netns exec $NS ip link set ${DEV}b up
ip netns exec $NS ip route add default via $ADDR_A dev $DEV_B
ip netns exec $NS su -c "xterm -bg $COL &" USERNAME