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