Skip to content

1. IP 协议相关技术

1.1 DNS

DNS 解析只指路不带路。

根域的 DNS 服务器信息保存在互联网中所有的 DNS 服务器中。

因此,客户端只要能够找到任意一台 DNS 服务器,就可以通过它找到根域 DNS 服务器,然后再一路顺藤摸瓜找到位于下层的某台目标 DNS 服务器。

域名解析的工作流程:

  1. 浏览器先查下自己的缓存里面有没有,没有就向操作系统的缓存要,还没有就 hosts 文件,如果还是没有,就会 DNS 服务器进行查询。
  2. 客户端首先发送一个DNS请求给本地DNS服务器,问 www.server.com 的地址是什么
  3. 本地域名服务器收到请求后,查询自己的缓存中能否找到这个 www.server.com 的地址,有则返回;没有则询问它的根域名服务器。根域名服务器是最高层次的,它不直接解析,而是指路
  4. 根域名服务器收到请求之后,发现后置是 .com,返回 .com 顶级域名服务器地址给本地域名服务器,让它去问顶级域名服务器
  5. 本地 DNS 收到顶级域名服务器的地址后,发起请求问.com 顶级域名服务器www.server.com 的地址
  6. 顶级域名服务器收到请求之后,返回负责 server.com 区域的权威 DNS 服务器的地址
  7. 本地 DNS 于是转向问权威 DNS 服务器。server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
  8. 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
  9. 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。

1.1.1 传输层协议

DNS同时占用UDP和TCP端口53。

  • DNS区域传输的时候使用TCP协议:

辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。 

  • 域名解析时使用UDP协议

客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。 

1.2 ARP

ARP 用来获取下一跳的 MAC 地址。

在传输一个 IP 数据报的时候,确定了源 IP 地址和目标 IP 地址后,就会通过主机「路由表」确定 IP 数据包下一跳。然而,网络层的下一层是数据链路层,所以我们还要知道「下一跳」的 MAC 地址。

1.2.1 如何工作的

ARP 是借助 ARP 请求 ARP 响应两种类型的包确定 MAC 地址的。

主机会通过广播发送 ARP 请求,这个包中包含了想要知道的 MAC 地址的主机 IP 地址。 当同个链路中的所有设备收到 ARP 请求时,会去拆开 ARP 请求包里的内容,如果 ARP 请求包中的目标 IP 地址与自己的 IP 地址一致,那么这个设备就将自己的 MAC 地址塞入 ARP 响应包返回给主机。

操作系统通常会把第一次通过 ARP 获取的 MAC 地址缓存起来,以便下次直接从缓存中找到对应 IP 地址的 MAC 地址。缓存是有有效期的。

1.2.2 RARP

RARP 与 ARP 相反,是已知 MAC 地址求 IP 地址。

例如将打印机服务器等小型嵌入式设备接入到网络时就经常会用得到。

通常这需要架设一台 RARP 服务器,在这个服务器上注册设备的 MAC 地址及其 IP 地址。然后再将这个设备接入到网络,接着:

  1. 该设备会发送一条「我的 MAC 地址是 XXXX,请告诉我,我的 IP 地址应该是什么」的请求信息。
  2. RARP 服务器接到这个消息后返回「MAC 地址为 XXXX 的设备,IP 地址为 XXXX」的信息给这个设备。

1.3 DHCP

DHCP(Dynamic Host Configuration Protocol)

  1. 客户端首先发起 DHCP 发现报文的IP数据包,由于客户端没有IP地址,也不知道DHCP服务器的地址,所以使用 UDP广播通信,源IP地址使用0.0.0.0:68,目的地址使用255.255.255.255:67。DHCP 客户端将改IP数据包传递给链路层,然后链路层将改帧广播到所有的网络中设备。
  2. DHCP 服务器收到发现报文时,用 DHCP 提供报文响应客户端。该报文仍然使用 IP 广播地址255.255.255.255:67作为目的地址,报文信息携带服务器提供:可租约的 IP 地址、子网掩码、默认网关、DNS 服务器和IP地址使用租期
  3. 客户端收到一个或多个提供报文后,选择一个,并向选中的服务器发送 DHCP 请求报文进行响应,回显配置的参数
  4. 最后服务器用DHCP ACK报文响应,应答所要求的参数。

租约的 IP 地址快到期后,客户端会向服务器发送 DHCP 请求报文: - 服务器同意续租,使用 DHCP ACK应答,客户端就会延长租期 - 服务器不同意续租,使用 DHCP NACK 报文应答,客户端就要停止使用租约的IP地址,然后客户端可以发送DHCP请求消息(DHCPDISCOVER)来重新申请IP地址。

1.3.1 中继代理

可以发现,DHCP 交互中,全程都是使用 UDP 广播通信

用的是广播,那如果 DHCP 服务器和客户端不是在同一个局域网内,路由器又不会转发广播包,那不是每个网络都要配一个 DHCP 服务器?

为了解决这一问题,就出现了 DHCP 中继代理(Relay Proxy)。有了 DHCP 中继代理以后,对不同网段的 IP 地址分配也可以由一个 DHCP 服务器统一进行管理。

  • DHCP 客户端会向 DHCP 中继代理发送 DHCP 请求包,而 DHCP 中继代理在收到这个广播包以后,再以单播的形式发给 DHCP 服务器。

  • 服务器端收到该包以后再向 DHCP 中继代理以单播的形式返回应答,并由 DHCP 中继代理将此包广播给 DHCP 客户端。

因此,DHCP 服务器即使不在同一个链路上也可以实现统一分配和管理 IP 地址。

中继代理通常由网络路由器或网络设备进行。

1.4 NAT

NAT:网络地址转换

NAT 是在私有IP地址和公有IP地址之间转换的技术。

NAPT:由于绝大多数的网络应用都是使用传输层协议 TCP 或 UDP 来传输数据的。因此,可以把 IP 地址 + 端口号一起进行转换。这种转换技术就叫网络地址与端口转换 NAPT

上图中,两个私有 IP 地址都转换 IP 地址为公有地址 120.229.175.121,但是以不同的端口号作为区分。

于是,生成一个 NAPT 路由器的转换表,就可以正确地转换地址跟端口的组合,令客户端 A、B 能同时与服务器之间进行通信。

这种转换表在 NAT 路由器上自动生成。例如,在 TCP 的情况下,建立 TCP 连接首次握手时的 SYN 包一经发出,就会生成这个表。而后又随着收到关闭连接时发出 FIN 包的确认应答从表中被删除。

1.4.1 存在的问题

由于 NAT/NAPT 都依赖于自己的转换表,因此会有以下的问题:

  • 外部无法主动与 NAT 内部服务器建立连接,因为 NAPT 转换表没有转换记录。
  • 转换表的生成与转换操作都会产生性能开销。
  • 通信过程中,如果 NAT 路由器重启了,所有的 TCP 连接都将被重置。

1.4.2 解决的方法

  • 改用 IPv6
  • NAT 穿透技术,俗称内网穿透技术

NAT 穿透技术

它能够让网络应用程序主动发现自己位于 NAT 设备之后,并且会主动获得 NAT 设备的公有 IP,并为自己建立端口映射条目,注意这些都是 NAT 设备后的应用程序自动完成的。

在 NAT 穿透技术中,NAT 设备后的应用程序处于主动地位,它已经明确地知道 NAT 设备要修改它外发的数据包,于是它主动配合 NAT 设备的操作,主动地建立好映射,这样就不像以前由 NAT 设备来建立映射了。

就是客户端主动从 NAT 设备获取公有 IP 地址,然后自己建立端口映射条目,然后用这个条目对外通信,就不需要 NAT 设备来进行转换了。

1.4.3 NAT 穿透拓展

为了实现NAT穿透,有几种常见的技术和协议可供选择,包括(来自ChatGPT):

  • 端口映射(Port Mapping):通过在NAT设备上配置端口映射规则,将公共IP地址和端口映射到私有网络中的特定主机和端口上,实现公网访问私有网络的能力。
  • UPnP(Universal Plug and Play):UPnP协议允许设备在本地网络中自动进行端口映射和配置,以便在私有网络中的主机能够接收来自公共网络的连接。
  • STUN(Session Traversal Utilities for NAT):STUN协议用于发现和绕过NAT设备。它通过在客户端和服务器之间进行交互,获取公共IP地址和端口信息,以便建立直接的通信通道(由于这些信息已经经过NAT设备的映射,因此其他设备可以将响应发送回客户端,客户端也能够收到来自其他设备的直接通信)。
  • TURN(Traversal Using Relays around NAT):TURN协议是一种基于中继的解决方案,当直接通信无法建立时,它允许在公共网络上设置一个中继服务器,用于中转数据流量。

注意⚠️:客户端与其他设备建立直接通信的成功与否仍然取决于网络环境、NAT设备和NAT类型的限制。

1.5 ICMP

ICMP(Internet Control Message Protocol)互联网控制报文协议,主要用于在IP网络中传递控制信息和错误报告。ICMP 报文是封装在 IP 包里面,它工作在网络层。

网络包在复杂的网络传输环境里,常常会遇到各种问题。

当遇到问题的时候,需要传出消息,报告遇到了什么问题,这样才可以调整传输策略,以此来控制整个局面。

1.5.1 主要功能

ICMP协议在TCP/IP协议族中位于网络层(或称为互联网层),与IP协议一起工作,提供以下主要功能(来自ChatGPT):

  • 错误报告:ICMP用于向源主机发送错误报告,以通知发生在网络层的问题。例如,当目标主机不可达、超时、或发生路由错误时,通过ICMP向源主机发送相应的错误报告,帮助诊断和解决网络问题。
  • 回送请求和回送应答:ICMP的回送请求和回送应答(Ping)功能用于测试主机之间的连通性。通过发送一个特定的ICMP回送请求消息到目标主机,可以检查目标主机是否可达,并通过接收回送应答消息来测量往返时间(RTT)和网络延迟等信息。
  • 路由通知:ICMP用于传递与路由相关的信息。例如,当发生路由器发现、路由表更新或路由器重新启动等情况时,ICMP可以发送相应的路由通知消息。
  • 重定向消息:ICMP的重定向消息用于通知主机发送数据包时可以选择更优的路由。当某个主机发送数据包到一个中间路由器,并且有更优的路由可用时,路由器可以发送一个重定向消息给主机,告知它使用更合适的路由。
  • 时间戳请求和应答:ICMP的时间戳请求和应答功能用于获取网络中主机的时间戳信息。通过发送时间戳请求消息到目标主机,可以获取目标主机的时间戳,并通过接收时间戳应答消息来进行时间同步或测量网络延迟。

1.5.2 类型

大致可分为两类:

  • 查询报文,用于诊断
  • 差错报文,通知出错原因的错误消息

1.5.2.1 目标不可达

举例 5 种常见的目标不可达类型的代码:

  • 网络不可达代码为 0
    • IP 地址是分为网络号和主机号的,所以当路由器中的路由器表匹配不到接收方 IP 的网络号,就通过 ICMP 协议以网络不可达(Network Unreachable)的原因告知主机。
  • 主机不可达代码为 1
    • 当路由表中没有该主机的信息,或者该主机没有连接到网络,那么会通过 ICMP 协议以主机不可达(Host Unreachable)的原因告知主机。
  • 协议不可达代码为 2
    • 当主机使用 TCP 协议访问对端主机时,能找到对端的主机了,可是对端主机的防火墙已经禁止 TCP 协议访问,那么会通过 ICMP 协议以协议不可达的原因告知主机。
  • 端口不可达代码为 3
    • 当主机访问对端主机 8080 端口时,这次能找到对端主机了,防火墙也没有限制,可是发现对端主机没有进程监听 8080 端口,那么会通过 ICMP 协议以端口不可达的原因告知主机。
  • 需要进行分片但设置了不分片位代码为 4
    • 发送端主机发送 IP 数据报时,将 IP 首部的分片禁止标志位设置为1。根据这个标志位,途中的路由器遇到超过 MTU 大小的数据包时,不会进行分片,而是直接抛弃。随后,通过一个 ICMP 的不可达消息类型,代码为 4 的报文,告知发送端主机。

1.5.2.2 原点抑制消息

在使用低速广域线路的情况下,连接 WAN 的路由器可能会遇到网络拥堵的问题。

ICMP 原点抑制消息的目的就是为了缓和这种拥堵情况。

当路由器向低速线路发送数据时,其发送队列的缓存变为零而无法发送出去时,可以向 IP 包的源地址发送一个 ICMP 原点抑制消息。

收到这个消息的主机借此了解在整个线路的某一处发生了拥堵的情况,从而增大 IP 包的传输间隔,减少网络拥堵的情况。

然而,由于这种 ICMP 可能会引起不公平的网络通信,一般不被使用。

1.5.2.3 重定向消息

如果路由器发现发送端主机使用了「不是最优」的路径发送数据,那么它会返回一个 ICMP 重定向消息给这个主机。

在这个消息中包含了最合适的路由信息和源数据。这主要发生在路由器持有更好的路由信息的情况下。路由器会通过这样的 ICMP 消息告知发送端,让它下次发给另外一个路由器。

1.5.2.4 超时消息

IP 包中有一个字段叫做 TTL (Time To Live,生存周期),它的值随着每经过一次路由器就会减 1,直到减到 0 时该 IP 包会被丢弃。

此时,路由器将会发送一个 ICMP 超时消息给发送端主机,并通知该包已被丢弃。

设置 IP 包生存周期的主要目的,是为了在路由控制遇到问题发生循环状况时,避免 IP 包无休止地在网络上被转发

1.6 IGMP

由前文可知 D 类地址是组播地址,那就说明是只有一组的主机能收到数据包,不在一组的主机不能收到数组包,怎么管理是否是在一组呢?那么,就需要 IGMP 协议了。

IGMP 是因特网组管理协议,工作在主机(组播成员)和最后一跳路由之间

  • IGMP 报文向路由器申请加入和退出组播组,默认情况下路由器是不会转发组播包到连接中的主机,除非主机通过 IGMP 加入到组播组,主机申请加入到组播组时,路由器就会记录 IGMP 路由器表,路由器后续就会转发组播包到对应的主机了。
  • IGMP 报文采用 IP 封装,IP 头部的协议号为 2,而且 TTL 字段值通常为 1,因为 IGMP 是工作在主机与连接的路由器之间。

IGMP 分为了三个版本分别是,IGMPv1、IGMPv2、IGMPv3。接下来,以 IGMPv2 作为例子,说说常规查询与响应和离开组播组这两个工作机制。

1.6.1 常规查询与响应工作机制

  1. 路由器会周期性发送目的地址为 224.0.0.1(表示同一网段内所有主机和路由器) IGMP 常规查询报文
  2. 主机 1 和 主机 3 收到这个查询,随后会启动报告延迟计时器,计时器的时间是随机的,通常是 0~10 秒,计时器超时后主机就会发送 IGMP 成员关系报告报文(源 IP 地址为自己主机的 IP 地址,目的 IP 地址为组播地址)。如果在定时器超时之前,收到同一个组内的其他主机发送的成员关系报告报文,则自己不再发送,这样可以减少网络中多余的 IGMP 报文数量。
  3. 路由器收到主机的成员关系报文后,就会在 IGMP 路由表中加入该组播组,后续网络中一旦该组播地址的数据到达路由器,它会把数据包转发出去。

1.6.2 离开组播组工作机制

离开组播组的情况一,网段中仍有该组播组:

  • 主机 1 要离开组 224.1.1.1,发送 IGMPv2 离组报文,报文的目的地址是 224.0.0.2(表示发向网段内的所有路由器)
  • 路由器 收到该报文后,以 1 秒为间隔连续发送 IGMP 特定组查询报文(共计发送 2 个),以便确认该网络是否还有 224.1.1.1 组的其他成员。
  • 主机 3 仍然是组 224.1.1.1 的成员,因此它立即响应这个特定组查询。路由器知道该网络中仍然存在该组播组的成员,于是继续向该网络转发 224.1.1.1 的组播数据包。

离开组播组的情况二,网段中没有该组播组:

  • 主机 1 要离开组播组 224.1.1.1,发送 IGMP 离组报文。
  • 路由器收到该报文后,以 1 秒为间隔连续发送 IGMP 特定组查询报文(共计发送 2 个)。此时在该网段内,组 224.1.1.1 已经没有其他成员了,因此没有主机响应这个查询。
  • 一定时间后,路由器认为该网段中已经没有 224.1.1.1 组播组成员了,将不会再向这个网段转发该组播地址的数据包。