summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/defaults/rc.conf1
-rw-r--r--etc/rc.d/Makefile5
-rwxr-xr-xetc/rc.d/local_unbound91
-rw-r--r--etc/rc.subr9
-rw-r--r--share/man/man5/rc.conf.510
-rw-r--r--share/man/man8/rc.85
-rw-r--r--share/man/man8/rc.subr.85
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc2
-rw-r--r--usr.sbin/unbound/Makefile1
-rw-r--r--usr.sbin/unbound/local-setup/Makefile6
-rwxr-xr-xusr.sbin/unbound/local-setup/local-unbound-setup.sh357
11 files changed, 488 insertions, 4 deletions
diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index 39957278..80f279d 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -270,6 +270,7 @@ hastd_enable="NO" # Run the HAST daemon (YES/NO).
hastd_program="/sbin/hastd" # path to hastd, if you want a different one.
hastd_flags="" # Optional flags to hastd.
ctld_enable="NO" # CAM Target Layer / iSCSI target daemon.
+local_unbound_enable="NO" # local caching resolver
#
# named. It may be possible to run named in a sandbox, man security for
# details.
diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile
index 153918d..82775f9 100644
--- a/etc/rc.d/Makefile
+++ b/etc/rc.d/Makefile
@@ -150,6 +150,7 @@ FILES= DAEMON \
tmp \
${_ubthidhci} \
ugidfw \
+ ${_unbound} \
${_utx} \
var \
virecover \
@@ -184,6 +185,10 @@ _nscd= nscd
_ubthidhci= ubthidhci
.endif
+.if ${MK_UNBOUND} != "no"
+_unbound= local_unbound
+.endif
+
.if ${MK_UTMPX} != "no"
_utx= utx
.endif
diff --git a/etc/rc.d/local_unbound b/etc/rc.d/local_unbound
new file mode 100755
index 0000000..899e356
--- /dev/null
+++ b/etc/rc.d/local_unbound
@@ -0,0 +1,91 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: local_unbound
+# REQUIRE: SERVERS cleanvar
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="local_unbound"
+desc="local caching forwarding resolver"
+rcvar="local_unbound_enable"
+
+command="/usr/sbin/unbound"
+extra_commands="anchor configtest reload setup"
+start_precmd="local_unbound_prestart"
+reload_precmd="local_unbound_configtest"
+anchor_cmd="local_unbound_anchor"
+configtest_cmd="local_unbound_configtest"
+setup_cmd="local_unbound_setup"
+pidfile="/var/run/${name}.pid"
+
+: ${local_unbound_workdir:=/var/unbound}
+: ${local_unbound_config:=${local_unbound_workdir}/unbound.conf}
+: ${local_unbound_flags:=-c${local_unbound_config}}
+: ${local_unbound_forwardconf:=${local_unbound_workdir}/forward.conf}
+: ${local_unbound_anchor:=${local_unbound_workdir}/root.key}
+: ${local_unbound_forwarders:=}
+
+load_rc_config $name
+
+do_as_unbound()
+{
+ echo "$@" | su -m unbound
+}
+
+#
+# Retrieve or update the DNSSEC root anchor
+#
+local_unbound_anchor()
+{
+ do_as_unbound /usr/sbin/unbound-anchor -a ${local_unbound_anchor}
+ # we can't trust the exit code - check if the file exists
+ [ -f ${local_unbound_anchor} ]
+}
+
+#
+# Check the unbound configuration file
+#
+local_unbound_configtest()
+{
+ do_as_unbound /usr/sbin/unbound-checkconf ${local_unbound_config}
+}
+
+#
+# Create the unbound configuration file and update resolv.conf to
+# point to unbound.
+#
+local_unbound_setup()
+{
+ echo "Performing initial setup."
+ /usr/sbin/local-unbound-setup -n \
+ -u unbound \
+ -w ${local_unbound_workdir} \
+ -c ${local_unbound_config} \
+ -f ${local_unbound_forwardconf} \
+ -a ${local_unbound_anchor} \
+ ${local_unbound_forwarders}
+}
+
+#
+# Before starting, check that the configuration file and root anchor
+# exist. If not, attempt to generate them.
+#
+local_unbound_prestart()
+{
+ # Create configuration file
+ if [ ! -f ${local_unbound_config} ] ; then
+ run_rc_command setup
+ fi
+
+ # Retrieve DNSSEC root key
+ if [ ! -f ${local_unbound_anchor} ] ; then
+ run_rc_command anchor
+ fi
+}
+
+load_rc_config $name
+run_rc_command "$1"
diff --git a/etc/rc.subr b/etc/rc.subr
index bce2257..aee0c95 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -546,6 +546,8 @@ check_startmsgs()
#
# rcvar Display what rc.conf variable is used (if any).
#
+# enabled Return true if the service is enabled.
+#
# Variables available to methods, and after run_rc_command() has
# completed:
#
@@ -614,7 +616,7 @@ run_rc_command()
eval _override_command=\$${name}_program
command=${_override_command:-$command}
- _keywords="start stop restart rcvar $extra_commands"
+ _keywords="start stop restart rcvar enabled $extra_commands"
rc_pid=
_pidcmd=
_procname=${procname:-${command}}
@@ -635,6 +637,11 @@ run_rc_command()
rc_usage $_keywords
fi
+ if [ "$rc_arg" = "enabled" ] ; then
+ checkyesno ${rcvar}
+ return $?
+ fi
+
if [ -n "$flags" ]; then # allow override from environment
rc_flags=$flags
else
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 054e444..4f14c7f 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 10, 2013
+.Dd September 23, 2013
.Dt RC.CONF 5
.Os
.Sh NAME
@@ -2041,6 +2041,13 @@ is set to
.Dq Li YES ,
these are the flags to pass to
.Xr hastd 8 .
+.It Va local_unbound_enable
+.Pq Vt bool
+If set to
+.Dq Li YES ,
+run the
+.Xr unbound 8
+daemon as a local caching resolver.
.It Va named_enable
.Pq Vt bool
If set to
@@ -4786,6 +4793,7 @@ The default is 30.
.Xr sysctl 8 ,
.Xr syslogd 8 ,
.Xr timed 8 ,
+.Xr unbound 8 ,
.Xr usbconfig 8 ,
.Xr wlandebug 8 ,
.Xr yp 8 ,
diff --git a/share/man/man8/rc.8 b/share/man/man8/rc.8
index cca05d4..32d0ade 100644
--- a/share/man/man8/rc.8
+++ b/share/man/man8/rc.8
@@ -35,7 +35,7 @@
.\" @(#)rc.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd January 14, 2012
+.Dd September 23, 2013
.Dt RC 8
.Os
.Sh NAME
@@ -312,6 +312,9 @@ Defaults to displaying the process ID of the program (if running).
If the script starts a process (rather than performing a one-off
operation), wait for the command to exit.
Otherwise it is not necessary to support this argument.
+.It Cm enabled
+Return 0 if the service is enabled and 1 if it is not.
+This command does not print anything.
.It Cm rcvar
Display which
.Xr rc.conf 5
diff --git a/share/man/man8/rc.subr.8 b/share/man/man8/rc.subr.8
index 8ed2470..7c3b654 100644
--- a/share/man/man8/rc.subr.8
+++ b/share/man/man8/rc.subr.8
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 14, 2012
+.Dd September 23, 2012
.Dt RC.SUBR 8
.Os
.Sh NAME
@@ -379,6 +379,9 @@ Perform a
then a
.Cm start .
Defaults to displaying the process ID of the program (if running).
+.It Cm enabled
+Return 0 if the service is enabled and 1 if it is not.
+This command does not print anything.
.It Cm rcvar
Display which
.Xr rc.conf 5
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index 8ca6975..028e01f 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -4375,6 +4375,7 @@ OLD_FILES+=usr/share/man/man8/telnetd.8.gz
#.endif
.if ${MK_UNBOUND} == no
+OLD_FILES+=etc/rc.d/local_unbound
OLD_FILES+=usr/lib/private/libunbound.a
OLD_FILES+=usr/lib/private/libunbound.so
OLD_LIBS+=usr/lib/private/libunbound.so.5
@@ -4385,6 +4386,7 @@ OLD_FILES+=usr/lib32/private/libunbound.so
OLD_LIBS+=usr/lib32/private/libunbound.so.5
OLD_FILES+=usr/lib32/private/libunbound_p.a
.endif
+OLD_FILES+=usr/sbin/local-unbound-setup
OLD_FILES+=usr/sbin/unbound
OLD_FILES+=usr/sbin/unbound-anchor
OLD_FILES+=usr/sbin/unbound-checkconf
diff --git a/usr.sbin/unbound/Makefile b/usr.sbin/unbound/Makefile
index 2672d23..3eb12fe 100644
--- a/usr.sbin/unbound/Makefile
+++ b/usr.sbin/unbound/Makefile
@@ -1,5 +1,6 @@
# $FreeBSD$
SUBDIR= daemon anchor checkconf control
+SUBDIR+= local-setup
.include <bsd.subdir.mk>
diff --git a/usr.sbin/unbound/local-setup/Makefile b/usr.sbin/unbound/local-setup/Makefile
new file mode 100644
index 0000000..7a1bc0441
--- /dev/null
+++ b/usr.sbin/unbound/local-setup/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+SCRIPTS= local-unbound-setup.sh
+MAN= #
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/unbound/local-setup/local-unbound-setup.sh b/usr.sbin/unbound/local-setup/local-unbound-setup.sh
new file mode 100755
index 0000000..11561ac
--- /dev/null
+++ b/usr.sbin/unbound/local-setup/local-unbound-setup.sh
@@ -0,0 +1,357 @@
+#!/bin/sh
+#-
+# Copyright (c) 2013 Dag-Erling Smørgrav
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$
+#
+
+#
+# Configuration variables
+#
+user=""
+unbound_conf=""
+forward_conf=""
+workdir=""
+chrootdir=""
+anchor=""
+pidfile=""
+resolv_conf=""
+resolvconf_conf=""
+service=""
+start_unbound=""
+forwarders=""
+
+#
+# Global variables
+#
+self=$(basename $(realpath "$0"))
+bkext=$(date "+%Y%m%d.%H%M%S")
+
+#
+# Set default values for unset configuration variables.
+#
+set_defaults() {
+ : ${user:=unbound}
+ : ${workdir:=/var/unbound}
+ : ${unbound_conf:=${workdir}/unbound.conf}
+ : ${forward_conf:=${workdir}/forward.conf}
+ : ${anchor:=${workdir}/root.key}
+ : ${pidfile:=/var/run/local_unbound.pid}
+ : ${resolv_conf:=/etc/resolv.conf}
+ : ${resolvconf_conf:=/etc/resolvconf.conf}
+ : ${service:=local_unbound}
+ : ${start_unbound:=yes}
+}
+
+#
+# Verify that the configuration files are inside the working
+# directory, and if so, set the chroot directory accordingly.
+#
+set_chrootdir() {
+ chrootdir="${workdir}"
+ for file in "${unbound_conf}" "${forward_conf}" "${anchor}" ; do
+ if [ "${file#${workdir%/}/}" = "${file}" ] ; then
+ echo "warning: ${file} is outside ${workdir}" >&2
+ chrootdir=""
+ fi
+ done
+ if [ -z "${chrootdir}" ] ; then
+ echo "warning: disabling chroot" >&2
+ fi
+}
+
+#
+# Scan through /etc/resolv.conf looking for uncommented nameserver
+# lines that don't point to localhost and return their values.
+#
+get_nameservers() {
+ while read line ; do
+ local bareline=${line%%\#*}
+ local key=${bareline%% *}
+ local value=${bareline#* }
+ case ${key} in
+ nameserver)
+ case ${value} in
+ 127.0.0.1|::1|localhost|localhost.*)
+ ;;
+ *)
+ echo "${value}"
+ ;;
+ esac
+ ;;
+ esac
+ done
+}
+
+#
+# Scan through /etc/resolv.conf looking for uncommented nameserver
+# lines. Comment out any that don't point to localhost. Finally,
+# append a nameserver line that points to localhost, if there wasn't
+# one already, and enable the edns0 option.
+#
+gen_resolv_conf() {
+ local localhost=no
+ local edns0=no
+ while read line ; do
+ local bareline=${line%%\#*}
+ local key=${bareline%% *}
+ local value=${bareline#* }
+ case ${key} in
+ nameserver)
+ case ${value} in
+ 127.0.0.1|::1|localhost|localhost.*)
+ localhost=yes
+ ;;
+ *)
+ echo -n "# "
+ ;;
+ esac
+ ;;
+ options)
+ case ${value} in
+ *edns0*)
+ edns0=yes
+ ;;
+ esac
+ ;;
+ esac
+ echo "${line}"
+ done
+ if [ "${localhost}" = "no" ] ; then
+ echo "nameserver 127.0.0.1"
+ fi
+ if [ "${edns0}" = "no" ] ; then
+ echo "options edns0"
+ fi
+}
+
+#
+# Generate resolvconf.conf so it updates forward.conf in addition to
+# resolv.conf. Note "in addition to" rather than "instead of",
+# because we still want it to update the domain name and search path
+# if they change. Setting name_servers to "127.0.0.1" ensures that
+# the libc resolver will try unbound first.
+#
+gen_resolvconf_conf() {
+ echo "# Generated by $self"
+ echo "name_servers=\"127.0.0.1\""
+ echo "unbound_conf=\"${forward_conf}\""
+ echo "unbound_pid=\"${pidfile}\""
+ echo "unbound_service=\"${service}\""
+ # resolvconf(8) likes to restart rather than reload - consider
+ # forcing its hand?
+ #echo "unbound_restart=\"service ${service} reload\""
+}
+
+#
+# Generate forward.conf
+#
+gen_forward_conf() {
+ echo "# Generated by $self"
+ echo "forward-zone:"
+ echo " name: ."
+ for forwarder ; do
+ if expr "${forwarder}" : "^[0-9:.]\{1,\}$" >/dev/null ; then
+ echo " forward-addr: ${forwarder}"
+ else
+ echo " forward-host: ${forwarder}"
+ fi
+ done
+}
+
+#
+# Generate unbound.conf
+#
+gen_unbound_conf() {
+ echo "# Generated by $self"
+ echo "server:"
+ echo " username: ${user}"
+ echo " directory: ${workdir}"
+ echo " chroot: ${chrootdir}"
+ echo " pidfile: ${pidfile}"
+ echo " auto-trust-anchor-file: ${anchor}"
+ echo ""
+ if [ -f "${forward_conf}" ] ; then
+ echo "include: ${forward_conf}"
+ fi
+}
+
+#
+# Replace one file with another, making a backup copy of the first,
+# but only if the new file is different from the old.
+#
+replace() {
+ local file="$1"
+ local newfile="$2"
+ if [ ! -f "${file}" ] ; then
+ echo "${file} created"
+ mv "${newfile}" "${file}"
+ elif ! cmp -s "${file}" "${newfile}" ; then
+ local oldfile="${file}.${bkext}"
+ echo "original ${file} saved as ${oldfile}"
+ mv "${file}" "${oldfile}"
+ mv "${newfile}" "${file}"
+ else
+ echo "${file} not modified"
+ rm "${newfile}"
+ fi
+}
+
+#
+# Print usage message and exit
+#
+usage() {
+ exec >&2
+ echo "usage: $self [options] [forwarder ...]"
+ echo "options:"
+ echo " -n do not start unbound"
+ echo " -a path full path to trust anchor file"
+ echo " -c path full path to unbound configuration"
+ echo " -f path full path to forwarding configuration"
+ echo " -p path full path to pid file"
+ echo " -R path full path to resolvconf.conf"
+ echo " -r path full path to resolv.conf"
+ echo " -s service name of unbound service"
+ echo " -u user user to run unbound as"
+ echo " -w path full path to working directory"
+ exit 1
+}
+
+#
+# Main
+#
+main() {
+ umask 022
+
+ #
+ # Parse and validate command-line options
+ #
+ while getopts "a:c:f:np:R:r:s:u:w:" option ; do
+ case $option in
+ a)
+ anchor="$OPTARG"
+ ;;
+ c)
+ unbound_conf="$OPTARG"
+ ;;
+ f)
+ forward_conf="$OPTARG"
+ ;;
+ n)
+ start_unbound="no"
+ ;;
+ p)
+ pidfile="$OPTARG"
+ ;;
+ R)
+ resolvconf_conf="$OPTARG"
+ ;;
+ r)
+ resolv_conf="$OPTARG"
+ ;;
+ s)
+ service="$OPTARG"
+ ;;
+ u)
+ user="$OPTARG"
+ ;;
+ w)
+ workdir="$OPTARG"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ done
+ shift $((OPTIND-1))
+ set_defaults
+
+ #
+ # Get the list of forwarders, either from the command line or
+ # from resolv.conf.
+ #
+ forwarders="$@"
+ if [ -z "$forwarders" ] ; then
+ echo "Extracting forwarders from ${resolv_conf}."
+ forwarders=$(get_nameservers <"${resolv_conf}")
+ fi
+
+ #
+ # Generate forward.conf.
+ #
+ if [ -z "${forwarders}" ] ; then
+ echo -n "No forwarders found in ${resolv_conf##*/}, "
+ if [ -f "${forward_conf}" ] ; then
+ echo "using existing ${forward_conf##*/}."
+ else
+ echo "unbound will recurse."
+ fi
+ else
+ local tmp_forward_conf=$(mktemp -u "${forward_conf}.XXXXX")
+ gen_forward_conf ${forwarders} >"${tmp_forward_conf}"
+ replace "${forward_conf}" "${tmp_forward_conf}"
+ fi
+
+ #
+ # Generate unbound.conf.
+ #
+ local tmp_unbound_conf=$(mktemp -u "${unbound_conf}.XXXXX")
+ set_chrootdir
+ gen_unbound_conf >"${tmp_unbound_conf}"
+ replace "${unbound_conf}" "${tmp_unbound_conf}"
+
+ #
+ # Start unbound, unless requested not to. Stop immediately if
+ # it is not enabled so we don't end up with a resolv.conf that
+ # points into nothingness. We could "onestart" it, but it
+ # wouldn't stick.
+ #
+ if [ "${start_unbound}" = "no" ] ; then
+ # skip
+ elif ! service "${service}" enabled ; then
+ echo "Please enable $service in rc.conf(5) and try again."
+ return 1
+ elif ! service "${service}" restart ; then
+ echo "Failed to start $service."
+ return 1
+ fi
+
+ #
+ # Rewrite resolvconf.conf so resolvconf updates forward.conf
+ # instead of resolv.conf.
+ #
+ local tmp_resolvconf_conf=$(mktemp -u "${resolvconf_conf}.XXXXX")
+ gen_resolvconf_conf >"${tmp_resolvconf_conf}"
+ replace "${resolvconf_conf}" "${tmp_resolvconf_conf}"
+
+ #
+ # Finally, rewrite resolv.conf.
+ #
+ local tmp_resolv_conf=$(mktemp -u "${resolv_conf}.XXXXX")
+ gen_resolv_conf <"${resolv_conf}" >"${tmp_resolv_conf}"
+ replace "${resolv_conf}" "${tmp_resolv_conf}"
+}
+
+main "$@"
OpenPOWER on IntegriCloud