When UCI local zone is private and static, Unbound covered private addresses with defaults. Optional delegated global IP6 prefix protection lacked a static zone, but it was prevented from appearing in global DNS responses. Domain names router-as-TLD, "lan." and "local." were static, but they lacked default SOA or NS such as Unbound had assinged to private addresses. Clean up these local zones UCI evaluation and block global DNS inclusion. Signed-off-by: Eric Luehrsen <ericluehrsen@hotmail.com>
1388 lines
38 KiB
Bash
1388 lines
38 KiB
Bash
#!/bin/sh
|
|
##############################################################################
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License version 2 as
|
|
# published by the Free Software Foundation.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# Copyright (C) 2016 Eric Luehrsen
|
|
#
|
|
##############################################################################
|
|
#
|
|
# Unbound is a full featured recursive server with many options. The UCI
|
|
# provided tries to simplify and bundle options. This should make Unbound
|
|
# easier to deploy. Even light duty routers may resolve recursively instead of
|
|
# depending on a stub with the ISP. The UCI also attempts to replicate dnsmasq
|
|
# features as used in base LEDE/OpenWrt. If there is a desire for more
|
|
# detailed tuning, then manual conf file overrides are also made available.
|
|
#
|
|
##############################################################################
|
|
|
|
UNBOUND_B_SLAAC6_MAC=0
|
|
UNBOUND_B_DNSSEC=0
|
|
UNBOUND_B_DNS64=0
|
|
UNBOUND_B_EXT_STATS=0
|
|
UNBOUND_B_GATE_NAME=0
|
|
UNBOUND_B_HIDE_BIND=1
|
|
UNBOUND_B_LOCL_BLCK=0
|
|
UNBOUND_B_LOCL_SERV=1
|
|
UNBOUND_B_MAN_CONF=0
|
|
UNBOUND_B_NTP_BOOT=1
|
|
UNBOUND_B_QUERY_MIN=0
|
|
UNBOUND_B_QRY_MINST=0
|
|
UNBOUND_B_AUTH_ROOT=0
|
|
|
|
UNBOUND_D_CONTROL=0
|
|
UNBOUND_D_DOMAIN_TYPE=static
|
|
UNBOUND_D_DHCP_LINK=none
|
|
UNBOUND_D_EXTRA_DNS=0
|
|
UNBOUND_D_LAN_FQDN=0
|
|
UNBOUND_D_PRIV_BLCK=1
|
|
UNBOUND_D_PROTOCOL=mixed
|
|
UNBOUND_D_RESOURCE=small
|
|
UNBOUND_D_RECURSION=passive
|
|
UNBOUND_D_WAN_FQDN=0
|
|
|
|
UNBOUND_IP_DNS64="64:ff9b::/96"
|
|
|
|
UNBOUND_N_EDNS_SIZE=1280
|
|
UNBOUND_N_FWD_PORTS=""
|
|
UNBOUND_N_RX_PORT=53
|
|
UNBOUND_N_ROOT_AGE=9
|
|
|
|
UNBOUND_TTL_MIN=120
|
|
|
|
UNBOUND_TXT_DOMAIN=lan
|
|
UNBOUND_TXT_FWD_ZONE=""
|
|
UNBOUND_TXT_HOSTNAME=thisrouter
|
|
|
|
UNBOUND_LIST_FORWARD=""
|
|
UNBOUND_LIST_INSECURE=""
|
|
|
|
##############################################################################
|
|
|
|
# keep track of assignments during inserted resource records
|
|
UNBOUND_LIST_DOMAINS=""
|
|
UNBOUND_LIST_IFACE=""
|
|
UNBOUND_LIST_PRV_IP6GLA=""
|
|
UNBOUND_LIST_LAN_NET=""
|
|
|
|
# Similar default SOA / NS RR as Unbound uses for private ARPA zones
|
|
UNBOUND_XSOA="3600 IN SOA localhost. nobody.invalid. 1 3600 1200 7200 600"
|
|
UNBOUND_XNS="3600 IN NS localhost."
|
|
|
|
##############################################################################
|
|
|
|
. /lib/functions.sh
|
|
. /lib/functions/network.sh
|
|
|
|
. /usr/lib/unbound/defaults.sh
|
|
. /usr/lib/unbound/dnsmasq.sh
|
|
. /usr/lib/unbound/iptools.sh
|
|
. /usr/lib/unbound/rootzone.sh
|
|
|
|
##############################################################################
|
|
|
|
create_interface_dns() {
|
|
local cfg="$1"
|
|
local ipcommand logint ignore ifname ifdashname
|
|
local name names address addresses
|
|
local ulaprefix if_fqdn host_fqdn
|
|
local mode_ptr="$UNBOUND_TXT_HOSTNAME"
|
|
local names="$UNBOUND_TXT_HOSTNAME"
|
|
|
|
# Create local-data: references for this hosts interfaces (router).
|
|
config_get logint "$cfg" interface
|
|
config_get_bool ignore "$cfg" ignore 0
|
|
network_get_device ifname "$cfg"
|
|
|
|
ifdashname="${ifname//./-}"
|
|
ipcommand="ip -o address show $ifname"
|
|
addresses=$( $ipcommand | awk '/inet/{sub(/\/.*/,"",$4); print $4}' )
|
|
ulaprefix=$( uci_get network.@globals[0].ula_prefix )
|
|
host_fqdn="$UNBOUND_TXT_HOSTNAME.$UNBOUND_TXT_DOMAIN"
|
|
if_fqdn="$ifdashname.$host_fqdn"
|
|
|
|
|
|
if [ -z "$ifdashname" ] ; then
|
|
# race conditions at init can rarely cause a blank device return
|
|
# the record format is invalid and Unbound won't load the conf file
|
|
mode=0
|
|
|
|
elif [ -n "$UNBOUND_LIST_IFACE" ] ; then
|
|
case "$UNBOUND_LIST_IFACE" in
|
|
*$ifdashname*)
|
|
# repeat such as dual WAN (eth0-1) and WAN6 (eth0-1)
|
|
mode=0
|
|
;;
|
|
|
|
*)
|
|
mode=1
|
|
;;
|
|
esac
|
|
|
|
else
|
|
mode=1
|
|
fi
|
|
|
|
|
|
if [ $mode -gt 0 ] ; then
|
|
UNBOUND_LIST_IFACE="$UNBOUND_LIST_IFACE $ifdashname"
|
|
|
|
|
|
if [ -z "${ulaprefix%%:/*}" ] ; then
|
|
# Nonsense so this option isn't globbed below
|
|
ulaprefix="fdno:such:addr::/48"
|
|
fi
|
|
|
|
|
|
if [ "$ignore" -gt 0 ] ; then
|
|
mode="$UNBOUND_D_WAN_FQDN"
|
|
else
|
|
mode="$UNBOUND_D_LAN_FQDN"
|
|
fi
|
|
fi
|
|
|
|
|
|
if [ "$mode" -gt 1 ] ; then
|
|
case "$mode" in
|
|
3)
|
|
mode_ptr="$host_fqdn"
|
|
names="$host_fqdn $UNBOUND_TXT_HOSTNAME"
|
|
;;
|
|
|
|
4)
|
|
mode_ptr="$if_fqdn"
|
|
names="$if_fqdn $host_fqdn $UNBOUND_TXT_HOSTNAME"
|
|
;;
|
|
esac
|
|
|
|
|
|
{
|
|
for address in $addresses ; do
|
|
case $address in
|
|
fe80:*|169.254.*)
|
|
echo " # note link address $address"
|
|
;;
|
|
|
|
[1-9a-f]*:*[0-9a-f])
|
|
# GA and ULA IP6 for HOST IN AAA records (ip command is robust)
|
|
for name in $names ; do
|
|
echo " local-data: \"$name. 120 IN AAAA $address\""
|
|
done
|
|
echo " local-data-ptr: \"$address 120 $mode_ptr\""
|
|
;;
|
|
|
|
[1-9]*.*[0-9])
|
|
# Old fashioned HOST IN A records
|
|
for name in $names ; do
|
|
echo " local-data: \"$name. 120 IN A $address\""
|
|
done
|
|
echo " local-data-ptr: \"$address 120 $mode_ptr\""
|
|
;;
|
|
esac
|
|
done
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
elif [ "$mode" -gt 0 ] ; then
|
|
{
|
|
for address in $addresses ; do
|
|
case $address in
|
|
fe80:*|169.254.*)
|
|
echo " # note link address $address"
|
|
;;
|
|
|
|
"${ulaprefix%%:/*}"*)
|
|
# Only this networks ULA and only hostname
|
|
echo " local-data: \"$UNBOUND_TXT_HOSTNAME. 120 IN AAAA $address\""
|
|
echo " local-data-ptr: \"$address 120 $UNBOUND_TXT_HOSTNAME\""
|
|
;;
|
|
|
|
[1-9]*.*[0-9])
|
|
echo " local-data: \"$UNBOUND_TXT_HOSTNAME. 120 IN A $address\""
|
|
echo " local-data-ptr: \"$address 120 $UNBOUND_TXT_HOSTNAME\""
|
|
;;
|
|
esac
|
|
done
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
create_local_zone() {
|
|
local target="$1"
|
|
local partial domain found
|
|
|
|
|
|
if [ -n "$UNBOUND_LIST_DOMAINS" ] ; then
|
|
for domain in $UNBOUND_LIST_DOMAINS ; do
|
|
case $target in
|
|
*"${domain}")
|
|
found=1
|
|
break
|
|
;;
|
|
|
|
[A-Za-z0-9]*.[A-Za-z0-9]*)
|
|
found=0
|
|
;;
|
|
|
|
*) # no dots
|
|
found=1
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
else
|
|
found=0
|
|
fi
|
|
|
|
|
|
if [ $found -eq 0 ] ; then
|
|
# New Zone! Bundle local-zones: by first two name tiers "abcd.tld."
|
|
partial=$( echo "$target" | awk -F. '{ j=NF ; i=j-1; print $i"."$j }' )
|
|
UNBOUND_LIST_DOMAINS="$UNBOUND_LIST_DOMAINS $partial"
|
|
echo " local-zone: $partial. transparent" >> $UNBOUND_CONFFILE
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
create_host_record() {
|
|
local cfg="$1"
|
|
local ip name
|
|
|
|
# basefiles dhcp "domain" clause which means host A, AAAA, and PRT record
|
|
config_get ip "$cfg" ip
|
|
config_get name "$cfg" name
|
|
|
|
|
|
if [ -n "$name" -a -n "$ip" ] ; then
|
|
create_local_zone "$name"
|
|
|
|
{
|
|
case $ip in
|
|
fe80:*|169.254.*)
|
|
echo " # note link address $ip for host $name"
|
|
;;
|
|
|
|
[1-9a-f]*:*[0-9a-f])
|
|
echo " local-data: \"$name. 120 IN AAAA $ip\""
|
|
echo " local-data-ptr: \"$ip 120 $name\""
|
|
;;
|
|
|
|
[1-9]*.*[0-9])
|
|
echo " local-data: \"$name. 120 IN A $ip\""
|
|
echo " local-data-ptr: \"$ip 120 $name\""
|
|
;;
|
|
esac
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
create_mx_record() {
|
|
local cfg="$1"
|
|
local domain relay pref
|
|
|
|
# Insert a static MX record
|
|
config_get domain "$cfg" domain
|
|
config_get relay "$cfg" relay
|
|
config_get pref "$cfg" pref 10
|
|
|
|
|
|
if [ -n "$domain" -a -n "$relay" ] ; then
|
|
create_local_zone "$domain"
|
|
echo " local-data: \"$domain. 120 IN MX $pref $relay.\"" \
|
|
>> $UNBOUND_CONFFILE
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
create_srv_record() {
|
|
local cfg="$1"
|
|
local srv target port class weight
|
|
|
|
# Insert a static SRV record such as SIP server
|
|
config_get srv "$cfg" srv
|
|
config_get target "$cfg" target
|
|
config_get port "$cfg" port
|
|
config_get class "$cfg" class 10
|
|
config_get weight "$cfg" weight 10
|
|
|
|
|
|
if [ -n "$srv" -a -n "$target" -a -n "$port" ] ; then
|
|
create_local_zone "$srv"
|
|
echo " local-data: \"$srv. 120 IN SRV $class $weight $port $target.\"" \
|
|
>> $UNBOUND_CONFFILE
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
create_cname_record() {
|
|
local cfg="$1"
|
|
local cname target
|
|
|
|
# Insert static CNAME record
|
|
config_get cname "$cfg" cname
|
|
config_get target "$cfg" target
|
|
|
|
|
|
if [ -n "$cname" -a -n "$target" ] ; then
|
|
create_local_zone "$cname"
|
|
echo " local-data: \"$cname. 120 IN CNAME $target.\"" >> $UNBOUND_CONFFILE
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
create_access_control() {
|
|
local cfg="$1"
|
|
local subnets subnets4 subnets6
|
|
local validip4 validip6
|
|
|
|
network_get_subnets subnets4 "$cfg"
|
|
network_get_subnets6 subnets6 "$cfg"
|
|
subnets="$subnets4 $subnets6"
|
|
|
|
|
|
if [ -n "$subnets" ] ; then
|
|
for subnet in $subnets ; do
|
|
validip4=$( valid_subnet4 $subnet )
|
|
validip6=$( valid_subnet6 $subnet )
|
|
|
|
|
|
if [ "$validip4" = "ok" -o "$validip6" = "ok" ] ; then
|
|
# For each "network" UCI add "access-control:" white list for queries
|
|
echo " access-control: $subnet allow" >> $UNBOUND_CONFFILE
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
bundle_domain_forward() {
|
|
UNBOUND_LIST_FORWARD="$UNBOUND_LIST_FORWARD $1"
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
bundle_domain_insecure() {
|
|
UNBOUND_LIST_INSECURE="$UNBOUND_LIST_INSECURE $1"
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
bundle_private_interface() {
|
|
local ipcommand ifsubnet ifsubnets ifname validip4
|
|
|
|
network_get_device ifname $1
|
|
|
|
|
|
if [ -n "$ifname" ] ; then
|
|
ipcommand="ip -o address show $ifname"
|
|
ifsubnets=$( $ipcommand | awk '/inet/{ print $4 }' )
|
|
|
|
|
|
if [ -n "$ifsubnets" ] ; then
|
|
for ifsubnet in $ifsubnets ; do
|
|
case $ifsubnet in
|
|
[1-9][0-9a-f][0-9a-f][0-9a-f]:*[0-9a-f])
|
|
# Special GLA protection for local block; ULA protected as a catagory
|
|
UNBOUND_LIST_PRV_IP6GLA="$UNBOUND_LIST_PRV_IP6GLA $ifsubnet"
|
|
;;
|
|
|
|
f[dc][0-9a-f][0-9a-f]:*[0-9a-f])
|
|
# Used to configure specific local-zone: data
|
|
UNBOUND_LIST_LAN_NET="$UNBOUND_LIST_LAN_NET $ifsubnet"
|
|
;;
|
|
|
|
*)
|
|
validip4=$( valid_subnet4 $ifsubnet )
|
|
|
|
|
|
if [ "$validip4" = "ok" ] ; then
|
|
UNBOUND_LIST_LAN_NET="$UNBOUND_LIST_LAN_NET $ifsubnet"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_mkdir() {
|
|
local filestuff
|
|
|
|
|
|
if [ "$UNBOUND_D_DHCP_LINK" = "odhcpd" ] ; then
|
|
local dhcp_origin=$( uci_get dhcp.@odhcpd[0].leasefile )
|
|
local dhcp_dir=$( dirname $dhcp_origin )
|
|
|
|
|
|
if [ ! -d "$dhcp_dir" ] ; then
|
|
# make sure odhcpd has a directory to write (not done itself, yet)
|
|
mkdir -p "$dhcp_dir"
|
|
fi
|
|
fi
|
|
|
|
|
|
if [ -f $UNBOUND_KEYFILE ] ; then
|
|
filestuff=$( cat $UNBOUND_KEYFILE )
|
|
|
|
|
|
case "$filestuff" in
|
|
*"state=2 [ VALID ]"*)
|
|
# Lets not lose RFC 5011 tracking if we don't have to
|
|
cp -p $UNBOUND_KEYFILE $UNBOUND_KEYFILE.keep
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
|
|
# Blind copy /etc/ to /var/lib/
|
|
mkdir -p $UNBOUND_VARDIR
|
|
rm -f $UNBOUND_VARDIR/dhcp_*
|
|
touch $UNBOUND_CONFFILE
|
|
touch $UNBOUND_SRV_CONF
|
|
touch $UNBOUND_EXT_CONF
|
|
cp -p /etc/unbound/* $UNBOUND_VARDIR/
|
|
|
|
|
|
if [ ! -f $UNBOUND_HINTFILE ] ; then
|
|
if [ -f /usr/share/dns/root.hints ] ; then
|
|
# Debian-like package dns-root-data
|
|
cp -p /usr/share/dns/root.hints $UNBOUND_HINTFILE
|
|
|
|
elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
|
|
logger -t unbound -s "default root hints (built in rootservers.net)"
|
|
fi
|
|
fi
|
|
|
|
|
|
if [ ! -f $UNBOUND_KEYFILE ] ; then
|
|
if [ -f /usr/share/dns/root.key ] ; then
|
|
# Debian-like package dns-root-data
|
|
cp -p /usr/share/dns/root.key $UNBOUND_KEYFILE
|
|
|
|
elif [ -x $UNBOUND_ANCHOR ] ; then
|
|
$UNBOUND_ANCHOR -a $UNBOUND_KEYFILE
|
|
|
|
elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
|
|
logger -t unbound -s "default trust anchor (built in root DS record)"
|
|
fi
|
|
fi
|
|
|
|
|
|
if [ -f $UNBOUND_KEYFILE.keep ] ; then
|
|
# root.key.keep is reused if newest
|
|
cp -u $UNBOUND_KEYFILE.keep $UNBOUND_KEYFILE
|
|
rm -f $UNBOUND_KEYFILE.keep
|
|
fi
|
|
|
|
|
|
# Ensure access and prepare to jail
|
|
chown -R unbound:unbound $UNBOUND_VARDIR
|
|
chmod 755 $UNBOUND_VARDIR
|
|
chmod 644 $UNBOUND_VARDIR/*
|
|
|
|
|
|
if [ -f $UNBOUND_CTLKEY_FILE -o -f $UNBOUND_CTLPEM_FILE \
|
|
-o -f $UNBOUND_SRVKEY_FILE -o -f $UNBOUND_SRVPEM_FILE ] ; then
|
|
# Keys (some) exist already; do not create new ones
|
|
chmod 640 $UNBOUND_CTLKEY_FILE $UNBOUND_CTLPEM_FILE \
|
|
$UNBOUND_SRVKEY_FILE $UNBOUND_SRVPEM_FILE
|
|
|
|
elif [ -x /usr/sbin/unbound-control-setup ] ; then
|
|
case "$UNBOUND_D_CONTROL" in
|
|
[2-3])
|
|
# unbound-control-setup for encrypt opt. 2 and 3, but not 4 "static"
|
|
/usr/sbin/unbound-control-setup -d $UNBOUND_VARDIR
|
|
|
|
chown -R unbound:unbound $UNBOUND_CTLKEY_FILE $UNBOUND_CTLPEM_FILE \
|
|
$UNBOUND_SRVKEY_FILE $UNBOUND_SRVPEM_FILE
|
|
|
|
chmod 640 $UNBOUND_CTLKEY_FILE $UNBOUND_CTLPEM_FILE \
|
|
$UNBOUND_SRVKEY_FILE $UNBOUND_SRVPEM_FILE
|
|
|
|
cp -p $UNBOUND_CTLKEY_FILE /etc/unbound/unbound_control.key
|
|
cp -p $UNBOUND_CTLPEM_FILE /etc/unbound/unbound_control.pem
|
|
cp -p $UNBOUND_SRVKEY_FILE /etc/unbound/unbound_server.key
|
|
cp -p $UNBOUND_SRVPEM_FILE /etc/unbound/unbound_server.pem
|
|
;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_control() {
|
|
if [ "$UNBOUND_D_CONTROL" -gt 1 ] ; then
|
|
if [ ! -f $UNBOUND_CTLKEY_FILE -o ! -f $UNBOUND_CTLPEM_FILE \
|
|
-o ! -f $UNBOUND_SRVKEY_FILE -o ! -f $UNBOUND_SRVPEM_FILE ] ; then
|
|
# Key files need to be present; if unbound-control-setup was found, then
|
|
# they might have been made during unbound_makedir() above.
|
|
UNBOUND_D_CONTROL=0
|
|
fi
|
|
fi
|
|
|
|
|
|
case "$UNBOUND_D_CONTROL" in
|
|
1)
|
|
{
|
|
# Local Host Only Unencrypted Remote Control
|
|
echo "remote-control:"
|
|
echo " control-enable: yes"
|
|
echo " control-use-cert: no"
|
|
echo " control-interface: 127.0.0.1"
|
|
echo " control-interface: ::1"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
2)
|
|
{
|
|
# Local Host Only Encrypted Remote Control
|
|
echo "remote-control:"
|
|
echo " control-enable: yes"
|
|
echo " control-use-cert: yes"
|
|
echo " control-interface: 127.0.0.1"
|
|
echo " control-interface: ::1"
|
|
echo " server-key-file: \"$UNBOUND_SRVKEY_FILE\""
|
|
echo " server-cert-file: \"$UNBOUND_SRVPEM_FILE\""
|
|
echo " control-key-file: \"$UNBOUND_CTLKEY_FILE\""
|
|
echo " control-cert-file: \"$UNBOUND_CTLPEM_FILE\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
[3-4])
|
|
{
|
|
# Network Encrypted Remote Control
|
|
# (3) may auto setup and (4) must have static key/pem files
|
|
# TODO: add UCI list for interfaces to bind
|
|
echo "remote-control:"
|
|
echo " control-enable: yes"
|
|
echo " control-use-cert: yes"
|
|
echo " control-interface: 0.0.0.0"
|
|
echo " control-interface: ::0"
|
|
echo " server-key-file: \"$UNBOUND_SRVKEY_FILE\""
|
|
echo " server-cert-file: \"$UNBOUND_SRVPEM_FILE\""
|
|
echo " control-key-file: \"$UNBOUND_CTLKEY_FILE\""
|
|
echo " control-cert-file: \"$UNBOUND_CTLPEM_FILE\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
esac
|
|
|
|
|
|
{
|
|
# Amend your own extended clauses here like forward zones or disable
|
|
# above (local, no encryption) and amend your own remote encrypted control
|
|
echo
|
|
echo "include: $UNBOUND_EXT_CONF" >> $UNBOUND_CONFFILE
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_forward() {
|
|
local fdomain fresolver resolvers
|
|
# Forward selected domains to the upstream (WAN) stub resolver. This may be
|
|
# faster or local pool addresses to ISP service login page. This may keep
|
|
# internal organization lookups, well, internal to the organization.
|
|
|
|
|
|
if [ -n "$UNBOUND_LIST_FORWARD" ] ; then
|
|
resolvers=$( grep nameserver /tmp/resolv.conf.auto | sed "s/nameserver//g" )
|
|
|
|
|
|
if [ -n "$resolvers" ] ; then
|
|
for fdomain in $UNBOUND_LIST_FORWARD ; do
|
|
{
|
|
echo "forward-zone:"
|
|
echo " name: \"$fdomain.\""
|
|
for fresolver in $resolvers ; do
|
|
echo " forward-addr: $fresolver"
|
|
done
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
done
|
|
fi
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_auth_root() {
|
|
local axfrservers="lax.xfr.dns.icann.org iad.xfr.dns.icann.org"
|
|
local httpserver="http://www.internic.net/domain/"
|
|
local authzones="root arpa in-addr.arpa ip6.arpa"
|
|
local server zone realzone
|
|
# Download or AXFR the root and arpa zones to reduce the work needed at
|
|
# top level of recursion. If your users will hit many ccTLD or you have
|
|
# tracking logs resolving many PTR, then this can speed things up.
|
|
# Total size of text in TMPFS could be about 5MB.
|
|
|
|
|
|
if [ "$UNBOUND_B_AUTH_ROOT" -gt 0 ] ; then
|
|
for zone in $authzones ; do
|
|
if [ "$zone" = "root" ] ; then
|
|
realzone="."
|
|
else
|
|
realzone=$zone
|
|
fi
|
|
|
|
|
|
{
|
|
echo "auth-zone:"
|
|
echo " name: \"$realzone\""
|
|
for server in $axfrservers ; do
|
|
echo " master: \"$server\""
|
|
done
|
|
echo " url: \"$httpserver$zone.zone\""
|
|
echo " fallback-enabled: yes"
|
|
echo " for-downstream: no"
|
|
echo " for-upstream: yes"
|
|
echo " zonefile: \"$zone.zone\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
done
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_conf() {
|
|
local rt_mem rt_conn modulestring domain ifsubnet
|
|
|
|
# Make fresh conf file
|
|
echo > $UNBOUND_CONFFILE
|
|
|
|
|
|
{
|
|
# Make fresh conf file
|
|
echo "# $UNBOUND_CONFFILE generated by UCI $( date )"
|
|
echo
|
|
echo "server:"
|
|
echo " username: unbound"
|
|
echo " chroot: \"$UNBOUND_VARDIR\""
|
|
echo " directory: \"$UNBOUND_VARDIR\""
|
|
echo " pidfile: \"$UNBOUND_PIDFILE\""
|
|
echo
|
|
# No threading
|
|
echo " num-threads: 1"
|
|
echo " msg-cache-slabs: 1"
|
|
echo " rrset-cache-slabs: 1"
|
|
echo " infra-cache-slabs: 1"
|
|
echo " key-cache-slabs: 1"
|
|
echo
|
|
# Interface Wildcard (access contol handled by "option local_service")
|
|
echo " interface: 0.0.0.0"
|
|
echo " interface: ::0"
|
|
echo " outgoing-interface: 0.0.0.0"
|
|
echo " outgoing-interface: ::0"
|
|
echo
|
|
# Logging
|
|
echo " use-syslog: yes"
|
|
echo " verbosity: 1"
|
|
echo " statistics-interval: 0"
|
|
echo " statistics-cumulative: no"
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
|
|
if [ "$UNBOUND_B_EXT_STATS" -gt 0 ] ; then
|
|
{
|
|
# Log More
|
|
echo " extended-statistics: yes"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
else
|
|
{
|
|
# Log Less
|
|
echo " extended-statistics: no"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
case "$UNBOUND_D_PROTOCOL" in
|
|
ip4_only)
|
|
{
|
|
echo " do-ip4: yes"
|
|
echo " do-ip6: no"
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
ip6_only)
|
|
{
|
|
echo " do-ip4: no"
|
|
echo " do-ip6: yes"
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
ip6_prefer)
|
|
{
|
|
echo " do-ip4: yes"
|
|
echo " do-ip6: yes"
|
|
echo " prefer-ip6: yes"
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
mixed)
|
|
{
|
|
echo " do-ip4: yes"
|
|
echo " do-ip6: yes"
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
*)
|
|
if [ ! -f "$UNBOUND_TIMEFILE" ] ; then
|
|
logger -t unbound -s "default protocol configuration"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
|
|
{
|
|
# protocol level tuning
|
|
echo " edns-buffer-size: $UNBOUND_N_EDNS_SIZE"
|
|
echo " msg-buffer-size: 8192"
|
|
echo " port: $UNBOUND_N_RX_PORT"
|
|
echo " outgoing-port-permit: 10240-65535"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
|
|
{
|
|
# Other harding and options for an embedded router
|
|
echo " harden-short-bufsize: yes"
|
|
echo " harden-large-queries: yes"
|
|
echo " harden-glue: yes"
|
|
echo " harden-below-nxdomain: no"
|
|
echo " harden-referral-path: no"
|
|
echo " use-caps-for-id: no"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
|
|
if [ -f "$UNBOUND_HINTFILE" ] ; then
|
|
# Optional hints if found
|
|
echo " root-hints: \"$UNBOUND_HINTFILE\"" >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_B_DNSSEC" -gt 0 -a -f "$UNBOUND_KEYFILE" ] ; then
|
|
{
|
|
echo " auto-trust-anchor-file: \"$UNBOUND_KEYFILE\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
else
|
|
echo >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
case "$UNBOUND_D_RESOURCE" in
|
|
# Tiny - Unbound's recommended cheap hardware config
|
|
tiny) rt_mem=1 ; rt_conn=1 ;;
|
|
# Small - Half RRCACHE and open ports
|
|
small) rt_mem=8 ; rt_conn=5 ;;
|
|
# Medium - Nearly default but with some added balancintg
|
|
medium) rt_mem=16 ; rt_conn=10 ;;
|
|
# Large - Double medium
|
|
large) rt_mem=32 ; rt_conn=10 ;;
|
|
# Whatever unbound does
|
|
*) rt_mem=0 ; rt_conn=0 ;;
|
|
esac
|
|
|
|
|
|
if [ "$rt_mem" -gt 0 ] ; then
|
|
{
|
|
# Set memory sizing parameters
|
|
echo " outgoing-range: $(($rt_conn*64))"
|
|
echo " num-queries-per-thread: $(($rt_conn*32))"
|
|
echo " outgoing-num-tcp: $(($rt_conn))"
|
|
echo " incoming-num-tcp: $(($rt_conn))"
|
|
echo " rrset-cache-size: $(($rt_mem*256))k"
|
|
echo " msg-cache-size: $(($rt_mem*128))k"
|
|
echo " key-cache-size: $(($rt_mem*128))k"
|
|
echo " neg-cache-size: $(($rt_mem*64))k"
|
|
echo " infra-cache-numhosts: $(($rt_mem*256))"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
|
|
logger -t unbound -s "default memory configuration"
|
|
fi
|
|
|
|
|
|
# Assembly of module-config: options is tricky; order matters
|
|
modulestring="iterator"
|
|
|
|
|
|
if [ "$UNBOUND_B_DNSSEC" -gt 0 ] ; then
|
|
if [ ! -f "$UNBOUND_TIMEFILE" -a "$UNBOUND_B_NTP_BOOT" -gt 0 ] ; then
|
|
# DNSSEC chicken and egg with getting NTP time
|
|
echo " val-override-date: -1" >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
{
|
|
echo " harden-dnssec-stripped: yes"
|
|
echo " val-clean-additional: yes"
|
|
echo " ignore-cd-flag: yes"
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
|
|
modulestring="validator $modulestring"
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_B_DNS64" -gt 0 ] ; then
|
|
echo " dns64-prefix: $UNBOUND_IP_DNS64" >> $UNBOUND_CONFFILE
|
|
|
|
modulestring="dns64 $modulestring"
|
|
fi
|
|
|
|
|
|
{
|
|
# Print final module string
|
|
echo " module-config: \"$modulestring\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
|
|
case "$UNBOUND_D_RECURSION" in
|
|
passive)
|
|
{
|
|
# Some query privacy but "strict" will break some servers
|
|
if [ "$UNBOUND_B_QRY_MINST" -gt 0 \
|
|
-a "$UNBOUND_B_QUERY_MIN" -gt 0 ] ; then
|
|
echo " qname-minimisation: yes"
|
|
echo " qname-minimisation-strict: yes"
|
|
elif [ "$UNBOUND_B_QUERY_MIN" -gt 0 ] ; then
|
|
echo " qname-minimisation: yes"
|
|
else
|
|
echo " qname-minimisation: no"
|
|
fi
|
|
# Use DNSSEC to quickly understand NXDOMAIN ranges
|
|
if [ "$UNBOUND_B_DNSSEC" -gt 0 ] ; then
|
|
echo " aggressive-nsec: yes"
|
|
echo " prefetch-key: no"
|
|
fi
|
|
# On demand fetching
|
|
echo " prefetch: no"
|
|
echo " target-fetch-policy: \"0 0 0 0 0\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
aggressive)
|
|
{
|
|
# Some query privacy but "strict" will break some servers
|
|
if [ "$UNBOUND_B_QRY_MINST" -gt 0 \
|
|
-a "$UNBOUND_B_QUERY_MIN" -gt 0 ] ; then
|
|
echo " qname-minimisation: yes"
|
|
echo " qname-minimisation-strict: yes"
|
|
elif [ "$UNBOUND_B_QUERY_MIN" -gt 0 ] ; then
|
|
echo " qname-minimisation: yes"
|
|
else
|
|
echo " qname-minimisation: no"
|
|
fi
|
|
# Use DNSSEC to quickly understand NXDOMAIN ranges
|
|
if [ "$UNBOUND_B_DNSSEC" -gt 0 ] ; then
|
|
echo " aggressive-nsec: yes"
|
|
echo " prefetch-key: yes"
|
|
fi
|
|
# Prefetch what can be
|
|
echo " prefetch: yes"
|
|
echo " target-fetch-policy: \"3 2 1 0 0\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
*)
|
|
if [ ! -f "$UNBOUND_TIMEFILE" ] ; then
|
|
logger -t unbound -s "default recursion configuration"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
|
|
{
|
|
# Reload records more than 10 hours old
|
|
# DNSSEC 5 minute bogus cool down before retry
|
|
# Adaptive infrastructure info kept for 15 minutes
|
|
echo " cache-min-ttl: $UNBOUND_TTL_MIN"
|
|
echo " cache-max-ttl: 36000"
|
|
echo " val-bogus-ttl: 300"
|
|
echo " infra-host-ttl: 900"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
|
|
if [ "$UNBOUND_B_HIDE_BIND" -gt 0 ] ; then
|
|
{
|
|
# Block server id and version DNS TXT records
|
|
echo " hide-identity: yes"
|
|
echo " hide-version: yes"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_D_PRIV_BLCK" -gt 0 ] ; then
|
|
{
|
|
# Remove _upstream_ or global reponses with private addresses.
|
|
# Unbounds own "local zone" and "forward zone" may still use these.
|
|
# RFC1918, RFC3927, RFC4291, RFC6598, RFC6890
|
|
echo " private-address: 10.0.0.0/8"
|
|
echo " private-address: 100.64.0.0/10"
|
|
echo " private-address: 169.254.0.0/16"
|
|
echo " private-address: 172.16.0.0/12"
|
|
echo " private-address: 192.168.0.0/16"
|
|
echo " private-address: fc00::/7"
|
|
echo " private-address: fe80::/10"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
if [ -n "$UNBOUND_LIST_PRV_IP6GLA" -a "$UNBOUND_D_PRIV_BLCK" -gt 1 ] ; then
|
|
for ifsubnet in $UNBOUND_LIST_PRV_IP6GLA ; do
|
|
# Remove global DNS responses with your local network IP6 GLA
|
|
echo " private-address: $ifsubnet" >> $UNBOUND_CONFFILE
|
|
done
|
|
|
|
|
|
echo >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_B_LOCL_BLCK" -gt 0 ] ; then
|
|
{
|
|
# Remove DNS reponses from upstream with loopback IP
|
|
# Black hole DNS method for ad blocking, so consider...
|
|
echo " private-address: 127.0.0.0/8"
|
|
echo " private-address: ::1/128"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
if [ -n "$UNBOUND_LIST_INSECURE" ] ; then
|
|
for domain in $UNBOUND_LIST_INSECURE ; do
|
|
# Except and accept domains without (DNSSEC); work around broken domains
|
|
echo " domain-insecure: \"$domain\"" >> $UNBOUND_CONFFILE
|
|
done
|
|
|
|
|
|
echo >> $UNBOUND_CONFFILE
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_access() {
|
|
# TODO: Unbound 1.6.0 added "tags" and "views", so we can add tags to
|
|
# each access-control IP block, and then divert access.
|
|
# -- "guest" WIFI will not be allowed to see local zone data
|
|
# -- "child" LAN can black whole a list of domains to http~deadpixel
|
|
|
|
|
|
if [ "$UNBOUND_B_LOCL_SERV" -gt 0 ] ; then
|
|
# Only respond to queries from which this device has an interface.
|
|
# Prevent DNS amplification attacks by not responding to the universe.
|
|
config_load network
|
|
config_foreach create_access_control interface
|
|
|
|
|
|
{
|
|
echo " access-control: 127.0.0.0/8 allow"
|
|
echo " access-control: ::1/128 allow"
|
|
echo " access-control: fe80::/10 allow"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
else
|
|
{
|
|
echo " access-control: 0.0.0.0/0 allow"
|
|
echo " access-control: ::0/0 allow"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
|
|
|
|
{
|
|
# Amend your own "server:" stuff here
|
|
echo " include: $UNBOUND_SRV_CONF"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_adblock() {
|
|
# TODO: Unbound 1.6.0 added "tags" and "views"; lets work with adblock team
|
|
local adb_enabled adb_file
|
|
|
|
|
|
if [ ! -x /usr/bin/adblock.sh -o ! -x /etc/init.d/adblock ] ; then
|
|
adb_enabled=0
|
|
else
|
|
/etc/init.d/adblock enabled && adb_enabled=1 || adb_enabled=0
|
|
fi
|
|
|
|
|
|
if [ "$adb_enabled" -gt 0 ] ; then
|
|
{
|
|
# Pull in your selected openwrt/pacakges/net/adblock generated lists
|
|
for adb_file in $UNBOUND_VARDIR/adb_list.* ; do
|
|
echo " include: $adb_file"
|
|
done
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_hostname() {
|
|
local ifsubnet ifarpa
|
|
|
|
|
|
if [ -n "$UNBOUND_TXT_DOMAIN" ] ; then
|
|
{
|
|
# Hostname as TLD works, but not transparent through recursion
|
|
echo " domain-insecure: $UNBOUND_TXT_HOSTNAME"
|
|
echo " private-domain: $UNBOUND_TXT_HOSTNAME"
|
|
echo " local-zone: $UNBOUND_TXT_HOSTNAME. static"
|
|
echo " local-data: \"$UNBOUND_TXT_HOSTNAME. $UNBOUND_XSOA\""
|
|
echo " local-data: \"$UNBOUND_TXT_HOSTNAME. $UNBOUND_XNS\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
|
|
|
|
case "$UNBOUND_D_DOMAIN_TYPE" in
|
|
deny|inform_deny|refuse|static)
|
|
if [ -n "$UNBOUND_LIST_PRV_IP6GLA" \
|
|
-a "$UNBOUND_D_PRIV_BLCK" -gt 1 ] ; then
|
|
for ifsubnet in $UNBOUND_LIST_PRV_IP6GLA ; do
|
|
ifarpa=$( domain_ptr_any "$ifsubnet" )
|
|
|
|
|
|
if [ -n "$ifarpa" ] ; then
|
|
{
|
|
# Do NOT forward queries with your GLA ip6.arpa
|
|
echo " domain-insecure: $ifarpa"
|
|
echo " local-zone: $ifarpa. $UNBOUND_D_DOMAIN_TYPE"
|
|
echo " local-data: \"$ifarpa. $UNBOUND_XSOA\""
|
|
echo " local-data: \"$ifarpa. $UNBOUND_XNS\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
done
|
|
fi
|
|
|
|
|
|
if [ -n "$UNBOUND_LIST_LAN_NET" \
|
|
-a "$UNBOUND_D_PRIV_BLCK" -gt 0 ] ; then
|
|
for ifsubnet in $UNBOUND_LIST_LAN_NET ; do
|
|
ifarpa=$( domain_ptr_any "$ifsubnet" )
|
|
|
|
|
|
if [ -n "$ifarpa" ] ; then
|
|
{
|
|
# Do NOT forward queries with your ULA ip6.arpa or in-addr.arpa
|
|
echo " domain-insecure: $ifarpa"
|
|
echo " local-zone: $ifarpa. $UNBOUND_D_DOMAIN_TYPE"
|
|
echo " local-data: \"$ifarpa. $UNBOUND_XSOA\""
|
|
echo " local-data: \"$ifarpa. $UNBOUND_XNS\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
done
|
|
fi
|
|
|
|
|
|
{
|
|
# avoid upstream involvement in RFC6762
|
|
echo " domain-insecure: local"
|
|
echo " private-domain: local"
|
|
echo " local-zone: local. $UNBOUND_D_DOMAIN_TYPE"
|
|
echo " local-data: \"local. $UNBOUND_XSOA\""
|
|
echo " local-data: \"local. $UNBOUND_XNS\""
|
|
echo " local-data: \"local. 3600 IN TXT RFC6762\""
|
|
echo
|
|
# type static means only this router has your domain
|
|
# type transparent will permit forward-zone: or stub-zone: clauses
|
|
echo " domain-insecure: $UNBOUND_TXT_DOMAIN"
|
|
echo " private-domain: $UNBOUND_TXT_DOMAIN"
|
|
echo " local-zone: $UNBOUND_TXT_DOMAIN. $UNBOUND_D_DOMAIN_TYPE"
|
|
echo " local-data: \"$UNBOUND_TXT_DOMAIN. $UNBOUND_XSOA\""
|
|
echo " local-data: \"$UNBOUND_TXT_DOMAIN. $UNBOUND_XNS\""
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
;;
|
|
|
|
*)
|
|
# likely transparent domain with fordward-zone: clause to next router
|
|
echo " domain-insecure: $UNBOUND_TXT_DOMAIN"
|
|
echo " private-domain: $UNBOUND_TXT_DOMAIN"
|
|
echo " local-zone: $UNBOUND_TXT_DOMAIN. $UNBOUND_D_DOMAIN_TYPE"
|
|
echo
|
|
;;
|
|
esac
|
|
|
|
|
|
if [ "$UNBOUND_D_LAN_FQDN" -gt 0 -o "$UNBOUND_D_WAN_FQDN" -gt 0 ] ; then
|
|
config_load dhcp
|
|
config_foreach create_interface_dns dhcp
|
|
fi
|
|
|
|
|
|
if [ -f "$UNBOUND_DHCP_CONF" ] ; then
|
|
{
|
|
# Seed DHCP records because dhcp scripts trigger externally
|
|
# Incremental Unbound restarts may drop unbound-control add records
|
|
echo " include: $UNBOUND_DHCP_CONF"
|
|
echo
|
|
} >> $UNBOUND_CONFFILE
|
|
fi
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_records() {
|
|
if [ "$UNBOUND_D_EXTRA_DNS" -gt 0 ] ; then
|
|
# Parasite from the uci.dhcp.domain clauses
|
|
config_load dhcp
|
|
config_foreach create_host_record domain
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_D_EXTRA_DNS" -gt 1 ] ; then
|
|
config_foreach create_srv_record srvhost
|
|
config_foreach create_mx_record mxhost
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_D_EXTRA_DNS" -gt 2 ] ; then
|
|
config_foreach create_cname_record cname
|
|
fi
|
|
|
|
|
|
echo >> $UNBOUND_CONFFILE
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_uci() {
|
|
local cfg="$1"
|
|
local dnsmasqpath hostnm
|
|
|
|
hostnm=$( uci_get system.@system[0].hostname | awk '{print tolower($0)}' )
|
|
UNBOUND_TXT_HOSTNAME=${hostnm:-thisrouter}
|
|
|
|
config_get_bool UNBOUND_B_SLAAC6_MAC "$cfg" dhcp4_slaac6 0
|
|
config_get_bool UNBOUND_B_DNS64 "$cfg" dns64 0
|
|
config_get_bool UNBOUND_B_EXT_STATS "$cfg" extended_stats 0
|
|
config_get_bool UNBOUND_B_HIDE_BIND "$cfg" hide_binddata 1
|
|
config_get_bool UNBOUND_B_LOCL_SERV "$cfg" localservice 1
|
|
config_get_bool UNBOUND_B_MAN_CONF "$cfg" manual_conf 0
|
|
config_get_bool UNBOUND_B_QUERY_MIN "$cfg" query_minimize 0
|
|
config_get_bool UNBOUND_B_QRY_MINST "$cfg" query_min_strict 0
|
|
config_get_bool UNBOUND_B_AUTH_ROOT "$cfg" prefetch_root 0
|
|
config_get_bool UNBOUND_B_LOCL_BLCK "$cfg" rebind_localhost 0
|
|
config_get_bool UNBOUND_B_DNSSEC "$cfg" validator 0
|
|
config_get_bool UNBOUND_B_NTP_BOOT "$cfg" validator_ntp 1
|
|
|
|
config_get UNBOUND_IP_DNS64 "$cfg" dns64_prefix "64:ff9b::/96"
|
|
|
|
config_get UNBOUND_N_EDNS_SIZE "$cfg" edns_size 1280
|
|
config_get UNBOUND_N_RX_PORT "$cfg" listen_port 53
|
|
config_get UNBOUND_N_ROOT_AGE "$cfg" root_age 9
|
|
|
|
config_get UNBOUND_D_CONTROL "$cfg" unbound_control 0
|
|
config_get UNBOUND_D_DOMAIN_TYPE "$cfg" domain_type static
|
|
config_get UNBOUND_D_DHCP_LINK "$cfg" dhcp_link none
|
|
config_get UNBOUND_D_EXTRA_DNS "$cfg" add_extra_dns 0
|
|
config_get UNBOUND_D_LAN_FQDN "$cfg" add_local_fqdn 0
|
|
config_get UNBOUND_D_PRIV_BLCK "$cfg" rebind_protection 1
|
|
config_get UNBOUND_D_PROTOCOL "$cfg" protocol mixed
|
|
config_get UNBOUND_D_RECURSION "$cfg" recursion passive
|
|
config_get UNBOUND_D_RESOURCE "$cfg" resource small
|
|
config_get UNBOUND_D_WAN_FQDN "$cfg" add_wan_fqdn 0
|
|
|
|
config_get UNBOUND_TTL_MIN "$cfg" ttl_min 120
|
|
config_get UNBOUND_TXT_DOMAIN "$cfg" domain lan
|
|
|
|
config_list_foreach "$cfg" "domain_forward" bundle_domain_forward
|
|
config_list_foreach "$cfg" "domain_insecure" bundle_domain_insecure
|
|
config_list_foreach "$cfg" "rebind_interface" bundle_private_interface
|
|
|
|
UNBOUND_LIST_DOMAINS="nowhere $UNBOUND_TXT_DOMAIN"
|
|
|
|
if [ "$UNBOUND_D_DHCP_LINK" = "none" ] ; then
|
|
config_get_bool UNBOUND_B_DNSMASQ "$cfg" dnsmasq_link_dns 0
|
|
|
|
|
|
if [ "$UNBOUND_B_DNSMASQ" -gt 0 ] ; then
|
|
UNBOUND_D_DHCP_LINK=dnsmasq
|
|
|
|
|
|
if [ ! -f "$UNBOUND_TIMEFILE" ] ; then
|
|
logger -t unbound -s "Please use 'dhcp_link' selector instead"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_D_DHCP_LINK" = "dnsmasq" ] ; then
|
|
if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
|
|
UNBOUND_D_DHCP_LINK=none
|
|
else
|
|
/etc/init.d/dnsmasq enabled || UNBOUND_D_DHCP_LINK=none
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_D_DHCP_LINK" = "none" -a ! -f "$UNBOUND_TIMEFILE" ] ; then
|
|
logger -t unbound -s "cannot forward to dnsmasq"
|
|
fi
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_D_DHCP_LINK" = "odhcpd" ] ; then
|
|
if [ ! -x /usr/sbin/odhcpd -o ! -x /etc/init.d/odhcpd ] ; then
|
|
UNBOUND_D_DHCP_LINK=none
|
|
else
|
|
/etc/init.d/odhcpd enabled || UNBOUND_D_DHCP_LINK=none
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_D_DHCP_LINK" = "none" -a ! -f "$UNBOUND_TIMEFILE" ] ; then
|
|
logger -t unbound -s "cannot receive records from odhcpd"
|
|
fi
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_N_EDNS_SIZE" -lt 512 \
|
|
-o 4096 -lt "$UNBOUND_N_EDNS_SIZE" ] ; then
|
|
logger -t unbound -s "edns_size exceeds range, using default"
|
|
UNBOUND_N_EDNS_SIZE=1280
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_N_RX_PORT" -ne 53 ] \
|
|
&& [ "$UNBOUND_N_RX_PORT" -lt 1024 -o 10240 -lt "$UNBOUND_N_RX_PORT" ] ; then
|
|
logger -t unbound -s "privileged port or in 5 digits, using default"
|
|
UNBOUND_N_RX_PORT=53
|
|
fi
|
|
|
|
|
|
if [ "$UNBOUND_TTL_MIN" -gt 1800 ] ; then
|
|
logger -t unbound -s "ttl_min could have had awful side effects, using 300"
|
|
UNBOUND_TTL_MIN=300
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_resolv_setup() {
|
|
if [ "$UNBOUND_N_RX_PORT" != "53" ] ; then
|
|
return
|
|
fi
|
|
|
|
|
|
if [ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq enabled \
|
|
&& nslookup localhost 127.0.0.1#53 >/dev/null 2>&1 ; then
|
|
# unbound is configured for port 53, but dnsmasq is enabled and a resolver
|
|
# listens on localhost:53, lets assume dnsmasq manages the resolver file.
|
|
# TODO:
|
|
# really check if dnsmasq runs a local (main) resolver in stead of using
|
|
# nslookup that times out when no resolver listens on localhost:53.
|
|
return
|
|
fi
|
|
|
|
|
|
# unbound is designated to listen on 127.0.0.1#53,
|
|
# set resolver file to local.
|
|
rm -f /tmp/resolv.conf
|
|
|
|
{
|
|
echo "# /tmp/resolv.conf generated by Unbound UCI $( date )"
|
|
echo "nameserver 127.0.0.1"
|
|
echo "nameserver ::1"
|
|
echo "search $UNBOUND_TXT_DOMAIN."
|
|
} > /tmp/resolv.conf
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_resolv_teardown() {
|
|
case $( cat /tmp/resolv.conf ) in
|
|
*"generated by Unbound UCI"*)
|
|
# our resolver file, reset to auto resolver file.
|
|
rm -f /tmp/resolv.conf
|
|
ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
|
|
;;
|
|
esac
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_start() {
|
|
config_load unbound
|
|
config_foreach unbound_uci unbound
|
|
unbound_mkdir
|
|
|
|
|
|
if [ "$UNBOUND_B_MAN_CONF" -eq 0 ] ; then
|
|
unbound_conf
|
|
unbound_access
|
|
unbound_adblock
|
|
|
|
|
|
if [ "$UNBOUND_D_DHCP_LINK" = "dnsmasq" ] ; then
|
|
dnsmasq_link
|
|
else
|
|
unbound_hostname
|
|
unbound_records
|
|
fi
|
|
|
|
|
|
unbound_forward
|
|
unbound_auth_root
|
|
unbound_control
|
|
fi
|
|
|
|
|
|
unbound_resolv_setup
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
unbound_stop() {
|
|
unbound_resolv_teardown
|
|
rootzone_update
|
|
}
|
|
|
|
##############################################################################
|
|
|