dhclient does not reup valid_lft on service restart, kernel reaps IP

Bug #2024929 reported by Steven Haber
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
isc-dhcp (Ubuntu)
Confirmed
Undecided
Unassigned

Bug Description

Between Bionic and Focal, dhclient was patched to set the valid_lft on ipv4 addresses, which is a timer in the kernel that tells the kernel when to reap the IP. dhclient then is supposed to issue repeated `ip addr add` commands to reset this lft and prevent the kernel from releasing the IP. However, if you restart the dhclient service, it acquires a lease and then does *not* reup the lft. It only reups after a lease the currently running service knows about expires. So if you restart the dhclient service on a cadence that is faster than the DHCP leases in your network environment, you never see a lease expire during the lifetime of the service, which means the kernel will eventually rip the address out from under the server, causing a network outage. In some environments, the DCHP lease can be longer than a service restart cadence, and this bug can be very severe.

I'm using the most up-to-date version of Focal's dhclient package.

I'm not familiar with how the patch management for Ubuntu works, but the bug was introduced here:

commit 41013cf19647ec323a7100fb61d50779d8c8a205 (tag: import/4.4.1-2)
Author: Michael Gilbert <email address hidden>
Date: Tue Dec 11 03:55:12 2018 +0000

    4.4.1-2 (patches unapplied)

    Imported using git-ubuntu import.

These changes specifically:

diff --git a/debian/dhclient-script.linux b/debian/dhclient-script.linux
index 9b0d3f89..f9b734ab 100644
--- a/debian/dhclient-script.linux
+++ b/debian/dhclient-script.linux
@@ -246,6 +246,8 @@ case "$reason" in
             # new IP has been leased or leased IP changed => set it
             ip -4 addr add ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \
                 ${new_broadcast_address:+broadcast $new_broadcast_address} \
+ ${new_dhcp_lease_time:+valid_lft $new_dhcp_lease_time} \
+ ${new_dhcp_lease_time:+preferred_lft $new_dhcp_lease_time} \
                 dev ${interface} label ${interface}

             if [ -n "$new_interface_mtu" ]; then
@@ -277,6 +279,12 @@ case "$reason" in
                        fi
                    done
            fi
+ else # RENEW||REBIND
+ ip -4 addr change ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \
+ ${new_broadcast_address:+broadcast $new_broadcast_address} \
+ ${new_dhcp_lease_time:+valid_lft $new_dhcp_lease_time} \
+ ${new_dhcp_lease_time:+preferred_lft $new_dhcp_lease_time} \
+ dev ${interface} label ${interface}
         fi

         if [ -n "$alias_ip_address" ] &&
@@ -323,6 +331,8 @@ case "$reason" in
         # set IP from recorded lease
         ip -4 addr add ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \
             ${new_broadcast_address:+broadcast $new_broadcast_address} \
+ ${new_dhcp_lease_time:+valid_lft $new_dhcp_lease_time} \
+ ${new_dhcp_lease_time:+preferred_lft $new_dhcp_lease_time} \
             dev ${interface} label ${interface}

         if [ -n "$new_interface_mtu" ]; then

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in isc-dhcp (Ubuntu):
status: New → Confirmed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.