【Linux 网络基础】Linux 平台 DHCP 运作原理与握手过程详解

Linux 平台 DHCP 运作原理与握手过程详解

概述

  • DHCP(Dynamic Host Configuration Protocol)在以太网广播域内为主机自动分配 IPv4 地址及网络参数(子网掩码、默认网关、DNS 等)。
  • 客户端使用 UDP 68 端口,服务器使用 UDP 67 端口;初次阶段客户端常以源地址 0.0.0.0 向广播地址 255.255.255.255 发送报文。
  • Linux 上的 DHCP 客户端为用户态进程(如 dhclient, udhcpc, dhcpcd, systemd-networkd),通过套接字与内核网络栈交互,并最终使用 netlink/ioctl 配置 IP 地址和路由。

基础概念

  • 广播域:DHCP 依赖二层广播,跨网段时需要中继(Relay Agent)。
  • 关键字段:chaddr(客户端 MAC)、ciaddr(客户端当前 IP)、yiaddr(服务器分配的 IP)、giaddr(中继地址)、xid(事务 ID)。
  • 重要选项:
    • 53(消息类型)
    • 50(请求的 IP 地址)
    • 54(服务器标识)
    • 51(租约时长)
    • 1/3/6(子网掩码/默认网关/DNS)
    • 15(域名)
    • 121(无类静态路由)
    • 82(中继代理信息,交换机/中继用于安全审计与策略)

报文与端口

  • 客户端端口:UDP/68;服务器端口:UDP/67
  • 初次阶段无 IP 时:客户端以 0.0.0.0:68255.255.255.255:67 广播发送;服务器响应通常广播回客户端,或在具备条件时单播。
  • 续租阶段客户端已有地址:可能单播 REQUEST 到服务器的 UDP/67(更高效且更少广播)。

标准四步握手(DORA)

  • Discover:客户端广播 DHCPDISCOVER,表明需要地址与参数。
  • Offer:一个或多个服务器广播/单播 DHCPOFFER,给出候选 yiaddr 与参数集合;包含 Server Identifier(54)
  • Request:客户端选择其一后广播 DHCPREQUEST,指明目标服务器(选项 54)与请求 IP(选项 50);同时向其他服务器隐式拒绝。
  • Ack:目标服务器返回 DHCPACK,确认分配并给出完整参数与租约时间(选项 51);若拒绝则返回 DHCPNAK

续租与重绑定(T1/T2)

  • 租约时间由服务器设定(选项 51)。客户端维护两个阈值:
    • T1:通常为租约的 50%。到达后客户端单播 REQUEST 给原服务器续租。
    • T2:通常为租约的 87.5%。若 T1 阶段失败,T2 阶段客户端广播 REQUEST,尝试与任意可用服务器重绑定。
  • 若直到租约到期仍续租失败,客户端应释放地址并回到 Discover 阶段。

地址冲突检测与 ARP 行为

  • 一些客户端在获取 DHCPACK 后会进行 ARP Probe(如 arping -D)以检测地址是否被占用;若冲突,发送 DHCPDECLINE 给服务器并重新 Discover。
  • 成功配置后可能发送 Gratuitous ARP 通告自身地址,便于邻居缓存更新与冲突快速暴露。

Linux 平台常见实现

  • dhclient(ISC):传统、功能全面,广泛用于发行版;可通过钩子脚本执行路由/DNS 更新。
  • udhcpc(BusyBox):面向嵌入式(如 Ingenic 平台),体积小、启动快;通过 /usr/share/udhcpc/default.script 等脚本配置网络。
  • dhcpcd:集成度高,支持多特性与自动化配置。
  • systemd-networkd:在 *.network 中设置 DHCP=yes 即可自动完成握手与应用网络参数。
  • NetworkManager:桌面/服务器常用,统一管理 Wi‑Fi/以太网并调用后端 DHCP 客户端。

握手时序细节(初次获取)

  • 客户端创建 UDP 套接字并设置 SO_BROADCAST,绑定 0.0.0.0:68
  • 发送 DHCPDISCOVER(L2 广播 MAC ff:ff:ff:ff:ff:ff;L3 广播 255.255.255.255)。
  • 服务器接收后选择可用地址,检查租约池/冲突/策略(VLAN、snooping、ACL),生成 DHCPOFFER
  • 客户端可能收到多个 Offer,依据策略(服务器延迟、参数完整性、策略权重)选择一个,随后广播 DHCPREQUEST 指定服务器(选项 54)。
  • 服务器确认并返回 DHCPACK,含租约时间与参数。若发现冲突/策略不符则 DHCPNAK
  • 客户端应用配置(通过 netlink 设置 ip addr addip route add 等),更新 DNS(/etc/resolv.conf 或 resolvconf/systemd‑resolved),触发 ARP 通告。

续租与重绑定细节

  • T1 阶段:单播 REQUEST 给原服务器(ciaddr 为当前地址,Server Identifier 指向原服务器);成功则延长租约。
  • T2 阶段:若原服务器不可达,广播 REQUEST,任何服务器都可 ACK 续租或重新分配。
  • 失败与回退:若 NAK 或超时,客户端释放地址并回到 Discover;某些实现会暂时保留旧配置以避免瞬断。

中继与跨网段(Relay Agent)

  • 二层广播无法跨三层边界,需 DHCP 中继(例如 dhcrelay)。
  • 中继在接收客户端广播后将报文封装并转发到服务器,同时填充 giaddr 与可选的 Option 82。服务器据此返回响应给中继,再由中继转发回客户端。

多场景行为

  • 多网卡:每个接口独立握手与租约;避免同一 MAC 在不同 VLAN 产生冲突。
  • VLAN/Bridge:在桥接或 VLAN 接口上进行 DHCP;确保过滤策略(ebtables/交换机 ACL)允许 67/68 端口流量。
  • 虚拟化/容器:容器通常由宿主网络栈分配地址(如 Docker 使用桥接+NAT),容器内部一般不直接运行 DHCP 客户端;但在特定 CNI 或裸容器场景可启用。

安全与网络设备特性

  • DHCP Snooping:交换机记录可信端口与租约绑定,防止伪造服务器与地址欺骗。
  • Option 82:中继/交换机插入接入信息(端口/VLAN),服务器依据此进行精细策略。
  • 过滤与隔离:iptables/nftables/ebtables 需允许 UDP/67UDP/68;不当过滤会导致"无法获取地址"。

调试与排错

  • 抓包:tcpdump -i eth0 -vvv -n port 67 or port 68
  • 交互日志:
    • dhclient -v eth0 查看详细过程
    • journalctl -u systemd-networkdnmcli device show 观察状态
  • 常见问题:
    • 交换机未放通广播或 DHCP Snooping 策略错误→检查接入策略与可信端口。
    • 防火墙阻断 67/68→调整 iptables/nftables 规则。
    • 中继配置错误(giaddr/Option82)→检查中继路由与服务器策略。
    • 多服务器竞争→客户端应选择一个并在 Request 中明确 Server Identifier。

常见 DHCP 消息类型

  • DHCPDISCOVER:发现
  • DHCPOFFER:提供
  • DHCPREQUEST:请求/续租/重绑定
  • DHCPACK:确认
  • DHCPNAK:否认
  • DHCPDECLINE:地址冲突声明
  • DHCPRELEASE:主动释放
  • DHCPINFORM:客户端已有地址,需要仅获取参数(无分配)

实践建议(Linux)

  • 嵌入式/精简系统:优先使用 udhcpc 并定制脚本以最小化启动时延与依赖。
  • 服务器/桌面:使用 systemd-networkd 或 NetworkManager,统一管理并与策略/防火墙集成。
  • 配置文件示例(systemd-networkd):
    • /etc/systemd/network/10-eth0.network 中设置:DHCP=yes,可选 UseDomains=trueRouteMetric= 控制路由优先级。

快速命令参考

  • 启动客户端:sudo dhclient -v eth0
  • BusyBox 客户端:sudo udhcpc -i eth0 -f -v
  • 抓包:sudo tcpdump -i eth0 -vvv -n port 67 or port 68
  • 冲突检测:sudo arping -D -I eth0 <ip>

总结

  • DHCP 在 Linux 上通过用户态客户端配合内核网络栈,基于 UDP 广播完成 DORA 四步握手,并在租约周期内进行 T1/T2 续租与重绑定。
  • 正确的交换机/中继配置、主机防火墙策略与客户端实现选择,是确保可靠地址分配与网络可用性的关键。
相关推荐
Mu.3871 小时前
计算机网络模型
网络·网络协议·计算机网络·安全·http·https
s***4532 小时前
Linux 下安装 Golang环境
linux·运维·golang
xixixi777773 小时前
解析一下传输安全——“它是什么”,更是关于“它为何存在”、“如何实现”以及“面临何种挑战与未来”
网络·安全·通信
J***51684 小时前
Linux安装Redis以及Redis三种启动方式
linux·redis·bootstrap
4***17544 小时前
Linux 下安装 Golang环境
linux·运维·golang
Lenyiin4 小时前
《 Linux 修炼全景指南: 七 》 指尖下的利刃:深入理解 Vim 的高效世界
linux·运维·服务器·vim·lenyiin
jerryinwuhan5 小时前
socket由浅入深
网络
sulikey6 小时前
Linux基础指令与权限管理深度解析:从入门到精通
linux·运维·服务器·ubuntu·centos·linux命令·linux权限
s***46987 小时前
linux 设置tomcat开机启动
linux·运维·tomcat