DHCP 协议基础:四步握手与 PXE 特殊选项

DHCP,说白了就是给设备发「身份证」和「门牌号」的协议。但在 PXE 网络启动里,它干的活远不止分个 IP 那么简单。今天我们就把它拆开来看。

2.1 四步握手:Discover / Offer / Request / Ack

标准的 DHCP 交互,就是四个报文来回。我习惯叫它「DORA」—— Discover、Offer、Request、Ack。你想想看,这名字多好记。

核心流程:客户端广播找服务器 → 服务器回应 → 客户端确认 → 服务器最终确认。

DHCP 四步握手流程图 DHCP 客户端 DHCP 服务器 ① DHCP Discover(广播) ② DHCP Offer(单播/广播) ③ DHCP Request(广播) ④ DHCP Ack(单播/广播) 注意:PXE 环境中,Offer 和 Ack 通常包含 Option 60/66/67 客户端通过 Option 60 标识自己为 PXE 客户端

这四步看起来简单,但每个报文里都藏着玄机。我一个个说。

① DHCP Discover

客户端刚启动,没有 IP,也不知道 DHCP 服务器在哪。它只能发广播——目标 IP 是 255.255.255.255,源 IP 是 0.0.0.0。这个报文里,客户端会带上自己的 MAC 地址,以及它想要的选项。

我的经验:在 PXE 环境里,Discover 报文必须包含 Option 60(Vendor Class Identifier),值为 "PXEClient"。否则服务器可能不把它当 PXE 客户端处理。我曾经遇到过一台老网卡,固件里没写这个选项,折腾了半天才发现。

② DHCP Offer

服务器收到 Discover 后,会从地址池里挑一个 IP,连同子网掩码、网关、DNS 等信息,打包成 Offer 发回去。注意,Offer 可以是单播,也可以是广播,取决于客户端的设置。

在 PXE 场景下,Offer 里最关键的是三个选项:

  • Option 60:服务器确认客户端是 PXE 客户端
  • Option 66:TFTP 服务器地址
  • Option 67:启动文件名(如 pxelinux.0)

③ DHCP Request

客户端可能收到多个 Offer(如果网络里有多个 DHCP 服务器)。它会选一个,然后广播 Request,告诉所有服务器:「我选了某某服务器给的 IP,其他的请收回。」

这里有个细节——Request 也是广播。为什么?因为客户端还没正式拿到 IP,其他服务器需要知道它拒绝了谁的 Offer。

④ DHCP Ack

被选中的服务器收到 Request 后,发回 Ack 确认。这时客户端才真正拿到 IP 租约。在 PXE 环境里,Ack 里同样会携带 Option 66 和 67,告诉客户端去哪下载启动文件。

注意:如果服务器发的是 Nak(拒绝),那客户端就得从头再来。我见过有些网络里因为 IP 地址池满了,客户端反复 Discover 就是拿不到 IP,最后 PXE 启动超时。排查时记得先看 DHCP 地址池余量。

2.2 Option 60/66/67 在 PXE 中的特殊作用

这三个选项,是 PXE 启动的「灵魂」。没有它们,客户端就算拿到 IP 也不知道下一步该干嘛。

选项编号 选项名称 在 PXE 中的作用 典型值
60 Vendor Class Identifier 标识客户端为 PXE 客户端,触发服务器下发启动参数 "PXEClient"
66 TFTP Server Name 指定 TFTP 服务器的 IP 地址或主机名 192.168.1.100 或 tftp.example.com
67 Bootfile Name 指定要下载的启动文件名 pxelinux.0 或 bootmgr.exe

Option 60:身份标识

客户端在 Discover 里带上 Option 60,值固定为 "PXEClient"。服务器看到这个值,就知道:「哦,这是个要网络启动的家伙。」然后服务器会在 Offer 和 Ack 里带上 Option 66 和 67。

如果没有 Option 60,服务器会把它当普通 DHCP 客户端处理,只给 IP 和基本网络参数,不给启动信息。那客户端拿到 IP 后,就卡住了——它不知道去哪下载启动文件。

关键点:Option 60 是 PXE 启动的「开关」。服务器端通常配置为:如果收到 Option 60 = "PXEClient",则下发 Option 66 和 67;否则只给普通 IP 参数。

Option 66:TFTP 服务器地址

这个选项告诉客户端:「你的启动文件放在这个服务器上。」值可以是 IP 地址,也可以是主机名。如果是主机名,客户端需要能解析 DNS——这在早期 PXE 阶段往往不现实,所以我建议直接用 IP 地址。

我曾经在一个项目里,客户把 Option 66 配成了主机名,但 DHCP 服务器没给 DNS 选项,结果客户端解析不了,启动失败。排查了俩小时才发现是这个问题。

Option 67:启动文件名

这个选项指定了客户端要下载的具体文件。常见的启动文件有:

  • pxelinux.0:Syslinux 的 PXE 引导文件,Linux 环境常用
  • bootmgr.exe:Windows 的启动管理器
  • undionly.kpxe:iPXE 的链式加载文件

注意,文件名是大小写敏感的。我见过有人把 "pxelinux.0" 写成了 "Pxelinux.0",结果 TFTP 服务器找不到文件,客户端一直报 "File not found"。

2.3 实际配置示例

下面是一个 ISC DHCP 服务器的配置片段,展示了如何为 PXE 客户端设置 Option 60/66/67:

# /etc/dhcp/dhcpd.conf 片段
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.100 192.168.1.200;
  option routers 192.168.1.1;
  option domain-name-servers 192.168.1.1;

  # 匹配 PXE 客户端
  class "pxe-clients" {
    match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
    option tftp-server-name "192.168.1.10";
    option bootfile-name "pxelinux.0";
  }
}

这段配置的意思是:如果客户端发来的 Option 60 以 "PXEClient" 开头,就给它分配 IP,并告诉它 TFTP 服务器是 192.168.1.10,启动文件是 pxelinux.0。

我的建议:在生产环境里,最好把 TFTP 服务器和 DHCP 服务器分开部署。DHCP 只负责分 IP 和下发启动参数,TFTP 只负责传文件。这样排查问题时,责任边界清晰。

2.4 常见问题与避坑

  • 客户端拿不到 IP:检查 DHCP 服务器地址池是否耗尽,或者客户端与服务器之间是否有 VLAN 隔离。
  • 拿到 IP 但下载不了启动文件:先 ping 一下 TFTP 服务器,再检查 Option 66 的地址是否正确。我遇到过有人把 IP 写反了。
  • 文件下载到一半卡住:TFTP 是基于 UDP 的,大文件传输容易丢包。建议用 tftp-hpa 这类支持 blksize 选项的服务器,把块大小调到 1468 字节。
  • Option 60 不匹配:有些客户端固件发的 Option 60 不是标准的 "PXEClient",可能是 "PXEClient:Arch:00000" 之类的变体。配置时用 substring 匹配前 9 个字符比较稳妥。

嗯,DHCP 这部分就讲到这里。四步握手是基础,Option 60/66/67 是 PXE 的钥匙。理解了这些,后面讲 TFTP 和引导文件加载时,你就知道它们是怎么串起来的了。