[OpenWRT 23.05] Reverse DNS w/ dual stack IPv6

Thought I'd post this after trying a few different approaches to getting the outcome I'm after, if it helps anyone else, or if someone sees this and knows a cleaner approach.

I have a network with a few VLANs for different devices, I want IPv6 support but also want to attribute traffic for eg. stats in AdGuard Home.

I start with a set of files per network in the format <mac> <internet allowed> <hostname> eg. my IOT vlan config can look like:

00:11:22:33:44:55 y smarttoaster.iot.lan
AA:BB:CC:DD:EE:FF n camera.iot.lan

I then use a script to fetch IPs associated with those mac addresses:

#!/bin/sh

# Check if the correct number of arguments is provided
if [ "$#" -ne 2 ]; then
  echo "Usage: $0 <input_file_with_mac_and_host> <output_host_file>"
  exit 1
fi

# Input file containing MAC and Host info
input_file="$1"

# Output host file path
output_file="$2"

# Clear the output file if it exists
> "$output_file"

# Get the IP-to-MAC mapping from `ip neigh` and store it
ip_neigh_output=$(ip neigh)

# Loop through the file line by line
while read -r line; do
  # Skip empty lines
  if [ -z "$line" ]; then
    continue
  fi

  # Split out each column address
  mac=$(echo "$line" | awk '{print $1}')
  allowed=$(echo "$line" | awk '{print $2}')
  host=$(echo "$line" | awk '{print $3}')

  # Get the IP addresses associated with the MAC address from the stored `ip neigh` output
  ips=$(echo "$ip_neigh_output" | grep -i "$mac" | awk '{print $1}')

  # Check if any IP addresses were found
  if [ -n "$ips" ]; then
    # Loop through each found IP and append to the output file
    for ip in $ips; do
      echo "$ip $host" >> "$output_file"
    done
  fi
done < "$input_file"

and generate per-vlan hosts file + trigger DNSMasq to update with a script like below:

#!/bin/sh

# Generate DNS hosts files
./gen_dns_list.sh /path/to/config/<vlan1> /path/to/hosts/<vlan1>
./gen_dns_list.sh /path/to/config/<vlan2> /path/to/hosts/<vlan2>

# Trigger dnsmasq update
odhcpd-update > /dev/null 2>&1
echo "odchpd-update triggered"

which I have triggered by a few hotplug events/on a timer so the hosts files stay up to date. The host files are loaded into DNSmasq with list addnhosts '/path/to/hosts/<vlan>' entries in /etc/config/dhcp.

I also have a script that extracts the MAC addresses that have internet allowed column set to y:

#!/bin/sh

# Check if the correct number of arguments is provided
if [ "$#" -ne 2 ]; then
  echo "Usage: $0 <input_file_with_mac_and_host> <output_mac_file>"
  exit 1
fi

# Input file containing MAC and Host info
input_file="$1"

# Output mac file path
output_file="$2"

# Clear the output file if it exists
> "$output_file"

# Loop through the file line by line
while read -r line; do
  # Skip empty lines
  if [ -z "$line" ]; then
    continue
  fi

  # Split out each column address
  mac=$(echo "$line" | awk '{print $1}')
  allowed=$(echo "$line" | awk '{print $2}')
  host=$(echo "$line" | awk '{print $3}')

  # Write only if internet allowed flag set
  if [ "$allowed" = "y" ]; then
    echo "$mac" >> "$output_file"
  fi

done < "$input_file"

echo "Mac file generated: $output_file"

and I generate the MAC list per-vlan and trigger firewall4 to update the ipset with a script like:

#!/bin/sh

# Generate MAC hosts files
./gen_mac_list.sh /path/toconfig/<vlan 1> /path/to/maclists/<vlan 1>
./gen_mac_list.sh /path/toconfig/<vlan 2> /path/to/maclists/<vlan 2>

# Flush and rebuild firewall ipset
echo "Flushing NFT mac sets"
nft flush set inet fw4 mac_allowlist_<vlan 1>
nft flush set inet fw4 mac_allowlist_<vlan 2>
fw4 reload-sets

which I run everytime I edit my config files.

In my firewall rules I have every vlan covered by the above set to not allow WAN access in my zone rules, and setup ipset and explicit allowlist rules in /etc/config/firewall as follows:

config ipset
        option name 'mac_allowlist_<vlan>'
        list match 'src_mac'
        option loadfile /path/to/maclists/<vlan>'

config rule
        option name '<vlan>-Allowlist'
        list proto 'all'
        option src '<vlan>'
        option ipset 'mac_allowlist_<vlan>'
        option dest 'wan'
        option target 'ACCEPT'

this allows me to have some basic allowlist control over internet connectivity of IOT devices, and causes devices to lose internet connectivity if they rotate mac addresses (eg. I forget to turn off rotating mac or forget and reconnect to the wifi network causing the mac address to be re-randomized) and makes it quickly noticeable so I can update the MAC address associated with that host. Note the emphasis on basic, this isn't a security solution and doesn't protect against MAC cloning.

I also enter the hosts in the format <hostname>.<vlan>.lan and have dnsmasq local domain set to unassigned.lan so hosts on the guest network or otherwise don't appear in the config get <hostname>.unassigned.lan