《TCP/IP 详解 卷1:协议》第6章:DHCP和自动配置
DHCP
DHCP的设计基于一种早期协议——称为Internet引导程序协议(BOOTP)[RFC0951][RFC1542],它目前已过时。BOOTP为客户提供有限的配置信息,并且没有提供一种机制来支持改变已提供的信息。DHCP使用租用的概念来扩展BOOTP模型[GC89],并且可提供主机操作所需的所有信息。租用允许客户机使用一个商定的时间来配置信息。
地址池和租用
在动态分配中,DHCP 客户机请求分配一个 IP 地址。服务器从可用的地址池中选择一个地址作为响应。通常,这个地址池是专门为 DHCP 分配的一段连续 IP 地址范围。
分配给客户机的地址在一定时间内有效,这段时间称为租用期(Lease Time)。客户机可以在租用期内使用该地址,并可在期满前申请续约。
租用期是 DHCP 服务器的重要配置参数,长度可以从几分钟到几天不等,甚至可以设置为“无限”(不推荐,除非在非常简单的网络中)。
长租用期:地址稳定、续约频率低,网络负载小,但地址池可能更快耗尽。
短租用期:地址回收快,资源利用率高,但增加续租请求的频率和网络负载。
常见租用期设置:
- 默认值通常为 12~24 小时
- 微软建议:小型网络:8 天,大型网络:16~24 天
客户机在租用期过半时会开始尝试续订。
在发送请求时,客户机会提供如主机名、所需租用期、曾使用的地址副本、MAC 地址等信息。服务器结合这些信息以及接收请求的接口和当前时间等,决定分配的地址及配置内容,并将租用信息保存在持久性存储中,如非易失性内存或磁盘,以保证服务器重启后租约依然有效。
DHCP和BOOTP格式
DHCP 扩展了早期的 BOOTP 协议,并保持向后兼容性,使 BOOTP 客户端能够在没有 DHCP 服务器的网络中继续使用现有的 BOOTP 服务。
整个消息格式包括如下主要字段:
Op
:操作字段,标识消息类型,1 表示请求,2 表示应答;htype
和hlen
:分别表示硬件类型(如以太网为1)和硬件地址长度(以太网为6);hops
:跳数字段,初始由客户端设置为0,每经过一个中继代理就加1;xid
(事务 ID):客户端生成的随机数,用于将应答与请求匹配;secs
:客户端启动以来的时间(秒);flags
:16 位标志字段,目前定义了广播标志位,指示客户端是否希望服务器使用广播方式回复;ciaddr
:客户端 IP 地址(如果已知);yiaddr
:“你的” IP 地址,由服务器提供;siaddr
:下一服务器的 IP 地址,通常用于引导或文件下载;giaddr
:中继代理的 IP 地址;chaddr
:客户端硬件地址(通常是 MAC 地址),用于标识客户端;sname
和file
:服务器名称和引导文件名称,可选字段,分别为 64 字节和 128 字节;options
:可变长度的选项字段,用于扩展 DHCP 功能,也是 DHCP 与 BOOTP 的主要区别。
BOOTP 的原始格式由多个 RFC(如 RFC 951、RFC 1542 和 RFC 2131)定义,DHCP 在其基础上增加了选项字段,使协议具备更大的灵活性。选项字段用于承载如租用时间、服务器标识、请求参数列表等关键信息,也是区分 DHCP 消息与传统 BOOTP 消息的主要方式。
DHCP和BOOTP选项
由于 DHCP 是对 BOOTP 的扩展,原有 BOOTP 消息格式中缺少的一些字段功能通过“选项”机制实现。DHCP 选项采用标准格式,每个选项以一个 8 位的标签(Option Type)开始,紧接着可能是长度字节和实际值字节。简单选项直接使用固定字节长度的值,而可变长度选项使用一个长度字段指明后续选项值的字节数。
目前广泛支持的 DHCP/BOOTP 选项由 [RFC2132] 定义,常用选项包括:
0
填充(Pad)1
子网掩码3
路由器地址6
域名服务器(DNS)15
域名50
请求的 IP 地址51
地址租用期52
选项超载53
DHCP 消息类型(必需)54
DHCP 服务器标识符55
参数请求列表56
DHCP 错误消息58
租约更新时间(renewal)59
重新绑定时间(rebinding)61
客户机标识符119
域搜索列表255
结束选项
其中,DHCP 消息类型(选项53) 是关键字段,用于标识 DHCP 消息的具体类型。其取值包括:
1
DHCPDISCOVER:发现服务器2
DHCPOFFER:服务器提供配置3
DHCPREQUEST:客户端请求配置4
DHCPDECLINE:拒绝配置5
DHCPACK:确认配置6
DHCPNAK:拒绝确认7
DHCPRELEASE:释放租用8
DHCPINFORM:请求附加信息9
DHCPFORCERENEW(RFC3203)10~13
:如 DHCPLEASEQUERY、DHCPLEASEUNASSIGNED 等,由 RFC4388 定义
这些选项通常存放在消息尾部的 options
字段中,但在空间不足的情况下也可以放置在 sname
(服务器名称)和 file
(引导文件名)字段中,这种情况称为选项超载,必须借助 选项 52(Option Overload) 来标明实际载荷字段位置。
对于超过 255 字节的数据,[RFC3396] 提出了长选项机制:同一选项可重复出现,接收方需按顺序拼接内容作为一个整体选项进行处理。特别地,若涉及选项超载,解析顺序为:options 字段 → 引导文件名字段 → 服务器名字段(从后向前)。
选项机制的应用范围非常广泛,不仅能传递基本 TCP/IP 配置信息,还支持多个扩展协议。常见的扩展选项包括:
- NetWare 简单配置(RFC2241, RFC2242)
- 用户类标识(RFC3004)
- 完全限定域名 FQDN(RFC4702)
- iSNS 存储服务(RFC4174)
- 广播和组播服务控制器 BCMCS(RFC4280)
- 时区配置(RFC4833)
- 自动配置(RFC2563)
- 子网选择(RFC3011)
- 域名服务选择(RFC2937)
- 网络接入认证(PANA)服务器(RFC5192)
DHCP协议操作
DHCP 消息是带有一组特殊选项的 BOOTP 消息。其基础结构和 BOOTP 一致,但在操作上引入了更多动态配置机制。当一台新客户机连接到网络时,它通过以下过程完成 IP 地址分配和配置参数获取:
- 客户机首先发现网络中的可用 DHCP 服务器及其提供的地址;
- 客户机选择某台服务器及其提供的 IP 地址,并发出请求;
- 若服务器仍保留该地址,将通过确认分配此地址给客户机。
消息结构与发送行为
- 客户机发送的请求中,
op
字段被设置为BOOTREQUEST
; options
字段的前 4 字节为魔术 Cookie 值:99 130 83 99
(来自 RFC2132);- 使用 UDP/IP 数据报封装:
- 源地址:
0.0.0.0:68
- 目标地址:
255.255.255.255:67
- 源地址:
- 服务器响应:
- 源地址:服务器 IP 和端口 67
- 目标地址:客户端广播地址和端口 68
DHCP 消息交换过程
-
DHCPDISCOVER(发现)
客户机通过广播 DHCPDISCOVER 消息查找服务器。 -
DHCPOFFER(提供)
每个接收到请求的服务器(包括中继)响应 DHCPOFFER 消息,提供:- IP 地址(在 yiaddr 字段中)
- 子网掩码、DNS 等配置参数(作为选项提供)
- 地址租用时间 T
- 更新时间 T1(默认 T/2)
- 重新绑定时间 T2(默认 7T/8)
-
DHCPREQUEST(请求)
客户机选择某个服务器发来的 DHCPOFFER,并广播一个包含:- 请求的 IP 地址(Option 50)
- 服务器标识符(Option 54)
的 DHCPREQUEST 消息。
-
DHCPACK 或 DHCPNAK
- 被选中的服务器发送 DHCPACK 表示成功分配;
- 若地址不可用(被抢占或配置冲突),则服务器发送 DHCPNAK 拒绝请求;
- 其他服务器清除该客户机相关状态。
地址冲突检测与释放
- 客户机收到 DHCPACK 后,通常会通过 ARP 探测新地址是否被占用(ACD);
- 如果检测到地址冲突,发送 DHCPDECLINE 消息给服务器;
- 客户机等待默认的 10 秒后可重试;
- 如果在租约未过期前释放地址,发送 DHCPRELEASE 消息。
已有地址的情况
- 续租:客户机直接发送 DHCPREQUEST 请求当前地址,服务器回应 DHCPACK 或 DHCPNAK;
- 仅请求额外信息:使用 DHCPINFORM 消息,表示地址已存在但需要其他配置参数(例如 DNS、NTP 等),服务器回应 DHCPACK 提供附加信息。
DHCP状态机
DHCP 协议在客户机和服务器中运行一个状态机,用于指示下一步应处理的消息类型。状态机的转换由消息的发送、接收或定时器超时触发。
客户机的状态机从 INIT
(初始)状态开始,此时客户机尚未获得任何网络配置。状态机的主要流程如下:
- INIT:客户机没有任何信息,广播发送 DHCPDISCOVER 消息。
- SELECTING:接收来自多个服务器的 DHCPOFFER 消息,等待选择合适的服务器和 IP 地址。
- REQUESTING:客户机决定使用某个 DHCPOFFER 后,发送包含服务器标识符的 DHCPREQUEST 消息。
- 若收到 DHCPACK,进入 BOUND 状态;
- 若收到 DHCPNAK,返回 INIT 状态;
- 若收到不需要的地址的 DHCPACK,发送 DHCPDECLINE 并返回 INIT 状态。
- BOUND:客户机已获得有效 IP 地址和配置,可正常通信。此状态下,地址有效期受到租约时间 T 的限制。
- 在 BOUND 状态下:
- 当租约的一半时间(T1)到期,客户机进入 RENEWING 状态,尝试与原服务器更新租约;
- 若收到 DHCPACK,成功更新,返回 BOUND;
- 若失败,等待 T2。
- 当 T2 到期,客户机进入 REBINDING 状态,尝试与任意服务器重新获得地址;
- 若仍失败,租约到期,客户机释放地址,返回 INIT 或断开网络连接。
- 当租约的一半时间(T1)到期,客户机进入 RENEWING 状态,尝试与原服务器更新租约;
DHCPv6
随着 IPv6 的引入,原有的基于 IPv4 的 DHCP 协议已无法满足需求,因此定义了新的 DHCPv6 协议(详见 [RFC8415])。DHCPv6 的设计目标是为 IPv6 网络提供动态地址分配和其他配置参数的传输。
- 地址分配方式:
- 支持 无状态 和 有状态 两种配置方式:
- 无状态(Stateless):仅分发其他配置信息(如 DNS),不分发地址。
- 有状态(Stateful):与 DHCPv4 类似,负责地址分配和管理。
- 与 IPv6 的自动配置机制(SLAAC)协同工作。
- 支持 无状态 和 有状态 两种配置方式:
IPv6生命周期
IPv6地址可能会经历以下几个主要状态:
-
临时(Tentative)状态:
- 地址刚刚被生成或分配后,尚未完成重复地址检测(DAD)。
- 在该状态下,地址通常不可用于一般通信,但可以用于邻居发现(Neighbor Discovery,详见第8章)。
- 重复地址检测用于确保网络中没有其他设备使用相同地址。
-
乐观(Optimistic)状态:
- 一种改进的DAD机制 [RFC4429]。
- 在DAD未完成前允许该地址有限用途(例如,尽快响应某些延迟敏感服务)。
- 尽管地址尚未完全通过DAD验证,但它可以临时参与部分通信。
- 该地址可能同时处于乐观状态和其他如“废弃”等状态,表示在逻辑上仍未可用。
-
首选(Preferred)状态:
- 地址已完成DAD检查,可以正常用于所有通信。
- 地址处于有效使用期内,可以作为源地址或目标地址。
- 所有正常通信在此状态下进行。
-
废弃(Deprecated)状态:
- 首选地址的有效期(Preferred Lifetime)过期后进入该状态。
- 地址仍可用于已有连接(如 TCP 会话),但不可用于新连接的发起。
- 此状态用于平滑迁移,防止中断已有通信。
-
无效(Invalid)状态:
- 地址的整体有效期(Valid Lifetime)过期后,将被完全撤销。
- 此时地址不能用于任何用途,必须从接口中删除。
DHCPv6消息格式
DHCPv6 消息通过 UDP/IPv6 数据报进行封装,客户端使用端口 546,服务器使用端口 547(详细内容见第10章)。消息通常从客户端发送到 DHCPv6 服务器或中继代理,使用主机的链路本地地址作为源地址。
DHCPv6 消息格式有两种类型。一种是基本格式,适用于客户端与服务器之间的通信,结构中包含消息类型、事务 ID 和一组可扩展的选项。选项部分可用于传递分配的地址、DNS、租约时间等配置信息。
另一种是中继消息格式,适用于中继代理和服务器之间的通信。它在基本格式的基础上增加了链路地址和对等方地址字段。链路地址字段表示客户端所在链路的地址,而对等方地址字段表示中继代理接收到该消息时的源地址,即客户端的地址。
被中继的原始 DHCP 消息则封装在一个选项中。需要注意的是,中继转发可能是链式的,一个中继代理可以转发来自另一个中继代理的消息,这种机制提升了 DHCPv6 在复杂网络结构中的适应能力。
身份关联
身份关联(IA)是 DHCPv6 中客户机与服务器之间用于标识一组地址的标识符。每个请求地址的客户机接口必须至少包含一个 IA,并通过唯一的 IAID(身份关联标识符)标识。每个 IA 只能关联一个接口。
IA 包含的配置信息包括一个或多个 IPv6 地址,以及每个地址对应的租约信息:首选生命周期、有效生命周期和租期控制参数(T1 和 T2)。这些地址可以是常规地址,也可以是临时地址。临时地址通过引入随机数生成,有助于提升用户隐私,通常与常规地址同时分配,并定期更新。
当服务器为某个 IA 分配地址时,会根据链路、客户机标识(如 DUID)及其他请求选项执行策略决策,从而选择适当的地址集返回给客户端。
DHCP唯一标识符
DHCP唯一标识符(DUID)用于标识一台DHCPv6客户机或服务器,并被设计为可持续一段时间。服务器用它标识所选地址(作为IA的一部分)对应的客户机和配置信息,客户机用它标识感兴趣的服务器。DUID长度是可变的,对于大多数用途来说,客户机和服务器将它看作一个不透明的值。
协议操作
-
判断是否启用 DHCPv6:
- 客户端接收 ICMPv6 路由器通告,查看其中的 M 位和 O 位:
- M = 1:使用 DHCPv6 获取地址。
- O = 1:使用 DHCPv6 获取附加信息(如 DNS)。
- M = 0 且 O = 0:完全使用无状态地址自动配置(SLAAC)。
- 客户端接收 ICMPv6 路由器通告,查看其中的 M 位和 O 位:
-
初始化阶段:
- 客户端生成链路本地地址。
- 执行路由器发现操作,确认网络是否有路由器存在。
-
发现服务器(四消息交换):
- 客户端组播发送
DHCPSOLICIT
消息,寻找 DHCPv6 服务器。 - 一个或多个服务器响应
DHCPADVERTISE
消息,提供配置信息。 - 客户端发送
DHCPREQUEST
,选择其中一个服务器进行请求。 - 服务器回复
DHCPREPLY
,确认地址和配置信息,完成绑定。
- 客户端组播发送
-
简化流程(两消息交换):
- 如果客户端已知服务器位置,或仅需获取非地址类信息,可跳过前两步。
- 客户端直接发送
DHCPREQUEST
,服务器回复DHCPREPLY
。
-
绑定标识与管理:
- 每个地址绑定由以下三要素标识:
- DUID(客户端标识符)
- IA 类型(临时、非临时或前缀)
- IAID(身份关联标识符)
- 每个绑定可能包含多个地址租约,一个事务可处理多个绑定。
- 每个地址绑定由以下三要素标识:
DHCP中继
DHCP 中继代理的作用是将客户机的广播请求转发到远端的 DHCP 服务器,并将服务器的应答消息返回给客户端。这一机制允许网络中只部署少量中心化的 DHCP 服务器,同时服务多个子网,从而简化网络管理并提高灵活性。
网段A(含客户端) <–> 中继代理 <–> DHCP服务器 <–> 网段B。
中继代理的关键操作包括:
- 接收广播请求:如 DHCPDISCOVER(v4)或 DHCPSOLICIT(v6);
- 封装并转发为单播消息:发送到指定的 DHCP 服务器;
- 将服务器响应转回客户端:解封装并广播或单播转发给对应客户端。
在 DHCPv4 中,中继使用 giaddr
字段标识客户端所属子网;在 DHCPv6 中,中继使用 RELAY-FORW
和 RELAY-REPL
消息,并包括 link-address
和 peer-address
等字段。
DHCP认证
认证选项格式
- Code:90
- Length:认证选项总长度(不含 Code 和 Length)
- Protocol / Algorithm / RDM:指定使用的协议、认证算法和重放检测机制
- Replay Detection Field:用于检测消息重放(例如时间戳、序列号)
- Authentication Information:认证信息字段,可包括共享密钥或消息认证码(MAC)
认证方法
简单认证(协议和算法字段为 0)
- 使用一个共享的静态令牌(如密码、文本字符串)
- 客户机和服务器必须配置相同的令牌
- 缺乏强加密,易被截获,安全性较差
- 可防止误配置和偶发错误
延期认证(协议和算法字段为 1)
- 客户机在
DHCPDISCOVER
或DHCPINFORM
中加入认证选项 - 服务器在
DHCPOFFER
和DHCPACK
中返回认证信息 - 使用消息认证码(MAC)确保消息来源可信且内容完整
- 需要客户机与服务器之间预共享密钥
重放攻击检测(Replay Detection)
- 由 RDM(Replay Detection Method)字段决定
- 若 RDM 为 0,重放检测字段为单调递增值(如时间戳)
- 检测机制能阻止攻击者捕获、存储、重放旧消息
应用限制
尽管认证机制提升了安全性,但在实际应用中并不常见,原因包括:
- 客户机和服务器之间需分发和维护共享密钥,部署复杂
- 认证机制提出较晚,DHCP 已广泛部署,难以回溯修改
无状态地址自动配置
无状态地址自动配置(Stateless Address Autoconfiguration, SLAAC)允许主机无需人工干预或 DHCP 服务器就能自动配置 IP 地址,特别适用于链路本地通信。对于全球可路由地址,仍可能需要路由器协助或 DHCP 参与。
IPv4链路本地地址的动态配置
主机在没有手动配置和 DHCP 响应时,随机从地址池中选择一个地址。使用 ARP 检查该地址是否冲突(冲突则重试)。
- 标准:RFC3927
- 地址范围:
169.254.1.0
至169.254.254.255
(子网掩码255.255.0.0
)
仅在本地链路通信中有效,不能跨路由器使用。常用于简易的点对点或小型局域网环境中。
链路本地地址的IPv6 SLAAC
定义于 [RFC4862],目标是主机自动生成链路本地 IPv6 地址。可独立工作(无路由器),也可与路由器通告结合生成全球地址。可配合 DHCPv6(无状态模式)获取额外配置项
SLAAC 地址生成流程如下:
-
生成链路本地地址:地址前缀为
fe80::/10
,接口标识符来自 MAC 地址或临时生成,地址设为“临时”状态,进行重复地址检测(DAD)。 -
重复地址检测(DAD):发送 ICMPv6 邻居请求,判断地址是否被使用。收到邻居通告即判定地址冲突,放弃使用。DAD 失败时需手动配置或重新尝试地址生成。
全球地址生成(当有路由器时):路由器通告(RA)中提供前缀及标志,主机将前缀 + 接口标识符组合成全球地址,地址有效性和首选时间由通告中字段决定。
IPv6 自动配置通常不适用于需要精确地址管理的网络。链路本地地址(如 fe80::
)不可用于 Internet 通信,仅适用于局部网络、无路由器环境或简单设备初始化。
自动配置成功 ≠ 网络配置成功,DNS/路由常需另配
DHCP和DNS交互
DHCP 客户机获取 IP 地址时,通常同时获取 DNS 服务器地址。DNS 服务器用于将域名解析为 IP 地址,是访问互联网的基础,没有 DNS,用户几乎无法访问现代网络资源。
本地 DNS 可处理局域网中的专用域名映射(如 .home
),一般需手工配置,繁琐且易出错。
动态 DNS 可自动更新名称与 IP 地址的映射,DHCP/DNS 可集成于同一服务中(如 Linux dnsmasq
)。
集成式 DHCP/DNS 示例机制:
- 客户机发送
DHCPREQUEST
,包含客户端标识符或主机名 - DHCP 服务器分配 IP 并发送
DHCPACK
- 在回应前,DNS 内部数据库同步更新映射
- 后续 DNS 请求可直接解析该客户机的主机名与 IP 地址
实现自动化的主机名解析,简化局域网管理,避免手动同步主机名与 IP 地址,减少配置错误。
以太网上的PPP
PPPoE(PPP over Ethernet)用于在以太网链路上传输PPP协议,常用于宽带接入(如 DSL)。替代DHCP用于网络配置,支持身份认证、加密、压缩和IP地址协商。
PPPoE 的主要优势
- 点对点连接模型:每个用户建立独立的 PPP 会话,支持差异化配置
- 支持认证机制:例如 PAP、CHAP,可绑定用户名密码
- 可计费与审计:ISP 可追踪用户行为和使用时间
- 适用于 ISP 无需分配公网 IP、客户端仍能上网的场景(结合 NAT)
协议过程
发现阶段消息交换(PAD,PPPoE Active Discovery):
消息 | 方向 | 描述 |
---|---|---|
PADI | 客户机 → 广播 | 寻找PPPoE服务器 |
PADO | 服务器 → 客户机 | 响应请求,提供连接信息 |
PADR | 客户机 → 服务器 | 选择一个服务器,发起连接请求 |
PADS | 服务器 → 客户机 | 确认连接,分配会话ID |
PADT | 任意一方 → 对方 | 终止PPP会话 |
- 所有消息都封装在以太网帧中,使用
EtherType
0x8863(发现)或 0x8864(PPP会话) - 消息格式中包含:
- Version(通常为1)
- Type
- Code(区分消息类型)
- Session ID
- Payload:使用 TLV(Type-Length-Value)结构,类似 DHCP 选项