lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

unbound.sh (24813B)


      1 #!/bin/sh
      2 ##############################################################################
      3 #
      4 # This program is free software; you can redistribute it and/or modify
      5 # it under the terms of the GNU General Public License version 2 as
      6 # published by the Free Software Foundation.
      7 #
      8 # This program is distributed in the hope that it will be useful,
      9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11 # GNU General Public License for more details.
     12 #
     13 # Copyright (C) 2016 Eric Luehrsen
     14 #
     15 ##############################################################################
     16 #
     17 # This builds the basic UCI components currently supported for Unbound. It is
     18 # intentionally NOT comprehensive and bundles a lot of options. The UCI is to
     19 # be a simpler presentation of the total Unbound conf set.
     20 #
     21 ##############################################################################
     22 
     23 UNBOUND_B_CONTROL=0
     24 UNBOUND_B_SLAAC6_MAC=0
     25 UNBOUND_B_DNSSEC=0
     26 UNBOUND_B_DNS64=0
     27 UNBOUND_B_GATE_NAME=0
     28 UNBOUND_B_HIDE_BIND=1
     29 UNBOUND_B_LOCL_BLCK=0
     30 UNBOUND_B_LOCL_SERV=1
     31 UNBOUND_B_MAN_CONF=0
     32 UNBOUND_B_NTP_BOOT=1
     33 UNBOUND_B_PRIV_BLCK=1
     34 UNBOUND_B_QUERY_MIN=0
     35 UNBOUND_B_QRY_MINST=0
     36 
     37 UNBOUND_D_DOMAIN_TYPE=static
     38 UNBOUND_D_DHCP_LINK=none
     39 UNBOUND_D_LAN_FQDN=0
     40 UNBOUND_D_PROTOCOL=mixed
     41 UNBOUND_D_RESOURCE=small
     42 UNBOUND_D_RECURSION=passive
     43 UNBOUND_D_WAN_FQDN=0
     44 
     45 UNBOUND_IP_DNS64="64:ff9b::/96"
     46 
     47 UNBOUND_N_EDNS_SIZE=1280
     48 UNBOUND_N_FWD_PORTS=""
     49 UNBOUND_N_RX_PORT=53
     50 UNBOUND_N_ROOT_AGE=9
     51 
     52 UNBOUND_TTL_MIN=120
     53 
     54 UNBOUND_TXT_DOMAIN=lan
     55 UNBOUND_TXT_FWD_ZONE=""
     56 UNBOUND_TXT_HOSTNAME=thisrouter
     57 
     58 ##############################################################################
     59 
     60 UNBOUND_LIBDIR=/usr/lib/unbound
     61 UNBOUND_VARDIR=/var/lib/unbound
     62 
     63 UNBOUND_PIDFILE=/var/run/unbound.pid
     64 
     65 UNBOUND_SRV_CONF=$UNBOUND_VARDIR/unbound_srv.conf
     66 UNBOUND_EXT_CONF=$UNBOUND_VARDIR/unbound_ext.conf
     67 UNBOUND_DHCP_CONF=$UNBOUND_VARDIR/unbound_dhcp.conf
     68 UNBOUND_CONFFILE=$UNBOUND_VARDIR/unbound.conf
     69 
     70 UNBOUND_KEYFILE=$UNBOUND_VARDIR/root.key
     71 UNBOUND_HINTFILE=$UNBOUND_VARDIR/root.hints
     72 UNBOUND_TIMEFILE=$UNBOUND_VARDIR/unbound.time
     73 
     74 ##############################################################################
     75 
     76 UNBOUND_ANCHOR=/usr/sbin/unbound-anchor
     77 UNBOUND_CONTROL=/usr/sbin/unbound-control
     78 UNBOUND_CONTROL_CFG="$UNBOUND_CONTROL -c $UNBOUND_CONFFILE"
     79 
     80 ##############################################################################
     81 
     82 . /lib/functions.sh
     83 . /lib/functions/network.sh
     84 
     85 . $UNBOUND_LIBDIR/dnsmasq.sh
     86 . $UNBOUND_LIBDIR/iptools.sh
     87 . $UNBOUND_LIBDIR/rootzone.sh
     88 
     89 ##############################################################################
     90 
     91 copy_dash_update() {
     92   # TODO: remove this function and use builtins when this issues is resovled.
     93   # Due to OpenWrt/LEDE divergence "cp -u" isn't yet universally available.
     94   local filetime keeptime
     95 
     96 
     97   if [ -f $UNBOUND_KEYFILE.keep ] ; then
     98     # root.key.keep is reused if newest
     99     filetime=$( date -r $UNBOUND_KEYFILE +%s )
    100     keeptime=$( date -r $UNBOUND_KEYFILE.keep +%s )
    101 
    102 
    103     if [ $keeptime -gt $filetime ] ; then
    104       cp $UNBOUND_KEYFILE.keep $UNBOUND_KEYFILE
    105     fi
    106 
    107 
    108     rm -f $UNBOUND_KEYFILE.keep
    109   fi
    110 }
    111 
    112 ##############################################################################
    113 
    114 create_interface_dns() {
    115   local cfg="$1"
    116   local ipcommand logint ignore ifname ifdashname
    117   local name names address addresses
    118   local ulaprefix if_fqdn host_fqdn mode mode_ptr
    119 
    120   # Create local-data: references for this hosts interfaces (router).
    121   config_get logint "$cfg" interface
    122   config_get_bool ignore "$cfg" ignore 0
    123   network_get_device ifname "$cfg"
    124 
    125   ifdashname="${ifname//./-}"
    126   ipcommand="ip -o address show $ifname"
    127   addresses="$($ipcommand | awk '/inet/{sub(/\/.*/,"",$4); print $4}')"
    128   ulaprefix="$(uci_get network @globals[0] ula_prefix)"
    129   host_fqdn="$UNBOUND_TXT_HOSTNAME.$UNBOUND_TXT_DOMAIN"
    130   if_fqdn="$ifdashname.$host_fqdn"
    131 
    132 
    133   if [ -z "${ulaprefix%%:/*}" ] ; then
    134     # Nonsense so this option isn't globbed below
    135     ulaprefix="fdno:such:addr::/48"
    136   fi
    137 
    138 
    139   if [ "$ignore" -gt 0 ] ; then
    140     mode="$UNBOUND_D_WAN_FQDN"
    141   else
    142     mode="$UNBOUND_D_LAN_FQDN"
    143   fi
    144 
    145 
    146   case "$mode" in
    147   3)
    148     mode_ptr="$host_fqdn"
    149     names="$host_fqdn  $UNBOUND_TXT_HOSTNAME"
    150     ;;
    151 
    152   4)
    153     if [ -z "$ifdashname" ] ; then
    154       # race conditions at init can rarely cause a blank device return
    155       # the record format is invalid and Unbound won't load the conf file
    156       mode_ptr="$host_fqdn"
    157       names="$host_fqdn  $UNBOUND_TXT_HOSTNAME"
    158     else
    159       mode_ptr="$if_fqdn"
    160       names="$if_fqdn  $host_fqdn  $UNBOUND_TXT_HOSTNAME"
    161     fi
    162     ;;
    163 
    164   *)
    165     mode_ptr="$UNBOUND_TXT_HOSTNAME"
    166     names="$UNBOUND_TXT_HOSTNAME"
    167     ;;
    168   esac
    169 
    170 
    171   if [ "$mode" -gt 1 ] ; then
    172     {
    173       for address in $addresses ; do
    174         case $address in
    175         fe80:*|169.254.*)
    176           echo "  # note link address $address"
    177           ;;
    178 
    179         [1-9a-f]*:*[0-9a-f])
    180           # GA and ULA IP6 for HOST IN AAA records (ip command is robust)
    181           for name in $names ; do
    182             echo "  local-data: \"$name. 120 IN AAAA $address\""
    183           done
    184           echo "  local-data-ptr: \"$address 120 $mode_ptr\""
    185           ;;
    186 
    187         [1-9]*.*[0-9])
    188           # Old fashioned HOST IN A records
    189           for name in $names ; do
    190             echo "  local-data: \"$name. 120 IN A $address\""
    191           done
    192           echo "  local-data-ptr: \"$address 120 $mode_ptr\""
    193           ;;
    194         esac
    195       done
    196       echo
    197     } >> $UNBOUND_CONFFILE
    198 
    199   elif [ "$mode" -gt 0 ] ; then
    200     {
    201       for address in $addresses ; do
    202         case $address in
    203         fe80:*|169.254.*)
    204           echo "  # note link address $address"
    205           ;;
    206 
    207         "${ulaprefix%%:/*}"*)
    208           # Only this networks ULA and only hostname
    209           echo "  local-data: \"$UNBOUND_TXT_HOSTNAME. 120 IN AAAA $address\""
    210           echo "  local-data-ptr: \"$address 120 $UNBOUND_TXT_HOSTNAME\""
    211           ;;
    212 
    213         [1-9]*.*[0-9])
    214           echo "  local-data: \"$UNBOUND_TXT_HOSTNAME. 120 IN A $address\""
    215           echo "  local-data-ptr: \"$address 120 $UNBOUND_TXT_HOSTNAME\""
    216           ;;
    217         esac
    218       done
    219       echo
    220     } >> $UNBOUND_CONFFILE
    221   fi
    222 }
    223 
    224 ##############################################################################
    225 
    226 create_access_control() {
    227   local cfg="$1"
    228   local subnets subnets4 subnets6
    229   local validip4 validip6
    230 
    231   network_get_subnets  subnets4 "$cfg"
    232   network_get_subnets6 subnets6 "$cfg"
    233   subnets="$subnets4 $subnets6"
    234 
    235 
    236   if [ -n "$subnets" ] ; then
    237     for subnet in $subnets ; do
    238       validip4=$( valid_subnet4 $subnet )
    239       validip6=$( valid_subnet6 $subnet )
    240 
    241 
    242       if [ "$validip4" = "ok" -o "$validip6" = "ok" ] ; then
    243         # For each "network" UCI add "access-control:" white list for queries
    244         echo "  access-control: $subnet allow" >> $UNBOUND_CONFFILE
    245       fi
    246     done
    247   fi
    248 }
    249 
    250 ##############################################################################
    251 
    252 create_domain_insecure() {
    253   echo "  domain-insecure: \"$1\"" >> $UNBOUND_CONFFILE
    254 }
    255 
    256 ##############################################################################
    257 
    258 unbound_mkdir() {
    259   local resolvsym=0
    260   local dhcp_origin=$( uci get dhcp.@odhcpd[0].leasefile )
    261   local dhcp_dir=$( dirname "$dhcp_origin" )
    262   local filestuff
    263 
    264 
    265   if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
    266     resolvsym=1
    267   else
    268     /etc/init.d/dnsmasq enabled || resolvsym=1
    269   fi
    270 
    271 
    272   if [ "$resolvsym" -gt 0 ] ; then
    273     rm -f /tmp/resolv.conf
    274 
    275 
    276     {
    277       # Set resolver file to local but not if /etc/init.d/dnsmasq will do it.
    278       echo "nameserver 127.0.0.1"
    279       echo "nameserver ::1"
    280       echo "search $UNBOUND_TXT_DOMAIN"
    281     } > /tmp/resolv.conf
    282   fi
    283 
    284 
    285   if [ "$UNBOUND_D_DHCP_LINK" = "odhcpd" -a ! -d "$dhcp_dir" ] ; then
    286     # make sure odhcpd has a directory to write (not done itself, yet)
    287     mkdir -p "$dhcp_dir"
    288   fi
    289 
    290 
    291   if [ -f $UNBOUND_KEYFILE ] ; then
    292     filestuff=$( cat $UNBOUND_KEYFILE )
    293 
    294 
    295     case "$filestuff" in
    296       *"state=2 [  VALID  ]"*)
    297         # Lets not lose RFC 5011 tracking if we don't have to
    298         cp -p $UNBOUND_KEYFILE $UNBOUND_KEYFILE.keep
    299         ;;
    300     esac
    301   fi
    302 
    303 
    304   # Blind copy /etc/ to /var/lib/
    305   mkdir -p $UNBOUND_VARDIR
    306   rm -f $UNBOUND_VARDIR/dhcp_*
    307   touch $UNBOUND_CONFFILE
    308   touch $UNBOUND_SRV_CONF
    309   touch $UNBOUND_EXT_CONF
    310   cp -p /etc/unbound/* $UNBOUND_VARDIR/
    311 
    312 
    313   if [ ! -f $UNBOUND_HINTFILE ] ; then
    314     if [ -f /usr/share/dns/root.hints ] ; then
    315       # Debian-like package dns-root-data
    316       cp -p /usr/share/dns/root.hints $UNBOUND_HINTFILE
    317 
    318     elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
    319       logger -t unbound -s "iterator will use built-in root hints"
    320     fi
    321   fi
    322 
    323 
    324   if [ ! -f $UNBOUND_KEYFILE ] ; then
    325     if [ -f /usr/share/dns/root.key ] ; then
    326       # Debian-like package dns-root-data
    327       cp -p /usr/share/dns/root.key $UNBOUND_KEYFILE
    328 
    329     elif [ -x $UNBOUND_ANCHOR ] ; then
    330       $UNBOUND_ANCHOR -a $UNBOUND_KEYFILE
    331 
    332     elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
    333       logger -t unbound -s "validator will use built-in trust anchor"
    334     fi
    335   fi
    336 
    337 
    338   copy_dash_update
    339 
    340 
    341   # Ensure access and prepare to jail
    342   chown -R unbound:unbound $UNBOUND_VARDIR
    343   chmod 775 $UNBOUND_VARDIR
    344   chmod 664 $UNBOUND_VARDIR/*
    345 }
    346 
    347 ##############################################################################
    348 
    349 unbound_control() {
    350   if [ "$UNBOUND_B_CONTROL" -gt 0 ] ; then
    351     {
    352       # Enable remote control tool, but only at local host for security
    353       # You can hand write fancier encrypted access with /etc/..._ext.conf
    354       echo "remote-control:"
    355       echo "  control-enable: yes"
    356       echo "  control-use-cert: no"
    357       echo "  control-interface: 127.0.0.1"
    358       echo "  control-interface: ::1"
    359       echo
    360     } >> $UNBOUND_CONFFILE
    361   fi
    362 
    363 
    364   {
    365     # Amend your own extended clauses here like forward zones or disable
    366     # above (local, no encryption) and amend your own remote encrypted control
    367     echo
    368     echo "include: $UNBOUND_EXT_CONF" >> $UNBOUND_CONFFILE
    369     echo
    370   } >> $UNBOUND_CONFFILE
    371 }
    372 
    373 ##############################################################################
    374 
    375 unbound_conf() {
    376   local cfg="$1"
    377   local rt_mem rt_conn modulestring
    378 
    379 
    380   {
    381     # Make fresh conf file
    382     echo "# $UNBOUND_CONFFILE generated by UCI $( date )"
    383     echo
    384   } > $UNBOUND_CONFFILE
    385 
    386 
    387   {
    388     # No threading
    389     echo "server:"
    390     echo "  username: unbound"
    391     echo "  num-threads: 1"
    392     echo "  msg-cache-slabs: 1"
    393     echo "  rrset-cache-slabs: 1"
    394     echo "  infra-cache-slabs: 1"
    395     echo "  key-cache-slabs: 1"
    396     echo
    397   } >> $UNBOUND_CONFFILE
    398 
    399 
    400   {
    401     # Logging
    402     echo "  verbosity: 1"
    403     echo "  statistics-interval: 0"
    404     echo "  statistics-cumulative: no"
    405     echo "  extended-statistics: no"
    406     echo
    407   } >> $UNBOUND_CONFFILE
    408 
    409 
    410   {
    411     # Interfaces (access contol "option local_service")
    412     echo "  interface: 0.0.0.0"
    413     echo "  interface: ::0"
    414     echo "  outgoing-interface: 0.0.0.0"
    415     echo "  outgoing-interface: ::0"
    416     echo
    417   } >> $UNBOUND_CONFFILE
    418 
    419 
    420   case "$UNBOUND_D_PROTOCOL" in
    421     ip4_only)
    422       {
    423         echo "  do-ip4: yes"
    424         echo "  do-ip6: no"
    425       } >> $UNBOUND_CONFFILE
    426       ;;
    427 
    428     ip6_only)
    429       {
    430         echo "  do-ip4: no"
    431         echo "  do-ip6: yes"
    432       } >> $UNBOUND_CONFFILE
    433       ;;
    434 
    435     ip6_prefer)
    436       {
    437         echo "  do-ip4: yes"
    438         echo "  do-ip6: yes"
    439         echo "  prefer-ip6: yes"
    440       } >> $UNBOUND_CONFFILE
    441       ;;
    442 
    443     *)
    444       {
    445         echo "  do-ip4: yes"
    446         echo "  do-ip6: yes"
    447       } >> $UNBOUND_CONFFILE
    448       ;;
    449   esac
    450 
    451 
    452   {
    453     # protocol level tuning
    454     echo "  edns-buffer-size: $UNBOUND_N_EDNS_SIZE"
    455     echo "  msg-buffer-size: 8192"
    456     echo "  port: $UNBOUND_N_RX_PORT"
    457     echo "  outgoing-port-permit: 10240-65535"
    458     echo
    459   } >> $UNBOUND_CONFFILE
    460 
    461 
    462   {
    463     # Other harding and options for an embedded router
    464     echo "  harden-short-bufsize: yes"
    465     echo "  harden-large-queries: yes"
    466     echo "  harden-glue: yes"
    467     echo "  harden-below-nxdomain: no"
    468     echo "  harden-referral-path: no"
    469     echo "  use-caps-for-id: no"
    470     echo
    471   } >> $UNBOUND_CONFFILE
    472 
    473 
    474   {
    475     # Default Files
    476     echo "  use-syslog: yes"
    477     echo "  chroot: \"$UNBOUND_VARDIR\""
    478     echo "  directory: \"$UNBOUND_VARDIR\""
    479     echo "  pidfile: \"$UNBOUND_PIDFILE\""
    480   } >> $UNBOUND_CONFFILE
    481 
    482 
    483   if [ -f "$UNBOUND_HINTFILE" ] ; then
    484     # Optional hints if found
    485     echo "  root-hints: \"$UNBOUND_HINTFILE\"" >> $UNBOUND_CONFFILE
    486   fi
    487 
    488 
    489   if [ "$UNBOUND_B_DNSSEC" -gt 0 -a -f "$UNBOUND_KEYFILE" ] ; then
    490     {
    491       echo "  auto-trust-anchor-file: \"$UNBOUND_KEYFILE\""
    492       echo
    493     } >> $UNBOUND_CONFFILE
    494 
    495   else
    496     echo >> $UNBOUND_CONFFILE
    497   fi
    498 
    499 
    500   case "$UNBOUND_D_RESOURCE" in
    501     # Tiny - Unbound's recommended cheap hardware config
    502     tiny)   rt_mem=1  ; rt_conn=1 ;;
    503     # Small - Half RRCACHE and open ports
    504     small)  rt_mem=8  ; rt_conn=5 ;;
    505     # Medium - Nearly default but with some added balancintg
    506     medium) rt_mem=16 ; rt_conn=10 ;;
    507     # Large - Double medium
    508     large)  rt_mem=32 ; rt_conn=10 ;;
    509     # Whatever unbound does
    510     *) rt_mem=0 ; rt_conn=0 ;;
    511   esac
    512 
    513 
    514   if [ "$rt_mem" -gt 0 ] ; then
    515     {
    516       # Set memory sizing parameters
    517       echo "  outgoing-range: $(($rt_conn*64))"
    518       echo "  num-queries-per-thread: $(($rt_conn*32))"
    519       echo "  outgoing-num-tcp: $(($rt_conn))"
    520       echo "  incoming-num-tcp: $(($rt_conn))"
    521       echo "  rrset-cache-size: $(($rt_mem*256))k"
    522       echo "  msg-cache-size: $(($rt_mem*128))k"
    523       echo "  key-cache-size: $(($rt_mem*128))k"
    524       echo "  neg-cache-size: $(($rt_mem*64))k"
    525       echo "  infra-cache-numhosts: $(($rt_mem*256))"
    526       echo
    527     } >> $UNBOUND_CONFFILE
    528 
    529   elif [ ! -f "$UNBOUND_TIMEFILE" ] ; then
    530     logger -t unbound -s "default memory resource consumption"
    531   fi
    532 
    533   # Assembly of module-config: options is tricky; order matters
    534   modulestring="iterator"
    535 
    536 
    537   if [ "$UNBOUND_B_DNSSEC" -gt 0 ] ; then
    538     if [ ! -f "$UNBOUND_TIMEFILE" -a "$UNBOUND_B_NTP_BOOT" -gt 0 ] ; then
    539       # DNSSEC chicken and egg with getting NTP time
    540       echo "  val-override-date: -1" >> $UNBOUND_CONFFILE
    541     fi
    542 
    543 
    544     {
    545       echo "  harden-dnssec-stripped: yes"
    546       echo "  val-clean-additional: yes"
    547       echo "  ignore-cd-flag: yes"
    548     } >> $UNBOUND_CONFFILE
    549 
    550 
    551     modulestring="validator $modulestring"
    552   fi
    553 
    554 
    555   if [ "$UNBOUND_B_DNS64" -gt 0 ] ; then
    556     echo "  dns64-prefix: $UNBOUND_IP_DNS64" >> $UNBOUND_CONFFILE
    557 
    558     modulestring="dns64 $modulestring"
    559   fi
    560 
    561 
    562   {
    563     # Print final module string
    564     echo "  module-config: \"$modulestring\""
    565     echo
    566   }  >> $UNBOUND_CONFFILE
    567 
    568 
    569   if [ "$UNBOUND_B_QRY_MINST" -gt 0 -a "$UNBOUND_B_QUERY_MIN" -gt 0 ] ; then
    570     {
    571       # Some query privacy but "strict" will break some name servers
    572       echo "  qname-minimisation: yes"
    573       echo "  qname-minimisation-strict: yes"
    574     } >> $UNBOUND_CONFFILE
    575 
    576   elif [ "$UNBOUND_B_QUERY_MIN" -gt 0 ] ; then
    577     # Minor improvement on query privacy
    578     echo "  qname-minimisation: yes" >> $UNBOUND_CONFFILE
    579 
    580   else
    581     echo "  qname-minimisation: no" >> $UNBOUND_CONFFILE
    582   fi
    583 
    584 
    585   case "$UNBOUND_D_RECURSION" in
    586     passive)
    587       {
    588         echo "  prefetch: no"
    589         echo "  prefetch-key: no"
    590         echo "  target-fetch-policy: \"0 0 0 0 0\""
    591         echo
    592       } >> $UNBOUND_CONFFILE
    593       ;;
    594 
    595     aggressive)
    596       {
    597         echo "  prefetch: yes"
    598         echo "  prefetch-key: yes"
    599         echo "  target-fetch-policy: \"3 2 1 0 0\""
    600         echo
    601       } >> $UNBOUND_CONFFILE
    602       ;;
    603 
    604     *)
    605       if [ ! -f "$UNBOUND_TIMEFILE" ] ; then
    606         logger -t unbound -s "default recursion configuration"
    607       fi
    608       ;;
    609   esac
    610 
    611 
    612   {
    613     # Reload records more than 10 hours old
    614     # DNSSEC 5 minute bogus cool down before retry
    615     # Adaptive infrastructure info kept for 15 minutes
    616     echo "  cache-min-ttl: $UNBOUND_TTL_MIN"
    617     echo "  cache-max-ttl: 36000"
    618     echo "  val-bogus-ttl: 300"
    619     echo "  infra-host-ttl: 900"
    620     echo
    621   } >> $UNBOUND_CONFFILE
    622 
    623 
    624   if [ "$UNBOUND_B_HIDE_BIND" -gt 0 ] ; then
    625     {
    626       # Block server id and version DNS TXT records
    627       echo "  hide-identity: yes"
    628       echo "  hide-version: yes"
    629       echo
    630     } >> $UNBOUND_CONFFILE
    631   fi
    632 
    633 
    634   if [ "$UNBOUND_B_PRIV_BLCK" -gt 0 ] ; then
    635     {
    636       # Remove _upstream_ or global reponses with private addresses.
    637       # Unbounds own "local zone" and "forward zone" may still use these.
    638       # RFC1918, RFC3927, RFC4291, RFC6598, RFC6890
    639       echo "  private-address: 10.0.0.0/8"
    640       echo "  private-address: 100.64.0.0/10"
    641       echo "  private-address: 169.254.0.0/16"
    642       echo "  private-address: 172.16.0.0/12"
    643       echo "  private-address: 192.168.0.0/16"
    644       echo "  private-address: fc00::/8"
    645       echo "  private-address: fd00::/8"
    646       echo "  private-address: fe80::/10"
    647     } >> $UNBOUND_CONFFILE
    648   fi
    649 
    650 
    651   if [ "$UNBOUND_B_LOCL_BLCK" -gt 0 ] ; then
    652     {
    653       # Remove DNS reponses from upstream with loopback IP
    654       # Black hole DNS method for ad blocking, so consider...
    655       echo "  private-address: 127.0.0.0/8"
    656       echo "  private-address: ::1/128"
    657       echo
    658     } >> $UNBOUND_CONFFILE
    659 
    660   else
    661     echo >> $UNBOUND_CONFFILE
    662   fi
    663 
    664 
    665   # Except and accept domains as insecure (DNSSEC); work around broken domains
    666   config_list_foreach "$cfg" "domain_insecure" create_domain_insecure
    667   echo >> $UNBOUND_CONFFILE
    668 }
    669 
    670 ##############################################################################
    671 
    672 unbound_access() {
    673   # TODO: Unbound 1.6.0 added "tags" and "views", so we can add tags to
    674   # each access-control IP block, and then divert access.
    675   # -- "guest" WIFI will not be allowed to see local zone data
    676   # -- "child" LAN can black whole a list of domains to http~deadpixel
    677 
    678 
    679   if [ "$UNBOUND_B_LOCL_SERV" -gt 0 ] ; then
    680     # Only respond to queries from which this device has an interface.
    681     # Prevent DNS amplification attacks by not responding to the universe.
    682     config_load network
    683     config_foreach create_access_control interface
    684 
    685 
    686     {
    687       echo "  access-control: 127.0.0.0/8 allow"
    688       echo "  access-control: ::1/128 allow"
    689       echo "  access-control: fe80::/10 allow"
    690       echo
    691     } >> $UNBOUND_CONFFILE
    692 
    693   else
    694     {
    695       echo "  access-control: 0.0.0.0/0 allow"
    696       echo "  access-control: ::0/0 allow"
    697       echo
    698     } >> $UNBOUND_CONFFILE
    699   fi
    700 
    701 
    702   {
    703     # Amend your own "server:" stuff here
    704     echo "  include: $UNBOUND_SRV_CONF"
    705     echo
    706   } >> $UNBOUND_CONFFILE
    707 }
    708 
    709 ##############################################################################
    710 
    711 unbound_adblock() {
    712   # TODO: Unbound 1.6.0 added "tags" and "views"; lets work with adblock team
    713   local adb_enabled adb_file
    714 
    715   if [ ! -x /usr/bin/adblock.sh -o ! -x /etc/init.d/adblock ] ; then
    716     adb_enabled=0
    717   else
    718     /etc/init.d/adblock enabled && adb_enabled=1 || adb_enabled=0
    719   fi
    720 
    721 
    722   if [ "$adb_enabled" -gt 0 ] ; then
    723     {
    724       # Pull in your selected openwrt/pacakges/net/adblock generated lists
    725       for adb_file in $UNBOUND_VARDIR/adb_list.* ; do
    726         echo "  include: $adb_file"
    727       done
    728       echo
    729     } >> $UNBOUND_CONFFILE
    730   fi
    731 }
    732 
    733 ##############################################################################
    734 
    735 unbound_hostname() {
    736   if [ -n "$UNBOUND_TXT_DOMAIN" ] ; then
    737     {
    738       # TODO: Unbound 1.6.0 added "tags" and "views" and we could make
    739       # domains by interface to prevent DNS from "guest" to "home"
    740       echo "  local-zone: $UNBOUND_TXT_DOMAIN. $UNBOUND_D_DOMAIN_TYPE"
    741       echo "  domain-insecure: $UNBOUND_TXT_DOMAIN"
    742       echo "  private-domain: $UNBOUND_TXT_DOMAIN"
    743       echo
    744       echo "  local-zone: $UNBOUND_TXT_HOSTNAME. $UNBOUND_D_DOMAIN_TYPE"
    745       echo "  domain-insecure: $UNBOUND_TXT_HOSTNAME"
    746       echo "  private-domain: $UNBOUND_TXT_HOSTNAME"
    747       echo
    748     } >> $UNBOUND_CONFFILE
    749 
    750 
    751     case "$UNBOUND_D_DOMAIN_TYPE" in
    752     deny|inform_deny|refuse|static)
    753       {
    754         # avoid upstream involvement in RFC6762 like responses (link only)
    755         echo "  local-zone: local. $UNBOUND_D_DOMAIN_TYPE"
    756         echo "  domain-insecure: local"
    757         echo "  private-domain: local"
    758         echo
    759       } >> $UNBOUND_CONFFILE
    760       ;;
    761     esac
    762 
    763 
    764     if [ "$UNBOUND_D_LAN_FQDN" -gt 0 -o "$UNBOUND_D_WAN_FQDN" -gt 0 ] ; then
    765       config_load dhcp
    766       config_foreach create_interface_dns dhcp
    767     fi
    768 
    769 
    770     if [ -f "$UNBOUND_DHCP_CONF" ] ; then
    771       {
    772         # Seed DHCP records because dhcp scripts trigger externally
    773         # Incremental Unbound restarts may drop unbound-control add records
    774         echo "  include: $UNBOUND_DHCP_CONF"
    775         echo
    776       } >> $UNBOUND_CONFFILE
    777     fi
    778   fi
    779 }
    780 
    781 ##############################################################################
    782 
    783 unbound_uci() {
    784   local cfg="$1"
    785   local dnsmasqpath hostnm
    786 
    787   hostnm="$(uci_get system.@system[0].hostname | awk '{print tolower($0)}')"
    788   UNBOUND_TXT_HOSTNAME=${hostnm:-thisrouter}
    789 
    790   config_get_bool UNBOUND_B_SLAAC6_MAC "$cfg" dhcp4_slaac6 0
    791   config_get_bool UNBOUND_B_DNS64      "$cfg" dns64 0
    792   config_get_bool UNBOUND_B_HIDE_BIND  "$cfg" hide_binddata 1
    793   config_get_bool UNBOUND_B_LOCL_SERV  "$cfg" localservice 1
    794   config_get_bool UNBOUND_B_MAN_CONF   "$cfg" manual_conf 0
    795   config_get_bool UNBOUND_B_QUERY_MIN  "$cfg" query_minimize 0
    796   config_get_bool UNBOUND_B_QRY_MINST  "$cfg" query_min_strict 0
    797   config_get_bool UNBOUND_B_PRIV_BLCK  "$cfg" rebind_protection 1
    798   config_get_bool UNBOUND_B_LOCL_BLCK  "$cfg" rebind_localhost 0
    799   config_get_bool UNBOUND_B_CONTROL    "$cfg" unbound_control 0
    800   config_get_bool UNBOUND_B_DNSSEC     "$cfg" validator 0
    801   config_get_bool UNBOUND_B_NTP_BOOT   "$cfg" validator_ntp 1
    802 
    803   config_get UNBOUND_IP_DNS64    "$cfg" dns64_prefix "64:ff9b::/96"
    804 
    805   config_get UNBOUND_N_EDNS_SIZE "$cfg" edns_size 1280
    806   config_get UNBOUND_N_RX_PORT   "$cfg" listen_port 53
    807   config_get UNBOUND_N_ROOT_AGE  "$cfg" root_age 9
    808 
    809   config_get UNBOUND_D_DOMAIN_TYPE "$cfg" domain_type static
    810   config_get UNBOUND_D_DHCP_LINK   "$cfg" dhcp_link none
    811   config_get UNBOUND_D_LAN_FQDN    "$cfg" add_local_fqdn 0
    812   config_get UNBOUND_D_PROTOCOL    "$cfg" protocol mixed
    813   config_get UNBOUND_D_RECURSION   "$cfg" recursion passive
    814   config_get UNBOUND_D_RESOURCE    "$cfg" resource small
    815   config_get UNBOUND_D_WAN_FQDN    "$cfg" add_wan_fqdn 0
    816 
    817   config_get UNBOUND_TTL_MIN     "$cfg" ttl_min 120
    818   config_get UNBOUND_TXT_DOMAIN  "$cfg" domain lan
    819 
    820 
    821   if [ "$UNBOUND_D_DHCP_LINK" = "none" ] ; then
    822     config_get_bool UNBOUND_B_DNSMASQ   "$cfg" dnsmasq_link_dns 0
    823 
    824 
    825     if [ "$UNBOUND_B_DNSMASQ" -gt 0 ] ; then
    826       UNBOUND_D_DHCP_LINK=dnsmasq
    827       
    828       
    829       if [ ! -f "$UNBOUND_TIMEFILE" ] ; then
    830         logger -t unbound -s "Please use 'dhcp_link' selector instead"
    831       fi
    832     fi
    833   fi
    834 
    835 
    836   if [ "$UNBOUND_D_DHCP_LINK" = "dnsmasq" ] ; then
    837     if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
    838       UNBOUND_D_DHCP_LINK=none
    839     else
    840       /etc/init.d/dnsmasq enabled || UNBOUND_D_DHCP_LINK=none
    841     fi
    842 
    843 
    844     if [ "$UNBOUND_D_DHCP_LINK" = "none" -a ! -f "$UNBOUND_TIMEFILE" ] ; then
    845       logger -t unbound -s "cannot forward to dnsmasq"
    846     fi
    847   fi
    848 
    849 
    850   if [ "$UNBOUND_D_DHCP_LINK" = "odhcpd" ] ; then
    851     if [ ! -x /usr/sbin/odhcpd -o ! -x /etc/init.d/odhcpd ] ; then
    852       UNBOUND_D_DHCP_LINK=none
    853     else
    854       /etc/init.d/odhcpd enabled || UNBOUND_D_DHCP_LINK=none
    855     fi
    856 
    857 
    858     if [ "$UNBOUND_D_DHCP_LINK" = "none" -a ! -f "$UNBOUND_TIMEFILE" ] ; then
    859       logger -t unbound -s "cannot receive records from odhcpd"
    860     fi
    861   fi
    862 
    863 
    864   if [ "$UNBOUND_N_EDNS_SIZE" -lt 512 \
    865     -o 4096 -lt "$UNBOUND_N_EDNS_SIZE" ] ; then
    866     # exceeds range, back to default
    867     UNBOUND_N_EDNS_SIZE=1280
    868   fi
    869 
    870 
    871   if [ "$UNBOUND_N_RX_PORT" -lt 1024 \
    872     -o 10240 -lt "$UNBOUND_N_RX_PORT" ] ; then
    873     # special port or in 5 digits, back to default
    874     UNBOUND_N_RX_PORT=53
    875   fi
    876 
    877 
    878   if [ "$UNBOUND_TTL_MIN" -gt 1800 ] ; then
    879     # that could have had awful side effects
    880     UNBOUND_TTL_MIN=300
    881   fi
    882 }
    883 
    884 ##############################################################################
    885 
    886 unbound_start() {
    887   config_load unbound
    888   config_foreach unbound_uci unbound
    889   unbound_mkdir
    890 
    891 
    892   if [ "$UNBOUND_B_MAN_CONF" -eq 0 ] ; then
    893     unbound_conf
    894     unbound_access
    895     unbound_adblock
    896 
    897     if [ "$UNBOUND_D_DHCP_LINK" = "dnsmasq" ] ; then
    898       dnsmasq_link
    899     else
    900       unbound_hostname
    901     fi
    902 
    903     unbound_control
    904   fi
    905 }
    906 
    907 ##############################################################################
    908 
    909 unbound_stop() {
    910   local resolvsym=0
    911 
    912   rootzone_update
    913 
    914 
    915   if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
    916     resolvsym=1
    917   else
    918     /etc/init.d/dnsmasq enabled || resolvsym=1
    919   fi
    920 
    921 
    922   if [ "$resolvsym" -gt 0 ] ; then
    923     # set resolver file to normal, but don't stomp on dnsmasq
    924     rm -f /tmp/resolv.conf
    925     ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
    926   fi
    927 }
    928 
    929 ##############################################################################
    930