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
.