xref: /freebsd/usr.sbin/unbound/setup/local-unbound-setup.sh (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
1b70d78d6SDag-Erling Smørgrav#!/bin/sh
2b70d78d6SDag-Erling Smørgrav#-
3*4d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause
4b70d78d6SDag-Erling Smørgrav#
5b70d78d6SDag-Erling Smørgrav# Copyright (c) 2013 Dag-Erling Smørgrav
6b70d78d6SDag-Erling Smørgrav# All rights reserved.
7b70d78d6SDag-Erling Smørgrav#
8b70d78d6SDag-Erling Smørgrav# Redistribution and use in source and binary forms, with or without
9b70d78d6SDag-Erling Smørgrav# modification, are permitted provided that the following conditions
10b70d78d6SDag-Erling Smørgrav# are met:
11b70d78d6SDag-Erling Smørgrav# 1. Redistributions of source code must retain the above copyright
12b70d78d6SDag-Erling Smørgrav#    notice, this list of conditions and the following disclaimer.
13b70d78d6SDag-Erling Smørgrav# 2. Redistributions in binary form must reproduce the above copyright
14b70d78d6SDag-Erling Smørgrav#    notice, this list of conditions and the following disclaimer in the
15b70d78d6SDag-Erling Smørgrav#    documentation and/or other materials provided with the distribution.
16b70d78d6SDag-Erling Smørgrav#
17b70d78d6SDag-Erling Smørgrav# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18b70d78d6SDag-Erling Smørgrav# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19b70d78d6SDag-Erling Smørgrav# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20b70d78d6SDag-Erling Smørgrav# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21b70d78d6SDag-Erling Smørgrav# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22b70d78d6SDag-Erling Smørgrav# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23b70d78d6SDag-Erling Smørgrav# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24b70d78d6SDag-Erling Smørgrav# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25b70d78d6SDag-Erling Smørgrav# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26b70d78d6SDag-Erling Smørgrav# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27b70d78d6SDag-Erling Smørgrav# SUCH DAMAGE.
28b70d78d6SDag-Erling Smørgrav#
29b70d78d6SDag-Erling Smørgrav#
30b70d78d6SDag-Erling Smørgrav
31d0d49703SDag-Erling SmørgravD="${DESTDIR}"
32d0d49703SDag-Erling Smørgravecho "destination: ${D}"
33d0d49703SDag-Erling Smørgrav
34b70d78d6SDag-Erling Smørgrav#
35b70d78d6SDag-Erling Smørgrav# Configuration variables
36b70d78d6SDag-Erling Smørgrav#
37b70d78d6SDag-Erling Smørgravuser=""
38b70d78d6SDag-Erling Smørgravunbound_conf=""
39b70d78d6SDag-Erling Smørgravforward_conf=""
40b70d78d6SDag-Erling Smørgravlanzones_conf=""
41b70d78d6SDag-Erling Smørgravcontrol_conf=""
42b70d78d6SDag-Erling Smørgravcontrol_socket=""
43b70d78d6SDag-Erling Smørgravworkdir=""
44b70d78d6SDag-Erling Smørgravconfdir=""
45b70d78d6SDag-Erling Smørgravchrootdir=""
46b70d78d6SDag-Erling Smørgravanchor=""
47b70d78d6SDag-Erling Smørgravpidfile=""
48b70d78d6SDag-Erling Smørgravresolv_conf=""
49b70d78d6SDag-Erling Smørgravresolvconf_conf=""
50b70d78d6SDag-Erling Smørgravservice=""
51b70d78d6SDag-Erling Smørgravstart_unbound=""
52d0d49703SDag-Erling Smørgravuse_tls=""
53b70d78d6SDag-Erling Smørgravforwarders=""
54b70d78d6SDag-Erling Smørgrav
55b70d78d6SDag-Erling Smørgrav#
56b70d78d6SDag-Erling Smørgrav# Global variables
57b70d78d6SDag-Erling Smørgrav#
58b70d78d6SDag-Erling Smørgravself=$(basename $(realpath "$0"))
59d0d49703SDag-Erling Smørgravbkdir=/var/backups
60b70d78d6SDag-Erling Smørgravbkext=$(date "+%Y%m%d.%H%M%S")
61b70d78d6SDag-Erling Smørgrav
62b70d78d6SDag-Erling Smørgrav#
63d0d49703SDag-Erling Smørgrav# Regular expressions
64d0d49703SDag-Erling Smørgrav#
65d0d49703SDag-Erling SmørgravRE_octet="([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
66d0d49703SDag-Erling SmørgravRE_ipv4="(${RE_octet}(\\.${RE_octet}){3})"
67d0d49703SDag-Erling SmørgravRE_word="([0-9A-Fa-f]{1,4})"
68e5f02c14SDag-Erling SmørgravRE_ipv6="((${RE_word}:){1,}(:|${RE_word}?(:${RE_word})*)|::1)"
69d0d49703SDag-Erling SmørgravRE_port="([1-9][0-9]{0,3}|[1-5][0-9]{4,4}|6([0-4][0-9]{3}|5([0-4][0-9]{2}|5([0-2][0-9]|3[0-5]))))"
70d0d49703SDag-Erling SmørgravRE_dnsname="([0-9A-Za-z-]{1,}(\\.[0-9A-Za-z-]{1,})*\\.?)"
71d0d49703SDag-Erling SmørgravRE_forward_addr="((${RE_ipv4}|${RE_ipv6})(@${RE_port})?)"
72d0d49703SDag-Erling SmørgravRE_forward_name="(${RE_dnsname}(@${RE_port})?)"
73d0d49703SDag-Erling SmørgravRE_forward_tls="(${RE_forward_addr}(#${RE_dnsname})?)"
74d0d49703SDag-Erling Smørgrav
75d0d49703SDag-Erling Smørgrav#
76b70d78d6SDag-Erling Smørgrav# Set default values for unset configuration variables.
77b70d78d6SDag-Erling Smørgrav#
78b70d78d6SDag-Erling Smørgravset_defaults() {
79b70d78d6SDag-Erling Smørgrav	: ${user:=unbound}
80b70d78d6SDag-Erling Smørgrav	: ${workdir:=/var/unbound}
81b70d78d6SDag-Erling Smørgrav	: ${confdir:=${workdir}/conf.d}
82b70d78d6SDag-Erling Smørgrav	: ${unbound_conf:=${workdir}/unbound.conf}
83b70d78d6SDag-Erling Smørgrav	: ${forward_conf:=${workdir}/forward.conf}
84b70d78d6SDag-Erling Smørgrav	: ${lanzones_conf:=${workdir}/lan-zones.conf}
85b70d78d6SDag-Erling Smørgrav	: ${control_conf:=${workdir}/control.conf}
86b70d78d6SDag-Erling Smørgrav	: ${control_socket:=/var/run/local_unbound.ctl}
87b70d78d6SDag-Erling Smørgrav	: ${anchor:=${workdir}/root.key}
88b70d78d6SDag-Erling Smørgrav	: ${pidfile:=/var/run/local_unbound.pid}
89b70d78d6SDag-Erling Smørgrav	: ${resolv_conf:=/etc/resolv.conf}
90b70d78d6SDag-Erling Smørgrav	: ${resolvconf_conf:=/etc/resolvconf.conf}
91b70d78d6SDag-Erling Smørgrav	: ${service:=local_unbound}
92b70d78d6SDag-Erling Smørgrav	: ${start_unbound:=yes}
93d0d49703SDag-Erling Smørgrav	: ${use_tls:=no}
94b70d78d6SDag-Erling Smørgrav}
95b70d78d6SDag-Erling Smørgrav
96b70d78d6SDag-Erling Smørgrav#
97b70d78d6SDag-Erling Smørgrav# Verify that the configuration files are inside the working
98b70d78d6SDag-Erling Smørgrav# directory, and if so, set the chroot directory accordingly.
99b70d78d6SDag-Erling Smørgrav#
100b70d78d6SDag-Erling Smørgravset_chrootdir() {
101b70d78d6SDag-Erling Smørgrav	chrootdir="${workdir}"
102b70d78d6SDag-Erling Smørgrav	for file in "${unbound_conf}" "${forward_conf}" \
103b70d78d6SDag-Erling Smørgrav	    "${lanzones_conf}" "${control_conf}" "${anchor}" ; do
104b70d78d6SDag-Erling Smørgrav		if [ "${file#${workdir%/}/}" = "${file}" ] ; then
105b70d78d6SDag-Erling Smørgrav			echo "warning: ${file} is outside ${workdir}" >&2
106b70d78d6SDag-Erling Smørgrav			chrootdir=""
107b70d78d6SDag-Erling Smørgrav		fi
108b70d78d6SDag-Erling Smørgrav	done
109b70d78d6SDag-Erling Smørgrav	if [ -z "${chrootdir}" ] ; then
110b70d78d6SDag-Erling Smørgrav		echo "warning: disabling chroot" >&2
111b70d78d6SDag-Erling Smørgrav	fi
112b70d78d6SDag-Erling Smørgrav}
113b70d78d6SDag-Erling Smørgrav
114b70d78d6SDag-Erling Smørgrav#
115b70d78d6SDag-Erling Smørgrav# Scan through /etc/resolv.conf looking for uncommented nameserver
116b70d78d6SDag-Erling Smørgrav# lines that don't point to localhost and return their values.
117b70d78d6SDag-Erling Smørgrav#
118b70d78d6SDag-Erling Smørgravget_nameservers() {
119b70d78d6SDag-Erling Smørgrav	while read line ; do
120b70d78d6SDag-Erling Smørgrav		local bareline=${line%%\#*}
121b70d78d6SDag-Erling Smørgrav		local key=${bareline%% *}
122b70d78d6SDag-Erling Smørgrav		local value=${bareline#* }
123b70d78d6SDag-Erling Smørgrav		case ${key} in
124b70d78d6SDag-Erling Smørgrav		nameserver)
125b70d78d6SDag-Erling Smørgrav			case ${value} in
126b70d78d6SDag-Erling Smørgrav			127.0.0.1|::1|localhost|localhost.*)
127b70d78d6SDag-Erling Smørgrav				;;
128b70d78d6SDag-Erling Smørgrav			*)
129b70d78d6SDag-Erling Smørgrav				echo "${value}"
130b70d78d6SDag-Erling Smørgrav				;;
131b70d78d6SDag-Erling Smørgrav			esac
132b70d78d6SDag-Erling Smørgrav			;;
133b70d78d6SDag-Erling Smørgrav		esac
134b70d78d6SDag-Erling Smørgrav	done
135b70d78d6SDag-Erling Smørgrav}
136b70d78d6SDag-Erling Smørgrav
137b70d78d6SDag-Erling Smørgrav#
138b70d78d6SDag-Erling Smørgrav# Scan through /etc/resolv.conf looking for uncommented nameserver
139b70d78d6SDag-Erling Smørgrav# lines.  Comment out any that don't point to localhost.  Finally,
140b70d78d6SDag-Erling Smørgrav# append a nameserver line that points to localhost, if there wasn't
141b70d78d6SDag-Erling Smørgrav# one already, and enable the edns0 option.
142b70d78d6SDag-Erling Smørgrav#
143b70d78d6SDag-Erling Smørgravgen_resolv_conf() {
144b70d78d6SDag-Erling Smørgrav	local localhost=no
145b70d78d6SDag-Erling Smørgrav	local edns0=no
146b70d78d6SDag-Erling Smørgrav	while read line ; do
147b70d78d6SDag-Erling Smørgrav		local bareline=${line%%\#*}
148b70d78d6SDag-Erling Smørgrav		local key=${bareline%% *}
149b70d78d6SDag-Erling Smørgrav		local value=${bareline#* }
150b70d78d6SDag-Erling Smørgrav		case ${key} in
151b70d78d6SDag-Erling Smørgrav		nameserver)
152b70d78d6SDag-Erling Smørgrav			case ${value} in
153b70d78d6SDag-Erling Smørgrav			127.0.0.1|::1|localhost|localhost.*)
154b70d78d6SDag-Erling Smørgrav				localhost=yes
155b70d78d6SDag-Erling Smørgrav				;;
156b70d78d6SDag-Erling Smørgrav			*)
157b70d78d6SDag-Erling Smørgrav				echo -n "# "
158b70d78d6SDag-Erling Smørgrav				;;
159b70d78d6SDag-Erling Smørgrav			esac
160b70d78d6SDag-Erling Smørgrav			;;
161b70d78d6SDag-Erling Smørgrav		options)
162b70d78d6SDag-Erling Smørgrav			case ${value} in
163b70d78d6SDag-Erling Smørgrav			*edns0*)
164b70d78d6SDag-Erling Smørgrav				edns0=yes
165b70d78d6SDag-Erling Smørgrav				;;
166b70d78d6SDag-Erling Smørgrav			esac
167b70d78d6SDag-Erling Smørgrav			;;
168b70d78d6SDag-Erling Smørgrav		esac
169b70d78d6SDag-Erling Smørgrav		echo "${line}"
170b70d78d6SDag-Erling Smørgrav	done
171b70d78d6SDag-Erling Smørgrav	if [ "${localhost}" = "no" ] ; then
172b70d78d6SDag-Erling Smørgrav		echo "nameserver 127.0.0.1"
173b70d78d6SDag-Erling Smørgrav	fi
174b70d78d6SDag-Erling Smørgrav	if [ "${edns0}" = "no" ] ; then
175b70d78d6SDag-Erling Smørgrav		echo "options edns0"
176b70d78d6SDag-Erling Smørgrav	fi
177b70d78d6SDag-Erling Smørgrav}
178b70d78d6SDag-Erling Smørgrav
179b70d78d6SDag-Erling Smørgrav#
180b70d78d6SDag-Erling Smørgrav# Boilerplate
181b70d78d6SDag-Erling Smørgrav#
182b70d78d6SDag-Erling Smørgravdo_not_edit() {
183b70d78d6SDag-Erling Smørgrav	echo "# This file was generated by $self."
184b70d78d6SDag-Erling Smørgrav	echo "# Modifications will be overwritten."
185b70d78d6SDag-Erling Smørgrav}
186b70d78d6SDag-Erling Smørgrav
187b70d78d6SDag-Erling Smørgrav#
188b70d78d6SDag-Erling Smørgrav# Generate resolvconf.conf so it updates forward.conf in addition to
189b70d78d6SDag-Erling Smørgrav# resolv.conf.  Note "in addition to" rather than "instead of",
190b70d78d6SDag-Erling Smørgrav# because we still want it to update the domain name and search path
191b70d78d6SDag-Erling Smørgrav# if they change.  Setting name_servers to "127.0.0.1" ensures that
192b70d78d6SDag-Erling Smørgrav# the libc resolver will try unbound first.
193b70d78d6SDag-Erling Smørgrav#
194b70d78d6SDag-Erling Smørgravgen_resolvconf_conf() {
195b70d78d6SDag-Erling Smørgrav	local style="$1"
196b70d78d6SDag-Erling Smørgrav	do_not_edit
1979b20ab1eSDag-Erling Smørgrav	echo "libc=\"NO\""
198b70d78d6SDag-Erling Smørgrav	if [ "${style}" = "dynamic" ] ; then
199b70d78d6SDag-Erling Smørgrav		echo "unbound_conf=\"${forward_conf}\""
200b70d78d6SDag-Erling Smørgrav		echo "unbound_pid=\"${pidfile}\""
201b70d78d6SDag-Erling Smørgrav		echo "unbound_service=\"${service}\""
202b70d78d6SDag-Erling Smørgrav		# resolvconf(8) likes to restart rather than reload
203b70d78d6SDag-Erling Smørgrav		echo "unbound_restart=\"service ${service} reload\""
204b70d78d6SDag-Erling Smørgrav	else
205b70d78d6SDag-Erling Smørgrav		echo "# Static DNS configuration"
206b70d78d6SDag-Erling Smørgrav	fi
207b70d78d6SDag-Erling Smørgrav}
208b70d78d6SDag-Erling Smørgrav
209b70d78d6SDag-Erling Smørgrav#
210b70d78d6SDag-Erling Smørgrav# Generate forward.conf
211b70d78d6SDag-Erling Smørgrav#
212b70d78d6SDag-Erling Smørgravgen_forward_conf() {
213b70d78d6SDag-Erling Smørgrav	do_not_edit
214b70d78d6SDag-Erling Smørgrav	echo "forward-zone:"
215b70d78d6SDag-Erling Smørgrav	echo "        name: ."
216d0d49703SDag-Erling Smørgrav	for forwarder ; do echo "${forwarder}" ; done |
217d0d49703SDag-Erling Smørgrav	if [ "${use_tls}" = "yes" ] ; then
218d0d49703SDag-Erling Smørgrav		echo "        forward-tls-upstream: yes"
219d0d49703SDag-Erling Smørgrav		sed -nE \
2206b938197SDag-Erling Smørgrav		    -e "s/^${RE_forward_tls}\$/        forward-addr: \\1/p"
221b70d78d6SDag-Erling Smørgrav	else
222d0d49703SDag-Erling Smørgrav		sed -nE \
223d0d49703SDag-Erling Smørgrav		    -e "s/^${RE_forward_addr}\$/        forward-addr: \\1/p" \
224d0d49703SDag-Erling Smørgrav		    -e "s/^${RE_forward_name}\$/        forward-host: \\1/p"
225b70d78d6SDag-Erling Smørgrav	fi
226b70d78d6SDag-Erling Smørgrav}
227b70d78d6SDag-Erling Smørgrav
228b70d78d6SDag-Erling Smørgrav#
229b70d78d6SDag-Erling Smørgrav# Generate lan-zones.conf
230b70d78d6SDag-Erling Smørgrav#
231b70d78d6SDag-Erling Smørgravgen_lanzones_conf() {
232b70d78d6SDag-Erling Smørgrav	do_not_edit
233b70d78d6SDag-Erling Smørgrav	echo "server:"
234b70d78d6SDag-Erling Smørgrav	echo "        # Unblock reverse lookups for LAN addresses"
235b70d78d6SDag-Erling Smørgrav	echo "        unblock-lan-zones: yes"
236b70d78d6SDag-Erling Smørgrav	echo "        insecure-lan-zones: yes"
237b70d78d6SDag-Erling Smørgrav}
238b70d78d6SDag-Erling Smørgrav
239b70d78d6SDag-Erling Smørgrav#
240b70d78d6SDag-Erling Smørgrav# Generate control.conf
241b70d78d6SDag-Erling Smørgrav#
242b70d78d6SDag-Erling Smørgravgen_control_conf() {
243b70d78d6SDag-Erling Smørgrav	do_not_edit
244b70d78d6SDag-Erling Smørgrav	echo "remote-control:"
245b70d78d6SDag-Erling Smørgrav	echo "        control-enable: yes"
246b70d78d6SDag-Erling Smørgrav	echo "        control-interface: ${control_socket}"
247b70d78d6SDag-Erling Smørgrav	echo "        control-use-cert: no"
248b70d78d6SDag-Erling Smørgrav}
249b70d78d6SDag-Erling Smørgrav
250b70d78d6SDag-Erling Smørgrav#
251b70d78d6SDag-Erling Smørgrav# Generate unbound.conf
252b70d78d6SDag-Erling Smørgrav#
253b70d78d6SDag-Erling Smørgravgen_unbound_conf() {
254b70d78d6SDag-Erling Smørgrav	do_not_edit
255b70d78d6SDag-Erling Smørgrav	echo "server:"
256b70d78d6SDag-Erling Smørgrav	echo "        username: ${user}"
257b70d78d6SDag-Erling Smørgrav	echo "        directory: ${workdir}"
258b70d78d6SDag-Erling Smørgrav	echo "        chroot: ${chrootdir}"
259b70d78d6SDag-Erling Smørgrav	echo "        pidfile: ${pidfile}"
260b70d78d6SDag-Erling Smørgrav	echo "        auto-trust-anchor-file: ${anchor}"
261d0d49703SDag-Erling Smørgrav	if [ "${use_tls}" = "yes" ] ; then
2628932f7ceSTijl Coosemans		echo "        tls-system-cert: yes"
263d0d49703SDag-Erling Smørgrav	fi
264b70d78d6SDag-Erling Smørgrav	echo ""
265b70d78d6SDag-Erling Smørgrav	if [ -f "${forward_conf}" ] ; then
266b70d78d6SDag-Erling Smørgrav		echo "include: ${forward_conf}"
267b70d78d6SDag-Erling Smørgrav	fi
268b70d78d6SDag-Erling Smørgrav	if [ -f "${lanzones_conf}" ] ; then
269b70d78d6SDag-Erling Smørgrav		echo "include: ${lanzones_conf}"
270b70d78d6SDag-Erling Smørgrav	fi
271b70d78d6SDag-Erling Smørgrav	if [ -f "${control_conf}" ] ; then
272b70d78d6SDag-Erling Smørgrav		echo "include: ${control_conf}"
273b70d78d6SDag-Erling Smørgrav	fi
274b70d78d6SDag-Erling Smørgrav	if [ -d "${confdir}" ] ; then
275b70d78d6SDag-Erling Smørgrav		echo "include: ${confdir}/*.conf"
276b70d78d6SDag-Erling Smørgrav	fi
277b70d78d6SDag-Erling Smørgrav}
278b70d78d6SDag-Erling Smørgrav
279b70d78d6SDag-Erling Smørgrav#
280202ec220SDag-Erling Smørgrav# Rename a file we are about to replace.
281202ec220SDag-Erling Smørgrav#
282202ec220SDag-Erling Smørgravbackup() {
283202ec220SDag-Erling Smørgrav	local file="$1"
284d0d49703SDag-Erling Smørgrav	if [ -f "${D}${file}" ] ; then
285d0d49703SDag-Erling Smørgrav		local bkfile="${bkdir}/${file##*/}.${bkext}"
286202ec220SDag-Erling Smørgrav		echo "Original ${file} saved as ${bkfile}"
287d0d49703SDag-Erling Smørgrav		mv "${D}${file}" "${D}${bkfile}"
288202ec220SDag-Erling Smørgrav	fi
289202ec220SDag-Erling Smørgrav}
290202ec220SDag-Erling Smørgrav
291202ec220SDag-Erling Smørgrav#
292d0d49703SDag-Erling Smørgrav# Wrapper for mktemp which respects DESTDIR
293d0d49703SDag-Erling Smørgrav#
294d0d49703SDag-Erling Smørgravtmp() {
295d0d49703SDag-Erling Smørgrav	local file="$1"
296d0d49703SDag-Erling Smørgrav	mktemp -u "${D}${file}.XXXXX"
297d0d49703SDag-Erling Smørgrav}
298d0d49703SDag-Erling Smørgrav
299d0d49703SDag-Erling Smørgrav#
300b70d78d6SDag-Erling Smørgrav# Replace one file with another, making a backup copy of the first,
301b70d78d6SDag-Erling Smørgrav# but only if the new file is different from the old.
302b70d78d6SDag-Erling Smørgrav#
303b70d78d6SDag-Erling Smørgravreplace() {
304b70d78d6SDag-Erling Smørgrav	local file="$1"
305b70d78d6SDag-Erling Smørgrav	local newfile="$2"
306d0d49703SDag-Erling Smørgrav	if [ ! -f "${D}${file}" ] ; then
307b70d78d6SDag-Erling Smørgrav		echo "${file} created"
308d0d49703SDag-Erling Smørgrav		mv "${newfile}" "${D}${file}"
309d0d49703SDag-Erling Smørgrav	elif ! cmp -s "${D}${file}" "${newfile}" ; then
310202ec220SDag-Erling Smørgrav		backup "${file}"
311d0d49703SDag-Erling Smørgrav		mv "${newfile}" "${D}${file}"
312b70d78d6SDag-Erling Smørgrav	else
313b70d78d6SDag-Erling Smørgrav		echo "${file} not modified"
314b70d78d6SDag-Erling Smørgrav		rm "${newfile}"
315b70d78d6SDag-Erling Smørgrav	fi
316b70d78d6SDag-Erling Smørgrav}
317b70d78d6SDag-Erling Smørgrav
318b70d78d6SDag-Erling Smørgrav#
319b70d78d6SDag-Erling Smørgrav# Print usage message and exit
320b70d78d6SDag-Erling Smørgrav#
321b70d78d6SDag-Erling Smørgravusage() {
322b70d78d6SDag-Erling Smørgrav	exec >&2
323b70d78d6SDag-Erling Smørgrav	echo "usage: $self [options] [forwarder ...]"
324b70d78d6SDag-Erling Smørgrav	echo "options:"
325b70d78d6SDag-Erling Smørgrav	echo "    -n          do not start unbound"
326b70d78d6SDag-Erling Smørgrav	echo "    -a path     full path to trust anchor file"
327b70d78d6SDag-Erling Smørgrav	echo "    -C path     full path to additional configuration directory"
328b70d78d6SDag-Erling Smørgrav	echo "    -c path     full path to unbound configuration file"
329b70d78d6SDag-Erling Smørgrav	echo "    -f path     full path to forwarding configuration"
330b70d78d6SDag-Erling Smørgrav	echo "    -O path     full path to remote control socket"
331b70d78d6SDag-Erling Smørgrav	echo "    -o path     full path to remote control configuration"
332b70d78d6SDag-Erling Smørgrav	echo "    -p path     full path to pid file"
333b70d78d6SDag-Erling Smørgrav	echo "    -R path     full path to resolvconf.conf"
334b70d78d6SDag-Erling Smørgrav	echo "    -r path     full path to resolv.conf"
335b70d78d6SDag-Erling Smørgrav	echo "    -s service  name of unbound service"
336b70d78d6SDag-Erling Smørgrav	echo "    -u user     user to run unbound as"
337b70d78d6SDag-Erling Smørgrav	echo "    -w path     full path to working directory"
338b70d78d6SDag-Erling Smørgrav	exit 1
339b70d78d6SDag-Erling Smørgrav}
340b70d78d6SDag-Erling Smørgrav
341b70d78d6SDag-Erling Smørgrav#
342b70d78d6SDag-Erling Smørgrav# Main
343b70d78d6SDag-Erling Smørgrav#
344b70d78d6SDag-Erling Smørgravmain() {
345b70d78d6SDag-Erling Smørgrav	umask 022
346b70d78d6SDag-Erling Smørgrav
347b70d78d6SDag-Erling Smørgrav	#
348b70d78d6SDag-Erling Smørgrav	# Parse and validate command-line options
349b70d78d6SDag-Erling Smørgrav	#
350d0d49703SDag-Erling Smørgrav	while getopts "a:C:c:f:no:p:R:r:s:tu:w:" option ; do
351b70d78d6SDag-Erling Smørgrav		case $option in
352b70d78d6SDag-Erling Smørgrav		a)
353b70d78d6SDag-Erling Smørgrav			anchor="$OPTARG"
354b70d78d6SDag-Erling Smørgrav			;;
355b70d78d6SDag-Erling Smørgrav		C)
356b70d78d6SDag-Erling Smørgrav			confdir="$OPTARG"
357b70d78d6SDag-Erling Smørgrav			;;
358b70d78d6SDag-Erling Smørgrav		c)
359b70d78d6SDag-Erling Smørgrav			unbound_conf="$OPTARG"
360b70d78d6SDag-Erling Smørgrav			;;
361b70d78d6SDag-Erling Smørgrav		f)
362b70d78d6SDag-Erling Smørgrav			forward_conf="$OPTARG"
363b70d78d6SDag-Erling Smørgrav			;;
364b70d78d6SDag-Erling Smørgrav		n)
365b70d78d6SDag-Erling Smørgrav			start_unbound="no"
366b70d78d6SDag-Erling Smørgrav			;;
367b70d78d6SDag-Erling Smørgrav		O)
368b70d78d6SDag-Erling Smørgrav			control_socket="$OPTARG"
369b70d78d6SDag-Erling Smørgrav			;;
370b70d78d6SDag-Erling Smørgrav		o)
371b70d78d6SDag-Erling Smørgrav			control_conf="$OPTARG"
372b70d78d6SDag-Erling Smørgrav			;;
373b70d78d6SDag-Erling Smørgrav		p)
374b70d78d6SDag-Erling Smørgrav			pidfile="$OPTARG"
375b70d78d6SDag-Erling Smørgrav			;;
376b70d78d6SDag-Erling Smørgrav		R)
377b70d78d6SDag-Erling Smørgrav			resolvconf_conf="$OPTARG"
378b70d78d6SDag-Erling Smørgrav			;;
379b70d78d6SDag-Erling Smørgrav		r)
380b70d78d6SDag-Erling Smørgrav			resolv_conf="$OPTARG"
381b70d78d6SDag-Erling Smørgrav			;;
382b70d78d6SDag-Erling Smørgrav		s)
383b70d78d6SDag-Erling Smørgrav			service="$OPTARG"
384b70d78d6SDag-Erling Smørgrav			;;
385d0d49703SDag-Erling Smørgrav		t)
386d0d49703SDag-Erling Smørgrav			use_tls="yes"
387d0d49703SDag-Erling Smørgrav			;;
388b70d78d6SDag-Erling Smørgrav		u)
389b70d78d6SDag-Erling Smørgrav			user="$OPTARG"
390b70d78d6SDag-Erling Smørgrav			;;
391b70d78d6SDag-Erling Smørgrav		w)
392b70d78d6SDag-Erling Smørgrav			workdir="$OPTARG"
393b70d78d6SDag-Erling Smørgrav			;;
394b70d78d6SDag-Erling Smørgrav		*)
395b70d78d6SDag-Erling Smørgrav			usage
396b70d78d6SDag-Erling Smørgrav			;;
397b70d78d6SDag-Erling Smørgrav		esac
398b70d78d6SDag-Erling Smørgrav	done
399b70d78d6SDag-Erling Smørgrav	shift $((OPTIND-1))
400b70d78d6SDag-Erling Smørgrav	set_defaults
401b70d78d6SDag-Erling Smørgrav
402b70d78d6SDag-Erling Smørgrav	#
403b70d78d6SDag-Erling Smørgrav	# Get the list of forwarders, either from the command line or
404b70d78d6SDag-Erling Smørgrav	# from resolv.conf.
405b70d78d6SDag-Erling Smørgrav	#
406b70d78d6SDag-Erling Smørgrav	forwarders="$@"
407202ec220SDag-Erling Smørgrav	case "${forwarders}" in
408202ec220SDag-Erling Smørgrav	[Nn][Oo][Nn][Ee])
409202ec220SDag-Erling Smørgrav		forwarders="none"
410202ec220SDag-Erling Smørgrav		style=recursing
411202ec220SDag-Erling Smørgrav		;;
412202ec220SDag-Erling Smørgrav	"")
4136b938197SDag-Erling Smørgrav		if [ -f "${D}${resolv_conf}" ] ; then
414b70d78d6SDag-Erling Smørgrav			echo "Extracting forwarders from ${resolv_conf}."
415d0d49703SDag-Erling Smørgrav			forwarders=$(get_nameservers <"${D}${resolv_conf}")
4166b938197SDag-Erling Smørgrav		fi
417b70d78d6SDag-Erling Smørgrav		style=dynamic
418202ec220SDag-Erling Smørgrav		;;
419202ec220SDag-Erling Smørgrav	*)
420b70d78d6SDag-Erling Smørgrav		style=static
421202ec220SDag-Erling Smørgrav		;;
422202ec220SDag-Erling Smørgrav	esac
423b70d78d6SDag-Erling Smørgrav
424b70d78d6SDag-Erling Smørgrav	#
425b70d78d6SDag-Erling Smørgrav	# Generate forward.conf.
426b70d78d6SDag-Erling Smørgrav	#
427b70d78d6SDag-Erling Smørgrav	if [ -z "${forwarders}" ] ; then
428b70d78d6SDag-Erling Smørgrav		echo -n "No forwarders found in ${resolv_conf##*/}, "
429b70d78d6SDag-Erling Smørgrav		if [ -f "${forward_conf}" ] ; then
430b70d78d6SDag-Erling Smørgrav			echo "using existing ${forward_conf##*/}."
431b70d78d6SDag-Erling Smørgrav		else
432b70d78d6SDag-Erling Smørgrav			echo "unbound will recurse."
433b70d78d6SDag-Erling Smørgrav		fi
434202ec220SDag-Erling Smørgrav	elif [ "${forwarders}" = "none" ] ; then
435202ec220SDag-Erling Smørgrav		echo "Forwarding disabled, unbound will recurse."
436202ec220SDag-Erling Smørgrav		backup "${forward_conf}"
437b70d78d6SDag-Erling Smørgrav	else
438d0d49703SDag-Erling Smørgrav		local tmp_forward_conf=$(tmp "${forward_conf}")
439b70d78d6SDag-Erling Smørgrav		gen_forward_conf ${forwarders} | unexpand >"${tmp_forward_conf}"
440b70d78d6SDag-Erling Smørgrav		replace "${forward_conf}" "${tmp_forward_conf}"
441b70d78d6SDag-Erling Smørgrav	fi
442b70d78d6SDag-Erling Smørgrav
443b70d78d6SDag-Erling Smørgrav	#
444b70d78d6SDag-Erling Smørgrav	# Generate lan-zones.conf.
445b70d78d6SDag-Erling Smørgrav	#
446d0d49703SDag-Erling Smørgrav	local tmp_lanzones_conf=$(tmp "${lanzones_conf}")
447b70d78d6SDag-Erling Smørgrav	gen_lanzones_conf | unexpand >"${tmp_lanzones_conf}"
448b70d78d6SDag-Erling Smørgrav	replace "${lanzones_conf}" "${tmp_lanzones_conf}"
449b70d78d6SDag-Erling Smørgrav
450b70d78d6SDag-Erling Smørgrav	#
451b70d78d6SDag-Erling Smørgrav	# Generate control.conf.
452b70d78d6SDag-Erling Smørgrav	#
453d0d49703SDag-Erling Smørgrav	local tmp_control_conf=$(tmp "${control_conf}")
454b70d78d6SDag-Erling Smørgrav	gen_control_conf | unexpand >"${tmp_control_conf}"
455b70d78d6SDag-Erling Smørgrav	replace "${control_conf}" "${tmp_control_conf}"
456b70d78d6SDag-Erling Smørgrav
457b70d78d6SDag-Erling Smørgrav	#
458b70d78d6SDag-Erling Smørgrav	# Generate unbound.conf.
459b70d78d6SDag-Erling Smørgrav	#
460d0d49703SDag-Erling Smørgrav	local tmp_unbound_conf=$(tmp "${unbound_conf}")
461b70d78d6SDag-Erling Smørgrav	set_chrootdir
462b70d78d6SDag-Erling Smørgrav	gen_unbound_conf | unexpand >"${tmp_unbound_conf}"
463b70d78d6SDag-Erling Smørgrav	replace "${unbound_conf}" "${tmp_unbound_conf}"
464b70d78d6SDag-Erling Smørgrav
465b70d78d6SDag-Erling Smørgrav	#
466b70d78d6SDag-Erling Smørgrav	# Start unbound, unless requested not to.  Stop immediately if
467b70d78d6SDag-Erling Smørgrav	# it is not enabled so we don't end up with a resolv.conf that
468b70d78d6SDag-Erling Smørgrav	# points into nothingness.  We could "onestart" it, but it
469b70d78d6SDag-Erling Smørgrav	# wouldn't stick.
470b70d78d6SDag-Erling Smørgrav	#
471b70d78d6SDag-Erling Smørgrav	if [ "${start_unbound}" = "no" ] ; then
472b70d78d6SDag-Erling Smørgrav		# skip
473b70d78d6SDag-Erling Smørgrav	elif ! service "${service}" enabled ; then
474b70d78d6SDag-Erling Smørgrav		echo "Please enable $service in rc.conf(5) and try again."
475b70d78d6SDag-Erling Smørgrav		return 1
476b70d78d6SDag-Erling Smørgrav	elif ! service "${service}" restart ; then
477b70d78d6SDag-Erling Smørgrav		echo "Failed to start $service."
478b70d78d6SDag-Erling Smørgrav		return 1
479b70d78d6SDag-Erling Smørgrav	fi
480b70d78d6SDag-Erling Smørgrav
481b70d78d6SDag-Erling Smørgrav	#
482b70d78d6SDag-Erling Smørgrav	# Rewrite resolvconf.conf so resolvconf updates forward.conf
483b70d78d6SDag-Erling Smørgrav	# instead of resolv.conf.
484b70d78d6SDag-Erling Smørgrav	#
485d0d49703SDag-Erling Smørgrav	local tmp_resolvconf_conf=$(tmp "${resolvconf_conf}")
486b70d78d6SDag-Erling Smørgrav	gen_resolvconf_conf "${style}" | unexpand >"${tmp_resolvconf_conf}"
487b70d78d6SDag-Erling Smørgrav	replace "${resolvconf_conf}" "${tmp_resolvconf_conf}"
488b70d78d6SDag-Erling Smørgrav
489b70d78d6SDag-Erling Smørgrav	#
490b70d78d6SDag-Erling Smørgrav	# Finally, rewrite resolv.conf.
491b70d78d6SDag-Erling Smørgrav	#
492d0d49703SDag-Erling Smørgrav	local tmp_resolv_conf=$(tmp "${resolv_conf}")
493d0d49703SDag-Erling Smørgrav	gen_resolv_conf <"${D}${resolv_conf}" | unexpand >"${tmp_resolv_conf}"
494b70d78d6SDag-Erling Smørgrav	replace "${resolv_conf}" "${tmp_resolv_conf}"
495b70d78d6SDag-Erling Smørgrav}
496b70d78d6SDag-Erling Smørgrav
497b70d78d6SDag-Erling Smørgravmain "$@"
498