Merge pull request #4853 from StevenHessing/noddos
[feed/packages.git] / net / unbound / files / unbound.sh
index d918152d7c982ffb686463f218ebd3ed6087d8f3..e0a1e52540954a5243521f00e29a223878313903 100644 (file)
 #
 ##############################################################################
 #
-# 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.
 #
 ##############################################################################
 
-UNBOUND_B_CONTROL=0
 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
@@ -34,8 +37,10 @@ UNBOUND_B_PRIV_BLCK=1
 UNBOUND_B_QUERY_MIN=0
 UNBOUND_B_QRY_MINST=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_PROTOCOL=mixed
 UNBOUND_D_RESOURCE=small
@@ -57,6 +62,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 +79,12 @@ 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
+
+UNBOUND_CTLKEY_FILE=$UNBOUND_VARDIR/unbound_control.key
+UNBOUND_CTLPEM_FILE=$UNBOUND_VARDIR/unbound_control.pem
+UNBOUND_SRVKEY_FILE=$UNBOUND_VARDIR/unbound_server.key
+UNBOUND_SRVPEM_FILE=$UNBOUND_VARDIR/unbound_server.pem
 
 ##############################################################################
 
@@ -124,8 +139,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 +238,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
@@ -256,32 +400,11 @@ 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
 
 
-  if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
-    resolvsym=1
-  else
-    /etc/init.d/dnsmasq enabled || resolvsym=1
-  fi
-
-
-  if [ "$resolvsym" -gt 0 ] ; then
-    rm -f /tmp/resolv.conf
-
-
-    {
-      # Set resolver file to local but not if /etc/init.d/dnsmasq will do it.
-      echo "nameserver 127.0.0.1"
-      echo "nameserver ::1"
-      echo "search $UNBOUND_TXT_DOMAIN"
-    } > /tmp/resolv.conf
-  fi
-
-
   if [ "$UNBOUND_D_DHCP_LINK" = "odhcpd" -a ! -d "$dhcp_dir" ] ; then
     # make sure odhcpd has a directory to write (not done itself, yet)
     mkdir -p "$dhcp_dir"
@@ -315,7 +438,7 @@ unbound_mkdir() {
       # Debian-like package dns-root-data
       cp -p /usr/share/dns/root.hints $UNBOUND_HINTFILE
 
-    else
+    elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
       logger -t unbound -s "iterator will use built-in root hints"
     fi
   fi
@@ -329,7 +452,7 @@ unbound_mkdir() {
     elif [ -x $UNBOUND_ANCHOR ] ; then
       $UNBOUND_ANCHOR -a $UNBOUND_KEYFILE
 
-    else
+    elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
       logger -t unbound -s "validator will use built-in trust anchor"
     fi
   fi
@@ -340,17 +463,54 @@ unbound_mkdir() {
 
   # Ensure access and prepare to jail
   chown -R unbound:unbound $UNBOUND_VARDIR
-  chmod 775 $UNBOUND_VARDIR
-  chmod 664 $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_B_CONTROL" -gt 0 ] ; then
+  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)
     {
-      # Enable remote control tool, but only at local host for security
-      # You can hand write fancier encrypted access with /etc/..._ext.conf
+      # Local Host Only Unencrypted Remote Control
       echo "remote-control:"
       echo "  control-enable: yes"
       echo "  control-use-cert: no"
@@ -358,7 +518,42 @@ unbound_control() {
       echo "  control-interface: ::1"
       echo
     } >> $UNBOUND_CONFFILE
-  fi
+    ;;
+
+  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
 
 
   {
@@ -376,15 +571,14 @@ unbound_conf() {
   local cfg="$1"
   local rt_mem rt_conn modulestring
 
+  # Make fresh conf file
+  echo > $UNBOUND_CONFFILE
+
 
   {
     # Make fresh conf file
     echo "# $UNBOUND_CONFFILE generated by UCI $( date )"
     echo
-  } > $UNBOUND_CONFFILE
-
-
-  {
     # No threading
     echo "server:"
     echo "  username: unbound"
@@ -394,27 +588,33 @@ unbound_conf() {
     echo "  infra-cache-slabs: 1"
     echo "  key-cache-slabs: 1"
     echo
-  } >> $UNBOUND_CONFFILE
-
-
-  {
+    # 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 "  verbosity: 1"
     echo "  statistics-interval: 0"
     echo "  statistics-cumulative: no"
-    echo "  extended-statistics: no"
-    echo
   } >> $UNBOUND_CONFFILE
 
 
-  {
-    # Interfaces (access contol "option local_service")
-    echo "  interface: 0.0.0.0"
-    echo "  interface: ::0"
-    echo "  outgoing-interface: 0.0.0.0"
-    echo "  outgoing-interface: ::0"
-    echo
-  } >> $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
@@ -526,7 +726,7 @@ unbound_conf() {
       echo
     } >> $UNBOUND_CONFFILE
 
-  else
+  elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
     logger -t unbound -s "default memory resource consumption"
   fi
 
@@ -602,7 +802,9 @@ unbound_conf() {
       ;;
 
     *)
-      logger -t unbound -s "default recursion configuration"
+      if [ ! -f "$UNBOUND_TIMEFILE" ] ; then
+        logger -t unbound -s "default recursion configuration"
+      fi
       ;;
   esac
 
@@ -778,15 +980,40 @@ 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
   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
@@ -794,7 +1021,6 @@ unbound_uci() {
   config_get_bool UNBOUND_B_QRY_MINST  "$cfg" query_min_strict 0
   config_get_bool UNBOUND_B_PRIV_BLCK  "$cfg" rebind_protection 1
   config_get_bool UNBOUND_B_LOCL_BLCK  "$cfg" rebind_localhost 0
-  config_get_bool UNBOUND_B_CONTROL    "$cfg" unbound_control 0
   config_get_bool UNBOUND_B_DNSSEC     "$cfg" validator 0
   config_get_bool UNBOUND_B_NTP_BOOT   "$cfg" validator_ntp 1
 
@@ -804,8 +1030,10 @@ unbound_uci() {
   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_PROTOCOL    "$cfg" protocol mixed
   config_get UNBOUND_D_RECURSION   "$cfg" recursion passive
@@ -815,6 +1043,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
@@ -822,7 +1051,11 @@ unbound_uci() {
 
     if [ "$UNBOUND_B_DNSMASQ" -gt 0 ] ; then
       UNBOUND_D_DHCP_LINK=dnsmasq
-      logger -t unbound -s "Please use 'dhcp_link' selector instead"
+
+
+      if [ ! -f "$UNBOUND_TIMEFILE" ] ; then
+        logger -t unbound -s "Please use 'dhcp_link' selector instead"
+      fi
     fi
   fi
 
@@ -835,7 +1068,7 @@ unbound_uci() {
     fi
 
 
-    if [ "$UNBOUND_D_DHCP_LINK" = "none" ] ; then
+    if [ "$UNBOUND_D_DHCP_LINK" = "none" -a ! -f "$UNBOUND_TIMEFILE" ] ; then
       logger -t unbound -s "cannot forward to dnsmasq"
     fi
   fi
@@ -849,7 +1082,7 @@ unbound_uci() {
     fi
 
 
-    if [ "$UNBOUND_D_DHCP_LINK" = "none" ] ; then
+    if [ "$UNBOUND_D_DHCP_LINK" = "none" -a ! -f "$UNBOUND_TIMEFILE" ] ; then
       logger -t unbound -s "cannot receive records from odhcpd"
     fi
   fi
@@ -857,29 +1090,71 @@ unbound_uci() {
 
   if [ "$UNBOUND_N_EDNS_SIZE" -lt 512 \
     -o 4096 -lt "$UNBOUND_N_EDNS_SIZE" ] ; then
-    # exceeds range, back to default
+    logger -t unbound -s "edns_size exceeds range, using default"
     UNBOUND_N_EDNS_SIZE=1280
   fi
 
 
-  if [ "$UNBOUND_N_RX_PORT" -lt 1024 \
-    -o 10240 -lt "$UNBOUND_N_RX_PORT" ] ; then
-    # special port or in 5 digits, back to default
+  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
-    # that could have had awful side effects
+    logger -t unbound -s "ttl_min could have had awful side effects, using 300"
     UNBOUND_TTL_MIN=300
   fi
 }
 
 ##############################################################################
 
+_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
+}
+
+##############################################################################
+
+_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
 
 
@@ -892,32 +1167,23 @@ unbound_start() {
       dnsmasq_link
     else
       unbound_hostname
+      unbound_records
     fi
 
     unbound_control
   fi
+
+
+  _resolv_setup
 }
 
 ##############################################################################
 
 unbound_stop() {
-  local resolvsym=0
-
-  rootzone_update
+  _resolv_teardown
 
 
-  if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
-    resolvsym=1
-  else
-    /etc/init.d/dnsmasq enabled || resolvsym=1
-  fi
-
-
-  if [ "$resolvsym" -gt 0 ] ; then
-    # set resolver file to normal, but don't stomp on dnsmasq
-    rm -f /tmp/resolv.conf
-    ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
-  fi
+  rootzone_update
 }
 
 ##############################################################################