aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorEric Luehrsen <ericluehrsen@hotmail.com>2018-06-10 15:20:24 -0400
committerEric Luehrsen <ericluehrsen@hotmail.com>2018-06-12 22:32:54 -0400
commita7fd69233d59ce38ac73598bb44d20cc05b04d15 (patch)
treeca180aae5e55d385c0f0339cc314278f6b8feeb0 /net
parentd6e7f64a3dabf86e39ffbce8478366e0c214a535 (diff)
unbound: improve local zone evaluation in UCI
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>
Diffstat (limited to 'net')
-rw-r--r--net/unbound/Makefile2
-rw-r--r--net/unbound/files/README.md15
-rw-r--r--net/unbound/files/iptools.sh22
-rw-r--r--net/unbound/files/odhcpd.sh4
-rw-r--r--net/unbound/files/unbound.sh223
5 files changed, 189 insertions, 77 deletions
diff --git a/net/unbound/Makefile b/net/unbound/Makefile
index a6de8db33..12144aeb9 100644
--- a/net/unbound/Makefile
+++ b/net/unbound/Makefile
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=unbound
PKG_VERSION:=1.7.2
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
diff --git a/net/unbound/files/README.md b/net/unbound/files/README.md
index 4e81162f8..d89704438 100644
--- a/net/unbound/files/README.md
+++ b/net/unbound/files/README.md
@@ -139,7 +139,7 @@ config unbound
### Hybrid Manual/UCI
You like the UCI. Yet, you need to add some difficult to standardize options, or just are not ready to make a UCI request yet. The files `/etc/unbound/unbound_srv.conf` and `/etc/unbound/unbound_ext.conf` will be copied to Unbounds chroot directory and included during auto generation.
-The former will be added to the end of the `server:` clause. The later will be added to the end of the file for extended `forward:` and `view:` clauses. You can also disable unbound-control in the UCI which only allows "localhost" connections unencrypted, and then add an encrypted remote `control:` clause.
+The file `unbound_srv.conf` will be added into the `server:` clause. The file `unbound_ext.conf` will be added to the end of all configuration. It is for extended `forward-zone:`, `stub-zone:`, `auth-zone:`, and `view:` clauses. You can also disable unbound-control in the UCI which only allows "localhost" connections unencrypted, and then add an encrypted remote `control:` clause.
## Complete List of UCI Options
**/etc/config/unbound**:
@@ -196,8 +196,11 @@ config unbound
option domain_type 'static'
Unbound local-zone: <domain> <type>. This allows you to lock
- down or allow forwarding of your domain, your router host name
- without suffix, and leakage of RFC6762 "local."
+ down or allow forwarding of the local zone. Notable types:
+ static - typical single router setup much like OpenWrt dnsmasq default
+ refuse - to answer overtly with DNS code REFUSED
+ deny - to drop queries for the local zone
+ transparent - to use your manually added forward-zone: or stub-zone: clause
option edns_size '1280'
Bytes. Extended DNS is necessary for DNSSEC. However, it can run
@@ -226,9 +229,9 @@ config unbound
configuration. Make changes to /etc/unbound/unbound.conf.
option prefetch_root '0'
- Boolean. Enable Unbound authority zone clauses for "." (root), "arpa,"
- "in-addr.arpa," and "ip6.arpa" and obtain complete zone files from public
- servers using http or AXFR (gTLD are unfortunately not as public).
+ Boolean. Cache the entire root. Enable Unbound `auth-zone:` clauses for
+ "." (root), "arpa," "in-addr.arpa," and "ip6.arpa." Obtain complete zone
+ files from public servers using http or AXFR. (see RFC7706)
option protocol 'mixed'
Unbound can limit its protocol used for recursive queries.
diff --git a/net/unbound/files/iptools.sh b/net/unbound/files/iptools.sh
index 1725242ec..9985f76d0 100644
--- a/net/unbound/files/iptools.sh
+++ b/net/unbound/files/iptools.sh
@@ -138,3 +138,25 @@ private_subnet() {
##############################################################################
+domain_ptr_any() {
+ local subnet=$1
+ local arpa validip4 validip6
+
+ validip4=$( valid_subnet4 $subnet )
+ validip6=$( valid_subnet6 $subnet )
+
+
+ if [ "$validip4" = "ok" ] ; then
+ arpa=$( domain_ptr_ip4 "$subnet" )
+ elif [ "$validip6" = "ok" ] ; then
+ arpa=$( domain_ptr_ip6 "$subnet" )
+ fi
+
+
+ if [ -n "$arpa" ] ; then
+ echo $arpa
+ fi
+}
+
+##############################################################################
+
diff --git a/net/unbound/files/odhcpd.sh b/net/unbound/files/odhcpd.sh
index 9c01dc6f6..93efa73ad 100644
--- a/net/unbound/files/odhcpd.sh
+++ b/net/unbound/files/odhcpd.sh
@@ -43,7 +43,9 @@ odhcpd_zonedata() {
local dhcp_origin=$( uci_get dhcp.@odhcpd[0].leasefile )
- if [ "$dhcp_link" = "odhcpd" -a -f "$dhcp_origin" ] ; then
+ if [ "$dhcp_link" = "odhcpd" \
+ -a -f "$dhcp_origin" \
+ -a -n "$dhcp_domain" ] ; then
# Capture the lease file which could be changing often
sort $dhcp_origin > $dhcp_ls_new
diff --git a/net/unbound/files/unbound.sh b/net/unbound/files/unbound.sh
index 2fda84e86..a22117751 100644
--- a/net/unbound/files/unbound.sh
+++ b/net/unbound/files/unbound.sh
@@ -63,12 +63,18 @@ UNBOUND_TXT_HOSTNAME=thisrouter
UNBOUND_LIST_FORWARD=""
UNBOUND_LIST_INSECURE=""
-UNBOUND_LIST_PRV_SUBNET=""
##############################################################################
-# keep track of local-domain: assignments during inserted resource records
+# 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."
##############################################################################
@@ -82,34 +88,13 @@ UNBOUND_LIST_DOMAINS=""
##############################################################################
-copy_dash_update() {
- # TODO: remove this function and use builtins when this issues is resovled.
- # Due to OpenWrt/LEDE divergence "cp -u" isn't yet universally available.
- local filetime keeptime
-
-
- if [ -f $UNBOUND_KEYFILE.keep ] ; then
- # root.key.keep is reused if newest
- filetime=$( date -r $UNBOUND_KEYFILE +%s )
- keeptime=$( date -r $UNBOUND_KEYFILE.keep +%s )
-
-
- if [ $keeptime -gt $filetime ] ; then
- cp $UNBOUND_KEYFILE.keep $UNBOUND_KEYFILE
- fi
-
-
- rm -f $UNBOUND_KEYFILE.keep
- fi
-}
-
-##############################################################################
-
create_interface_dns() {
local cfg="$1"
local ipcommand logint ignore ifname ifdashname
local name names address addresses
- local ulaprefix if_fqdn host_fqdn mode mode_ptr
+ 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
@@ -124,45 +109,60 @@ create_interface_dns() {
if_fqdn="$ifdashname.$host_fqdn"
- if [ -z "${ulaprefix%%:/*}" ] ; then
- # Nonsense so this option isn't globbed below
- ulaprefix="fdno:such:addr::/48"
- fi
+ 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
- if [ "$ignore" -gt 0 ] ; then
- mode="$UNBOUND_D_WAN_FQDN"
else
- mode="$UNBOUND_D_LAN_FQDN"
+ mode=1
fi
- case "$mode" in
- 3)
- mode_ptr="$host_fqdn"
- names="$host_fqdn $UNBOUND_TXT_HOSTNAME"
- ;;
+ 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
+
- 4)
- 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
+ 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"
- else
+ ;;
+
+ 4)
mode_ptr="$if_fqdn"
names="$if_fqdn $host_fqdn $UNBOUND_TXT_HOSTNAME"
- fi
- ;;
-
- *)
- mode_ptr="$UNBOUND_TXT_HOSTNAME"
- names="$UNBOUND_TXT_HOSTNAME"
- ;;
- esac
+ ;;
+ esac
- if [ "$mode" -gt 1 ] ; then
{
for address in $addresses ; do
case $address in
@@ -385,21 +385,37 @@ bundle_domain_insecure() {
##############################################################################
bundle_private_interface() {
- local ipcommand ifsubnet ifsubnets ifname
+ local ipcommand ifsubnet ifsubnets ifname validip4
network_get_device ifname $1
+
if [ -n "$ifname" ] ; then
- ipcommand="ip -6 -o address show $ifname"
- ifsubnets=$( $ipcommand | awk '/inet6/{ print $4 }' )
+ 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])
+ [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_SUBNET="$UNBOUND_LIST_PRV_SUBNET $ifsubnet" ;;
+ 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
@@ -411,6 +427,7 @@ bundle_private_interface() {
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 )
@@ -422,6 +439,7 @@ unbound_mkdir() {
fi
fi
+
if [ -f $UNBOUND_KEYFILE ] ; then
filestuff=$( cat $UNBOUND_KEYFILE )
@@ -469,7 +487,11 @@ unbound_mkdir() {
fi
- copy_dash_update
+ 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
@@ -809,6 +831,7 @@ unbound_conf() {
logger -t unbound -s "default memory configuration"
fi
+
# Assembly of module-config: options is tricky; order matters
modulestring="iterator"
@@ -941,8 +964,8 @@ unbound_conf() {
fi
- if [ -n "$UNBOUND_LIST_PRV_SUBNET" -a "$UNBOUND_D_PRIV_BLCK" -gt 1 ] ; then
- for ifsubnet in $UNBOUND_LIST_PRV_SUBNET ; do
+ 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
@@ -1019,6 +1042,7 @@ 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
@@ -1040,31 +1064,90 @@ unbound_adblock() {
##############################################################################
unbound_hostname() {
+ local ifsubnet ifarpa
+
+
if [ -n "$UNBOUND_TXT_DOMAIN" ] ; then
{
- # TODO: Unbound 1.6.0 added "tags" and "views" and we could make
- # domains by interface to prevent DNS from "guest" to "home"
- echo " local-zone: $UNBOUND_TXT_DOMAIN. $UNBOUND_D_DOMAIN_TYPE"
- echo " domain-insecure: $UNBOUND_TXT_DOMAIN"
- echo " private-domain: $UNBOUND_TXT_DOMAIN"
- echo
- echo " local-zone: $UNBOUND_TXT_HOSTNAME. $UNBOUND_D_DOMAIN_TYPE"
+ # 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 like responses (link only)
- echo " local-zone: local. $UNBOUND_D_DOMAIN_TYPE"
+ # 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
@@ -1227,6 +1310,7 @@ unbound_resolv_setup() {
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
@@ -1237,6 +1321,7 @@ unbound_resolv_setup() {
return
fi
+
# unbound is designated to listen on 127.0.0.1#53,
# set resolver file to local.
rm -f /tmp/resolv.conf