本文目录
Internet Protocol 网际协议运行在五层协议的体系结构(Physical Layer物理层、Data Link Layer数据链路层、Network Layer网络层、Transport Layer传输层、Application Layer应用层)中的网络层,它是TCP/IP协议族中最为核心的协议之一,负责为数据包提供无连接的、不可靠的、尽最大努力交付的服务。
IPv4
Internet Protocol version 4,网际协议版本4 是1982年在SATNET和1983年1月在ARPANET上部署用于生产的第一个版本。IPv4由IETF(互联网工程任务组)在1981年9月发布的RFC 791中描述,该RFC替换了1980年1月发布的RFC 760。IPv4使用32位(4字节)地址,因此地址空间中只有4,294,967,296(2^32)个地址。然而,随着互联网的快速发展,这些地址很快被耗尽。
IPv4地址的分配和管理由多个机构负责,包括ICANN(因特网名字与号码指派公司)及其下属的区域互联网注册管理机构(RIR)。尽管IPv4地址空间有限,但通过各种技术手段(如网络地址转换NAT、无类别域间路由CIDR等),IPv4地址的枯竭速度得到了显著减缓。然而,到2019年11月26日,全球所有43亿个IPv4地址已分配完毕,标志着IPv4地址的完全耗尽。
IPv4 编址
IPv4 地址由 32 位二进制数标识,按 8位 划分成 4个字节,为了方便书写和记忆,一般使用十进制来写每个字节的值(0
~ 255
),每个字节中间以 .
间隔 (形如 192.168.3.128
)。
IPv4 地址的分类
A 类地址
- 地址范围:从1.0.0.0到126.255.255.255。
- 默认子网掩码:255.0.0.0(或/8)。
- 第一个和最后一个地址:网络地址(如1.0.0.0)和广播地址(如126.255.255.255)不可用。
- 用途:A类地址分配给拥有大量主机的大型网络,但由于地址空间有限,实际上A类地址的使用已经非常少。
B 类地址
- 地址范围:从128.0.0.0到191.255.255.255。
- 默认子网掩码:255.255.0.0(或/16)。
- 第一个和最后一个地址:网络地址(如128.0.0.0)和广播地址(如191.255.255.255)不可用。
- 用途:B类地址用于中等规模的网络。然而,随着互联网的扩展,B类地址也逐渐变得稀缺。
C 类地址
- 地址范围:从192.0.0.0到223.255.255.255。
- 默认子网掩码:255.255.255.0(或/24)。
- 第一个和最后一个地址:网络地址(如192.0.0.0)和广播地址(如223.255.255.255)不可用。
- 用途:C类地址是为小型网络设计的,是目前最广泛使用的IPv4地址类型。
D 类地址
- 地址范围:从224.0.0.0到239.255.255.255。
- 用途:D类地址被保留用于多播(Multicast)地址,也称为组播地址。多播允许将数据包同时发送给网络中的一组选定设备,而不是单个设备
E 类地址
- 地址范围:从240.0.0.0到255.255.255.255。
- 用途:E类地址目前保留未用,但在某些情况下被用作实验和研究目的。
特殊地址
0.0.0.0
-
表示无效目标或未知目标
在IPv4网络中,0.0.0.0地址通常被用来表示一个无效的、未知的或者不可用的目标。这意味着,如果数据包的目的地址是0.0.0.0,那么这些数据包不会被发送到任何具体的网络设备上,而是可能会被丢弃或特殊处理。 -
服务器上所有IP的监听
在服务器配置中,0.0.0.0地址具有特殊的含义。它并不指向网络中的任何具体物理设备,而是代表服务器上的所有IP地址。换句话说,当服务器上的某个服务监听在0.0.0.0上时,它实际上是在监听该服务器所有网络接口上的所有IP地址。这增加了配置的灵活性,使得无论客户端通过哪个IP地址访问服务器,该服务都能够接受连接。在服务器的防火墙规则配置中,来源0.0.0.0/0
表示接收所有 IP 地址的来源:
-
默认路由
在路由表中,0.0.0.0地址表示默认路由。当路由表中没有找到完全匹配的路由时,数据包会被发送到默认路由指定的下一跳地址。这有助于确保数据包在无法直接到达目的地址时,能够被正确地转发到下一个路由器或网络设备上。 -
未分配IP时的表示
当一台主机还没有被分配一个IP地址时,它可以使用0.0.0.0地址来表示自己。这种情况下,0.0.0.0地址并不代表一个有效的网络地址,而是用于标识主机当前处于未分配IP地址的状态。 -
网关地址的特殊含义
在网关配置中,0.0.0.0地址有时被用作直连规则的标识。这意味着当前记录对应的目的地与本机在同一个网段内,通信时不需要经过网关(路由器)。这种情况下,数据包可以通过二层交换机直接通过MAC地址进行通信,而无需经过三层路由。 -
容器网络中的应用
在容器网络中,0.0.0.0地址也有特殊的应用。当命中容器的路由表直连规则时,如果目的IP是在局域网内,那么数据包可以直接通过二层网络发送,而无需走到出口网关。这有助于优化容器间的通信效率。
255.255.255.255
255.255.255.255是一个特殊的IPv4地址,被称为受限广播地址(Limited Broadcast Address)或本地广播地址(Local Broadcast Address)。它用于在同一个局域网(LAN)内发送广播数据包给所有的设备,而不会被路由器转发到其他网络。
当主机向255.255.255.255发送数据包时,该数据包会被网络上的所有设备接收,包括交换机、路由器(但仅限于与发送设备位于同一局域网内的路由器接口)和其他主机。然而,由于这是一个受限的广播地址,路由器通常不会将其转发到网络之外,从而避免了广播风暴和不必要的网络流量。
127.0.0.0 ~ 127.255.255.255
127开头的地址在IPv4地址分类中属于保留地址,具体来说是用于本地回环(Loopback)测试的。这类地址不会出现在任何网络上,也不会被路由器转发。当主机向一个127开头的地址发送数据包时,数据包不会离开主机,而是被主机上的网络接口软件捕获并处理,这通常用于测试本地网络接口或应用程序。
具体来说,127.0.0.0到127.255.255.255的地址范围都被保留用于本地回环测试。其中,一个特别常用的地址是127.0.0.1,它被称为本地回环地址或环回地址(Loopback Address)。通过这个地址,主机可以向自己发送数据包,并在不经过任何网络接口的情况下直接接收这些数据包,这在进行网络编程和测试时非常有用。localhost
通常被解析到 127.0.0.1
。修改 hosts
文件可以更改本机的主机名,默认主机名就是 localhost
。hosts
文件通常缓存了 域名 到 IP 地址的映射。
Windows 系统的 hosts
文件通常位于 C:\Windows\System32\drivers\etc
目录下,而 Unix / Linux 系统的 hosts
文件通常位于 /etc/hosts
。
在 hosts
文件中添加一行 127.0.0.1 jackey-song.com
并保存,然后分别使用 ping
命令和 dig
命令:
ping
命令会查询 hosts
文件中 DNS(域名系统)缓存的记录,而 dig
命令会绕过本地的 hosts
缓存直接访问 DNS 服务器。(Windows 并不自带 dig 命令,需要手动安装 BIND 工具集,并配置环境变量方可使用 dig 命令。)
ping
命令主要用于测试主机之间网络连接的可达性,使用 ICMP 协议。当使用 ping
命令跟一个域名 jackey-song.com 时,操作系统会首先尝试解析这个域名到对应的IP地址。这个解析过程遵循 DNS 的解析流程,但会首先查看本地缓存(如/etc/hosts文件,在Windows中是%SystemRoot%\System32\drivers\etc\hosts)中的记录。
- 查询hosts文件:ping命令在尝试解析域名时,首先会查看本地的hosts文件,因为hosts文件提供了域名到IP地址的直接映射,这可以绕过DNS服务器直接解析域名。
- 使用DNS解析:如果hosts文件中没有对应的记录,系统会继续通过配置的DNS服务器进行解析。
dig
(domain information groper)命令是一个强大的DNS查询工具,查询DNS名称服务器的信息。dig
主要用于诊断DNS问题,提供详细的DNS查询过程和结果。
- 不直接查询hosts文件:dig命令专注于DNS的查询,因此它不会直接查看或使用本地的hosts文件。这是因为hosts文件是本地系统用来覆盖DNS解析结果的,而dig的设计目的是直接和DNS系统交互,获取DNS的原始响应。
- 直接与DNS服务器交互:当使用dig查询一个域名时,它会直接向指定的(或系统默认的)DNS服务器发送查询请求,并显示从服务器返回的所有信息。
你可能会想 127.0.0.0 ~ 127.255.255.255
之间总共有 2563 = 16,777,216 个 IP 地址,为什么要用这么多的 IP 地址作用本地回环测试?
在实际使用中,这些地址并不是全部用于单独的本地回环测试实例,而是整个范围都被视为等价的,通常都代表“本机”或“本地”的概念。
在大多数操作系统和网络环境中,127.0.0.1 是最常用的本地回环地址,因为它简单且易于记忆。然而,技术上来说,可以使用范围内的任何地址来进行本地回环测试,但结果将是相同的——数据包都会在本机内部循环,而不会发送到外部网络。
为什么保留整个范围而不是仅仅一个地址?这主要是出于以下几个原因:
- 兼容性:保留整个/8(即前8位)范围有助于确保与不同操作系统和网络设备的兼容性。不同的系统或应用可能出于不同的原因或历史遗留问题而使用不同的地址。
- 灵活性:虽然实际上并不需要这么多地址来进行本地回环测试,但保留整个范围提供了额外的灵活性。例如,某些应用或测试环境可能希望使用不同的地址来模拟多个本地接口或进行特定的配置。
- 避免冲突:虽然这些地址在本地网络上不会与任何外部地址冲突,但保留整个范围有助于避免将来可能的混淆或误用。
- 历史原因:IPv4地址的分配和保留是基于历史发展和标准化过程的。随着时间的推移,某些决策可能看起来不再那么必要,但它们仍然是协议的一部分。
IPv4 地址段详细说明
地址块 | 地址范围 | 地址数量 | 范围 | 描述 |
---|---|---|---|---|
0.0.0.0/8 | 0.0.0.0–0.255.255.255 | 16777216 | 软件 | 当前(本地,“此”)网络 |
10.0.0.0/8 | 10.0.0.0–10.255.255.255 | 16777216 | 私有网络 | 用于私有网络内的本地通信 |
100.64.0.0/10 | 100.64.0.0–100.127.255.255 | 4194304 | 私有网络 | 服务提供商与其订户之间使用运营商级NAT时的共享地址空间 |
127.0.0.0/8 | 127.0.0.0–127.255.255.255 | 16777216 | 主机 | 用于本地主机的回环地址 |
169.254.0.0/16 | 169.254.0.0–169.254.255.255 | 65536 | 子网 | 当未指定IP地址时,用于单个链路上的两个主机之间的链路本地地址 |
172.16.0.0/12 | 172.16.0.0–172.31.255.255 | 1048576 | 私有网络 | 用于私有网络内的本地通信 |
192.0.0.0/24 | 192.0.0.0–192.0.0.255 | 256 | 私有网络 | IETF协议分配,DS-Lite |
192.0.2.0/24 | 192.0.2.0–192.0.2.255 | 256 | 文档 | 分配为TEST-NET-1,用于文档和示例 |
192.88.99.0/24 | 192.88.99.0–192.88.99.255 | 256 | 互联网 | 保留。曾用于IPv6到IPv4中继 |
192.168.0.0/16 | 192.168.0.0–192.168.255.255 | 65536 | 私有网络 | 用于私有网络内的本地通信 |
198.18.0.0/15 | 198.18.0.0–198.19.255.255 | 131072 | 私有网络 | 用于两个独立子网之间互联网通信的基准测试 |
198.51.100.0/24 | 198.51.100.0–198.51.100.255 | 256 | 文档 | 分配为TEST-NET-2,用于文档和示例 |
203.0.113.0/24 | 203.0.113.0–203.0.113.255 | 256 | 文档 | 分配为TEST-NET-3,用于文档和示例 |
224.0.0.0/4 | 224.0.0.0–239.255.255.255 | 268435456 | 互联网 | 用于组播(以前的D类网络) |
233.252.0.0/24 | 233.252.0.0–233.252.0.255 | 256 | 文档 | 分配为MCAST-TEST-NET,用于文档和示例(注意这是上述组播空间的一部分) |
240.0.0.0/4 | 240.0.0.0–255.255.255.254 | 268435455 | 互联网 | 保留供未来使用(以前的E类网络) |
255.255.255.255/32 | 255.255.255.255 | 1 | 子网 | 保留为“受限广播”目标地址 |
私有网络
注意到以上表格中的私有网络,公网 IP 地址中并不会出现这些私有网络地址段中的 IP 地址。公网 IP 地址即在 Internet 上可以通过 公网 IP 地址直接访问到的地址,通常服务器都会分配公网 IP 地址。私有网络通常使用 NAT 技术共用一个公网IP地址连接到 Internet。使用私有IP地址有助于节省全球公共IP地址资源,降低网络成本,并提高网络的安全性。因为外部网络无法直接访问使用私有IP的内部设备,这减少了外部攻击的风险。
你也许会思考,为什么家里的、公司的路由器或者电脑的 IP 地址总是 192.168
开头的?当你登录路由器管理界面的时候是不是经常在浏览器的搜索栏输入 192.168.0.1
或者 192.168.1.1
亦或者 192.168.n.n
?
这是因为 192.168.0.0/16
地址范围是最常用的私有IP地址范围之一,许多家用路由器在出厂时都会默认配置为使用192.168网段的IP地址。在家庭网络中,各个设备通过路由器(有线或WiFi)组成了一个很小的局域网,路由器为每一个设备分配局域网IP地址,在同一个局域网中的两台设备,可以使用局域网IP地址进行通信(前提还要配置好相应的防火墙规则,在防火墙没有放行指定通信端口的情况下,通信仍然不会成功),但是跨局域网的两台设备并不能直接通过各自的局域网IP地址进行通信。想要让处在两个不同局域网的两台设备直接进行通信,需要使用一些跨局域网组网的工具。tailscale 是一款不错的工具,在不同设备上登录同一个 tailscale 账号,就可以让这些设备实现跨局域网组网,tailscale 会为每一个设备重新分配一个局域网IP地址,这样就可以通过 tailscale 分配的 IP 地址跨局域网远程控制另外一台主机了。Tailscale 跨局域网组网的原理主要基于 WireGuard 协议,WireGuard 是一种新型的、高性能的 VPN 协议,Taiscale 通过 WireGuard 协议,将不同网络环境的设备组成一个虚拟局域网(VLAN, Virtual Local Area Network),使这些设备能够互相访问。
tailscale 的管理员界面:
100.86.97.108
是我的本地主机在四川,100.82.84.58
是我的远程主机在安徽,在这里可以看到 tailscale 为它们分配的私有网络 IP 地址都是在 100.64.0.0
~ 100.127.255.255
(私有网络地址段) 范围内。下面使用 python 编程让它们通信:远程主机100.82.84.58
中运行了 main.py 程序,里面的代码是一段简单的TCP服务器代码,它监听了12000端口号,等待外部的连接;本地主机100.86.97.108
运行了多次 TCPclient.py 程序,每次都连接到 100.82.84.58:12000
,并向其发送了小写英文句子,服务器端接收到小写的英文句子后,将其打印并处理成 大写英文句子 返回给客户端,客户端接收到 大写英文句子后打印在 terminal。
NAT 技术
IPv4 的公网 IP 地址是非常有限的资源,不可能为所有的网络用户都分配一个 公网IP 地址来访问 Internet,况且直接使用公网IP 地址连接到网络会让主机暴漏在公共的网络环境中,极大增加了主机受攻击的风险。NAT(Network Address Translation)技术,即网络地址转换技术,是一种在IP数据报文头中转换IP地址和端口号的技术。该技术主要用于解决IPv4地址资源短缺的问题,同时增强网络安全性和提高网络性能。NAT技术在现代网络通信中扮演着至关重要的角色,它使得内部网络(如企业内网、家庭网络等)的设备能够安全、有效地访问外部网络(如互联网)。NAT技术主要包括以下几种类型:
- 静态NAT(Static NAT):
- 实现私网地址和公网地址的一对一映射。
- 适用于需要固定公网IP地址的场景,如服务器对外提供服务。
- 缺点是不能节约公网IP地址资源。
- 动态NAT(Dynamic NAT):
- 多个私网IP地址对应多个公网IP地址,基于地址池进行一对一映射。
- 当内部主机访问外部网络时,动态地从地址池中分配一个未使用的公网IP地址给该主机。
- 主机不再访问外部网络时,回收分配的公网IP地址,重新放回地址池。
- 网络地址端口转换(NAPT/PAT, Network Address Port Translation / Port Address Translation):
- 实现一个公网IP地址和多个私网IP地址之间的映射,通过修改源端口号或目的端口号来实现。
- 可以极大地节约公网IP地址资源,是家庭网络和小型企业网络常用的NAT方式。
现在绝大多数的家庭网络都使用了 NAT 技术(通常是 NAPT)连接到互联网,家庭的路由器通常不会直接分配公网IP地址,虽然路由器中也有 NAT 功能,但更一般的情况下是在 ISP (Internet Service Provider 互联网服务提供商) 的某处实现 NAT 功能。
IPv4 数据报
字段名称 | 字段长度(比特) | 描述 |
---|---|---|
版本(Version) | 4 | 表示IP协议的版本,IPv4的值为4。 |
首部长度(Header Length) | 4 | 表示IP数据报首部的长度,以32位(4字节)为单位,最大值为15,即60字节。普通IP数据报为5,即20字节。 |
区分服务(Differentiated Services)/服务类型(Type of Service, TOS) | 8 | 用来指示希望得到的服务类型,如低延迟、高吞吐量或高可靠性。但在实际中很少使用。 |
总长度(Total Length) | 16 | IP数据报的总长度(包括首部和数据),以字节为单位,最大值为65535字节。 |
标识(Identification) | 16 | 用于唯一标识每一个IP数据报,在分片时,所有分片共享同一个标识。 |
标志(Flags) | 3 | 包含分片控制信息。第一位未使用,第二位DF表示不允许分片,第三位MF表示还有更多分片。 |
片偏移(Fragment Offset) | 13 | 当数据报被分片时,该字段表示分片在原数据报中的位置,以8字节为单位。 |
生存时间(TTL, Time To Live) | 8 | 数据报可以经过的最大路由器数。每经过一个路由器,TTL减1,为0时丢弃。 |
协议(Protocol) | 8 | 指示数据报所携带的数据使用的协议类型,如ICMP(1)、TCP(6)、UDP(17)等。 |
首部校验和(Header Checksum) | 16 | 用于校验IP数据报首部的完整性,不校验数据部分。 |
源地址(Source IP Address) | 32 | 发送数据报的源IP地址。 |
目的地址(Destination IP Address) | 32 | 接收数据报的目的IP地址。 |
可选项(Options) | 可变 | 允许IP首部被扩展,包含一些可选字段,如安全、路由等。大多数IP数据报不包含此字段。 |
填充(Padding) | 可变 | 用于确保首部长度是4字节的整数倍,不足时填充0。 |
数据(Data) | 可变 | 传输的数据,可以是运输层报文段(如TCP、UDP报文段)或其他数据。 |
首部校验和
IPv4 数据报中一个比较关键的字段是 首部校验和,用于校验IP数据报首部的完整性。该字段占16位,只校验数据报的首部,不包括数据部分。这是因为数据报每经过一个路由器,其首部中的某些字段(如生存时间TTL、标志Flags、片偏移Fragment Offset等)都可能发生变化,而数据部分则保持不变。校验首部而非数据部分可以减少计算的工作量,同时确保首部在传输过程中未被篡改。
首部校验和校验首部数据完整性的方法主要采用“反码求和校验”算法,具体步骤如下:
- 初始化校验和字段:在发送方,首先需要将校验和字段初始化为0。
- 划分首部为16位单元:将IP数据报首部按照16比特(即2个字节)为一组进行划分。如果首部的长度不是16比特的整数倍,则最后一组用0补齐。
- 反码求和:采用二进制反码算术运算将所有16位单元相加(忽略溢出)。这里的“反码求和”指的是直接相加,但在处理溢出时不是简单地丢弃,而是将溢出的高位加到最低位上。需要注意的是,这里的“反码”并非指先对每个单元求反码再求和,而是一个术语上的描述,用于区分普通的加法运算。
- 迭代求和直到高16位为0:将得到的结果(可能是一个32位的结果)的高16位与低16位相加,如果高16位不为0,则继续迭代这个过程,直到高16位为0为止。最终得到的是一个16位的结果。
- 取反得到校验和:将这个16位结果按位取反(即将0变为1,将1变为0),得到的就是IP数据报首部的校验和。这个校验和被存储在首部的校验和字段中,随数据报一起发送。
在接收方,当收到IP数据报后,会重复上述过程(除了初始化校验和字段为0这一步),但这次会包括发送方已经计算并存储在首部中的校验和字段。如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该是一个全1的16位数(因为发送方取反后存储的是反码)。如果结果不是全1(即校验和错误),那么接收方会认为首部在传输过程中发生了错误,并丢弃这个数据报。
这种校验方法虽然简单,但能够有效地检测出首部在传输过程中的大部分错误,如位翻转、错位等。然而,它并不能保证数据报的绝对安全性,因为存在某些错误模式可能无法被检测出来(如两个相同的错误位)。因此,在实际应用中,还需要结合其他安全措施来确保数据的完整性和安全性。
发送方计算首部校验和:
0100 0101 0000 0000
版本4,首部长度5
0000 0000 0010 1000
总长度40
0000 0000 1000 0000
标识 128
0000 0000 0000 0000
标志、片偏移
0000 1010 0000 0110
存活时间10,协议6(TCP)
0000 0000 0000 0000
首部校验和,发送方首先置为0
1101 1110 0001 0110
源IP地址前两个字节 222.22
0100 0001 0000 1010
源IP地址后两个字节 55.10
1000 1011 0000 1001
目的地址前两个字节 139.9
0000 0101 0000 1011
目的地址后两个字节 5.11
逐步求和:
0100 0101 0000 0000
+
0000 0000 0010 1000
= 0100 0101 0010 1000
0100 0101 0010 1000
+
0000 0000 1000 0000
+
0000 0000 0000 0000
= 0100 0101 1010 1000
0100 0101 1010 1000
+
0000 1010 0000 0110
+
0000 0000 0000 0000
= 0100 1111 1010 1110
0100 1111 1010 1110
+
1101 1110 0001 0110
= 0010 1101 1100 0101
高位进位会加到结果中(将溢出的高位加到最低位上)
0010 1101 1100 0101
+
0100 0001 0000 1010
= 0110 1110 1100 1111
0110 1110 1100 1111
+
1000 1011 0000 1001
= 1111 1001 1101 1000
1111 1001 1101 1000
+
0000 0101 0000 1011
= 1111 1110 1110 0011
取反 ~1111 1110 1110 0011
= 0000 0001 0001 1100
得到首部校验码,写入首部相应的字段中。
接收方计算首部校验和进行检验:
0100 0101 0000 0000
版本4,首部长度5
0000 0000 0010 1000
总长度40
0000 0000 1000 0000
标识 128
0000 0000 0000 0000
标志、片偏移
0000 1010 0000 0110
存活时间10,协议6(TCP)
0000 0001 0001 1100
首部校验和,发送方计算结果
1101 1110 0001 0110
源IP地址前两个字节 222.22
0100 0001 0000 1010
源IP地址后两个字节 55.10
1000 1011 0000 1001
目的地址前两个字节 139.9
0000 0101 0000 1011
目的地址后两个字节 5.11
计算过程同上,最后得到的结果是:1111 1111 1111 1111
,表明传输过程中首部各个字段的值没有因为意外而改变。(发送方将首部校验和字段置为0,求和得到的是其他各个字段数值的总和,将这个总和取反后放到首部校验和字段进行传输;在接收方,如果首部数据在传输的过程中没有出现任何差错,那么除了首部校验和以外的其他字段的所有数值的总和,与当前首部校验和字段的二进制数是互为取反的关系,所以它们相加一定是一个全是 1 的二进制数。但是传输过程中如果首部校验和中的某一位出现了差错,而其他字段的数值恰巧也出现了差错,使得其他字段的二进制数值的总和在对应的二进制位上与首部校验和出现差错的位互为取反关系,那么相加的结果也是一个全是 1 的二进制数,在这种情况下首部校验和就失去了检测差错的作用,不过这种概率应该比较低,但不是绝对没有。)
IPv4 的缺陷
IPv4 诞生诞生于 20世纪80年代初期,采用 32 位地址空间,可以提供大约42亿个唯一的IP地址,在当时的设计者看来,这一数字完全够用。但是随着互联网飞速发展和普及,尤其是进入21世纪后,物联网、智能家居、云计算等技术的兴起,使得连接到互联网的设备数量急剧增加,从而导致了IPv4地址资源的枯竭(虽然 NAT 技术缓解了IPv4地址资源的枯竭,但终究是治标不治本)。
目前,虽然IPv4仍在广泛使用,但向IPv6的过渡已成为不可逆转的趋势。全球各国和互联网企业都在积极推动IPv6的部署和应用,以确保互联网的可持续发展和满足未来互联网设备数量增长的需求。
IPv6
IPv6 于20世纪90年代初步研究和设计,以应对 IPv4 地址资源的枯竭。在IPv6的上下文中,报文既可以被称为“数据报”,也可以被称为“数据包”,这两个术语在大多数情况下是可以互换使用的。
IPv6 的IP地址长度为 128比特,
可以有 2128 = 340282366920938463463374607431768211456
≈
\approx
≈ 3.40282366920938×1038 个 IP 地址,号称可以为地球上每一粒沙子分配一个 IP地址。
IPv6 数据报(数据包)
IPv6 数据报首部的长度为 40 字节,首部之后跟着数据部分。IPv6 数据报首部共有 8 个字段:
-
Version 版本:占 4 bit (0~3),该字段的值为6。
-
Traffic class 流量类型:占 8 bit (4~11),相当于 IPv4 的 TOS ( Type Of Service 服务类型) 字段。主要作用有:
- 优先级标识:Traffic Class字段是一个8位的字段,虽然目前仅使用了其中的4位(其余位可能在未来被使用或进一步研究),但它能够有效地区分不同优先级的数据包。其中,0到7的值通常分配给需要拥塞控制的流量,而8到15的值则分配给不受控制的流量,如音频/视频数据等,这些数据类型通常需要更高的优先级以保证传输质量。
- 流量控制:在路由器发生拥塞时,Traffic Class字段可以帮助路由器根据数据包的优先级来决定哪些数据包应该被优先处理,哪些数据包应该被丢弃。这种机制有助于优化网络资源的分配,确保关键数据的传输不受影响。
- QoS保障:Traffic Class字段还可以用于标识需要特殊处理的实时数据传输,如语音和视频流。通过为这些数据包分配较高的优先级,网络可以确保它们能够获得足够的带宽和低的延迟,从而满足实时传输的需求,保障服务质量(QoS)。
- 灵活性:虽然Traffic Class字段目前的使用方式相对固定,但随着网络技术和应用的发展,其使用方式可能会变得更加灵活和多样化。例如,未来可能会开发更多的算法和机制来充分利用Traffic Class字段的潜力,以应对更加复杂和多样化的网络需求。
-
Flow label 流标签:占 20 bit (12~31),主要作用有:
- 区分实时流量:在网络中,流可以理解为特定应用或进程的来自某一源地址发往一个或多个目的地址的连续单播、组播或任播报文。通过流标签,可以标记这些报文的数据流类型,从而在网络层区分不同的报文。
- 提高处理效率:流标签与源地址和目的地址一起,为特定数据流指定了网络中的转发路径。这样,报文在IP网络中传输时会保持原有的顺序,提高了处理效率。特别是在传输语音、视频等实时性要求较高的数据时,流标签的作用显得尤为重要。
- 增强QoS能力:由于流标签可以被转发路由器识别,因此可以用于实现网络中的QoS(Quality of Service,服务质量)功能。通过对流标签的识别,路由器可以对不同优先级的数据流进行不同的处理,例如为实时性要求高的数据流分配更多的带宽和更低的延迟,从而确保数据流的传输质量。
- 简化流标识:与IPv4相比,IPv6通过引入流标签字段,简化了流的标识方式。在IPv4中,通常需要五元组(源地址、目的地址、源端口、目的端口和传输层协议号)来唯一标识一条流。而在IPv6中,只需要流标签、源地址和目的地址三个字段就可以唯一标识一条流,这使得流的标识更加简单和高效。
- 扩展性:流标签字段的设计还考虑到了未来的扩展性。虽然目前流标签字段的长度为20位,但未来可以根据需要对其进行扩展,以支持更多的数据流类型和更精细的流量控制策略。
-
Payload length 有效荷载长度:占 16 bit (32~47),指明跟在数据报首部之后的数据正文的长度,单位是字节。在IPv6网络中,由于MTU(最大传输单元)的限制,有时需要对大报文进行分片处理。在这种情况下,Payload Length字段的值会相应地发生变化,以反映每个分片的数据长度。接收端在接收到这些分片后,会根据Payload Length字段的值以及分片标志和偏移量等信息,对分片进行重组,以恢复出原始的IPv6报文。
-
Next header 下一个首部:占 8 bit (48~55),其值的范围为 0 ~ 255。作用:
- 支持多种协议和扩展头:该字段的值可以是预定义的协议号,如ICMPv6(58)、TCP(6)、UDP(17)等,也可以是特定的值来指示IPv6扩展头,如0表示IPv6 Hop-by-Hop Option扩展头,43表示IPv6路由扩展头,59表示没有下一个头部(No Next Header)。
- ICMPv6(58):用于IPv6网络的控制消息,如错误报告、网络诊断等。
- TCP(6):传输控制协议,提供面向连接的、可靠的字节流服务。
- UDP(17):用户数据报协议,提供无连接的、不可靠的报文传输服务。
- 指示下一个头部类型:Next Header字段用于指示IPv6数据报头部中下一个扩展头或负载的类型。
- 0:表示接下来的头部是IPv6扩展头。IPv6扩展头是一种可选的头部,用于提供额外的功能和选项。
- 59:表示该数据报没有下一个头部,即数据报头部已经结束,没有再跟随其他头部。这在某些情况下非常有用,特别是在数据报的最后一个头部时。
- 应用:
- 数据报解析:接收端根据Next Header字段的值来解析和处理接下来的数据报头部或负载。
- 网络通信:在网络通信过程中,Next Header字段确保了数据报能够按照正确的协议和扩展头进行处理,从而保证了数据的可靠传输。
- 支持多种协议和扩展头:该字段的值可以是预定义的协议号,如ICMPv6(58)、TCP(6)、UDP(17)等,也可以是特定的值来指示IPv6扩展头,如0表示IPv6 Hop-by-Hop Option扩展头,43表示IPv6路由扩展头,59表示没有下一个头部(No Next Header)。
-
Hop limit 跳限制:占 8 bit (56 ~ 63),Hop Limit字段定义了IPv6数据包在网络中可以经过的最大路由器数量(即跳数)。每经过一个路由器,该字段的值就会减1。当该字段的值减少到0时,数据包将被丢弃,并且路由器可能会向源节点发送一个ICMPv6 "Time Exceeded"错误消息。通过限制数据包在网络中的跳数,Hop Limit字段有助于防止数据包因无限循环而耗尽网络资源。在IPv6网络中,默认情况下,许多设备和系统会将Hop Limit字段的初始值设置为64。这意味着,除非在传输过程中被修改,否则数据包在经过64个路由器后将被丢弃。在网络设备(如路由器和交换机)上,管理员可以通过特定的配置命令来管理IPv6数据包的Hop Limit值。这包括设置初始的Hop Limit值、修改现有值以及在特定情况下重置为默认值等。在设计IPv6网络时,管理员需要根据网络规模和拓扑结构来合理设置Hop Limit值,以确保数据包能够在预期的时间内到达目的地,同时避免不必要的资源消耗。在网络出现故障时,Hop Limit字段的值可以作为排查问题的一个线索。如果数据包在到达目标之前就被丢弃,并且Hop Limit值已经耗尽,那么可能是由于网络中的某些设备配置不当或存在环路等问题。
-
Source address 源地址:占 128 bit,16 字节。
-
Destination address 目的地址。
分片 / 重新组装:
IPv6 不允许在路由器上进行分片和重新组装,因为这些操作会消耗运行时间,影响网络的整体传输效率。当路由器收到的 IPv6 数据报太大而不能转发时,会丢弃该数据报,并给发送方返回一个 “分组太大” 的 ICMPv6 差错报文,于是发送方会使用较小的 IP 数据报重新发送。(将分片与组装放在发送发和接收方的端系统中,减少中间路由器的运行负担)。
舍弃首部校验和:
在运输层(TCP / UDP)和数据链路层 中都执行了检验操作,这使得 IP (网络层)的首部校验和字段实在有些多余,所以 IP 设计者舍弃了 IPv4 中的首部校验和字段,进一步减轻了 路由器 的负担。IPv4 中每台路由器都会计算首部校验和,舍弃它,会整体提升网络的性能。
IPv6 编址
前文已经提到 IPv6 的地址长度为 128 bit (16字节),IPv6 的表示方法为:使用十六进制表示,每隔两个字节使用 英文冒号 :
划分一个字段。连续的零字段可以使用双冒号(::)进行简化表示,但整个地址中只能出现一次双冒号。如果出现了两个连续的0字段,那么双冒号只能代替较长的那个字段。每个字段的前导0可以省略。
例如:
标准写法 2001:0db8:3902:00c2:0000:0000:0000:fe04
,
可以简写为:2001:db8:3902:c2::fe04
。
出现了两个连续的 0字段:2001:0000:0000:00c2:0000:0000:0000:fe04
,双冒号代替较长的。
可以简写为:2001:0:0:c2::fe04
。
IPv6 地址分类
IPv6地址分为多种类型,以满足不同的网络需求:
- 单播地址(Unicast Address):
- 标识一个网络接口。
- 目的地址为单播地址的报文会被送到被标识的接口。
- 包括可聚合全球单播地址、链路本地单播地址和站点本地单播地址(已废弃,被全球单播地址取代)。
- 组播地址(Multicast Address):
- 标识一组接口。
- 目的地址为组播地址的报文会被送到被标识的所有接口。
- 用于将报文同时传输到多个目的地,例如网络中的广播消息。
- 任播地址(Anycast Address):
- 标识一组网络接口,但目标为一个任播地址的报文只会被送到最近的一个被标识接口。
- 最近节点是由路由协议来定义的。
- 类似于DNS中的轮询解析,但更加灵活和高效。
- 未指定地址(Unspecified Address):
- 表示没有地址,用于初始化阶段。
- 格式为0:0:0:0:0:0:0:0/128或::/128。
- 环回地址(Loopback Address):
- 用于设备给自己发送报文。
- 格式为0:0:0:0:0:0:0:1/128或::1/128。
IPv6 地址段详细说明
CIDR地址块 | 起始地址 | 结束地址 | 地址数量 | 用途 | 目的 |
---|---|---|---|---|---|
::/128 | :: | :: | 1 | 软件 | 未指定地址 |
::1/128 | ::1 | ::1 | 1 | 主机 | 回环地址—一个将所有流量循环回其自身的虚拟接口,即本机 |
::ffff:0:0/96 | ::ffff:0.0.0.0 或 ::ffff:0:0 | ::ffff:255.255.255.255 | 232 | 软件 | IPv4映射地址 |
::ffff:0:0:0/96 | ::ffff:0:0.0.0.0 或 ::ffff:0:0:0 | ::ffff:0:255.255.255.255 | 232 | 软件 | IPv4转换地址 |
64:ff9b::/96 | 64:ff9b::0.0.0.0 或 64:ff9b::0:0 | 64:ff9b::255.255.255.255 | 232 | 全球互联网 | IPv4/IPv6转换 |
64:ff9b:1::/48 | 64:ff9b:1:: | 64:ff9b:1:ffff:ffff:ffff:ffff:ffff | 280,每个IPv4有248个 | 私有互联网 | IPv4/IPv6转换 |
100::/64 | 100:: | 100::ffff:ffff:ffff:ffff | 264 | 路由 | 丢弃前缀 |
2001::/32 | 2001:: | 2001:0:ffff:ffff:ffff:ffff:ffff:ffff | 296 | 全球互联网 | Teredo隧道 |
2001:20::/28 | 2001:20:: | 2001:2f:ffff:ffff:ffff:ffff:ffff:ffff | 2100 | 软件 | ORCHIDv2 |
2001:db8::/32 | 2001:db8:: | 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff | 296 | 文档 | 在文档和示例源代码中使用的地址 |
2002::/16 | 2002:: | 2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff | 2112 | 全球互联网 | 6to4寻址方案(已弃用) |
3fff::/20 | 3fff:: | 3fff:fff:ffff:ffff:ffff:ffff:ffff:ffff | 2108 | 文档 | 在文档和示例源代码中使用的地址 |
5f00::/16 | 5f00:: | 5f00:ffff:ffff:ffff:ffff:ffff:ffff:ffff | 2112 | 路由 | IPv6段路由(SRv6) |
fc00::/7 | fc00:: | fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | 2121 | 私有互联网 | 唯一本地地址 |
fe80::/64 from fe80::/10 | fe80:: | fe80::ffff:ffff:ffff:ffff | 264 | 链路 | 链路本地地址 |
ff00::/8 | ff00:: | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | 2120 | 全球互联网 | 组播地址 |
从 IPv4 到 IPv6
- 转换机制
- DNS64和NAT64:
- DNS64:DNS64是一种将IPv6地址和IPv4地址兼容的DNS服务。当IPv6客户端尝试访问仅支持IPv4的服务器时,DNS64服务器会合成一个伪造的AAAA记录(IPv6地址记录),这个记录包含了特定的前缀(如64:ff9b::/96)和实际的IPv4地址信息。这样,IPv6客户端就能够通过这个伪造的IPv6地址访问IPv4服务器。
- NAT64:NAT64路由器负责将IPv6报文转换为IPv4报文,以便在IPv4网络中传输。当NAT64路由器识别到伪造的IPv6地址时,它会提取出其中的IPv4地址部分,并将其转换为真实的IPv4报文,然后发送到目标IPv4服务器。响应报文在返回时,也会经过NAT64路由器的转换,从IPv4报文转换回IPv6报文,再发送给IPv6客户端。
- DNS64和NAT64:
- 隧道技术
- 隧道技术是实现IPv6在IPv4网络上传输的一种常用方法。其中,6to4隧道是一种典型的隧道技术:
- 6to4隧道:每个IPv6节点使用其IPv4地址(公共IPv4地址)生成一个6to4地址。6to4地址的前缀为2002::/16,IPv4地址嵌入在地址的后部分。当IPv6报文需要穿越IPv4网络时,它会被封装在IPv4报文中进行传输。接收方在收到封装后的IPv4报文后,会将其解封装,提取出原始的IPv6报文。
- 隧道技术是实现IPv6在IPv4网络上传输的一种常用方法。其中,6to4隧道是一种典型的隧道技术:
- 兼容地址
- IPv6还设计了一些特殊的地址格式来兼容IPv4地址:
- IPv4兼容地址:通过在IPv4地址前加上96位的0前缀(通常表示为两个冒号::),并将IPv4的点分十进制记法转换为IPv6格式,可以形成IPv4兼容地址。这种地址格式允许IPv6网络中的设备识别并处理IPv4地址。
- IPv6还设计了一些特殊的地址格式来兼容IPv4地址:
- 双栈技术
- 双栈技术是实现IPv4和IPv6互通的最直接方式。网络中的节点同时支持IPv4和IPv6协议栈,源节点根据目的节点的不同选用不同的协议栈进行通信。这种方式虽然部署成本高,但能够确保IPv4和IPv6之间的无缝互通。
IPv6 正在不断地完善和发展中,全球正在积极部署 IPv6。(2024)
关注微信公众号: