unbound: fix local cnames
authorTobias Waldvogel <tobias.waldvogel@gmail.com>
Tue, 16 Jul 2024 17:38:11 +0000 (19:38 +0200)
committerTianling Shen <cnsztl@gmail.com>
Fri, 16 Aug 2024 06:41:28 +0000 (14:41 +0800)
For cnames with a local data target the A RR is not resolved and
missing in the response. As most applications don't send another
query and fail, these entries are placed in a rpz zone instead.

Signed-off-by: Tobias Waldvogel <tobias.waldvogel@gmail.com>
net/unbound/files/defaults.sh
net/unbound/files/dnsmasq.sh
net/unbound/files/unbound.sh

index c26461b6e297b97fcc18ce16dc3e1f198eb2398a..72ecbea039548ffa282b0e660270bae768bacd3b 100644 (file)
@@ -30,6 +30,7 @@ UB_ZONE_CONF=$UB_VARDIR/zone.conf.tmp
 UB_CTRL_CONF=$UB_VARDIR/ctrl.conf.tmp
 UB_SRVMASQ_CONF=$UB_VARDIR/dnsmasq_srv.conf.tmp
 UB_EXTMASQ_CONF=$UB_VARDIR/dnsmasq_ext.conf.tmp
+UB_RPZCNAME_CONF=$UB_VARDIR/unbound_rpz_cname.conf
 
 # conf as found
 UB_TOTAL_CONF=$UB_VARDIR/unbound.conf
index 8db67cdac6d5fccf76f1c091644e8b2a9a6f3c8e..63e130c763cff518a04e030a0d948356be51fbd3 100644 (file)
@@ -31,6 +31,7 @@ DM_D_WAN_FQDN=0
 DM_LIST_KNOWN_ZONES="invalid"
 DM_LIST_TRN_ZONES=""
 DM_LIST_LOCAL_DATA=""
+DM_LIST_PRZ_DATA=""
 DM_LIST_LOCAL_PTR=""
 DM_LIST_FWD_PORTS=""
 DM_LIST_FWD_ZONES=""
@@ -180,10 +181,30 @@ create_cname_record() {
   config_get target "$cfg" target
 
 
+  # For cnames with a local data target the A RR is not resolved and missing
+  # in the response. As most applications don't send another query and fail,
+  # these entries are placed in a rpz zone instead.
   if [ -n "$cname" ] && [ -n "$target" ] ; then
-    create_local_zone "$cname"
-    record="$cname.@@300@@IN@@CNAME@@$target."
-    DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $record"
+    record="${DM_LIST_LOCAL_DATA#*${target}.@@*@@IN@@A@@}"
+    if [ "$record" == "$DM_LIST_LOCAL_DATA" ]; then
+      # Target is not a local data record => local data can be used
+      create_local_zone "$cname"
+      record="$cname.@@300@@IN@@CNAME@@$target."
+      DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $record"
+
+    else
+      # Target is a local data record => use rpz zone
+
+      # Add A RR at the end if still not present
+      record="$target@@A@@${record%% *}"
+      if [ "${DM_LIST_PRZ_DATA}" == "${DM_LIST_PRZ_DATA#*${record}}" ]; then
+        DM_LIST_PRZ_DATA="$DM_LIST_PRZ_DATA $record"
+      fi
+
+      # Add CNAME at the beginning
+      record="$cname@@CNAME@@$target."
+      DM_LIST_PRZ_DATA="$record $DM_LIST_PRZ_DATA"
+    fi
   fi
 }
 
@@ -280,6 +301,24 @@ dnsmasq_inactive() {
         echo
       fi
     } > $UB_SRVMASQ_CONF
+
+    if [ -n "$DM_LIST_PRZ_DATA" ] ; then
+      {
+        echo '$ORIGIN cname.rpz.localhost; generated by UCI'
+       echo ""
+        for record in $DM_LIST_PRZ_DATA; do
+          echo "${record//@@/ }"
+        done
+      } > $UB_RPZCNAME_CONF
+
+      {
+        echo "# $UB_EXTMASQ_CONF generated by UCI"
+        echo "rpz:"
+        echo "  name: cname.rpz.localhost"
+        echo "  zonefile: $UB_RPZCNAME_CONF"
+       echo ""
+      } > $UB_EXTMASQ_CONF
+    fi
   fi
 }
 
index 4ebbacd7b2fbb357e7f3acb60d0ee8b2c6a22851..0afa7ddfd50698c387f6a4ccb763d6b9b50acbb0 100644 (file)
@@ -914,6 +914,13 @@ unbound_conf() {
   fi
 
 
+  case $moduleopts in
+  *respip*)
+    modulestring="respip $modulestring"
+    ;;
+  esac
+
+
   {
     # Print final module string
     echo "  module-config: \"$modulestring\""