linux虚拟网桥接入实体网卡
本文将介绍虚拟网桥(bridge
)接入实体网卡。
此前已经介绍过linux
虚拟网桥(bridge
)在容器中的作用,本次将来介绍将网桥接入实体网卡。
本文所依赖的环境为:
root@debian:~# hostnamectl
Static hostname: windows11pro
Icon name: windowsBooks
Chassis: laptop 💻
Operating System: Debian GNU/Linux 12 (bookworm)
Kernel: Linux 6.1.0-26-amd64
Architecture: x86-64
Hardware Vendor: ASUSTeK COMPUTER INC.
Hardware Model: X441UVK
Firmware Version: X441UVK.314
root@debian:~#
操作的是切记不要使用虚拟机如,vmware
和virtualbox
等。
默认网卡混杂模式,在虚拟机中是没有开启的:https://docs.vmware.com/cn/VMware-vSphere/6.7/com.vmware.vsphere.security.doc/GUID-92F3AB1F-B4C5-4F25-A010-8820D7250350.html
关闭网络服务
默认情况下,NetworkManager.service
是Linux
系统中的网络管理工具,负责自动分配ip
地址等。由于要操作bridge
,所以需要暂时将其给关闭掉。否则,后续单独开启网卡,又会拉取到ip
地址等。
将NetworkManager.service
给停用掉,并且禁止开机自启。然后重启机器。
[root@localhost]:[~][tty:0]# systemctl disable NetworkManager.service
[root@localhost]:[~][tty:0]# systemctl stop NetworkManager.service
[root@localhost]:[~][tty:0]# reboot
重启完毕后,查看网络,应该是无ip
地址,且网卡状态为DOWN
的。
[root@localhost]:[~][tty:0]# ip a
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 noprefixroute
valid_lft forever preferred_lft forever
2: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:42:ac:11:65:bd brd ff:ff:ff:ff:ff:ff
[root@localhost]:[~][tty:0]#
网卡关闭后,我们需要手动配置一下ip
,确保机器能够上网。
[root@localhost]:[~][tty:0]# ip addr add 192.168.100.136/24 dev enp4s0
[root@localhost]:[~][tty:0]#
[root@localhost]:[~][tty:0]# ip link set enp4s0 up
[root@localhost]:[~][tty:0]#
[root@localhost]:[~][tty:0]# ping 192.168.100.1 -c 3
PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=1.06 ms
64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=0.651 ms
64 bytes from 192.168.100.1: icmp_seq=3 ttl=64 time=0.654 ms
--- 192.168.100.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2023ms
rtt min/avg/max/mdev = 0.651/0.789/1.062/0.193 ms
[root@localhost]:[~][tty:0]#
配置ip
后,并且手动启动网卡,ping
网关没问题。
[root@localhost]:[~][tty:0]# ping 8.8.8.8 -c 3
ping: connect: Network is unreachable
[root@localhost]:[~][tty:0]#
但是ping
外网会显示网络不可达,这是因为是手动添加的ip
地址,路由信息需要配置,需要添加一条默认路由,指向网关即可。
[root@localhost]:[~][tty:0]# ip route
192.168.100.0/24 dev enp4s0 proto kernel scope link src 192.168.100.136
[root@localhost]:[~][tty:0]#
[root@localhost]:[~][tty:0]# ip route add default via 192.168.100.1
[root@localhost]:[~][tty:0]#
[root@localhost]:[~][tty:0]# ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=33.7 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=55 time=34.0 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=55 time=34.7 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 33.735/34.158/34.742/0.426 ms
[root@localhost]:[~][tty:0]#
如上,手动配置的ip
也可以进行上网。需要清除该网卡上的ip
信息,并且给关闭掉网络。
[root@localhost]:[~][tty:0]# ip link set enp4s0 down
[root@localhost]:[~][tty:0]#
[root@localhost]:[~][tty:0]# ip addr flush dev enp4s0
[root@localhost]:[~][tty:0]#
[root@localhost]:[~][tty:0]# ip a
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 noprefixroute
valid_lft forever preferred_lft forever
2: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 02:42:ac:11:65:bd brd ff:ff:ff:ff:ff:ff
[root@localhost]:[~][tty:0]#
创建虚拟桥接
创建一个桥接bridge
。
[root@localhost]:[~][tty:0]# ip link add name br0 type bridge
[root@localhost]:[~][tty:0]#
[root@localhost]:[~][tty:0]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
link/ether 02:42:ac:11:65:bd brd ff:ff:ff:ff:ff:ff
3: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 0a:27:75:b4:30:69 brd ff:ff:ff:ff:ff:ff
[root@localhost]:[~][tty:0]#
将enp4s0
实体网卡加入到该虚拟桥接设备br0
中。
[root@localhost]:[~][tty:0]# ip link set enp4s0 master br0
为br0
配置ip
地址,注意这里是为桥接配置ip
地址,而非enp4s0
实体网络哦,因为接入到了bridge
中,可以将enp4s0
看做是一根网线。
[root@localhost]:[~][tty:0]# ip addr add 192.168.100.136/24 dev br0
[root@localhost]:[~][tty:0]#
[root@localhost]:[~][tty:0]# ip a
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 noprefixroute
valid_lft forever preferred_lft forever
2: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master br0 state DOWN group default qlen 1000
link/ether 02:42:ac:11:65:bd brd ff:ff:ff:ff:ff:ff
3: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 0a:27:75:b4:30:69 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.136/24 scope global br0
valid_lft forever preferred_lft forever
[root@localhost]:[~][tty:0]#
配置完成后,需要启动br0
和enp4s0
网卡,
[root@localhost]:[~][tty:0]# ip link set br0 up
[root@localhost]:[~][tty:0]# ip link set enp4s0 up
[root@localhost]:[~][tty:0]# ip a
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 noprefixroute
valid_lft forever preferred_lft forever
2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
link/ether 02:42:ac:11:65:bd brd ff:ff:ff:ff:ff:ff
inet6 fe80::56e1:adff:fee7:de8d/64 scope link
valid_lft forever preferred_lft forever
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 0a:27:75:b4:30:69 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.136/24 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::827:75ff:feb4:3069/64 scope link
valid_lft forever preferred_lft forever
[root@localhost]:[~][tty:0]#
可以看到,此时2个网卡的状态都是UP
。
尝试ping
一下网关。
[root@localhost]:[~][tty:0]# ping -c 3 192.168.100.1
PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=1.53 ms
64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=0.663 ms
64 bytes from 192.168.100.1: icmp_seq=3 ttl=64 time=0.666 ms
--- 192.168.100.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2009ms
rtt min/avg/max/mdev = 0.663/0.954/1.534/0.409 ms
[root@localhost]:[~][tty:0]#
再次添加默认路由后,ping
外网。
[root@localhost]:[~][tty:0]# ip route add default via 192.168.100.1
[root@localhost]:[~][tty:0]# ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=40.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=55 time=36.2 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=55 time=40.2 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 36.152/38.988/40.643/2.014 ms
[root@localhost]:[~][tty:0]#
可见,将实体网卡给到虚拟网桥,是行得通的。
创建虚拟网卡
现在需要操作的是,创建一对虚拟网卡,并且将其中一端放入net namespace
中,另外一端加入刚刚创建好的bridge
,并且为net namespace
中的网卡配置ip
地址,看是否能够和外部直接通信。
[root@localhost]:[~][tty:0]# ip link add name veth0 type veth peer name veth1
[root@localhost]:[~][tty:0]# ip a
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 noprefixroute
valid_lft forever preferred_lft forever
2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
link/ether 02:42:ac:11:65:bd brd ff:ff:ff:ff:ff:ff
inet6 fe80::56e1:adff:fee7:de8d/64 scope link
valid_lft forever preferred_lft forever
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 0a:27:75:b4:30:69 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.136/24 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::827:75ff:feb4:3069/64 scope link
valid_lft forever preferred_lft forever
4: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether ba:00:10:0e:f2:df brd ff:ff:ff:ff:ff:ff
5: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether a6:27:b0:61:da:eb brd ff:ff:ff:ff:ff:ff
[root@localhost]:[~][tty:0]#
如上,创建了一对虚拟网卡,名称分别为veth0
和veth1
。
现在需要新开一个终端,创建一个全新的net namespace
。
[root@localhost]:[~][tty:1]# unshare -m -i -u -n -f /bin/bash
(unshare) [root@localhost]:[~][tty:1]#
(unshare) [root@localhost]:[~][tty:1]# echo $$
1283
(unshare) [root@localhost]:[~][tty:1]#
(unshare) [root@localhost]:[~][tty:1]# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
(unshare) [root@localhost]:[~][tty:1]#
如上,创建了一个一个net namespace
,查看ip
,只有本地回环地址lo
。
切回原来的终端,将veth1
移入到刚刚创建的net namespace
中。
[root@localhost]:[~][tty:0]# ip link set veth1 netns 1283
[root@localhost]:[~][tty:0]#
回到net namespace
后,可以看到已经移入过来的网卡地址。
(unshare) [root@localhost]:[~][tty:1]# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: veth1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether ba:00:10:0e:f2:df brd ff:ff:ff:ff:ff:ff link-netnsid 0
(unshare) [root@localhost]:[~][tty:1]#
配置虚拟网卡地址
上述已经将veth1
移入到了net namespace
中,现在需要将外面的veth0
给加入到bridge
虚拟设备br0
中,并且将网卡给打开。
[root@localhost]:[~][tty:0]# ip link set veth0 master br0
[root@localhost]:[~][tty:0]# ip link set veth0 up
[root@localhost]:[~][tty:0]#
在net namespace
中,需要为刚刚移入的veth1
配置ip
地址。
(unshare) [root@localhost]:[~][tty:1]# ip addr add 192.168.100.137/24 dev veth1
(unshare) [root@localhost]:[~][tty:1]#
(unshare) [root@localhost]:[~][tty:1]# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: veth1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether ba:00:10:0e:f2:df brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.100.137/24 scope global veth1
valid_lft forever preferred_lft forever
(unshare) [root@localhost]:[~][tty:1]#
并且将网卡给打开。
(unshare) [root@localhost]:[~][tty:1]# ip link set veth1 up
(unshare) [root@localhost]:[~][tty:1]#
(unshare) [root@localhost]:[~][tty:1]# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5: veth1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether ba:00:10:0e:f2:df brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.100.137/24 scope global veth1
valid_lft forever preferred_lft forever
inet6 fe80::b800:10ff:fe0e:f2df/64 scope link tentative
valid_lft forever preferred_lft forever
(unshare) [root@localhost]:[~][tty:1]#
尝试ping
一下网关。
(unshare) [root@localhost]:[~][tty:1]# ping 192.168.100.1 -c 3
PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=1.28 ms
64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=0.704 ms
64 bytes from 192.168.100.1: icmp_seq=3 ttl=64 time=0.690 ms
--- 192.168.100.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2030ms
rtt min/avg/max/mdev = 0.690/0.890/1.278/0.273 ms
(unshare) [root@localhost]:[~][tty:1]#
但是ping
外网,依然会报错网络不可达。
(unshare) [root@localhost]:[~][tty:1]# ping 8.8.8.8 -c 3
ping: connect: Network is unreachable
(unshare) [root@localhost]:[~][tty:1]#
这是因为在net namespace
中,没有添加默认路由,需要添加上去即可。
(unshare) [root@localhost]:[~][tty:1]# ip route add default via 192.168.100.1
(unshare) [root@localhost]:[~][tty:1]#
(unshare) [root@localhost]:[~][tty:1]# ping 8.8.8.8 -c 3
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=36.9 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=55 time=34.6 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=55 time=33.5 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 33.493/35.014/36.908/1.418 ms
(unshare) [root@localhost]:[~][tty:1]#
总结
如果是桥接的真实网卡,且不做nat
的话,则不需要进行ip
转发,ip
转发一般在不同网络之间通信才需要开启,比如,这台机器的转发就没有开,不影响它桥接虚拟网卡,和外部进行通信。
[root@localhost]:[~][tty:3]# cat /proc/sys/net/ipv4/ip_forward
0
[root@localhost]:[~][tty:3]#
还有,一定在真实的机器下操作,我操作了vmware
等虚拟机,即使在linux
中,开启了混合模式的情况下,外部ping veth
的数据包最多只能达到br0
,就丢了,应该是和虚拟机有关系。
linux虚拟网桥接入实体网卡
https://wangli2025.github.io/2024/11/22/linux_network_bridge-2.html
本站均为原创文章,采用 CC BY-NC-ND 4.0 协议。转载请注明出处,不得用于商业用途。