DNS information in IPv6 Router Advertisement on MacOS X
Saturday Mar 26, 2011
On my IPv6 router, I have the router advertisement daemon 'radvd' running:
blackbox# more /etc/radvd.conf
interface eth0
{
AdvOtherConfigFlag on;
AdvManagedFlag off;
AdvSendAdvert on;
RDNSS 2001:db8:2b6::1 {
AdvRDNSSLifetime 84600;
};
prefix 2001:db8:2b6::/64
{
AdvOnLink on;
AdvAutonomous on;
};
};
The Line 'RDNSS 2001:db8:2b6::1' configures the advertisement daemon to send the DNS Servers IPv6 address '2001:db8:2b6::1' with a lifetime of 24 hours (86400 seconds).
When the 'rdnssd' service is then started on a MacOS X client, it will receive the DNS server information and write it into the file '/usr/local/var/run/rdnssd/resolv.conf' (this file location can be changed with the commandline option '–resolv-file' (however 'rdnssd' should never write directly into '/etc/resolv.conf', as this will overwrite any data received via DHCP). The content of this file after receiving the DNS information is
more /usr/local/var/run/rdnssd/resolv.conf nameserver 2001:db8:2b6::1
Whenever the 'rdnssd' daemon updates its 'resolv.conf' file, it can start a script (the script location can be configured with '–merge-hook merge-hook', the default location is '/usr/local/etc/rdnssd/merge-hook' ('rdnssd' comes with an example script for Linux, but this will not work on MacOS X).
simple 'rdnssd' script hook:
#! /bin/sh
#
# resolv.conf merge hook for rdnssd
# MacOS X 10.6 version
# Carsten Strotmann, March 2011
# partly based on a scipt by Stephan Oeste
set -e
system_resolv="/etc/resolv.conf"
rdnssd_resolv="/usr/local/var/run/rdnssd/resolv.conf"
# make sure that each IP only appears once
cat $system_resolv $rdnssd_resolv | sort | uniq > /tmp/resolv.conf.tmp
# get the IP addresses of all DNS servers
ip=`cat /tmp/resolv.conf.tmp | grep "nameserver" | awk '{printf "%s ", $2}'`
# get the local domain
domain=`cat /tmp/resolv.conf.tmp | grep "domain" | awk '{printf "%s ", $2}'`
rm /tmp/resolv.conf.tmp
PSID=$( (scutil | grep PrimaryService | sed -e 's/.*PrimaryService : //')<< EOF
open
get State:/Network/Global/IPv4
d.show
quit
EOF
)
scutil << EOF
open
d.init
d.add ServerAddresses * $ip
d.add DomainName $domain
set State:/Network/Service/$PSID/DNS
quit
EOF
This is the LaunchDaemon description for the 'rdnssd' service:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
<plist version='1.0'>
<dict>
<key>Label</key><string>net.linkfanel.ndisc6</string>
<key>ServiceDescription</key>
<string>Recursive DNS Solicitation Daemon</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/sbin/rdnssd</string>
<string>-f</string>
<string>-H/usr/local/etc/rdnssd/merge-hook</string>
<string>-r/usr/local/var/run/rdnssd/resolv.conf</string>
</array>
<key>WorkingDirectory</key>
<string>/</string>
<key>Debug</key><false/>
<key>Disabled</key><false/>
<key>OnDemand</key><false/>
<key>RunAtLoad</key><true/>
</dict>
</plist>
To start the 'rdnssd' service, copy the above plist into
/Library/LaunchDaemons/net.linkfanel.ndisc6.rdnssd.plist and
reconfigure launchd with sudo launchctl load -w /Library/LaunchDaemons/net.linkfanel.ndisc6.rdnssd.plist.