During intensive VM testing cycles with rapid provisioning and teardown (especially with tools like Puppet, Chef, or Ansible), DHCP leases can accumulate quickly. Unlike Windows systems, Linux VMs (particularly Ubuntu) don't automatically send DHCPRELEASE packets when shut down. With default lease times of 7 days, this leads to IP exhaustion - exactly what you're experiencing.
On Ubuntu systems running dhcpd
, leases are stored in:
/var/lib/dhcp/dhcpd.leases
This is a plain text file containing all active leases. Before modifying, create a backup:
sudo cp /var/lib/dhcp/dhcpd.leases /var/lib/dhcp/dhcpd.leases.bak
Method 1: Direct File Editing (For Precise Control)
1. Stop the DHCP server:
sudo service isc-dhcp-server stop
2. Open the leases file with root privileges:
sudo nano /var/lib/dhcp/dhcpd.leases
3. Locate leases by client identifier or MAC address. A lease block looks like:
lease 192.168.1.105 { starts 5 2024/02/16 14:32:15; ends 5 2024/02/23 14:32:15; hardware ethernet 00:0c:29:3f:5e:2d; uid "\001\000\014)?^"; client-hostname "test-vm-047"; }
4. Delete the entire lease block (from 'lease' to closing brace)
5. Restart DHCP server:
sudo service isc-dhcp-server start
Method 2: Using dhcpd Command Line
For individual lease removal without stopping service:
echo "lease 192.168.1.105 { }" | sudo tee -a /var/lib/dhcp/dhcpd.leases sudo service isc-dhcp-server restart
When dealing with hundreds of test VMs, use this Python script to clean stale leases:
#!/usr/bin/python3 import re from datetime import datetime, timedelta LEASE_FILE = '/var/lib/dhcp/dhcpd.leases' BACKUP_FILE = '/var/lib/dhcp/dhcpd.leases.bak' MAX_AGE_DAYS = 1 # Delete leases older than this def clean_leases(): with open(LEASE_FILE, 'r') as f: content = f.read() # Make backup with open(BACKUP_FILE, 'w') as f: f.write(content) leases = re.findall(r'(lease .*?\{.*?\})', content, re.DOTALL) current_time = datetime.now() new_content = [] for lease in leases: match = re.search(r'ends (\d) (\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2});', lease) if match: weekday = int(match.group(1)) end_time = datetime.strptime(match.group(2), '%Y/%m/%d %H:%M:%S') if (current_time - end_time) < timedelta(days=MAX_AGE_DAYS): new_content.append(lease) with open(LEASE_FILE, 'w') as f: f.write('\n'.join(new_content)) if __name__ == '__main__': clean_leases() print("Lease cleanup completed. Restart DHCP server to apply changes.")
1. Configure shorter lease times in /etc/dhcp/dhcpd.conf
for test subnets:
subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.200; default-lease-time 600; # 10 minutes max-lease-time 3600; # 1 hour option routers 192.168.1.1; }
2. Force DHCP release in VM shutdown scripts (/etc/init.d/halt
):
/sbin/dhclient -r
After cleaning, check available leases with:
dhcp-lease-list
Or parse the lease file directly:
grep -c "lease " /var/lib/dhcp/dhcpd.leases
During intensive VM provisioning tests (particularly with Ubuntu systems), we often encounter DHCP lease retention issues. The default Ubuntu behavior doesn't release DHCP leases upon VM termination, and with a typical 7-day lease duration, this quickly leads to IP exhaustion. Here's how to surgically remove stale leases without disrupting production systems.
On Ubuntu with dhcpd, leases are stored in:
/var/lib/dhcp/dhcpd.leases
This human-readable file contains all active leases with timestamps and client identifiers.
Use this command to find leases from your test VMs:
grep -A 5 "your-test-vm-prefix" /var/lib/dhcp/dhcpd.leases | less
Or for all inactive leases:
grep -B 5 "abandoned" /var/lib/dhcp/dhcpd.leases
1. First, back up the lease file:
sudo cp /var/lib/dhcp/dhcpd.leases /var/lib/dhcp/dhcpd.leases.bak
2. Edit the leases file (use caution - corrupting this can break DHCP):
sudo nano /var/lib/dhcp/dhcpd.leases
3. Find the lease block to remove (starts with 'lease' and ends with '}'). For example:
lease 192.168.1.105 { starts 5 2023/11/17 14:02:35; ends 5 2023/11/24 14:02:35; abandoned; hardware ethernet 00:0c:29:4f:8e:39; uid "\001\000\014)O\2179"; }
4. Delete the entire lease block (from 'lease' to closing '}')
After editing, restart dhcpd:
sudo service isc-dhcp-server restart # or for newer systems: sudo systemctl restart isc-dhcp-server
For frequent testing, create a cleanup script:
#!/bin/bash # Clean leases for test VMs with 'testvm-' in hostname sudo sed -i '/lease/,/}/ { /testvm-/d }' /var/lib/dhcp/dhcpd.leases sudo systemctl restart isc-dhcp-server
For test environments, consider these dhcpd.conf tweaks:
subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.200; default-lease-time 3600; # 1 hour for tests max-lease-time 7200; # 2 hours max option domain-name-servers 8.8.8.8; }