2

Is there a way to force ISC DHCPD to trigger expire or release for static lease right after client disconnect?

I want to trigger a script right after client connects ("on commit" DHCPD event) and disconnects ("on expiry" or "on release" DHCPD event).

While first works like a charm, latter ones never triggering. Any advices?

EDIT: A config snipplet (with test script):

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);
  }
}
GeekMagus
  • 507
  • 4
  • 13

3 Answers3

2

DHCP will generally keep the lease until the expiry time in an attempt to reissue the same lease to a client that reconnects later. It will only start to free up candidates when there is pressure on the scope from new clients.

This allows clients to reacquire the same address when they connect again without too long an interval between sessions and gives the appearance of nearly static addressing.

It is possible your scripts are not firing (by design) until the timer expires. You could try to force this by either increasing contention in the scope, or by reducing the timer durations to expedite the process.

Pekka
  • 530
  • 5
  • 15
  • This is a little strange, but I have tried to lower a lease lifetime without any effect. It seems what expiry or release event of the _static leases_ are never triggered. Or I'm doing something completely wrong... – GeekMagus Dec 20 '13 at 12:28
  • 2
    No, you are not. Static is static - it is manually pit in place. Static normally has no expiry. – TomTom Dec 20 '13 at 12:30
  • @Greshnik The ISC DHCPD documentation suggests that the release event occurs as soon as the client sends the release event. You can trigger this at the client (Windows IPCONFIG /RELEASE). Check whether the DNS processing is taking place correctly as described in the documentation. – Pekka Dec 20 '13 at 22:42
  • Just tested it. Used "dhclient -r" on linux host but this does not matter I think. First I tested a **dynamic lease** and on "dhclient -r" this triggers my script just fine. Then I switched back to **static one** and nothing can force it to trigger a **release event**. And as I describe in my own answer it seems a normal situation. – GeekMagus Dec 20 '13 at 23:15
  • @Greshnik Static reservation is intended for exactly that - clients that are unable to really manage the address lifetime themselves and where the server holds the address on behalf of the client. As you say, behaviour looks correct. – Pekka Dec 20 '13 at 23:31
  • Yea, I'm still seeking for a reasonable solution to track user disconnects. Have two, not so good ideas: cron script with fixed interval and something like nmap or ARP requests tracking. Both works, but require tracking, instead of relying on occurred events. – GeekMagus Dec 20 '13 at 23:35
  • Why do you need to have the static lease? The server will attempt to maintain the same address as long as there is no stress for addresses in the scope. Can you not allow the protocol to work as intended? – Pekka Dec 21 '13 at 07:50
1

If I correctly understood, to make a static lease you have something like this in your config:

host static-1 {
    hardware ethernet 00:01:02:03:04:05;
    fixed-address 192.168.1.40;
}

This will work as you expect, but will never release this IP-address (it does not matter if client send DHCPRELEASE or not) - because it is STATIC IP from dhcpd's point of view.

You must create a DYNAMIC IP (again, from dhcpd's point of view), so dhcpd will track it. You can do it like this:

# 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
}

To make your configuration more flexible, you can put class-subclass and pool-range declarations into different files and include them into main dhcpd.conf

#dhcpd.conf
authoritative;
min-lease-time ...;
... etc.

include "/path/to/classes.conf";
include "/path/to/subnet.conf";

As you can see, we put every client into its own class AND subclassed it into "static-ip" class. This is in case you want to have another subnet w/o static ip assignment, for ex.:

subnet 192.168.2.0 netmask 255.255.255.0 {
 range 192.168.2.10 192.168.2.100;
 deny members of "static-ip";
}

Then you must deny clients with static ip assignment to get IPs from this subnet (with deny keyword).

This way you get DYNAMIC IP (from dhcpd's point), but actually it will never change (from client's point)

halt
  • 106
  • 1
  • 7
  • Hmm, nice idea. Although it is not needed anymore, but it sounds like a really reasonable solution. Will mark it as accepted just for others to know and will try to implement on my spare time. – GeekMagus Jan 20 '16 at 18:59
  • I say more. Dhcpd server (with my example config) will also log all dhcp-conversation between client and server, what it does not do when using host declaration – halt Jan 20 '16 at 23:01
0

Thanks to @TomTom, I dig deeper in RFC2131 and confirm this behavior of static leases:

...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...

The reason why I didn't found it earlier because "static leases" called "permanent" inside RFC and Ctrl+F does not have built-in AI (unfortunately)

So I'm still seeking for a working way to handle clients who disconnects from the network.

GeekMagus
  • 507
  • 4
  • 13