Date: Fri, 24 Sep 2004 10:24:18 -0700 From: "Crist J. Clark" <cristjc@comcast.net> To: freebsd-net@freebsd.org Subject: nsupdate(8) rc.d Script Message-ID: <20040924172418.GA91417@blossom.cjclark.org>
next in thread | raw e-mail | index | archive | help
--1yeeQ81UyVL57Vl7 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline As I was setting up DNS for IPv6 on a test network, I started to get really tired of entering 128-bit addresses, for both forward and reverse lookups, into DNS by hand. It seemed somewhat silly to be doing all of this manually when the actual IPv6 hosts pretty much configure themselves with rtsol(8). So I went ahead setting up an nsupdate script to have the systems automatically use DNS updates to "register" themselves. I figured I might as well do IPv4 while I was at it. Now I'm wondering if this is something other people may find useful and whether I should commit it. I think there are enough knobs to make it work for most people. But there very well may be some assumptions that may make it totally unsuitable for a lot of systems too. I'm not 100% sure where to drop it into the rc.d order. Obviously, it is a network service, but it would be nice to sign up in DNS early so we have entries in DNS when other machines might try to look us up when we contact them in later rc.d scripts. One thing that might be nice is if we wait until a local DNS server starts in the case we are the server, but having a DNS server auto-update its own info... kinda a chicken-and-egg problem there, may not be a best practice. Finally, that is one long awk script. Is there a better tool or method for converting an IPv6 presentation address into the ip6.arpa format? And the script is not optimized to do the updates in the fewest number of packets. An update can only contain updates for a single zone. It makes the only safe assumption that any two domain names are not in the same zone unless they are the same. I do not know how to reduce the number of updates without making things a LOT more complicated and doing more total DNS queries to find out SOA information. To enable the updates, just add, nsupdate_enable="YES" To rc.conf(5). The patch to the default rc.conf has it disabled by default. IPv4 and IPv6 updates may be toggled individually, but IPv6 only works if ipv6_enable is also "on." Patch is against RELENG_5, but it should work fine in CURRENT. Suggestions, comments, or criticisms, public or private, are welcome. -- Crist J. Clark | cjclark@alum.mit.edu | cjclark@jhu.edu http://people.freebsd.org/~cjc/ | cjc@freebsd.org --1yeeQ81UyVL57Vl7 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="rc.nsupdate.patch" Index: src/etc/defaults/rc.conf =================================================================== RCS file: /ncvs/src/etc/defaults/rc.conf,v retrieving revision 1.212 diff -u -r1.212 rc.conf --- src/etc/defaults/rc.conf 27 Jul 2004 00:28:16 -0000 1.212 +++ src/etc/defaults/rc.conf 24 Sep 2004 16:54:34 -0000 @@ -139,6 +139,22 @@ # Choose correct tunnel addrs. #gifconfig_gif0="10.1.1.1 10.1.2.1" # Examples typically for a router. #gifconfig_gif1="10.1.1.2 10.1.2.2" # Examples typically for a router. +# Nsupdate(8) allows the machine to send DNS updates to "register" in DNS. +# IPv4 loopback (127/8), and IPv6 loopback (::1) and link-local (fe80::/17) +# addresses are not registered. +nsupdate_enable="NO" # Do any DNS updates. +nsupdate_flags="" # Pass additional arguments, e.g. to use DNSSEC TSIG, + # "-k /etc/namedb:MY_DYN_DNS_KEY" +nsupdate_command="/usr/sbin/nsupdate" # Default is base system's BIND. +nsupdate_ipv4="YES" # Register IPv4 addresses associated with interfaces. +nsupdate_ipv6="YES" # Register IPv6 addresses associated with interfaces. +nsupdate_ifaces="auto" # List interfaces, 'auto,' 'dhcp,' or 'nodhcp.' +nsupdate_ttl="3600" # Time-to-live for the DNS records. +nsupdate_reverse="YES" # Attempt to add "reverse" records, in-addr.arpa + # and ip6.arpa trees. +nsupdate_shutdown_remove="YES" # Remove our records at shutdown. +#nsupdate_hostname_ed0="dynamic-host.example.com" # Associate a hostname + # with an interface, otherwise system hostname used. # User ppp configuration. ppp_enable="NO" # Start user-ppp (or NO). Index: src/etc/rc.d/nsupdate =================================================================== RCS file: src/etc/rc.d/nsupdate diff -N src/etc/rc.d/nsupdate --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/etc/rc.d/nsupdate 24 Sep 2004 16:50:49 -0000 @@ -0,0 +1,124 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: nsupdate +# REQUIRE: NETWORKING +# KEYWORD: FreeBSD + +. /etc/rc.subr +. /etc/network.subr + +name="nsupdate" +rcvar=`set_rcvar` +start_cmd="nsupdate_start" +stop_cmd="nsupdate_stop" + +nsupdate_run() +{ + checkyesno nsupdate_ipv4 + _ipv4_enable="$?" + checkyesno ipv6_enable && checkyesno nsupdate_ipv6 + _ipv6_enable="$?" + checkyesno nsupdate_reverse + _do_reverse="$?" + case "$1" in + 'add') + _action='add' + _ttl="${nsupdate_ttl}" + ;; + 'delete') + _action='delete' + _ttl='' + ;; + *) + return 1 + ;; + esac + case "${nsupdate_ifaces}" in + 'auto') + _interfaces=`list_net_interfaces` + ;; + 'dhcp') + _interfaces=`list_net_interfaces dhcp` + ;; + 'nodhcp') + _interfaces=`list_net_interfaces nodhcp` + ;; + *) + _interfaces="${nsupdate_ifaces}" + esac + for _iface in ${_interfaces}; do + eval _hostname="\$nsupdate_hostname_${_iface}" + if [ -z "${_hostname}" ]; then + _hostname=`hostname` + fi + ifconfig "${_iface}" | + awk -v "inet4=${_ipv4_enable}" -v "inet6=${_ipv6_enable}" \ + -v "hostname=${_hostname}" -v "ttl=${_ttl}" \ + -v "do_reverse=${_do_reverse}" -v "action=${_action}" \ + '! inet4 && /inet / && $2 !~ /^127\./ { + printf "update %s %s %s a %s\n", action, + hostname, ttl, $2; + ip4[++i] = $2; + } + ! inet6 && /inet6 / && $2 !~ /^(fe80:|::1)/ { + printf "update %s %s %s aaaa %s\n", action, + hostname, ttl, $2; + ip6[++j] = $2; + } + END { + print ""; + if (do_reverse != 0) { + exit 0; + } + for (i in ip4) { + split(ip4[i], oct, /\./); + printf "update %s %d.%d.%d.%d.in-addr.arpa %s ptr %s\n", + action, + oct[4], oct[3], oct[2], oct[1], + ttl, hostname; + print ""; + } + for (j in ip6) { + cols = gsub(/:/, ":", ip6[j]); + zeroes = ""; + for (i = cols; i < 8; i++) { + zeros = zeros ":0"; + } + zeros = zeros ":"; + sub(/::/, zeros, ip6[j]); + split(ip6[j], shorts, /:/); + ip6str = ""; + for (i = 1; i <= 8; i++) { + shorts[i] = substr("000" shorts[i], + length(shorts[i])); + ip6str = ip6str shorts[i]; + } + revstr = ""; + for (i = 1; i <= length(ip6str); i++) { + revstr = substr(ip6str, i, 1) "." revstr; + } + printf "update %s %sip6.arpa %s ptr %s\n", + action, revstr, ttl, hostname; + print ""; + } + }' + done | + "${nsupdate_command}" ${nsupdate_flags} +} + +nsupdate_start() +{ + nsupdate_run add +} + +nsupdate_stop() +{ + checkyesno nsupdate_shutdown_remove || return 0 + nsupdate_run delete +} + +load_rc_config $name +run_rc_command "$1" --1yeeQ81UyVL57Vl7--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040924172418.GA91417>