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-ui-patchedAURdhcpcd-uiAUR 的补丁版本,使用 AppIndicator 替代了GtkStatusIcon, 基于 gtk3 编译并提供了 KDE 系统托盘图标。

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

要为 全部 网络接口提供服务,start/enable dhcpcd.service.

要仅为某个网络接口提供服务,start/enable 模板单元 dhcpcd@interface.service,其中的 interface 名通过 这里 进行查询。

建议使用模板单元方式,不管是那种方式,都会分配一个动态 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 ID 租约时,哪些是必须的,哪些是可选的。

注意: 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 可用,DNS信息将会发送给它处理,否则, dhcpcd将会自行将DNS信息写入/etc/resolv.conf。可以通过禁用/usr/lib/dhcpcd/dhcpcd-hooks/20-resolv.conf钩子防止dhcpcd重写/etc/resolv.conf文件,只需在/etc/dhcpcd.conf最后一段中添加以下内容即可:

nohook resolv.conf

或者,您可以创建一个名为/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时,可以在/etc/resolvconf.conf中设置DNS服务器地址, 这样,它们就不会被任何支持“resolvcconf”的软件覆盖。

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

客户端ID(Client 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可以在不指定接口的情况下使用(enabled),然而,可能systemd-udevd试图应用可预测的网络接口名称引导时导致意外的竞态条件(Race Condition):

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

为了避免这种情况,请按照#运行中的描述,绑定接口后再启用dhcpcd。然而,模板单元也有缺点,它不支持有线连接的热插拔,如果没有连接网线就会失败。为了解决这个问题,详见 #超时延迟

也可以在 dhcpcd.conf(5) 中使用denyinterfacesallowinterfaces参数来阻止dhcpcd绑定到内核名称,例如

denyinterfaces wlan* eth*

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

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

要让dhcpcd无限期等待一次,请编辑(edit)接口systemd单元并将timeout参数设置为0

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

要使其无限期等待,请设置单元Restart参数为always,单元退出后将会再次重启:

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

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

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

在默认配置中, dhcpcd@.service 会在获取 IP 地址后进入守护进程(dhcpcd -w )。启用单元后,会等待 IP 地址的分配,影响启动速度,要修正这个问题,请创建下面的 drop-in file:

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

也可以看看 FS#49685.

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