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