贵州省住房和城乡建设厅门户网站,wordpress入侵工具,微网站模板免费下载,为什么公司网站打开很慢继前两篇介绍了tun/tap和veth之后#xff0c;本篇将介绍Linux下常用的一种虚拟网络设备#xff0c;那就是bridge(桥)。
Linux ip netns 命令-CSDN博客
veth-pair,netns-CSDN博客
图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN_veth 转发 有拷贝-…继前两篇介绍了tun/tap和veth之后本篇将介绍Linux下常用的一种虚拟网络设备那就是bridge(桥)。
Linux ip netns 命令-CSDN博客
veth-pair,netns-CSDN博客
图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN_veth 转发 有拷贝-CSDN博客
virsh 获取虚机IP网桥ipbrctl,arp使用_virsh查看虚拟机ip-CSDN博客
ip tunnel 隧道技术-CSDN博客
Linux ip netns 命令-CSDN博客
本篇将通过实际的例子来一步一步解释bridge是如何工作的。 什么是bridge
首先bridge是一个虚拟网络设备所以具有网络设备的特征可以配置IP、MAC地址等其次bridge是一个虚拟交换机和物理交换机有类似的功能。
对于普通的网络设备来说只有两端从一端进来的数据会从另一端出去如物理网卡从外面网络中收到的数据会转发给内核协议栈而从协议栈过来的数据会转发到外面的物理网络中。
而bridge不同bridge有多个端口数据可以从任何端口进来进来之后从哪个口出去和物理交换机的原理差不多要看mac地址。
创建bridge
我们先用iproute2创建一个bridge
devdebian:~$ sudo ip link add name br0 type bridge
devdebian:~$ sudo ip link set br0 up
当刚创建一个bridge时它是一个独立的网络设备只有一个端口连着协议栈其它的端口啥都没连这样的bridge没有任何实际功能如下图所示
----------------------------------------------------------------
| |
| ------------------------------------------------ |
| | Newwork Protocol Stack | |
| ------------------------------------------------ |
| ↑ ↑ |
|..............|................................|................|
| ↓ ↓ |
| ---------- ------------ |
| | eth0 | | br0 | |
| ---------- ------------ |
| 192.168.3.21 ↑ |
| | |
| | |
--------------|-------------------------------------------------↓Physical Network 这里假设eth0是我们的物理网卡IP地址是192.168.3.21网关是192.168.3.1 将bridge和veth设备相连
创建一对veth设备并配置上IPdevdebian:~$ sudo ip link add veth0 type veth peer name veth1
devdebian:~$ sudo ip addr add 192.168.3.101/24 dev veth0
devdebian:~$ sudo ip addr add 192.168.3.102/24 dev veth1
devdebian:~$ sudo ip link set veth0 up
devdebian:~$ sudo ip link set veth1 up
将veth0连上br0devdebian:~$ sudo ip link set dev veth0 master br0
#通过bridge link命令可以看到br0上连接了哪些设备
devdebian:~$ sudo bridge link
6: veth0 state UP : BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 master br0 state forwarding priority 32 cost 2
这时候网络就变成了这个样子:
----------------------------------------------------------------
| |
| ------------------------------------------------ |
| | Newwork Protocol Stack | |
| ------------------------------------------------ |
| ↑ ↑ | ↑ |
|............|............|..............|............|..........|
| ↓ ↓ ↓ ↓ |
| ------ -------- ------- ------- |
| | .3.21| | | | .3.101| | .3.102| |
| ------ -------- ------- ------- |
| | eth0 | | br0 |---| veth0 | | veth1 | |
| ------ -------- ------- ------- |
| ↑ ↑ ↑ |
| | | | |
| | ------------ |
| | |
------------|---------------------------------------------------↓Physical Network 这里为了画图方便省略了IP地址前面的192.168比如.3.21就表示192.168.3.21 br0和veth0相连之后发生了几个变化 br0和veth0之间连接起来了并且是双向的通道 协议栈和veth0之间变成了单通道协议栈能发数据给veth0但veth0从外面收到的数据不会转发给协议栈 br0的mac地址变成了veth0的mac地址
相当于bridge在veth0和协议栈之间插了一脚在veth0上面做了点小动作将veth0本来要转发给协议栈的数据给拦截了全部转发给bridge了同时bridge也可以向veth0发数据。
下面来检验一下是不是这样的
通过veth0 ping veth1失败
devdebian:~$ ping -c 1 -I veth0 192.168.3.102
PING 192.168.2.1 (192.168.2.1) from 192.168.2.11 veth0: 56(84) bytes of data.
From 192.168.2.11 icmp_seq1 Destination Host Unreachable--- 192.168.2.1 ping statistics ---
1 packets transmitted, 0 received, 1 errors, 100% packet loss, time 0ms
为什么veth0加入了bridge之后就ping不通veth2了呢 先抓包看看
#由于veth0的arp缓存里面没有veth1的mac地址所以ping之前先发arp请求
#从veth1上抓包来看veth1收到了arp请求并且返回了应答
devdebian:~$ sudo tcpdump -n -i veth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
21:43:48.353509 ARP, Request who-has 192.168.3.102 tell 192.168.3.101, length 28
21:43:48.353518 ARP, Reply 192.168.3.102 is-at 26:58:a2:57:37:e9, length 28
#从veth0上抓包来看数据包也发出去了并且也收到了返回
devdebian:~$ sudo tcpdump -n -i veth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:44:09.775392 ARP, Request who-has 192.168.3.102 tell 192.168.3.101, length 28
21:44:09.775400 ARP, Reply 192.168.3.102 is-at 26:58:a2:57:37:e9, length 28
#再看br0上的数据包发现只有应答devdebian:~$ sudo tcpdump -n -i br0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:45:48.225459 ARP, Reply 192.168.3.102 is-at 26:58:a2:57:37:e9, length 28
从上面的抓包可以看出去和回来的流程都没有问题问题就出在veth0收到应答包后没有给协议栈而是给了br0于是协议栈得不到veth1的mac地址从而通信失败。
给bridge配上IP
通过上面的分析可以看出给veth0配置IP没有意义因为就算协议栈传数据包给veth0应答包也回不来。这里我们就将veth0的IP让给bridge。
devdebian:~$ sudo ip addr del 192.168.3.101/24 dev veth0
devdebian:~$ sudo ip addr add 192.168.3.101/24 dev br0
于是网络变成了这样子
----------------------------------------------------------------
| |
| ------------------------------------------------ |
| | Newwork Protocol Stack | |
| ------------------------------------------------ |
| ↑ ↑ ↑ |
|............|............|...........................|..........|
| ↓ ↓ ↓ |
| ------ -------- ------- ------- |
| | .3.21| | .3.101 | | | | .3.102| |
| ------ -------- ------- ------- |
| | eth0 | | br0 |---| veth0 | | veth1 | |
| ------ -------- ------- ------- |
| ↑ ↑ ↑ |
| | | | |
| | ------------ |
| | |
------------|---------------------------------------------------↓Physical Network 其实veth0和协议栈之间还是有联系的但由于veth0没有配置IP所以协议栈在路由的时候不会将数据包发给veth0就算强制要求数据包通过veth0发送出去但由于veth0从另一端收到的数据包只会给br0所以协议栈还是没法收到相应的arp应答包导致通信失败。 这里为了表达更直观将协议栈和veth0之间的联系去掉了veth0相当于一根网线。 再通过br0 ping一下veth1结果成功
devdebian:~$ ping -c 1 -I br0 192.168.3.102
PING 192.168.3.102 (192.168.3.102) from 192.168.3.101 br0: 56(84) bytes of data.
64 bytes from 192.168.3.102: icmp_seq1 ttl64 time0.121 ms--- 192.168.3.102 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev 0.121/0.121/0.121/0.000 ms
但ping网关还是失败因为这个bridge上只有两个网络设备分别是192.168.3.101和192.168.3.102br0不知道192.168.3.1在哪。
devdebian:~$ ping -c 1 -I br0 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.101 br0: 56(84) bytes of data.
From 192.168.3.101 icmp_seq1 Destination Host Unreachable--- 192.168.3.1 ping statistics ---
1 packets transmitted, 0 received, 1 errors, 100% packet loss, time 0ms 将物理网卡添加到bridge
将eth0添加到br0上
devdebian:~$ sudo ip link set dev eth0 master br0
devdebian:~$ sudo bridge link
2: eth0 state UP : BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 master br0 state forwarding priority 32 cost 4
6: veth0 state UP : mtu 1500 master br0 state forwarding priority 32 cost 2
br0根本不区分接入进来的是物理设备还是虚拟设备对它来说都一样的都是网络设备所以当eth0加入br0之后落得和上面veth0一样的下场从外面网络收到的数据包将无条件的转发给br0自己变成了一根网线。
这时通过eth0来ping网关失败但由于br0通过eth0这根网线连上了外面的物理交换机所以连在br0上的设备都能ping通网关这里连上的设备就是veth1和br0自己veth1是通过veth0这根网线连上去的而br0可以理解为自己有一块自带的网卡。
#通过eth0来ping网关失败
devdebian:~$ ping -c 1 -I eth0 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.21 eth0: 56(84) bytes of data.
From 192.168.3.21 icmp_seq1 Destination Host Unreachable--- 192.168.3.1 ping statistics ---
1 packets transmitted, 0 received, 1 errors, 100% packet loss, time 0ms
#通过br0来ping网关成功
devdebian:~$ ping -c 1 -I br0 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.101 br0: 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq1 ttl64 time27.5 ms--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev 27.518/27.518/27.518/0.000 ms
#通过veth1来ping网关成功devdebian:~$ ping -c 1 -I veth1 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.102 veth1: 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq1 ttl64 time68.8 ms--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev 68.806/68.806/68.806/0.000 ms
由于eth0已经变成了和网线差不多的功能所以在eth0上配置IP已经没有什么意义了并且还会影响协议栈的路由选择比如如果上面ping的时候不指定网卡的话协议栈有可能优先选择eth0导致ping不通所以这里需要将eth0上的IP去掉。
#在本人的测试机器上由于eth0上有IP
#访问192.168.3.0/24网段时会优先选择eth0
devdebian:~$ sudo route -v
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.3.1 0.0.0.0 UG 0 0 0 eth0
link-local * 255.255.0.0 U 1000 0 0 eth0
192.168.3.0 * 255.255.255.0 U 0 0 0 eth0
192.168.3.0 * 255.255.255.0 U 0 0 0 veth1
192.168.3.0 * 255.255.255.0 U 0 0 0 br0 #由于eth0已结接入了br0所有它收到的数据包都会转发给br0
#于是协议栈收不到arp应答包导致ping失败
devdebian:~$ ping -c 1 192.168.3.1
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
From 192.168.3.21 icmp_seq1 Destination Host Unreachable--- 192.168.3.1 ping statistics ---
1 packets transmitted, 0 received, 1 errors, 100% packet loss, time 0ms#将eth0上的IP删除掉
devdebian:~$ sudo ip addr del 192.168.3.21/24 dev eth0#再ping一次成功
devdebian:~$ ping -c 1 192.168.3.1
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq1 ttl64 time3.91 ms--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev 3.916/3.916/3.916/0.000 ms #这是因为eth0没有IP之后路由表里面就没有它了于是数据包会从veth1出去
devdebian:~$ sudo route -v
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.3.0 * 255.255.255.0 U 0 0 0 veth1
192.168.3.0 * 255.255.255.0 U 0 0 0 br0
#从这里也可以看出由于原来的默认路由走的是eth0所以当eth0的IP被删除之后
#默认路由不见了想要连接192.168.3.0/24以外的网段的话需要手动将默认网关加回来#添加默认网关然后再ping外网成功
devdebian:~$ sudo ip route add default via 192.168.3.1
devdebian:~$ ping -c 1 baidu.com
PING baidu.com (111.13.101.208) 56(84) bytes of data.
64 bytes from 111.13.101.208: icmp_seq1 ttl51 time30.6 ms--- baidu.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev 30.690/30.690/30.690/0.000 ms
经过上面一系列的操作后网络变成了这个样子
----------------------------------------------------------------
| |
| ------------------------------------------------ |
| | Newwork Protocol Stack | |
| ------------------------------------------------ |
| ↑ ↑ |
|.........................|...........................|..........|
| ↓ ↓ |
| ------ -------- ------- ------- |
| | | | .3.101 | | | | .3.102| |
| ------ -------- ------- ------- |
| | eth0 |---| br0 |---| veth0 | | veth1 | |
| ------ -------- ------- ------- |
| ↑ ↑ ↑ |
| | | | |
| | ------------ |
| | |
------------|---------------------------------------------------↓Physical Network
上面的操作中有几点需要注意 如果是在虚拟机上做上述操作记得打开网卡的混杂模式不是在Linux里面而是在虚拟机的配置上面如VirtualBox上相应虚拟机的网卡配置项里面不然veth1的网络会不通因为eth0不在混杂模式的话会丢掉目的mac地址是veth1的数据包 上面虽然通了但由于Linux下arp的特性当协议栈收到外面的arp请求时不管是问101还是102都会回复两个arp应答分别包含br0和veth1的mac地址也即Linux觉得外面发给101和102的数据包从br0和veth1进协议栈都一样没有区别。由于回复了两个arp应答而外面的设备只会用其中的一个并且具体用哪个会随着时间发生变化于是导致一个问题就是外面回复给102的数据包可能从101的br0上进来即通过102 ping外面时可能在veth1抓不到回复包而在br0上能抓到回复包。说明数据流在交换机那层没有完全的隔离开br0和veth1会收到对方的IP应答包。为了解决上述问题可以配置rp_filter, arp_filter, arp_ignore, arp_announce等参数但不建议这么做容易出错调试比较麻烦。 在无线网络环境中情况会变得比较复杂因为无线网络需要登录登陆后无线路由器只认一个mac地址所有从这台机器出去的mac地址都必须是那一个于是通过无线网卡上网的机器上的所有虚拟机想要上网的话都必须依赖虚拟机管理软件如VirtualBox将每个虚拟机的网卡mac地址转成出口的mac地址即无线网卡的mac地址数据包回来的时候还要转回来所以如果一个IP有两个ARP应答包的话有可能导致mac地址的转换有问题导致网络不通或者有时通有时不通。解决办法就是将连接进br0的所有设备的mac地址都改成和eth0一样的mac地址因为eth0的mac地址会被虚拟机正常的做转换。在上面的例子中执行下面的命令即可 devdebian:~$ sudo ip link set dev veth1 down
#08:00:27:3b:0d:b9是eth0的mac地址
devdebian:~$ sudo ip link set dev veth1 address 08:00:27:3b:0d:b9
devdebian:~$ sudo ip link set dev veth1 up
bridge必须要配置IP吗
在我们常见的物理交换机中有可以配置IP和不能配置IP两种不能配置IP的交换机一般通过com口连上去做配置更简单的交换机连com口的没有不支持任何配置而能配置IP的交换机可以在配置好IP之后通过该IP远程连接上去做配置从而更方便。
bridge就属于后一种交换机自带虚拟网卡可以配置IP该虚拟网卡一端连在bridge上另一端跟协议栈相连。和物理交换机一样bridge的工作不依赖于该虚拟网卡但bridge工作不代表机器能连上网要看组网方式。
删除br0上的IP:
devdebian:~$ sudo ip addr del 192.168.3.101/24 dev br0
于是网络变成了这样子相当于br0的一个端口通过eth0连着交换机另一个端口通过veth0连着veth1
----------------------------------------------------------------
| |
| ------------------------------------------------ |
| | Newwork Protocol Stack | |
| ------------------------------------------------ |
| ↑ |
|.....................................................|..........|
| ↓ |
| ------ -------- ------- ------- |
| | | | | | | | .3.102| |
| ------ -------- ------- ------- |
| | eth0 |---| br0 |---| veth0 | | veth1 | |
| ------ -------- ------- ------- |
| ↑ ↑ ↑ |
| | | | |
| | ------------ |
| | |
------------|---------------------------------------------------↓Physical Network
devdebian:~$ ping -c 1 192.168.3.1
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq1 ttl64 time1.24 ms--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev 1.242/1.242/1.242/0.000 ms
ping网关成功说明这种情况下br0不配置IP对通信没有影响数据包还能从veth1出去 上面如果没有veth0和veth1的话删除br0上的IP后网络将会不通因为没有设备和协议栈完全相连 bridge常用场景
上面通过例子展示了bridge的功能但例子中的那种部署方式没有什么实际用途还不如在一个网卡上配置多个IP地址来的直接。这里来介绍两种常见的部署方式。
虚拟机
虚拟机通过tun/tap或者其它类似的虚拟网络设备将虚拟机内的网卡同br0连接起来这样就达到和真实交换机一样的效果虚拟机发出去的数据包先到达br0然后由br0交给eth0发送出去数据包都不需要经过host机器的协议栈效率高。
--------------------------------------------------------------------------------------------------------------------------------------------------
| Host | VirtualMachine1 | VirtualMachine2 |
| | | |
| ------------------------------------------------ | ------------------------- | ------------------------- |
| | Newwork Protocol Stack | | | Newwork Protocol Stack | | | Newwork Protocol Stack | |
| ------------------------------------------------ | ------------------------- | ------------------------- |
| ↑ | ↑ | ↑ |
|..........................|.....................................|...................|.....................|....................|....................|
| ↓ | ↓ | ↓ |
| -------- | ------- | ------- |
| | .3.101 | | | .3.102| | | .3.103| |
| ------ -------- ------- | ------- | ------- |
| | eth0 |---| br0 |---|tun/tap| | | eth0 | | | eth0 | |
| ------ -------- ------- | ------- | ------- |
| ↑ ↑ ↑ | ↑ | ↑ |
| | | ------------------------------------------- | | |
| | ↓ | | | |
| | ------- | | | |
| | |tun/tap| | | | |
| | ------- | | | |
| | ↑ | | | |
| | -------------------------------------------------------------------------------|-------------------- |
| | | | |
| | | | |
| | | | |
------------|-------------------------------------------------------------------------------------------------------------------------------------↓Physical Network (192.168.3.0/24)
docker
由于容器运行在自己单独的network namespace里面所以都有自己单独的协议栈情况和上面的虚拟机差不多但它采用了另一种方式来和外界通信
--------------------------------------------------------------------------------------------------------------------------------------------------
| Host | Container 1 | Container 2 |
| | | |
| ------------------------------------------------ | ------------------------- | ------------------------- |
| | Newwork Protocol Stack | | | Newwork Protocol Stack | | | Newwork Protocol Stack | |
| ------------------------------------------------ | ------------------------- | ------------------------- |
| ↑ ↑ | ↑ | ↑ |
|............|.............|.....................................|...................|.....................|....................|....................|
| ↓ ↓ | ↓ | ↓ |
| ------ -------- | ------- | ------- |
| |.3.101| | .9.1 | | | .9.2 | | | .9.3 | |
| ------ -------- ------- | ------- | ------- |
| | eth0 | | br0 |---| veth | | | eth0 | | | eth0 | |
| ------ -------- ------- | ------- | ------- |
| ↑ ↑ ↑ | ↑ | ↑ |
| | | ------------------------------------------- | | |
| | ↓ | | | |
| | ------- | | | |
| | | veth | | | | |
| | ------- | | | |
| | ↑ | | | |
| | -------------------------------------------------------------------------------|-------------------- |
| | | | |
| | | | |
| | | | |
------------|-------------------------------------------------------------------------------------------------------------------------------------↓Physical Network (192.168.3.0/24)
容器中配置网关为.9.1发出去的数据包先到达br0然后交给host机器的协议栈由于目的IP是外网IP且host机器开启了IP forward功能于是数据包会通过eth0发送出去由于.9.1是内网IP所以一般发出去之前会先做NAT转换NAT转换和IP forward功能都需要自己配置。由于要经过host机器的协议栈并且还要做NAT转换所以性能没有上面虚拟机那种方案好优点是容器处于内网中安全性相对要高点。由于数据包统一由IP层从eth0转发出去所以不存在mac地址的问题在无线网络环境下也工作良好 上面两种部署方案中同一网段的每个网卡都有自己单独的协议栈所以不存在上面说的多个ARP的问题 Linux 上的基础网络设备详解 Harping on ARP MAC address spoofing It doesnt work with my Wireless card!