Discussion:
[Dnsmasq-discuss] Filter ULA answers
Craig Howard
2016-11-17 06:28:32 UTC
Permalink
I figured out a way to achieve my goal. There might be a feature
built into dnsmasq that does this natively, but what I'm doing is
using a dhcp-script to create a hostsdir. As a lease is created, I
create a with the name being the IP. I filter out the GUA addresses,
so the file is not created in that case. I hope this helps someone.

Here's the relevant bit of my config:

***@ap1:/usr/bin$ cat /etc/dnsmasq.conf | tail -7
# Manage names by script. The script runs, which updates /var/lib/dnsmasq.d
# This directory becomes a hostdir for dnsmasq. Names are generated by
# treating each file as an /etc/hosts entry. dnsmasq does an inotify of this
# directory, so changes are picked up dynamically. The script filteres out the
# GUA ipv6 address and returns the ULA address only from DNS.
dhcp-script=/usr/bin/dhcp-update.sh
hostsdir=/var/lib/dnsmasq.d

And here's my script:

***@ap1:/usr/bin$ cat dhcp-update.sh
#!/bin/sh

op="${1:-op}"
mac="${2:-mac}"
ip="${3:-ip}"
hostname="${4}"

is_v6=1
dir="/var/lib/dnsmasq.d"
log_tag="dhcp-update.sh"

if echo $ip | grep -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'; then
is_v6=0
logger -t $log_tag "v4 $op $mac $ip $hostname"
else
logger -t $log_tag "v6 $op $mac $ip $hostname"
fi

ula_prefix=$(uci get network.globals.ula_prefix | cut -d/ -f1)

# If there's no name, there's no point in setting up DNS
if [ -z $hostname ]; then
exit 0
fi

# For v6, only record ULA addresses
if [ $is_v6 -eq 1 ]; then
if ! echo $ip | grep -E "^$ula_prefix"; then
exit 0
fi
fi

# Create or delete a file, named by ip, containing a hosts entry
if [ $op = "del" ]; then
rm -f $dir/$ip
elif [ $op = "add" -o $op = "old" ]; then
rm -f $dir/$ip
echo "${ip} ${hostname}" > $dir/$ip
fi

exit 0
I've got dnsmasq running on my home network, which is dual-stack. I'm
playing around with ipv6, mostly with the goal of learning it. I've
got a machine on my network called brix. It's got both slaac and
dhcpv6 assigned addresses. Which means that when I dig it, I get
$ dig brix.choward.ca aaaa +short
fd0f:e273:26d2:0:feaa:14ff:fead:b208
fd0f:e273:26d2::16
2601:xxx:xxx:xxx::16
2601:xxx:xxx:xxx:feaa:14ff:fead:b208
The DNS cache cycles through those answers nicely. However, because
the answer mixes GUA and ULA and DNS cycles through the response
order, it's non-deterministic which address I'll use when I browse to
the HTTP server. This makes setting up ACLs hard. It also doesn't
allow me to follow the recommendation of preferring ULA when I'm
staying within my home network. (https://tools.ietf.org/html/rfc7368)
What I'd like to do is have dnsmasq return only the ULA addresses from
within my home network. I assume some people would prefer the
reverse, depending on how they've deployed dnsmasq. How can I filter
to return ULA answers only? I'm not seeing an obvious way.
Thanks,
Craig
Loading...