>From 6537efa58e4a454c2f54c25091f85a5c6557d49b Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin Date: Sun, 13 Apr 2008 15:24:55 +0400 Subject: [PATCH] Implement creation of named(8) forwarders file via /etc/rc.d/resolv Following the idea of Poul Henning-Kamp, the automated creation of the named forwarders file is implemented. In such configuration local named is thought to be used as the smart DNS cache. The following new rc.conf variables were introduced: - resolv_build_named_forwarders, - resolv_named_forwarders_file, - resolv_named_ip. New manual page, resolv(8), was written. Manual page rc.conf(5) was updated, reflecting the introduction of new variables. dhclient-script was changed to use /etc/rc.d/resolv to create /etc/resolv.conf. New kenv leaf, dhclient.*, was created (actually, there is no kenv registry, so I just used variables from the kenv's dhclient.* namespace) and DNS variables, obtained by dhclient, are stored there. I tried to minimize the impact of the dhclient-script changes upon the next updates of dhclient(8) from OpenBSD, so a new function that replaced add_new_resolv_conf was introduced. Commented entries about the usage of the generated forwarders file were added to the stock named.conf file. Signed-off-by: Eygene Ryabinkin --- etc/defaults/rc.conf | 8 ++ etc/namedb/named.conf | 12 ++ etc/rc.d/resolv | 124 ++++++++++++++++++-- sbin/dhclient/dhclient-script | 23 ++++- share/man/man5/rc.conf.5 | 18 +++ share/man/man8/Makefile | 1 + share/man/man8/resolv.8 | 259 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 434 insertions(+), 11 deletions(-) create mode 100644 share/man/man8/resolv.8 diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index cd9c142..8ef35d7 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -243,6 +243,14 @@ resolv_domain="" # DNS domain we're in. resolv_nameservers="" # List of DNS server IPs, separated by comma or space. # +# resolv. Building of named's forwarders file via dhclient or +# directly via /etc/rc.d/resolv. +# +resolv_build_named_forwarders="NO" # Build forwarders? +resolv_named_forwarders_file=/etc/namedb/named.forwarders.conf # Forwarders file +resolv_named_ip=127.0.0.1 # Where named is listening for requests + +# # kerberos. Do not run the admin daemons on slave servers # kerberos5_server_enable="NO" # Run a kerberos 5 master server (or NO). diff --git a/etc/namedb/named.conf b/etc/namedb/named.conf index bda9a02..508abf5 100644 --- a/etc/namedb/named.conf +++ b/etc/namedb/named.conf @@ -45,6 +45,18 @@ options { 127.0.0.1; }; */ + +// If you're building the forwarders table automatically (option +// resolv_build_named_forwarders is set to the appropriate value +// in the /etc/rc.conf), then you will want to uncomment the next +// line to include the created forwarders table. +// The default forwarders file name is used. If you had customized +// its location via rc.conf's variable resolv_named_forwarders_file, +// replace the name here as well. +/* + include "/etc/namedb/named.forwarders.conf"; + */ + /* * If there is a firewall between you and nameservers you want * to talk to, you might need to uncomment the query-source diff --git a/etc/rc.d/resolv b/etc/rc.d/resolv index 3f36a0c..e5f9f32 100644 --- a/etc/rc.d/resolv +++ b/etc/rc.d/resolv @@ -38,6 +38,9 @@ stop_cmd=':' load_rc_config $name +RNDC=/usr/sbin/rndc +CMP=/usr/bin/cmp + # Helper that echoes the contents of the resolv.conf to the stdout. # Arguments: # 1. domain name, @@ -47,26 +50,129 @@ load_rc_config $name build_resolv () { if [ -n "$1" ]; then echo domain "$1" + echo search "$1" + fi + + if checkyesno resolv_build_named_forwarders && + checkyesno named_enable; then + echo "nameserver $resolv_named_ip" fi set -- "$2" for ns in `IFS=', '; echo $*`; do echo nameserver $ns done + + if [ -f /etc/resolv.conf.tail ]; then + cat /etc/resolv.conf.tail + fi +} + +# Restarts named, if it is already running +named_condreload() { + if "$RNDC" status > /dev/null 2>&1; then + "$RNDC" reload + fi +} + +# Installs new version of the file. If the file to be installed is the +# same as the current one, nothing will be installed. +# Arguments. +# - $1: new file, +# - $2: old file that will be overwritten with the contents of a new one. +# +# Returns zero if the new content was installed and returns one +# when the old file was left untouched. +# +# New file will be removed before the function return. +install_new_file() { + [ -z "$1" ] && return 0 + if [ -z "$2" ]; then + rm -f "$1" + return 0 + fi + + [ -e "$1" -a -f "$1" ] || return 0 + if [ -e "$2" -a -f "$CMP" -a -x "$CMP" ] && \ + "$CMP" "$1" "$2" >/dev/null 2>/dev/null; then + rm -f "$1" + return 1 + else + cp -f "$1" "$2" + fi + + rm -f "$1" + return 0 } -# if the info is available via dhcp/kenv -# build the resolv.conf +# Build named's forwarders file if it is requested by configuration. +# Reloads named via 'rndc'. # -if [ ! -e /etc/resolv.conf -a \ +# Arguments. +# $1 - the list of forwarders, separated by ',' or ' '. +add_new_bind_forwarders() { + local tmpf + + tmpf="$resolv_named_forwarders_file".new.$$ + + [ -z "$1" ] && return + checkyesno resolv_build_named_forwarders || return + + echo 'forwarders {' > "$tmpf" + set -- "$1" + for nameserver in `IFS=', '; echo $*`; do + echo "$nameserver;" + done >> "$tmpf" + echo '};' >> "$tmpf" + + # New contents? Try to reload named. + if install_new_file "$tmpf" "$resolv_named_forwarders_file"; then + chown -RL root:wheel "$resolv_named_forwarders_file" + chmod -RL 644 "$resolv_named_forwarders_file" + + named_condreload + fi +} + +tmp_resolv=/etc/resolv.conf.new.$$ +rm -f "$tmp_resolv" +# If user specified static resolv parameters, use them. +if [ -n "${resolv_domain}" -o -n "${resolv_nameservers}" ]; then + build_resolv \ + "${resolv_domain}" "${resolv_nameservers}" \ + > "$tmp_resolv" + add_new_bind_forwarders "${resolv_nameservers}" +# dhclient-script calls us using kenv's dhclient.* parameters +elif [ -n "`/bin/kenv dhclient.domain-name-servers 2> /dev/null`" -o \ + -n "`/bin/kenv dhclient.domain-name 2> /dev/null`" ]; then + build_resolv \ + "`/bin/kenv dhclient.domain-name 2> /dev/null`" \ + "`/bin/kenv dhclient.domain-name-servers`" \ + > "$tmp_resolv" + add_new_bind_forwarders "`/bin/kenv dhclient.domain-name-servers`" +# If the info is available via dhcp/kenv (from the boot time) +# build the resolv.conf, but only if it is not already exists. +# This is the old historical behaviour of /etc/rc.d/resolv. +elif [ ! -e /etc/resolv.conf -a \ -n "`/bin/kenv dhcp.domain-name-servers 2> /dev/null`" ]; then build_resolv \ "`/bin/kenv dhcp.domain-name 2> /dev/null`" \ - "`/bin/kenv dhcp.domain-name-servers`" \ - > /etc/resolv.conf -elif [ -n "${resolv_domain}" -o -n "${resolv_nameservers}" ]; then - build_resolv \ - "${resolv_domain}" "${resolv_nameservers}" \ - > /etc/resolv.conf + "`/bin/kenv dhcp.domain-name-servers`" > "$tmp_resolv" + add_new_bind_forwarders "`/bin/kenv dhcp.domain-name-servers`" +else + # Create forwarders file without forwarding servers. + # We can not just make it empty, because in the case + # of the 'forward only;' directives, named will throw + # error about non-existent 'forwarders' clause. + if checkyesno resolv_build_named_forwarders; then + if [ -e "$resolv_named_forwarders_file" ]; then + cat << "EOF" > "$resolv_named_forwarders_file" +forwarders {}; +EOF + named_condreload + fi + fi fi +install_new_file "$tmp_resolv" /etc/resolv.conf + diff --git a/sbin/dhclient/dhclient-script b/sbin/dhclient/dhclient-script index f66da5a..9b14962 100644 --- a/sbin/dhclient/dhclient-script +++ b/sbin/dhclient/dhclient-script @@ -22,6 +22,7 @@ ARP=/usr/sbin/arp HOSTNAME=/bin/hostname IFCONFIG='/sbin/ifconfig -n' +KENV=/bin/kenv LOCALHOST=127.0.0.1 @@ -246,6 +247,22 @@ add_new_resolv_conf() { return 1 } +# This is the FreeBSD-specific implementation of resolv.conf updater. +# It sets appropriate variables and invokes the rc.d script that does +# the actual job. +fbsd_resolv () { + "$KENV" -u dhclient.domain-name 2>/dev/null + "$KENV" -u dhclient.domain-name-servers 2>/dev/null + + if [ -n "$new_domain_name" ]; then + "$KENV" dhclient.domain-name="$new_domain_name" + fi + if [ -n "$new_domain_name_servers" ]; then + "$KENV" dhclient.domain-name-servers="$new_domain_name_servers" + fi + /etc/rc.d/resolv restart +} + # Must be used on exit. Invokes the local dhcp client exit hooks, if any. exit_with_hooks() { exit_status=$1 @@ -333,7 +350,8 @@ BOUND|RENEW|REBIND|REBOOT) add_new_alias fi if is_default_interface; then - add_new_resolv_conf + # ORIGINAL CODE: add_new_resolv_conf + fbsd_resolv fi ;; @@ -370,7 +388,8 @@ TIMEOUT) if ! is_default_interface; then exit_with_hooks 0 fi - if add_new_resolv_conf; then + # ORIGINAL CODE: if add_new_resolv_conf; then + if fbsd_resolv; then exit_with_hooks 0 fi fi diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index af5d61f..cd3f039 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -1612,6 +1612,24 @@ Used for the programmatical building of comma- or space-separated list of nameservers. Used for the programmatical building of .Pa /etc/resolv.conf . +.It Va resolv_build_named_forwarders +.Pq Vt bool +Set to +.Dq Li YES +to create forwarders file for +.Xr named 8 . +See the stock +.Pa /etc/namedb/named.conf +for the example of forwarders file usage. +.It Va resolv_named_forwarders_file +.Pq Vt str +Location of the forwarders file. +.It Va resolv_named_ip +IP address where local named instance is listening for the queries. +Will be inserted to the +.Pa /etc/resolv.conf +as the first DNS server when building of the forwarders file is enabled. +Defaults to 127.0.0.1. .It Va kerberos5_server_enable .Pq Vt bool Set to diff --git a/share/man/man8/Makefile b/share/man/man8/Makefile index 4f50312..0613659 100644 --- a/share/man/man8/Makefile +++ b/share/man/man8/Makefile @@ -12,6 +12,7 @@ MAN= adding_user.8 \ rc.sendmail.8 \ rc.subr.8 \ rescue.8 \ + resolv.8 \ sticky.8 \ yp.8 diff --git a/share/man/man8/resolv.8 b/share/man/man8/resolv.8 new file mode 100644 index 0000000..e15e15c --- /dev/null +++ b/share/man/man8/resolv.8 @@ -0,0 +1,259 @@ +.\" Copyright (c) 2008 +.\" Eygene Ryabinkin . All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 13, 2008 +.Dt RESOLV 8 +.Os +. +. +.Sh NAME +.Nm resolv +.Nd resolver library rc.d script +. +. +.Sh SYNOPSIS +.Nm /etc/rc.d/resolv Cm Bro start | stop | restart Brc +. +. +.Sh DESCRIPTION +Startup script +.Pa /etc/rc.d/resolv +configures the +.Xr resolver 3 +library and can configure forwarders for the +.Xr named 8 . +. +. +.Sh OPTIONS +.Pp +Look into +.Xr rc.conf 5 +manual page and search for the +.Va resolv_* +entries to obtain the complete list of directives and the description +of their syntax. +. +. +.Sh IMPLEMENTATION NOTES +. +.Ss Generation of /etc/resolv.conf +. +.Pp +In order to generate +.Pa /etc/resolv.conf +on the fly, one should set the +.Xr rc.conf 5 +variables +.Va resolv_domain +and/or +.Va resolv_nameservers. +The current logic for the generation of +.Pa /etc/resolv.conf +is the following. +.Bl -enum +.It +Check if any +.Xr rc.conf 5 +variable, mentioned just above, is defined. +If yes, generate +.Pa /etc/resolv.conf +using the supplied values. +.It +Check if +.Xr kenv 2 +node +.Va kenv.domain-name-servers +is present. +If yes, generate +.Pa /etc/resolv.conf +using +.Va kenv.domain-name +and +.Va kenv.domain-name-servers . +.It +Check if +.Xr kenv 2 +nodes +.Va dhclient.domain-name-servers +and/or +.Va dhclient.domain-name +are present. +If yes, generate +.Pa /etc/resolv.conf +using their values. +The mentioned +.Xr kenv 1 +variables are produced by the +.Xr dhclient 8 +utility. +.El +.Pp +If the file +.Pa /etc/resolv.conf.tail +is present, its contents will be appended to the generated +.Pa /etc/resolv.conf . +. +.Ss Generation of named forwarders table +. +.Pp +.Nm +also can generate forwarders table for +.Xr named 8 . +The file can be used to point the local +.Xr named 8 +instance to the upstream DNS servers. +The typical usage this functionality is to make local DNS cache +that will consult upstream servers. +.Pp +This mode is activated when the variable +.Va resolv_build_named_forwarders +is enabled in +.Xr rc.conf 5 . +The file, whose name is stored in the +.Xr rc.conf 5 +variable +.Va resolv_named_forwarders_file , +is populated with the upstream DNS server addresses. +The addresses are obtained with the same algorithm as the +.Va nameserver +options in +.Pa /etc/resolv.conf , +described above. +.Pp +If +.Va named_enable +is set in the +.Xr rc.conf 5 , +then one additional +.Va nameserver +entry in the +.Pa /etc/resolv.conf +will be generated. +It will be put as the first DNS server and the IP will be taken +from the +.Xr rc.conf 5 +variable +.Va resolv_named_ip . +It is done to +.Qq glue +the +.Xr resolver 3 +library and the local +.Xr named 8 +instance. +. +. +.Sh FILES +.Bl -tag -width /etc/namedb/named_conf +.It Pa /etc/rc.conf +system-wide configuration variables. +.It Pa /etc/namedb/named.conf +.Xr named 9 +configuration file. +.It Pa /etc/namedb/named.forwarders.conf +default location of the produced forwarders file. +.It Pa /etc/resolv.conf +default +.Xr resolver 3 +configuration file. +.El +. +. +.Sh EXAMPLES +. +.Pp +The following +.Xr rc.conf 5 +options will automatically build +.Pa /etc/resolv.conf +with the corresponding configuration: +.Bd -literal -offset indent +resolv_domain="some.name.tld" +resolv_nameservers="192.168.2.1 192.168.100.254" +.Ed +. +.Pp +The addition the strings +.Bd -literal -offset indent +resolv_build_named_forwarders="YES" +resolv_named_ip="127.0.0.2" +.Ed +will result in the following contents of +.Pa /etc/resolv.conf +.Bd -literal -offset indent +domain some.name.tld +search some.name.tld +nameserver 127.0.0.2 +nameserver 192.168.2.1 +nameserver 192.168.100.254 + +.Ed +. +.Pp +Additionally, the file +.Pa /etc/namedb/named.forwarders.conf +will be populated with the servers 192.168.2.1 and 192.168.100.254. +In order to activate these servers in +.Xr named 9 , +one should uncomment (or add) the following lines to the +.Pa /etc/namedb/named.conf +.Bd -literal -offset indent +// Include the generated forwarders table. +// +// The default forwarders file name is used. +// If you had customized its location via rc.conf variable +// resolv_named_forwarders_file, replace the name here as well. + include "/etc/namedb/named.forwarders.conf"; +.Ed +. +. +.Sh SEE ALSO +.Xr resolver 3 , +.Xr resolver 5 , +.Xr rc.conf 5 , +.Xr named 9 , +.Xr kenv 1 , +.Xr kenv 2 , +.Xr dhclient 8 +. +. +.Sh HISTORY +The +.Nm +manual page first appeared in +.Fx 7.1 . +.Sh AUTHORS +The +.Nm +manual page was written by +.An Eygene Ryabinkin Aq rea-fbsd@codelabs.ru . -- 1.5.3.8