DHCP 服务异常怎么解决?169.254 地址与服务未开启的排查顺序
DHCP 服务异常分两类:一类是本机的 DHCP Client 服务没运行,或网卡被设成了手动地址,系统根本没去要地址;另一类是请求发出去了却没人应答,Windows 只好给自己配一个 169.254 开头的地址。先用 ipconfig /all 分清是哪一类,再按本机、网络、DHCP 服务器的顺序排查。
DHCP 服务异常怎么解决?先判断是哪一类问题:本机没去要地址,还是要了没人给。前者是电脑上的 DHCP Client 服务没有运行,或者网卡被设成了手动 IP,Windows 网络诊断会提示“DHCP 服务未开启”“未启用 DHCP”;后者是请求已经发出、网络里却没有 DHCP 服务器应答,系统拿不到地址,只好给自己配一个 169.254 开头的地址。排查顺序是:用 ipconfig /all 定性,检查 DHCP Client 服务,确认网卡为自动获取,释放并重新获取地址,排除网卡驱动和协议栈问题,最后到网络侧检查链路、VLAN、DHCP 服务器或中继,以及地址池是否用完。
先用 ipconfig /all 判断属于哪一种
以管理员身份打开命令提示符执行 ipconfig /all,找到正在使用的那块网卡:
以太网适配器 以太网:
描述. . . . . . . . . . . . . . . : Intel(R) Ethernet Connection I219-V
物理地址. . . . . . . . . . . . . : 00-1A-2B-3C-4D-5E
DHCP 已启用 . . . . . . . . . . . : 是
自动配置已启用. . . . . . . . . . : 是
自动配置 IPv4 地址 . . . . . . . : 169.254.37.112(首选)
子网掩码 . . . . . . . . . . . . : 255.255.0.0
默认网关. . . . . . . . . . . . . :
对照下表确定方向:
| 看到的情况 | 说明 | 先看哪一步 |
|---|---|---|
| “DHCP 已启用”为“是”,地址是 169.254.x.x,没有默认网关 | 请求发出去了,没收到可用的应答 | 第二步,然后第三步 |
| “DHCP 已启用”为“否” | 网卡被设成了手动地址,系统不会去要 | 第一步的网卡设置部分 |
| “媒体状态”为“媒体已断开连接” | 网线没插好、对端端口关闭或 Wi-Fi 没连上 | 先解决物理连接 |
| 地址后面显示“(重复)” | 拿到的地址和别的设备冲突 | 第三步、第四步中的地址冲突 |
| 网络诊断提示 DHCP Client 服务未运行,或服务启动失败 | 本机服务问题 | 第一步 |
169.254 开头的地址是什么意思
169.254.0.0/16 是 RFC 3927 规定的 IPv4 链路本地地址段,Windows 里叫“自动专用 IP 寻址”(APIPA)。网卡设为自动获取、却联系不上任何 DHCP 服务器时,系统在 169.254.1.0 到 169.254.254.255 之间挑一个地址,先用 ARP 确认没人占用,再配给自己,掩码是 255.255.0.0,没有网关。这样的地址只能和同一网段里同样是 169.254 的设备通信,访问不了网关和外网。之后系统大约每 5 分钟在后台重试一次 DHCP,一旦拿到正式地址就自动替换。
这个地址本身是 DHCP Client 服务在要不到地址后自己配的,所以看到 169.254,基本可以排除“服务未开启”,应当把注意力放在“为什么没人应答”上。另外,启用了 IPv6 的网卡上还会有一个 fe80 开头的地址,那是 IPv6 的链路本地地址,每块网卡都会自动生成,不是故障。
第一步:DHCP Client 服务没开启,或网卡没设成自动获取
普通电脑上说的“DHCP 服务”,指的是客户端服务 DHCP Client(服务名 Dhcp)。Windows Server 上另有一个 DHCP Server 服务,是给别人分配地址的服务器角色,两者不要混淆。
按 Win + R 输入 services.msc,找到 DHCP Client,启动类型应为“自动”,状态应为“正在运行”。命令行检查与启动(需要管理员权限):
Get-Service Dhcp | Select-Object Name, Status, StartType
Set-Service Dhcp -StartupType Automatic
Start-Service Dhcp
sc query Dhcp
sc qc Dhcp
sc config Dhcp start= auto
net start Dhcp
sc config 的 start= 后面必须有一个空格,这是 sc 命令的固定写法。启动时提示“Windows 无法启动 DHCP Client 服务(位于 本地计算机 上)”,就是常说的“本地计算机上的 DHCP 服务无法启动”,按后面的错误码处理:
| 报错 | 原因 | 处理 |
|---|---|---|
| 错误 1068:依存服务或组无法启动 | DHCP Client 依赖的服务或驱动没有运行 | sc qc Dhcp 看 DEPENDENCIES 一栏列出的依赖项(以实际输出为准),逐个 sc query 检查并启动,常见是 Network Store Interface Service(NSI)被禁用 |
| 错误 1079:此服务的帐户不同于运行于同一进程上的其他服务的帐户 | 服务的登录身份被改过 | 在服务属性的“登录”页改回“本地服务”,或执行 sc config Dhcp obj= "NT AUTHORITY\LocalService" password= "" |
| 错误 5:拒绝访问 | 权限被改,或被安全软件拦截 | 暂停第三方安全软件后重试;仍失败时依次执行 DISM /Online /Cleanup-Image /RestoreHealth 和 sfc /scannow 修复系统文件 |
| 启动类型显示“禁用” | 被优化软件或组策略关闭 | 改回“自动”;加入域的电脑改了又变回去,请管理员检查组策略 |
| 服务启动后马上停止 | 网卡驱动或网络组件异常 | 第二步的驱动与协议栈部分 |
服务正常,还要确认网卡本身是自动获取。网络诊断提示“以太网 未启用 DHCP”或“WLAN 未启用 DHCP”,意思是这块网卡被设成了手动 IP。图形界面里打开网卡属性,双击“Internet 协议版本 4 (TCP/IPv4)”,选“自动获得 IP 地址”和“自动获得 DNS 服务器地址”。命令行改法如下,先用 netsh interface show interface 查出网卡名称:
netsh interface ip set address name="以太网" source=dhcp
netsh interface ip set dns name="以太网" source=dhcp
PowerShell 可以先看各网卡的 DHCP 状态:
Get-NetIPInterface -AddressFamily IPv4 | Select-Object InterfaceAlias, Dhcp, ConnectionState
用 PowerShell 的 Set-NetIPInterface -Dhcp Enabled 切换时,原来手动配置的地址和网关可能还留在网卡上,netsh 的写法会一并清除,更省事。
第二步:释放并重新获取地址,排除驱动问题
ipconfig /release
ipconfig /renew
有多块网卡时,在命令后面加网卡名,例如 ipconfig /renew "以太网"。看结果:
- 拿到了正常地址:问题解决,多半是之前的租约或网卡状态异常。
- 提示无法联系 DHCP 服务器、请求超时(英文系统为
unable to contact your DHCP server. Request has timed out.):本机已经发出请求、没收到应答,转到第三步查网络。 - 提示网卡处于媒体断开状态,无法执行操作:物理连接没通,先查网线、端口或 Wi-Fi。
重新获取仍然失败、而同一网络里其他设备正常时,问题还在本机:
- 重启网卡:
Restart-NetAdapter -Name "以太网",或在设备管理器里禁用再启用。 - 检查驱动:设备管理器里网卡有黄色感叹号,或系统更新后网卡型号显示异常,到主板或网卡厂商的网站下载驱动重新安装。
Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, LinkSpeed, DriverVersion能看到当前的驱动版本和连接速率。 - 检查虚拟网卡:VPN 客户端、虚拟机软件会添加虚拟网卡和过滤驱动。启用 Hyper-V 外部虚拟交换机后,物理网卡上的 IPv4 会被取消,地址改由名为“vEthernet”的虚拟网卡获取,这是正常现象,不要在物理网卡上找地址。
- 重置网络协议栈:管理员身份执行下面两条命令后重启电脑。
netsh int ip reset会清掉手动配置的 IP,有静态配置的先记下来。
netsh winsock reset
netsh int ip reset
- 看客户端日志:事件查看器中依次展开“应用程序和服务日志 → Microsoft → Windows → Dhcp-Client”,或用命令读取:
Get-WinEvent -LogName "Microsoft-Windows-Dhcp-Client/Admin" -MaxEvents 20 |
Format-Table TimeCreated, Id, Message -AutoSize -Wrap
第三步:网络里有没有 DHCP 服务器应答
很多台设备同时拿不到地址,或者服务器、虚拟机在机房里拿不到地址,问题通常在网络侧。按下面的顺序查:
| 检查项 | 常见问题 | 怎么查 |
|---|---|---|
| 1. 链路 | 网口灯不亮,交换机端口被关闭或协商失败 | 华为 display interface brief,思科 show interfaces status |
| 2. 端口 VLAN | 接入端口划错 VLAN;服务器做了网卡绑定,交换机侧没配对应的聚合 | 核对端口所属 VLAN 与该 VLAN 应使用的网段 |
| 3. DHCP 服务器或中继 | 这个 VLAN 里没有 DHCP 服务器,网关上也没配置中继,广播出不了本网段 | 华为 display current-configuration interface Vlanif10 看有无 dhcp select relay 与 dhcp relay server-ip;思科 show running-config interface Vlan10 看有无 ip helper-address |
| 4. DHCP Snooping | 开了 Snooping,通往 DHCP 服务器或中继方向的端口没设为信任口,应答被交换机丢弃 | 查看 Snooping 配置与信任端口 |
| 5. 地址池 | 地址用完,服务器不再应答 | 第四步 |
| 6. 接入安全策略 | 端口安全、MAC 数量限制、802.1X 认证没通过 | 交换机日志与端口安全配置 |
要确认这个 VLAN 里到底有没有 DHCP 服务器在应答,在同一 VLAN 的一台 Linux 上执行:
sudo nmap --script broadcast-dhcp-discover -e eth0
它会发出一个 DHCP 发现请求,并列出所有应答者的地址(Server Identifier)和提供的地址(IP Offered)、网关、DNS。一个应答都没有,说明请求根本没人接;出现了不认识的服务器,说明网络里有人私设 DHCP,客户端可能拿到了错误的地址。
更直接的是在拿不到地址的那台机器上抓包(Linux 用下面的 tcpdump,Windows 可以用 Wireshark 配同样的过滤条件),看 DHCP 的四步交互(发现 DISCOVER、提供 OFFER、请求 REQUEST、确认 ACK)走到了哪一步:
sudo tcpdump -ni eth0 -e -v 'udp port 67 or udp port 68'
| 抓到的报文 | 结论 |
|---|---|
| 只有客户端反复发 DISCOVER | 没有服务器应答:VLAN 里没有服务器、中继没配,或应答被 Snooping 丢弃 |
| 有 OFFER,客户端却不继续发 REQUEST | 应答到了客户端,问题在客户端:本机防火墙、驱动或网卡过滤软件 |
| REQUEST 之后服务器回 NAK | 客户端请求的地址不属于当前网段,常见于设备从别的 VLAN 换过来,带着旧地址续租 |
| ACK 之后客户端发出 DECLINE | 客户端检测到分到的地址已被别人占用,服务器会把它标记为冲突,见第四步 |
第四步:DHCP 服务器端日志与地址池
请求有没有到达服务器、服务器为什么不给地址,日志里写得很清楚。
ISC DHCP(dhcpd):RHEL 系执行 journalctl -u dhcpd -f,Debian 系执行 journalctl -u isc-dhcp-server -f,然后让客户端重新获取。
DHCPDISCOVER from 00:1a:2b:3c:4d:5e via 10.0.10.1
DHCPOFFER on 10.0.10.57 to 00:1a:2b:3c:4d:5e via 10.0.10.1
DHCPDISCOVER from 00:1a:2b:3c:4d:5e via eth1: network 10.0.20.0/24: no free leases
DHCPDISCOVER from 00:1a:2b:3c:4d:5e via 10.0.30.1: unknown network segment
via 后面是中继的地址时,说明中继在工作;no free leases 表示这个网段的地址池用完了;unknown network segment 表示中继转来的请求在配置里找不到对应的 subnet 声明,要给这个网段补一个地址池。租约记录在 /var/lib/dhcpd/dhcpd.leases(RHEL 系)或 /var/lib/dhcp/dhcpd.leases(Debian 系)。ISC 已经停止维护 ISC DHCP,新部署可以考虑它的后继项目 Kea。
dnsmasq:执行 journalctl -u dnsmasq -f,地址池用完时会出现 no address available。
Windows DHCP 服务器:
Get-DhcpServerv4ScopeStatistics | Format-Table ScopeId, Free, InUse, PercentageInUse
交换机或路由器做 DHCP 服务器:华为执行 display ip pool name 地址池名 看已用和空闲数量;思科执行 show ip dhcp pool 看用量,show ip dhcp conflict 看被标记为冲突、暂不分配的地址。
地址池用完的常见原因:租期太长而设备流动快(访客网络尤其明显);冲突地址被服务器标记后暂停分配;有设备反复用不同的 MAC 申请。对应的处理是扩大地址池或缩短租期,清理冲突记录,并在交换机上限制每个端口学习的 MAC 数量。
Linux 客户端获取不到地址时,先看系统用的是哪个 DHCP 客户端:RHEL、Rocky 等用 NetworkManager,执行 nmcli device status 和 journalctl -u NetworkManager | grep -i dhcp;使用 netplan 的 Ubuntu Server 多由 systemd-networkd 负责,执行 networkctl status eth0 和 journalctl -u systemd-networkd | grep -i dhcp;仍在用 dhclient 的系统,执行 dhclient -r eth0 释放后,用 dhclient -v eth0 重新获取,反复出现 DHCPDISCOVER on eth0 to 255.255.255.255 port 67 并以 No DHCPOFFERS received. 结束,就是没人应答,回到第三步。注意 Linux 服务器通常不会像 Windows 那样自动配 169.254 地址,拿不到地址时网卡上就只是没有 IPv4。
在管理系统里怎么落地
机房里的 DHCP 故障,排查时常常卡在“这台机器接在哪个端口、端口在哪个 VLAN、这个 VLAN 的网关在哪台设备上”这几个问题上。Toplink DCIM 的服务器列表直接显示每台机器所接的交换机端口、端口速率和 VLAN,端口划错 VLAN 时可以在 交换机管理 里远程改正;IP 地址管理 为每个地址段记录 VLAN 和网关所在的交换机,查中继配置时知道该登录哪台设备。PXE 装机等用途的 DHCP 动态池可以单独建段并锁定,锁定的段不参与开通时的自动分配,避免静态分配出去的地址和动态池重叠,造成地址冲突。
常见问题
169.254 的地址能手动改成正常地址上网吗?
能临时用:按网络管理员给的地址、掩码、网关和 DNS 手动填写即可通信。但这只是绕开了 DHCP,同一网络里其他设备也拿不到地址时,说明 DHCP 服务器或中继本身有问题,仍然要修好。
用固定 IP 的电脑,可以禁用 DHCP Client 服务吗?
不建议。在 Windows 上这个服务还负责为本机向 DNS 服务器注册和更新记录,禁用后这部分功能随之失效;以后网卡改回自动获取时,也会因为服务没运行而拿不到地址。
为什么手机能连上 Wi-Fi,电脑却拿到 169.254?
说明路由器的 DHCP 在工作,问题多半在这台电脑:DHCP Client 服务、网卡驱动、安全软件或 VPN 虚拟网卡。也可能地址池很小、设备很多,恰好被用完,可以在路由器的已分配列表里核对。