To avoid dnsmasq writing out the whole leasefile on each request before replying. This gets slow on high‐latency storage. Also tweak DNS updates a bit.
		
			
				
	
	
		
			76 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Django/Jinja
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Django/Jinja
		
	
	
	
	
	
| #!/bin/sh
 | |
| 
 | |
| # This script replaces the dnsmasq leasefile with an sqlite database
 | |
| # for performance on slow storage, and updates DNS records for
 | |
| # assigned addresses.
 | |
| 
 | |
| cmd="${1}"
 | |
| 
 | |
| # dnsmasq calls this script on startup for each known lease, ignore it
 | |
| [ "${cmd}" != "init" ] && [ -z "${DNSMASQ_INTERFACE}" ] && exit 0
 | |
| 
 | |
| # parameters
 | |
| db=/var/lib/misc/dnsmasq.leases.db
 | |
| domain={{ domain }}
 | |
| ldap_user={{ password.ldap_user }}
 | |
| ttl=3600
 | |
| 
 | |
| # sanitize input
 | |
| mac="${2//[![:xdigit:]:]/}"
 | |
| ipv4="${3//[![:digit:].]/}"
 | |
| hostname="${4//[![:alnum:]_-]/}"
 | |
| client_id="${DNSMASQ_CLIENT_ID//[![:xdigit:]:]/}"
 | |
| 
 | |
| # construct SQL to query or update leases, and nsupdate script to update DNS records
 | |
| dns=""
 | |
| sql=""
 | |
| case "${cmd}" in
 | |
| "init")
 | |
| 	# init runs as root, so ensure the dnsmasq user can write to database later
 | |
| 	touch "${db}"
 | |
| 	chown dnsmasq:dnsmasq "${db}"
 | |
| 	setfacl -m u:dnsmasq:rwx "$(dirname ${db})"
 | |
| 	setfacl -m u:dnsmasq:r "/etc/krb5.keytab" # needed for DNS updates
 | |
| 
 | |
| 	# ensure the leases table exists, and get all leases from it
 | |
| 	sql="CREATE TABLE IF NOT EXISTS leases (
 | |
| 			ipv4 TEXT PRIMARY KEY NOT NULL,
 | |
| 			mac TEXT NOT NULL,
 | |
| 			hostname TEXT NOT NULL,
 | |
| 			client_id TEXT NOT NULL,
 | |
| 			renewed INTEGER NOT NULL);
 | |
| 		SELECT renewed, mac, ipv4, hostname, client_id FROM leases;"
 | |
| 	;;
 | |
| 
 | |
| "add" | "old")
 | |
| 	# add or update the lease
 | |
| 	sql="INSERT INTO leases
 | |
| 			VALUES ('${ipv4}', '${mac}', '${hostname:-*}', '${client_id:-*}', unixepoch())
 | |
| 			ON CONFLICT(ipv4) DO UPDATE SET renewed = unixepoch();"
 | |
| 
 | |
| 	# add or update the DNS record
 | |
| 	if [ -n "${hostname}" ] ; then
 | |
| 		dns="update add ${hostname}.${domain} ${ttl} A ${ipv4}\n"
 | |
| 	fi
 | |
| 	if [ -n "${DNSMASQ_OLD_HOSTNAME}" ] ; then
 | |
| 		dns="${dns}update del ${DNSMASQ_OLD_HOSTNAME}.${domain}\n"
 | |
| 	fi
 | |
| 	;;
 | |
| 
 | |
| "del")
 | |
| 	# delete the lease
 | |
| 	sql="DELETE FROM leases WHERE ipv4 = '${ipv4}';"
 | |
| 	# TODO probably delete the DNS record
 | |
| 	;;
 | |
| esac
 | |
| 
 | |
| # update lease database
 | |
| if [ -n "${sql}" ]; then
 | |
| 	sqlite3 -separator " " "${db}" "${sql}"
 | |
| fi
 | |
| 
 | |
| # update DNS records
 | |
| if [ -n "${dns}" ]; then
 | |
| 	kinit -k "${ldap_user}"
 | |
| 	echo -e "${dns}send" | nsupdate -g
 | |
| fi
 |