dhcpcd

来自 Arch Linux 中文维基

dhcpcd 是 DHCP 和 DHCPv6 客户端,是目前功能最丰富的开源 DHCP 客户端。项目主页包含了完整的功能列表。

注意: Roy Marple 的 dhcpcd(DHCP client daemon)和 Internet Systems Consortium 的 dhcpd(DHCP (server) daemon)是不同的软件。

安装[编辑 | 编辑源代码]

安装软件包 dhcpcd

dhcpcd-uiAUR 是 dhcpcd 和 GTK 前端,提供了对 wpa_supplicant 的可选支持。功能包括配置对话框、输入无线网络的密码等。

运行[编辑 | 编辑源代码]

要为所有的网络接口启动守护进程,启动或启用 dhcpcd.service

要单独为指定的网络接口启动守护进程,启动或启用模板单元 dhcpcd@interface.service,其中的 interface 名可从这里查询。

建议使用模板单元方式,详情请参阅 #dhcpcd 和 systemd 网络接口。无论哪种方式都会分配一个动态 IP 地址。要分配静态 IP 地址,请参阅 #静态配置

配置[编辑 | 编辑源代码]

主配置文件是 /etc/dhcpcd.conf,详情请参考 dhcpcd.conf(5),下面会介绍一些常用选项。

DHCP 静态路由[编辑 | 编辑源代码]

如果要在客户端设置静态路由,请使用 /etc/dhcpcd.exit-hook。下面的例子中添加了一个 VPN 子网 10.11.12.0/24 到网关 192.168.192.5 的静态路由:

/etc/dhcpcd.exit-hook
ip route add 10.11.12.0/24 via 192.168.192.5

可以在文件中配置多个路由。

DHCP 客户端标识[编辑 | 编辑源代码]

服务器可以通过下列方式不同的 DHCP 客户端:

  1. 主机名(或客户端发送的主机名),
  2. 所用网卡的 MAC 地址,
  3. Identity Association ID(身份关联 ID IAID),区分不同使用场景或接口的标识,
  4. DHCP 唯一标识(DUID)。

详情请参考 RFC 3315

DHCP 服务器通过配置决定申请 DHCP IP 租约时,哪些是必须的,哪些是可选的。

注意: dhcpcd 默认配置的是最常用的方式。服务器会自动确认上述标识,只有在出现问题时才需要额外配置。

如果无法通过 dhcpcd 默认配置获取 IP 地址,可以在 dhcpcd.conf 中尝试如下配置:

  • hostname 发送 /etc/hostname 中配置的主机名
  • clientid 发送 MAC 地址作为标识
  • iaid <interface> 生成并发送 IAID,可以在接口块(interface <interface>)中使用,参考:[1]),下面的选项更常用:
  • duid 将联合使用 DUID 和 IAID 作为标识。

DUID 的数值配置在 /var/lib/dhcpcd/duid 中,为了保证 DHCP 租约的有效性,需要保证 DUID 在整个网络中是唯一的,而 IAID 需要能区分每一个接口(RFC 4361)。

如果运行的是动态 DNS,请确保三个都是唯一的。如果网络中出现重复的 DUID,例如克隆的虚拟机中,有不同的主机名和 MAC 地址,但是没有修改 DUID 时,最新获取IP地址的客户端会清除之前 DUID 获取的地址。

静态配置[编辑 | 编辑源代码]

需要的配置在网络配置中均有说明,通常包含网络接口名称、IP 地址、路由地址和域名服务器。

/etc/dhcpcd.conf 中为 dhcpcd 配置静态地址:

/etc/dhcpcd.conf
interface eth0
static ip_address=192.168.0.10/24	
static routers=192.168.0.1
static domain_name_servers=192.168.0.1 8.8.8.8

还可以进行更复杂的配置,比如 arping 选项,详情请参考 dhcpcd.conf(5)

备用配置[编辑 | 编辑源代码]

可以为 dhcpcd 添加备用设置,当 DHCP 续租失败时使用。这对于无显示设备机器特别有用,动态地址无法获取时,使用静态地址作为备用,确保机器有可用的网络连接。

下面示例为 static_eth0 配置了 192.168.1.23 静态地址,192.168.1.1 网关,并将此配置设置为 eth0 的备用配置。

/etc/dhcpcd.conf
# define static profile
profile static_eth0
static ip_address=192.168.1.23/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

# fallback to static profile on eth0
interface eth0
fallback static_eth0

钩子[编辑 | 编辑源代码]

dhcpcd 会按字母顺序执行 /usr/lib/dhcpcd/dhcpcd-hooks/ 中配置的钩子,详情请参考 dhcpcd.conf(5)dhcpcd-run-hooks(8)

注意:
  • 可以在 dhcpcd.conf 中使用 nohook 禁用钩子。
  • 可以用 env 选项为所有钩子设置环境变量。例如要强制设置主机名,请使用 env force_hostname=YES

这篇文章的某些内容需要扩充。

原因: describe (at least some) provided hooks. (在 Talk:Dhcpcd 中讨论)

10-wpa_supplicant[编辑 | 编辑源代码]

通过创建一个符号链接启用这个钩子,不仅可以在当版本中使用,后期程序更新时也可使用:

# ln -s /usr/share/dhcpcd/hooks/10-wpa_supplicant /usr/lib/dhcpcd/dhcpcd-hooks/

如果启用了 10-wpa_supplicant 钩子,将会在无线接口上自动加载 wpa_supplicant,它仅在以下情况开启:

  • 不存在已在接口上监听的 wpa_supplicant 进程。
  • 至少存在一个 wpa_supplicant 配置文件。默认情况下,dhcpcd 将会按顺序检查以下配置文件:
/etc/wpa_supplicant/wpa_supplicant-interface.conf
/etc/wpa_supplicant/wpa_supplicant.conf
/etc/wpa_supplicant-interface.conf
/etc/wpa_supplicant.conf

但也可通过设置 env wpa_supplicant_conf=configuration_file_path/etc/dhcpcd.conf 中添加自定义配置文件路径。

注意: 钩子会在找到第一个配置文件时停止执行,因此,如果您有多个 wpa_supplient 配置文件,则应该考虑到这一点,否则“dhcpcd”可能会使用错误的配置文件。

如果您通过 wpa_supplicant 管理您的无线连接,钩子可能会创建一些不必要的连接事件。例如,如果您关闭了 wpa_supplicant,钩子可能会使无线接口再次打开。此外,如果您正在使用 netctl-autowpa_supplicant 将会根据 /run/network/wpa_supplicant_interface.conf 配置文件自动启动。因此,从钩子重新启动接口是不必要的,并且可能会导致 /etc/wpa_supplicant/wpa_supplicant.conf 文件在启动时解析错误,因为该文件在默认打包的版本中只包含虚拟的预设值。通过移出添加钩子的符号链接以禁用钩子,或者向 dhcpcd.conf 中添加 nohook wpa_supplicant 参数以解决这个问题。

小技巧[编辑 | 编辑源代码]

禁用 ARP 探测加速 DHCP 响应[编辑 | 编辑源代码]

dhcpcd 在内部实现了 DHCP 标准提议(RFC 2131),以通过 ARP 探测验证指定 IP 地址是否已被其他设备使用,在家庭网络环境下这通常是不必要的,因此,可以通过禁用 ARP 探测在每次连接时节约 5 秒左右的时间:

/etc/dhcpcd.conf
noarp

相当于将 --noarp 参数传递给 dhcpcd,并禁用 ARP 探测,从而加快使用 DHCP 连接到网络的速度。

移除旧的 DHCP 租约[编辑 | 编辑源代码]

在文件 /var/lib/dhcpcd/interface.lease 中,interface 是获得租约的接口名称,包含 DHCP 服务器发送的实际可用的 DHCP 租约响应。对一个无线接口来说,文件名则为 /var/lib/dhcpcd/interface-ssid.lease,其中 ssid 是无线网络名称。这些文件用于确定服务器分配的最近一个租约,文件的 mtime 属性用于确定租约的公告时间。如果最近的租约信息可用,则该租约信息将用于请求先前在网络上使用的相同 IP 地址,如果您不想要这样做,只需删除这些文件即可。

如果 DHCP 服务器仍然分配相同的 IP 地址,可能是因为服务器被配置为保持固定分配并且识别出了客户端发送的客户端 id(client id)或者是 DUID(详见 #DHCP 客户端标识),您可以通过停止 dhcpcd 并移除或重命名 /var/lib/dhcpcd/duid 文件来进行测试,dhcpcd 会在下次运行时重新生成这个文件。

请注意,DUID 旨在作为重启后和不同接口之间的持久化的机器标识符。如果要将系统迁移到新计算机上,则不应该留存这个文件。

多重引导获取不同 IP 地址[编辑 | 编辑源代码]

如果您使用双引导 Arch 和 macOS 或者是 Windows,并且每个系统想要获得不同的 IP 地址,您可以通过在每个操作系统指定不同的 DUID 来控制获得的 IP 地址。

在 Windows 下 DUID 应该保存在以下注册键下:

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Dhcpv6DUID

macOS 中可以在 Network\adapter\dhcp preferences panel 中直接访问修改。

如果您使用 dnsmasq 作为 DHCP 服务器,可以在其配置文件中通过恰当指定 dhcp-host= 规则来使用不同的 DUID。

/etc/resolv.conf[编辑 | 编辑源代码]

如果系统上 resolvconf英语resolvconf 可用,DNS 信息将会发送给它处理,否则,dhcpcd 将会自行将 DNS 信息写入 /etc/resolv.conf。可以通过禁用 /usr/lib/dhcpcd/dhcpcd-hooks/20-resolv.conf 钩子防止 dhcpcd 重写 /etc/resolv.conf 文件,只需在 /etc/dhcpcd.conf 最后一段中添加以下内容即可:

nohook resolv.conf

注意,一般来说,禁用此钩子也会使 dhcpcd 禁用 resolvconf。

或者,您可以创建一个名为 /etc/resolv.conf.head 的文件,其中包含您的 DNS 服务器信息。dhcpcd 将把这个文件的内容放在 /etc/resolv.conf 的开头。

或者,您可以将 dhcpcd 配置为每次使用相同的 DNS 服务器。想要这么做,请在 /etc/dhcpcd.conf 的末尾添加以下行,其中 dns-server-ip-addressses 是一个以空格分隔的 DNS IP 地址列表。

static domain_name_servers=dns-server-ip-addresses

例如,要设置 Google DNS 服务器:

static domain_name_servers=8.8.8.8 8.8.4.4
提示:当使用 openresolv英语openresolv 时,可以在 /etc/resolvconf.conf 中设置 DNS 服务器地址,这样,它们就不会被任何支持 resolvcconf 的软件覆盖。

问题解决[编辑 | 编辑源代码]

客户端 ID[编辑 | 编辑源代码]

如果您处在根据 MAC 地址过滤客户端 ID 的 DHCPv4 的网络中,则可能需要更改以下行:

/etc/dhcpcd.conf

# 根据 RFC4361,DHCPv4 使用和 DHCPv6 相同的 DUID+IAID 作为客户端 ID。
duid

改为:

/etc/dhcpcd.conf
# 使用接口的硬件地址作为客户端 ID(DHCPv4)。
clientid

否则,您可能无法获得租约,因为 DHCP 服务器可能无法正确读取 DHCPv6-风格的客户端 ID。有关更多信息,请参阅 RFC 4361

通过先释放 IP 地址检查 DHCP 问题[编辑 | 编辑源代码]

此问题可能在 DHCP 获得错误的 IP 分配时发生,例如当两个路由器通过 VPN 相连时。路由器通过 VPN 连接分配到了地址。要修复该问题,请以 root 身份释放该 IP 地址:

# dhcpcd -k

然后请求一个新地址:

# dhcpcd

您可能需要多次运行这两个命令。

路由器不兼容导致的问题[编辑 | 编辑源代码]

对于某些(不兼容的)路由器,除非您注释掉 /etc/dhcpcd.conf 中的以下行,否则无法正确连接。

require dhcp_server_identifier

除非您的网络上有多个 DHCP 服务器(非典型),否则这不会导致问题,详情请见这个页面

dhcpcd 和 systemd 网络接口[编辑 | 编辑源代码]

可以在不指定接口的情况下启用 dhcpcd.service。但系统启动时,该单元可能会在 systemd-udevd 尝试应用一个可预测的网络接口名称时与其产生竞争状态:

error changing net interface name wlan0 to wlp4s0: Device or resource busy" 

要避免该问题,请根据 dhcpcd.conf(5),使用 denyinterfacesallowinterfaces 以阻止 dhcpcd 绑定至内核名称,例如:

denyinterfaces wlan* eth*

也可如 #运行中所述,为每个接口启用 dhcpcd。但是,模板单元也有缺点,它不支持有线连接的热插拔,且如果没有连接网线就会失败。为解决这个问题,请参见 #超时延迟

超时延迟[编辑 | 编辑源代码]

如果 dhcpcd 在单个接口上运行,且在 30 秒后未能获得租约(例如,当服务器未准备好或网线未插入时),它将退出并返回错误。

要让 dhcpcd 无限期等待一次,请编辑单元并将timeout 设置为 0

/etc/systemd/system/dhcpcd@.service.d/timeout.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dhcpcd -w -q -t 0 %I

令单元在退出后重启以使其无限期等待:

/etc/systemd/system/dhcpcd@.service.d/dhcpcdrestart.conf
[Service]
Restart=always

已知问题[编辑 | 编辑源代码]

dhcpcd@.service 降低启动速度[编辑 | 编辑源代码]

在默认配置中,dhcpcd 的标识 -w 会使 dhcpcd@.service 在进入后台守护进程前等待 IP 地址的获取。如果启用了该单元,可能会导致启动时暂停并等待 IP 地址分配以继续启动流程。要修复该问题,请为该单元创建如下的附加配置片段

/etc/systemd/system/dhcpcd@.service.d/no-wait.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dhcpcd -b -q %I

另请参阅 FS#49685

参阅[编辑 | 编辑源代码]