有没有办法强制 ISC DHCPD 在客户端断开连接后立即触发静态租约过期或释放?
我想在客户端连接(“提交时” DHCPD 事件)和断开连接(“到期时”或“释放时” DHCPD 事件)后立即触发脚本。
虽然第一个方法有效,但第二个方法始终不起作用。有什么建议吗?
编辑:配置片段(带有测试脚本):
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.40 192.168.1.49;
on commit {
set ip = binary-to-ascii (10, 8, ".", leased-address);
execute ("/usr/local/bin/dhcp-test", "commit", ip);
}
on release {
set ip = binary-to-ascii (10, 8, ".", leased-address);
execute ("/usr/local/bin/dhcp-test", "release", ip);
}
on expiry {
set ip = binary-to-ascii (10, 8, ".", leased-address);
execute ("/usr/local/bin/dhcp-test", "expiry", ip);
}
}
答案1
如果我理解正确的话,要进行静态租约,您的配置中应该有类似这样的内容:
host static-1 {
hardware ethernet 00:01:02:03:04:05;
fixed-address 192.168.1.40;
}
这将按您预期的方式工作,但永远不会释放该 IP 地址(无论客户端是否发送 DHCPRELEASE) - 因为从 dhcpd 的角度来看它是静态 IP。
您必须创建一个动态 IP(再次从 dhcpd 的角度来看),这样 dhcpd 才会跟踪它。您可以这样做:
# First create pseudo class
class "static-ip" { match suffix(hardware, 6); }
# Here you will declare all MAC of your clients and make it a subclass of "static-ip"
# class "<UNIQ-CLASSNAME>" { match if suffix(hardware, 6) = <CLIENT-MAC-ADDRESS>; } subclass "static-ip" <CLIENT-MAC-ADDRESS>;
# Example
class "static-1" { match if suffix(hardware, 6) = 00:01:02:03:04:05; } subclass "static-ip" 00:01:02:03:04:05;
# Next allocate an address for every client (inside subnet declaration):
subnet 192.168.1.0 netmask 255.255.255.0 {
on commit {
set ip = binary-to-ascii (10, 8, ".", leased-address);
execute ("/usr/local/bin/dhcp-test", "commit", ip);
}
on release {
set ip = binary-to-ascii (10, 8, ".", leased-address);
execute ("/usr/local/bin/dhcp-test", "release", ip);
}
on expiry {
set ip = binary-to-ascii (10, 8, ".", leased-address);
execute ("/usr/local/bin/dhcp-test", "expiry", ip);
}
# pool { range <ip-addr>; allow members of "<UNIQ-CLASSNAME>"; }
pool { range 192.168.1.40; allow members of "static-1"; }
# pool { range 192.168.1.41; allow members of "static-2"; }
#... so on
}
为了使配置更加灵活,你可以将 class-subclass 和 pool-range 声明放入不同的文件中,然后包括将它们放入主 dhcpd.conf 中
#dhcpd.conf
authoritative;
min-lease-time ...;
... etc.
include "/path/to/classes.conf";
include "/path/to/subnet.conf";
如您所见,我们将每个客户端放入其自己的类中,并将其子类化为“静态 IP”类。这是为了防止您想要另一个没有静态 IP 分配的子网,例如:
subnet 192.168.2.0 netmask 255.255.255.0 {
range 192.168.2.10 192.168.2.100;
deny members of "static-ip";
}
然后,您必须拒绝具有静态 IP 分配的客户端从该子网获取 IP(使用否定关键词)。
这样你就得到了动态 IP(从 dhcpd 的角度来看),但实际上它永远不会改变(从客户端的角度来看)
答案2
DHCP 通常会保留租约直至到期,并尝试向稍后重新连接的客户端重新发出相同的租约。只有当新客户端对范围造成压力时,它才会开始释放候选者。
这使得客户端可以在再次连接时重新获取相同的地址,而无需在会话之间间隔太长,并且给出几乎静态寻址的外观。
您的脚本可能在计时器到期之前不会触发(按照设计)。您可以尝试通过增加范围内的争用或减少计时器持续时间来加快进程,从而强制执行此操作。
答案3
感谢@TomTom,我深入研究了 RFC2131 并确认了静态租约的这种行为:
...DHCP supports three mechanisms for IP address allocation. In
"automatic allocation", DHCP assigns a permanent IP address to a
client. In "dynamic allocation", DHCP assigns an IP address to a
client for a limited period of time (or until the client explicitly
relinquishes the address). In "manual allocation", a client's IP
address is assigned by the network administrator, and DHCP is used
simply to convey the assigned address to the client.
Dynamic allocation is the only one of the three mechanisms that
allows automatic reuse of an address that is no longer needed by the
client to which it was assigned...
我之所以没有早点发现它,是因为“静态租约“ 叫 ”永恒的“在 RFC 中,Ctrl+F 没有内置 AI(不幸的是)
所以我仍在寻找一种有效的方法来处理断开网络的客户端。