DHCP Client
RouterOS DHCP 客户端从 DHCP 服务器获取接口的 IPv4 地址与网络设置。本页说明客户端会应用租约中的哪些内容、请求与发送哪些选项、添加哪些路由等。
DHCP 客户端
子菜单: /ip/dhcp-client
DHCP 客户端从 DHCP 服务器获取接口的 IPv4 地址与网络设置。它通常用于连接路由器与 ISP 或其他上游网络的接口,可在任何类以太网接口上启用。DHCP 交换、租约与续租的工作方式请参阅 DHCP 概念。
客户端获得租约后,会将收到的设置应用到路由器:
- IP 地址与网络掩码作为动态地址添加到接口。
- 通过收到的网关添加动态默认路由,或添加收到的无类静态路由(option 121)。
add-default-route属性控制此行为。 - 收到的 DNS 服务器加入 DNS 解析器的动态服务器(
use-peer-dns),收到的 NTP 服务器加入 NTP 客户端的服务器(use-peer-ntp)。
客户端会在租约到期前续租。租约丢失或客户端被禁用时,动态地址与路由会被移除。
配置示例
简单 DHCP 客户端
在 ether1 接口上添加 DHCP 客户端:
/ip/dhcp-client/add interface=ether1
使用 print detail 查看客户端获得的租约及其收到的设置:
[admin@MikroTik] > /ip/dhcp-client/print detail
0 name="client1" interface=ether1 add-default-route=yes default-route-distance=1
default-route-tables=default check-gateway=none use-peer-dns=yes use-peer-ntp=yes
allow-reconfigure=no use-broadcast=both dhcp-options=hostname,clientid
status=bound address=192.168.0.65/24 gateway=192.168.0.1 dhcp-server=192.168.0.1
primary-dns=192.168.0.1 primary-ntp=192.168.0.1 expires-after=9m44s
DHCP 选项
客户端向 DHCP 服务器请求以下选项:
- Option 1:子网掩码。
- Option 3:网关地址。
- Option 6:DNS 服务器地址。
- Option 15:域名。
- Option 33:静态路由。
- Option 42:NTP 服务器地址。
- Option 43:厂商特定信息。
- Option 121:无类静态路由。
- Option 138:CAPWAP 接入控制器地址。
客户端发送其 dhcp-options 属性中列出的选项,这些选项从 /ip/dhcp-client/option 中定义的选项里选择。有三个预定义选项:
| 名称 | 代码 | 值 |
|---|---|---|
| clientid_duid | 61 | 0xff$(CLIENT_DUID) |
| clientid | 61 | 0x01$(CLIENT_MAC) |
| hostname | 12 | $(HOSTNAME) |
默认情况下,客户端发送 hostname 与 clientid:以路由器标识作为主机名,以及基于客户端接口 MAC 地址的客户端标识符。若要改用路由器 DUID 标识客户端(RFC 4361),请在 dhcp-options 中将 clientid 替换为 clientid_duid。选项值使用与 DHCP 服务器选项相同的语法。可包含的变量列在 /ip/dhcp-client/option 参考中。
属性
DHCP 客户端的全部属性、状态值与命令请参阅 /ip/dhcp-client CLI 参考。客户端添加的路由需要额外说明。
来自租约的路由
add-default-route 属性控制客户端添加哪些收到的路由:
yes(默认):当服务器发送无类静态路由(option 121)时,客户端添加这些路由;否则通过收到的网关(option 3)添加默认路由。存在 option 121 时,按 RFC 3442 要求忽略 option 3 中的网关,因此服务器必须在 option 121 中包含默认路由。special-classless:客户端同时添加无类静态路由以及通过收到网关的默认路由。适用于服务器发送无类静态路由但不含默认路由,且默认路由仍应来自 option 3 的情况。no:客户端不添加任何路由。
路由会使用 default-route-distance 中设置的距离(默认 1),并进入 default-route-tables 中列出的路由表。default 条目表示主路由表;当客户端接口属于 VRF 时,表示该 VRF 的路由表。条目也可以设置自己的距离,例如 default-route-tables=backup:5。
如果已存在另一条默认路由,则使用距离较小的路由。距离相同时,两条路由均处于活动状态,流量在它们之间分担(ECMP)。可使用 default-route-distance 控制优先使用哪条路由,并使用 check-gateway 在网关无响应时停止使用某条路由。
脚本示例
租约脚本可接收的变量列在 /ip/dhcp-client CLI 参考的 script 属性中。
租约脚本示例
本示例通过收到的网关向 WAN1 路由表添加默认路由,在网关变化时更新路由,并在租约结束时移除它。请先创建路由表,然后添加带脚本的客户端:
警告
请注意,某些变量在特定菜单中可能是保留名称,无法在这些菜单中使用。详情请参阅保留变量名。
/routing/table/add name=WAN1 fib
/ip/dhcp-client/add interface=ether2 add-default-route=no script={
:local count [/ip/route/print count-only where comment="WAN1"]
:if ($bound=1) do={
:if ($count = 0) do={
/ip/route/add gateway=$"gateway-address" comment="WAN1" routing-table=WAN1
} else={
:if ($count = 1) do={
:local test [/ip/route/find where comment="WAN1"]
:if ([/ip/route/get $test gateway] != $"gateway-address") do={
/ip/route/set $test gateway=$"gateway-address"
}
} else={
:error "Multiple routes found"
}
}
} else={
/ip/route/remove [find comment="WAN1"]
}
}
使用收到的 option 43 设置 ACS URL
DHCP 服务器可以在厂商特定信息选项(option 43)中发送 TR-069 自动配置服务器(ACS)的 URL。客户端脚本通过 vendor-specific 变量收到该选项,因此可在租约绑定时设置 TR-069 客户端的 ACS URL。TR-069 客户端是一个独立软件包。
/ip/dhcp-client/set [find interface=ether1] script={
:if ($bound=1) do={
/tr069-client/set acs-url=$"vendor-specific"
}
}
租约子网之外的默认网关
某些 DHCP 服务器发送的网关(option 3)不在租约子网内。例如,服务器提供 192.168.88.100/24,网关为 172.16.1.1。此时客户端添加的默认路由会保持非活动状态,因为无法访问该网关:
[admin@MikroTik] > /ip/route/print
Flags: D - DYNAMIC; I - INACTIVE, A - ACTIVE; c - CONNECT, d - DHCP
Columns: DST-ADDRESS, GATEWAY, DISTANCE
DST-ADDRESS GATEWAY DISTANCE
DId 0.0.0.0/0 172.16.1.1 1
DAc 192.168.88.0/24 ether1 0
要使网关可达,请将租约地址再次添加为 /32 地址,并以网关作为其网络。这会创建到该网关的直连路由。请在客户端脚本中执行此操作,脚本会收到租约地址、网关与接口:
/ip/dhcp-client/set [find interface=ether1] script={
/ip/address/add address=($"lease-address" . "/32") network=$"gateway-address" interface=$interface
}
这个简短脚本会在每次新租约时添加另一个地址。以下脚本只保留一个地址,并在租约地址或网关变化时替换它:
/ip/dhcp-client/set [find interface=ether1] script={
/ip/address {
:local ipId [find where comment="dhcpL address"]
:if ($ipId != "") do={
:if (!([get $ipId address] = ($"lease-address" . "/32") && [get $ipId network]=$"gateway-address")) do={
remove $ipId
add address=($"lease-address" . "/32") network=$"gateway-address" interface=$interface comment="dhcpL address"
}
} else={
add address=($"lease-address" . "/32") network=$"gateway-address" interface=$interface comment="dhcpL address"
}
}
}