目录
1. 从物理层到链路层的局域网连接
首先明确三点基础知识:
- MAC 层(数据链路层)是用来解决多路访问的堵车问题的
- ARP(Address Resolution Protocol,地址解析协议)是通过吼的方式来寻找目标 MAC 地址的,吼完之后记住一段时间,这个叫做缓存
- 交换机是有 MAC 学习能力的,学完就知道谁在哪儿,不用广播了
一个局域网里有多个交换机时,ARP 广播的模式容易产生广播风暴:ARP 广播时,交换机会将一个端口收到的包转发到其他所有的端口上。比如数据包经过交换机 A 到达交换机 B,交换机 B 又将包复制为多分广播出去。如果整个局域网存在一个环路,使得数据包又重新回到了最开始的交换机 A,这个包又会被 A 再次复制多份广播出去。如此循环,数据包会不停的转发,而且越来越多,最终占满带宽,或者使解析协议的硬件过载,形成广播风暴
2. 交换机与 VLAN
2.1 有两台交换机的拓扑结构
2.2 环路问题
当两个交换机将两个局域网同时连接起来的时候,就会出现环路问题:
此时就会出现之前提到的广播风暴。
2.3 STP 协议的基本概念
在数据结构中,有一个方法叫做最小生成树。在计算机网络中,生成树的算法叫做 STP(Spanning Tree Protocol)。
STP 协议中的基本概念如下:
- Root Bridge:也就是根交换机,是某棵树的老大,“掌门”
- Designated Bridges:翻译为指定交换机。可看成是“掌门”的“弟子”。对于树来说,就是一棵树的树枝
- Bridge Protocol Data Units(BPDU):翻译为网桥协议数据单元,可看成相互比较实力的协议。当两个交换机碰见时,就需要互相比一比内力。BPDU 只有掌门能发,已经隶属于某个掌门的交换机只能传达掌门的指示
- Priority Vector:翻译为优先级向量,可以比喻为实力(值越小越强),实际是一组 ID 数目,
Root Bridge ID, Root Path Cost, Bridge ID, and Port ID
2.4 STP 协议的工作过程
略
2.5 如何解决广播问题和安全问题
1. 物理隔离
每个部门有单独的交换机,配置单独的子网,这样部门之间的沟通就需要路由器了。
然而问题在于,有的部门人多,有的部门人少。如果每个部门有单独的交换机,口多了浪费,口少了不够用。
2. 虚拟隔离 VLAN
另一种方式是虚拟隔离,就是我们常说的 VLAN,又称虚拟局域网。使用 VLAN,一个交换机上会连属于多个局域网的机器。
为了让交换机区分哪个机器属于哪个局域网,我们只需要在原来的二层的头上加一个 TAG,里面有一个 VLAN ID,一共 12 位,这样就可以划分 4096 个 VLAN。
如果交换机是支持 VLAN 的,当这个交换机把二层的头取下来的时候,就能够识别这个 VLAN ID。这样只有相同 VLAN 的包,才会互相转发,不同 VLAN 的包是看不到的,这样就解决了广播问题和安全问题。
可以设置交换机每个口所属的 VLAN。而且对于交换机来说,每个 VLAN 的口都是可以重新设置的。例如,一个财务走了,把他所在的座位的口从 VLAN 30 移除掉。来了一个程序员,坐在财务的位置,就把这个口设置为 VLAN 10,十分灵活。
对于支持 VLAN 的交换机,有一种 Trunk 口,可以转发属于任何 VLAN 的口。交换机之间可以通过 Trunk 口相互连接。
2.6 小结
- 交换机的数目越来越多时,会遭遇环路问题,让网络包迷路,这时就需要使用 STP 协议,通过华山论剑比武的方式,将有环路的图变成没有环路的树,从而解决环路问题
- 交换机数目多会面临隔离问题,可以通过 VLAN 形成虚拟局域网,从而解决广播问题和安全问题
3. ICMP 与 ping
3.1 ICMP 互联网控制报文协议
ICMP 一般被认为属于网络层,和 IP 协议同一层,是管理和控制 IP 的一种协议
ping 是基于 ICMP 协议工作的。ICMP 全称 Internet Control Message Protocol,即互联网控制报文协议。
ICMP 报文是封装在 IP 包里面的。因为传输指令的时候,肯定需要源地址和目标地址。它本身非常简单,因为作为侦察兵,要轻装上阵,不能携带大量的包袱。
ICMP 报文有很多的类型,不同的类型有不同的代码。最常用的类型是主动请求为 8,主动请求的应答为 0。
1. 查询报文类型
ICMP 的查询报文类型,好比主帅传令侦察兵,会主动查看敌情。例如,常用的ping
就是查询报文,是一种主动请求、并且获得主动应答的 ICMP 协议。
对ping
的主动请求,进行网络抓包,称为 ICMP ECHO REQUEST。同理主动请求的回复,称为 ICMP ECHO REPLY。比起原生的 ICMP,这里面多了两个字段:一个是标识符,用来区分不同的报文;另一个是序号,用来记录报文的顺序。
在选项数据中,
ping
还会存放发送请求的时间值,用来计算往返时间,说明路程的长短
2. 差错报文类型
由异常情况发起的、来报告差错的报文,对应 ICMP 的差错报文类型。
常见的 ICMP 差错报文的例子如下:
- 终点不可达:3,包括网络不可达、主机不可达、协议不可达、端口不可达、需要进行分片但设置了不分片位
- 源站抑制:4,让源站放慢发送速度
- 时间超时:11,超过网络包的生存时间还是没到
- 路由重定向:5,让下次发给另一个路由器
3.2 ping 查询报文类型的使用
下图展示了ping
命令的发送和接收过程:
ping
命令执行的时候,源主机首先会构建一个 ICMP 请求数据包,这个包内包含多个字段,最重要的有两个:第一个是类型字段,对于请求数据包而言该字段为 8;另一个是顺序号,主要用于区分连续ping
的时候发出的多个数据包。每发出一个请求数据包,顺序号会自动加 1。为了能够计算往返时间 RTT,它会在报文的数据部分插入发送时间。然后,由 ICMP 协议将这个数据包连同地址
192.168.1.2
一起交给 IP 层。IP 层将以192.168.1.2
作为目的地址,本机 IP 地址作为源地址,加上一些其他控制信息,构建一个 IP 数据包。接下来,需要加入 MAC 头。可在 ARP 映射表中查找 IP 地址对应的 MAC 地址,如果没有,则需要发送 ARP 协议查询 MAC 地址。获得 MAC 地址后,由数据链路层构建一个数据帧,目的地址是 IP 层传过来的 MAC 地址,源地址则是本机的 MAC 地址,附加上一些控制信息,最后将它们传送出去。
主机 B 收到这个数据帧后,先检查它的目的 MAC 地址,符合本机则接收,否则就丢弃。接收后检查该数据帧,将 IP 数据包从帧中提取出来,交给本机的 IP 层。同样,IP 层检查后,将有用的信息提取后交给 ICMP 协议。
主机 B 会构建一个 ICMP 应答包,应答数据包的类型字段为 0,顺序号为接收到的请求数据包中的顺序号,然后再发送出去给主机 A。
在规定的时间内,源主机如果没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了,则说明可达。此时,源主机会用当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。
ping
这个程序使用了 ICMP 里面 ECHO REQUEST 和 ECHO REPLY 类型
3.3 Traceroute 差错报文类型的使用
有一个程序traceroute
,是个“大骗子”,它会使用 ICMP 的规则,故意制造一些能够产生错误的场景。
- 故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器
- 故意设置不分片,从而确定路径的 MTU
4. 网关 Gateway
在进行网卡配置的时候,除了 IP 地址,还需要配置网关(Gateway)。
4.1 MAC 头和 IP 头
一旦配置了 IP 地址和网关,往往就能够指定目标地址进行访问了。但在跨网关访问的时候,还牵扯到 MAC 地址和 IP 地址的变化。
在任何一台机器上,当要访问另一个 IP 地址的时候,都会先判断:这个目标 IP 地址和当前机器的 IP 地址是否在同一个网段,需要借助 CIDR(无类型域间选路)和子网掩码来实现。
- 如果是同一个网段:那就不需要访问网关,直接将源地址和目标地址放入 IP 头中,然后通过 ARP 获得 MAC 地址,将源 MAC 和目的 MAC 放入 MAC 头中,发出去就可以了
- 如果不是同一个网段:这时就需要发往默认网关 Gateway,Gateway 的地址一定是和源 IP 地址同一个网段的,往往不是第一个,就是第二个。例如
192.168.1.0/24
这个网段,Gateway 往往会是192.168.1.1/24
或者192.168.1.2/24
网关往往是一个路由器,是一个三层转发设备(即会把 MAC 头和 IP 头都取下来,然后根据里面的内容,看看接下来把包往哪里转发的设备)
4.2 静态路由
静态路由,其实就是在路由器上,配置一条一条规则。
MAC 地址是一个局域网内才有效的地址。因而,MAC 地址只要过了网关,就必定会改变,因为已经换了另一个局域网
对于 IP 头和 MAC 头哪些变、哪些不变的问题,可以分为两种类型:不改变 IP 地址的网关,称为转发网关;改变 IP 地址的网关,称为 NAT 网关。
1. 转发网关
服务器 A 要访问服务器 B,首先,因为不是一个网段的,会向网关192.168.1.1
发送包:
- 源 MAC:服务器 A 的 MAC
- 目标 MAC:
192.168.1.101
这个网口的 MAC - 源 IP:
192.168.1.101
- 目标 IP:
192.168.4.101
左边的网关收到包后,修改源 MAC 和目标 MAC,向右边的网关转发包:
- 源 MAC:
192.168.56.1
的 MAC 地址 - 目标 MAC:
192.168.56.2
的 MAC 地址 - 源 IP:
192.168.1.101
- 目标 IP:
192.168.4.101
路由器 B 收到包后,发送 ARP 获取192.168.4.101
的 MAC 地址,然后发送包:
- 源 MAC:
192.168.4.1
的 MAC 地址 - 目标 MAC:
192.168.4.101
的 MAC 地址 - 源 IP:
192.168.1.101
- 目标 IP:
192.168.4.101
包到达服务器 B,MAC 地址匹配,将包收进来。
从上面的过程可以看出,每到一个局域网,MAC 都是要变的,但是 IP 地址都不变。在 IP 头里面,不会保存任何网关的 IP 地址。所谓的下一跳是,某个 IP 要将这个 IP 地址转换为 MAC 放入 MAC 头。
2. NAT 网关
首先,目标服务器 B 在国际上要有一个国际的身份,例如192.168.56.2
。在网关 上,我们记下来,国际身份192.168.56.2
对应国内身份192.168.1.101
。凡是要访问192.168.56.2
的,都转成192.168.1.101
。
于是,源服务器 A 要访问目标服务器 B,先向路由器 A 发送包,内容为:
- 源 MAC:服务器 A 的 MAC 地址
- 目标 MAC:
192.168.1.1
这个网口的 MAC 地址 - 源 IP:
192.168.1.101
- 目标 IP:
192.168.56.2
之后路由器 A 发送包到路由器 B:
- 源 MAC:
192.168.56.1
的 MAC 地址 - 目标 MAC:
192.168.56.2
的 MAC 地址 - 源 IP:
192.168.56.1
- 目标 IP:
192.168.56.2
最后,路由器 B 发送包到服务器 B 的内容:
- 源 MAC:
192.168.1.1
的 MAC 地址 - 目标 MAC:
192.168.1.101
的 MAC 地址 - 源 IP:
192.168.56.1
- 目标 IP:
192.168.1.101
包到达服务器 B,MAC 地址匹配,将包收进来。
从这个过程可以看出,IP 地址也会改变,用英文说就是 Network Address Translation,简称 NAT。
4.3 小结
- 如果离开本局域网,就需要经过网关,网关是路由器的一个网口
- 路由器是一个三层设备,里面有如何寻找下一跳的规则
- 网关处理 MAC 和 IP 地址时有两种方式,一种是转发网关,另一种是 NAT 网关
5. 路由协议
5.1 如何配置路由?
通过之前的内容可以知道,路由器就是一台网络设备,它有多张网卡。当一个入口的网络包送到路由器时,他会根据一个本地的转发信息库,来决定如何正确的转发流量,这个转发信息库通常被称为路由表。
一张路由表中会有多条路由规则,每一条规则至少包含这三项信息:
- 目的网络:这个包想去哪儿?
- 出口设备:将包从哪个口扔出去?
- 下一跳网关:下一个路由器的地址
通过
route
或ip route
命令都可以对路由表进行查询或配置
例如,我们要设置ip route add 10.176.48.0/20 via 10.173.32.1 dev eth0
,就说明要去10.176.48.0/20
这个目标网络,要从eth0
端口出去,经过10.173.32.1
。这种配置方式的核心思想是:根据目的 IP 地址来配置路由。
5.2 如何配置策略路由?
在真实的复杂网络环境中,除了根据目的 IP 地址来配置路由外,还可以根据多个参数来配置路由,这就称为策略路由。
例如,我们设置:
> ip rule add from 192.168.1.0/24 table 10
> ip rule add from 192.168.2.0/24 table 20
表示从192.168.1.0/24
这个网段来的,使用table 10
中的路由表,而从192.168.2.0/24
网段来的,则使用table 20
的路由表。
在一条路由规则中,也可以走多条路径:
> ip route add default scope global nexthop via 100.100.100.1 weight 1 nexthop via 200.200.200.1 weight 2
这条规则表示下一跳有两个地方,分别是100.100.100.1
和200.200.200.1
,权重分别为1
和2
。
5.3 动态路由算法
使用动态路由协议的路由器,可以根据路由协议算法生成动态路由表,随网络运行状况的变化而变化。
可以将复杂的网络拓扑路径,抽象为图的结构。因而这就转化成如何在途中找到最短路径的问题。
1. 距离矢量路由算法
第一大类的算法称为距离矢量路由(Distance Vector Routing),它是基于 Bellman-Ford 算法的。
它的基本思想是:每个路由器都保存一个路由表,包含多行,每行对应网络中的一个路由器。每一行包含两部分信息:一个是要到目标路由器,从哪条线出去;另一个是到目标路由器的距离。
可以看出,每个路由器都知道全局信息,都知道自己和邻居之间的距离。为了更新路由表,每过几秒,每个路由器都将自己所知的到达所有路由器的距离告知邻居。
这样一来,每个路由器根据新收集的信息,计算和其他路由器的距离。例如一个邻居距离目标路由器的距离是M
,而自己距离邻居是X
,则自己距离目标路由器的距离是X+M
该算法虽然简单,但也存在问题:
- 好消息传得快,坏消息传得慢:新加入网络的路由器会被很快发现,而挂掉的路由器是没有广播的
- 每次发送的时候,都要发送整个全局路由表,网络带宽无法承受,从而限制了距离矢量路由的网络规模
2. 链路状态路由算法
第二大类算法是链路状态路由(Link State Routing),基于 Dijkstra 算法。
它的基本思想是:当一个路由器启动时,首先发现邻居,然后将自己和邻居之间的链路状态包广播出去,发送到整个网络的每个路由器。因而,每个路由器都能在本地构建一个完整的图,然后针对这个图使用 Dijkstra 算法,找到两点之间的最短路径。
链路状态路由算法只广播更新的或改变的网络拓扑,这使得更新信息更小,节省了带宽和 CPU 利用率。而且一旦一个路由器挂了,它的邻居都会广播这个消息,可以使得坏消息迅速收敛
5.4 动态路由协议
1. 基于链路状态路由算法的 OSPF
OSPF(Open Shortest Path First,开放式最短路径优先)就是这样一个基于链路状态路由算法的动态路由协议,主要用于数据中心内部的路由决策,因而称为内部网关协议(Interior Gateway Protocol,简称 IGP)。
内部网关协议的重点就是找到最短路径。当然,有时候 OSPF 可以发现多个最短的路径,可以在这多个路径中进行负载均衡,这常常被称为等价路由。
一般应用的接入层会有负载均衡 LVS,它可以和 OSPF 一起,实现高吞吐量的接入层设计
2. 基于距离矢量路由算法的 BGP
外网的路由协议又有所不同,我们称为外网路由协议(Border Gateway Protocol,简称 BGP)。
在网络世界中,一个个局域网成为自治系统 AS(Autonomous System),并根据对外的连接情况分为多种不同的类型。
每个自治系统都有边界路由器,通过它和外面的世界建立联系。
BGP 又分为两类:eBGP 和 iBGP。自治系统的边界路由器之间使用 eBGP 广播路由。而边界路由器要想将 BGP 学习到的路由导入到内部网络,则需要运行 iBGP,使得内部的路由器能够找到到达外网目的地的最优边界路由器。
BGP 协议使用的算法是路径矢量路由协议(Path Vector Protocol),它是距离矢量路由协议的升级版
5.5 小结
- 路由分静态路由和动态路由,静态路由可以配置复杂的策略路由,控制转发策略
- 动态路由主流算法有两种:距离矢量算法和链路状态算法。基于这两种算法产生两种协议:BGP 协议和 OSPF 协议