DnsMasq Network-Wide Blocking Part II. Dealing with Hostnames

NetworkAs stated last time; When you’re no longer serving DNS from the same machine as your DHCP server, local hostnames may become an issue.

If you’re like me, all the things you actually would be needing to access by name in that matter already have static addresses and /etc/hosts file entries. I had an idea that I thought should be shared though.

This is a little script I wrote. What it does, is takes the dhcp.leases file on an OpenWRT router and produces a correctly formatted hosts file. In the previous article, I offered my custom config, and you’ll see the option to have dnsmasq parse your /etc/hosts file — this is for that.

Weather you have 4 devices on your network, 40 or however many you’ve got, this is an easy way to get the local hostnames working on your new custom DNS setup.

Here is the code for Leases2Hosts, you can run it right on OpenWRT.

#!/bin/sh
# OpenWrt Leases2Hosts 0.01 -- BTA 03.13.2025 -- LostGeek.NET
# Transforms OpenWrt dhcp leases file into format suitable for external DNS server

LEASES_FILE="/tmp/dhcp.leases"
OUTPUT_FILE="/tmp/dhcp.hosts"

# Set domain suffix (leave blank to disable)
DOMAIN_SUFFIX=".lan"

# Ensure the leases file exists
[ -f "$LEASES_FILE" ] || { echo "Leases file not found!"; exit 1; }

# New hosts file header
echo "# Generated by Lease2Hosts" > "$OUTPUT_FILE"

# Process the leases file using BusyBox-compatible awk
awk -v suffix="$DOMAIN_SUFFIX" '
{
    ip = $3;
    hostname = $4;

    # Ignore entries where hostname is "*"
    if (hostname == "*") next;

    # Ensure hostname is not a MAC address (contains colons)
    if (index(hostname, ":") > 0) next;

    # Ensure hostname is only letters, numbers, dots, and dashes
    if (match(hostname, /^[a-zA-Z0-9.-]+$/)) {
        if (suffix != "") {
            print ip, hostname, hostname suffix;
        } else {
            print ip, hostname;
        }
    }
}' "$LEASES_FILE" >> "$OUTPUT_FILE"

echo "Hosts file:"
echo "-----"
cat $OUTPUT_FILE
echo "-----"
echo "Hosts file written: $OUTPUT_FILE"

You can run this once and be done, if you don’t always add and change devices. It can also be auto started via a cron job.

I think there is even a way to have an event-based trigger so perhaps it could run as soon as a new lease is given to a unique device. I’ll leave that up to the reader though!

For those who don’t know, what this does is reads the DHCP leases file; this has the IPs and hostnames of all DHCP clients on your network. It also has mac addresses though, and may contain nameless entries, both of which you obviously don’t want in your hosts file. I’d imagine this could be very useful if you’ve got a network full of machines, VMs, or IoT devices… heck, even a family with laptops, smartphones and tablets.

It produces output as follows: 10.0.0.1 workstation1 workstation1.local 10.0.0.2 laptop1 laptop1.local etc…

From the dhcp.leases file, which looks something like this: *1621306452 c8:3d:6b:55:f1:e5 10.0.0.22 Roku * 1772607384 2c:ab:67:3d:90:5d 10.0.0.29 piframe 01:2c:cf:67:3d:90:5d etc…*

Quite ugly — notice the double MAC?? Well, that happens, especially on modern cell phones which hide their mac as a privacy feature, and on cheap-o devices which don’t have the mac set in stone.

Originally MACs weren’t supposed to just be changed on a whim but rather burned into the device’s eprom. My script aims to sort out all of this non-sense. I have had excellent results using the script, however please review it before using the generated list. If you understand shell script basics and awk, you can gauge your own confidence in it being fairly safe, but I shall make no such guarantee.

Using cron and scp, you can automate putting this new hosts file on your DNS server. However, I’d recommend that you use it simply to save you time in formatting a hosts file from a large lease pool — and it seems to do so quite well.

© 2025 LostGeek.NET - All Rights Reserved. Powered by ClassicPress, NGINX, Debian GNU/Linux.