unbound: add option for dhcp UCI domain mx srv and cname

Base LEDE/OpenWrt UCI for dnsmasq provides for DNS override in
/etc/config/dhcp. It is desired to be able to use dnsmasq and
Unbound as transparently as possible. Option 'add_extra_dns'
will pull 'domain', 'mxhost', 'srvhost, and 'cname' from base.

netifd/procd have an interaction with DHCPv6/RA on WAN (FS#713).
Minor IP6 parameter updates can cause Unbound reload events every
few minutes. List option 'trigger' selects which interfaces may
cause reload. For example 'lan', 'wan' but not 'wan6'.

Squash other cosmetics.

Signed-off-by: Eric Luehrsen <ericluehrsen@hotmail.com>
This commit is contained in:
Eric Luehrsen 2017-05-09 22:46:39 -04:00
parent 2814a950f5
commit 9d96dfd468
6 changed files with 215 additions and 23 deletions

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=unbound
PKG_VERSION:=1.6.2
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE

View File

@ -73,7 +73,7 @@ config dhcp 'lan'
```
### Unbound and odhcpd
You may ask can Unbound replace dnsmasq? You can have DHCP-DNS records with Unbound and odhcpd only. The UCI scripts will allow Unbound to act like dnsmasq. When odhcpd configures each DHCP lease, it will call a script. The script provided with Unbound will read the lease file for DHCP-DNS records. You **must install** `unbound-control`, because the lease records are added and removed without starting, stopping, flushing cache, or re-writing conf files. (_restart overhead can be excessive with even a few mobile devices._)
You may ask, "can Unbound replace dnsmasq?" You can have DHCP-DNS records with Unbound and odhcpd only. The UCI scripts will allow Unbound to act like dnsmasq. When odhcpd configures each DHCP lease, it will call a script. The script provided with Unbound will read the lease file for DHCP-DNS records. You **must install** `unbound-control`, because the lease records are added and removed without starting, stopping, flushing cache, or re-writing conf files. (_restart overhead can be excessive with even a few mobile devices._)
Don't forget to disable or uninstall dnsmasq when you don't intend to use it. Strange results may occur. If you want to use default dnsmasq+odhcpd and add Unbound on top, then use the dnsmasq-serial or dnsmasq-parallel methods above.
@ -106,8 +106,7 @@ config dhcp 'lan'
option leasetime '12h'
option ra 'server'
option ra_management '1'
# issue your ULA and avoid default [fe80::]
list dns 'fdxx:xxxx:xxxx::1'
# odhcpd should issue ULA [fd00::/8] by default
...
config odhcpd 'odhcpd'
@ -146,6 +145,14 @@ The former will be added to the end of the `server:` clause. The later will be a
config unbound
Currently only one instance is supported.
option add_extra_dns '0'
Level. Execute traditional DNS overrides found in `/etc/config/dhcp`.
Optional so you may use other Unbound conf or redirect to NSD instance.
0 - Ignore `/etc/config/dhcp`
1 - Use only 'domain' clause (host records)
2 - Use 'domain', 'mxhost', and 'srvhost' clauses
3 - Use all of 'domain', 'mxhost', 'srvhost', and 'cname' clauses
option add_local_fqdn '0'
Level. This puts your routers host name in the LAN (local) DNS.
Each level is more detailed and comprehensive.
@ -271,9 +278,15 @@ config unbound
embedded devices don't have a real time power off clock. NTP needs
DNS to resolve servers. This works around the chicken-and-egg.
list domain_insecure
List. Domains or pointers that you wish to skip DNSSEC. Your DHCP
domains and pointers in dnsmasq will get this automatically.
list domain_insecure 'www.example.com'
Domain. Domains that you wish to skip DNSSEC. Your DHCP
domains and pointers will get this automatically.
list trigger 'lan' 'wan'
Interface (logical). This option is a work around for netifd/procd
interaction with WAN DHCPv6. Minor RA or DHCP changes in IP6 can
cause netifd to execute procd interface reload. Limit Unbound procd
triggers to LAN and WAN (IP4 only) to prevent restart @2-3 minutes.
```

View File

@ -45,7 +45,7 @@ odhcpd_zonedata() {
local dhcp_ls_old=$UNBOUND_VARDIR/dhcp_lease.old
local dhcp_ls_add=$UNBOUND_VARDIR/dhcp_lease.add
local dhcp_ls_del=$UNBOUND_VARDIR/dhcp_lease.del
local dhcp_origin=$( uci get dhcp.@odhcpd[0].leasefile )
local dhcp_origin=$( uci_get dhcp.@odhcpd[0].leasefile )
config_load unbound
config_foreach odhcpd_settings unbound

View File

@ -47,7 +47,7 @@ start_service() {
stop_service() {
unbound_stop
# Wait! on restart Unbound may take time writing closure stats to syslog
pidof $PROG && sleep 1
}
@ -55,9 +55,20 @@ stop_service() {
##############################################################################
service_triggers() {
# use soft reload to prevent continuous stop-start and cache flush
local trigger
local triggers=$( uci_get unbound.@unbound[0].trigger )
PROCD_RELOAD_DELAY=2000
procd_add_reload_trigger "unbound"
procd_add_raw_trigger "interface.*.up" 2000 /etc/init.d/unbound reload
if [ -n "$triggers" ] ; then
for trigger in $triggers ; do
# due to some netifd/procd interactions with IP6, limit interfaces
procd_add_reload_interface_trigger "$trigger"
done
else
procd_add_raw_trigger "interface.*.up" 2000 /etc/init.d/unbound reload
fi
}
##############################################################################

View File

@ -14,9 +14,12 @@
#
##############################################################################
#
# This builds the basic UCI components currently supported for Unbound. It is
# intentionally NOT comprehensive and bundles a lot of options. The UCI is to
# be a simpler presentation of the total Unbound conf set.
# 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.
#
##############################################################################
@ -36,6 +39,7 @@ UNBOUND_B_QRY_MINST=0
UNBOUND_D_DOMAIN_TYPE=static
UNBOUND_D_DHCP_LINK=none
UNBOUND_D_EXTRA_DNS=0
UNBOUND_D_LAN_FQDN=0
UNBOUND_D_PROTOCOL=mixed
UNBOUND_D_RESOURCE=small
@ -57,6 +61,11 @@ UNBOUND_TXT_HOSTNAME=thisrouter
##############################################################################
# keep track of local-domain: assignments during inserted resource records
UNBOUND_LIST_DOMAINS=""
##############################################################################
UNBOUND_LIBDIR=/usr/lib/unbound
UNBOUND_VARDIR=/var/lib/unbound
@ -69,7 +78,7 @@ UNBOUND_CONFFILE=$UNBOUND_VARDIR/unbound.conf
UNBOUND_KEYFILE=$UNBOUND_VARDIR/root.key
UNBOUND_HINTFILE=$UNBOUND_VARDIR/root.hints
UNBOUND_TIMEFILE=$UNBOUND_VARDIR/unbound.time
UNBOUND_TIMEFILE=$UNBOUND_VARDIR/hotplug.time
##############################################################################
@ -124,8 +133,8 @@ create_interface_dns() {
ifdashname="${ifname//./-}"
ipcommand="ip -o address show $ifname"
addresses="$($ipcommand | awk '/inet/{sub(/\/.*/,"",$4); print $4}')"
ulaprefix="$(uci_get network @globals[0] ula_prefix)"
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"
@ -223,6 +232,135 @@ create_interface_dns() {
##############################################################################
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
@ -257,8 +395,8 @@ create_domain_insecure() {
unbound_mkdir() {
local resolvsym=0
local dhcp_origin=$( uci get dhcp.@odhcpd[0].leasefile )
local dhcp_dir=$( dirname "$dhcp_origin" )
local dhcp_origin=$( uci_get dhcp.@odhcpd[0].leasefile )
local dhcp_dir=$( dirname $dhcp_origin )
local filestuff
@ -780,11 +918,35 @@ unbound_hostname() {
##############################################################################
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)}')"
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
@ -808,6 +970,7 @@ unbound_uci() {
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_PROTOCOL "$cfg" protocol mixed
config_get UNBOUND_D_RECURSION "$cfg" recursion passive
@ -817,6 +980,7 @@ unbound_uci() {
config_get UNBOUND_TTL_MIN "$cfg" ttl_min 120
config_get UNBOUND_TXT_DOMAIN "$cfg" domain lan
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
@ -824,8 +988,8 @@ unbound_uci() {
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
@ -898,6 +1062,7 @@ unbound_start() {
dnsmasq_link
else
unbound_hostname
unbound_records
fi
unbound_control

View File

@ -1,4 +1,5 @@
config unbound
option add_extra_dns '0'
option add_local_fqdn '1'
option add_wan_fqdn '0'
option dhcp_link 'none'
@ -24,5 +25,7 @@ config unbound
option unbound_control '0'
option validator '0'
option validator_ntp '1'
#list domain_insecure ''
list trigger 'lan'
list trigger 'wan'
#list domain_insecure 'www.example.com'