RPZ: code updates and bug fixes #2

Message ID 20240823213907.3528222-1-jon.murphy@ipfire.org
State New
Headers
Series RPZ: code updates and bug fixes #2 |

Commit Message

Jon Murphy Aug. 23, 2024, 9:39 p.m. UTC
  - feature: added "list" action
 - update: changed "cat << heredocs" to "echo > file"
 - update: remove path to executables
 - update: reformatted code and comments (tabs to spaces)
 - update: reworded some msg_log messages
 - update: change exit codes from "1" to unique exit code numbers
 - bug: added check for empty allow/block config file
 - bug: removed auth_zone_reload (had double reload for allow/block)
 - bug: change rpz config file to `chown nobody:nobody`
 - bug: change rpz config file to `chmod 644`

Signed-off-by: Jon Murphy <jon.murphy@ipfire.org>
---
 config/rootfiles/packages/rpz |   1 +
 config/rpz/00-rpz.conf        |  22 +--
 config/rpz/block.rpz.conf     |   7 +
 config/rpz/rpz-config         | 292 ++++++++++++++++++----------------
 config/rpz/rpz-metrics        | 163 ++++++++++---------
 config/rpz/rpz-sleep          |  26 +--
 lfs/rpz                       |  20 ++-
 src/paks/rpz/uninstall.sh     |   4 +
 src/paks/rpz/update.sh        |  22 ++-
 9 files changed, 297 insertions(+), 260 deletions(-)
 create mode 100644 config/rpz/block.rpz.conf
  

Patch

diff --git a/config/rootfiles/packages/rpz b/config/rootfiles/packages/rpz
index 183825362..73c3efa06 100644
--- a/config/rootfiles/packages/rpz
+++ b/config/rootfiles/packages/rpz
@@ -1,4 +1,5 @@ 
 etc/unbound/local.d/00-rpz.conf
+etc/unbound/local.d/block.rpz.conf
 etc/unbound/zonefiles
 etc/unbound/zonefiles/allow.rpz
 etc/unbound/zonefiles/block.rpz
diff --git a/config/rpz/00-rpz.conf b/config/rpz/00-rpz.conf
index 72c1d12e5..f005a4f2e 100644
--- a/config/rpz/00-rpz.conf
+++ b/config/rpz/00-rpz.conf
@@ -1,18 +1,10 @@ 
 server:
-	module-config: "respip validator iterator"
+    module-config: "respip validator iterator"
 
 rpz:
-    name:					allow.rpz
-    zonefile:				/etc/unbound/zonefiles/allow.rpz
-    rpz-action-override:	passthru
-    rpz-log:				yes
-    rpz-log-name:			allow
-    rpz-signal-nxdomain-ra:	yes
-
-rpz:
-    name:					block.rpz
-    zonefile:				/etc/unbound/zonefiles/block.rpz
-    rpz-action-override:	nxdomain
-    rpz-log:				yes
-    rpz-log-name:			block
-    rpz-signal-nxdomain-ra:	yes
+    name:                    allow.rpz
+    zonefile:                /etc/unbound/zonefiles/allow.rpz
+    rpz-action-override:     passthru
+    rpz-log:                 yes
+    rpz-log-name:            allow
+    rpz-signal-nxdomain-ra:  yes
diff --git a/config/rpz/block.rpz.conf b/config/rpz/block.rpz.conf
new file mode 100644
index 000000000..605684257
--- /dev/null
+++ b/config/rpz/block.rpz.conf
@@ -0,0 +1,7 @@ 
+rpz:
+    name:                    block.rpz
+    zonefile:                /etc/unbound/zonefiles/block.rpz
+    rpz-action-override:     nxdomain
+    rpz-log:                 yes
+    rpz-log-name:            block
+    rpz-signal-nxdomain-ra:  yes
diff --git a/config/rpz/rpz-config b/config/rpz/rpz-config
index a24a5c132..9278aa004 100644
--- a/config/rpz/rpz-config
+++ b/config/rpz/rpz-config
@@ -19,176 +19,186 @@ 
 #                                                                             #
 ###############################################################################
 
-#	v23 - 2024-07-30
+version="2024-08-18"	# v28
 
 ###############     Functions     ###############
 
 msg_log () {
-	/usr/bin/logger --tag "${tagName}" "$*"
-	if tty --silent ; then
-		echo "${tagName}:" "$*"
-	fi
+    logger --tag "${tagName}" "$*"
+    if tty --silent ; then
+        echo "${tagName}:" "$*"
+    fi
 }
 
 check_name () {
-	local testName="${1}"
-	#	check for a valid name
-	regex='^[a-zA-Z0-9_]+$'
-	if [[ ! "${testName}" =~ $regex ]] ; then
-		msg_log "error: rpz: the NAME is not valid: \"${testName}\". exit."
-		exit 1
-	fi
+    local testName="${1}"
+    #  check for a valid name
+    regex='^[a-zA-Z0-9_]+$'
+    if [[ ! "${testName}" =~ $regex ]] || [[ "${testName}" == "allow" ]] || [[ "${testName}" == "block" ]]; then
+        msg_log "error: rpz: the NAME is not valid: \"${testName}\". exit."
+        exit 101
+    fi
 }
 
 check_unbound_conf () {
-	#	check the above config files
-	msg_log "info: rpz: check for errors with \"unbound-checkconf\""
-	/usr/sbin/unbound-checkconf
-	exit_code=$?
-	if [[ "${exit_code}" -ne 0 ]] ; then
-		msg_log "error: rpz: unbound-checkconf. exit."
-		exit "${exit_code}"
-	fi
+    #  check the above config files
+    msg_log "info: rpz: check for errors with \"unbound-checkconf\""
+    unbound-checkconf
+    exit_code=$?
+    if [[ "${exit_code}" -ne 0 ]] ; then
+        msg_log "error: rpz: unbound-checkconf found invalid configuration."
+        msg_log "error: rpz: In the Terminal run the command \
+          \"unbound-checkconf\" for more information. exit."
+        exit 102
+    fi
 }
 
 make_rpz_file () {
-	local theType="${1}"	#	allow or block
-
-	theList="/var/ipfire/dns/rpz/${theType}list"			#	input custom list of domains
-	theZoneFile="/etc/unbound/zonefiles/${theType}.rpz"		#	output file for RPZ
-
-	theAction='.'
-	if [[ "${theType}" =~ "allow" ]] ; then
-		theAction='rpz-passthru.'
-	fi
-
-	#	does a list exist?
-	if [[ -s "${theList}" ]] ; then
-		#	drop any extra "blanks" and add "CNAME <RPZ action>." to each line
-		actionList=$( /usr/bin/awk '{$1=$1};1' "${theList}" |
-			/bin/sed "/^[^;].*[[:alnum:]]/ s|$|	CNAME	${theAction}|" )
-
-		msg_log "info: rpz: create zonefile for ${theList}"
-
-		/bin/cat <<-EOF > "${theZoneFile}"
-		; Name:				${theType} list
-		; Last modified:	$(date "+%Y-%m-%d at %H.%M.%S %Z")
-		;
-		;	domains with actions list
-		;
-		${actionList}
-		EOF
-
-		#	reload the zone that was just updated
-		zoneBase=$( basename "${theZoneFile}" )
-		/usr/sbin/unbound-control auth_zone_reload -q "${zoneBase}"
-	fi
+    local theType="${1}"    #   allow or block
+
+    theList="/var/ipfire/dns/rpz/${theType}list"         #  input custom list of domains
+    theZoneFile="/etc/unbound/zonefiles/${theType}.rpz"  #  output file for RPZ
+
+    #  does a list exist?
+    if ! [[ -s "${theList}" ]] ; then
+        msg_log "error: rpz: the ${theList} is empty. exit."
+        exit 103
+    fi
+
+    theAction='.'
+    if [[ "${theType}" =~ "allow" ]] ; then
+        theAction='rpz-passthru.'
+    fi
+
+    #  drop any extra "blanks" and add "CNAME <RPZ action>." to each line
+    actionList=$( awk '{$1=$1};1' "${theList}" |
+        sed "/^[^;].*[[:alnum:]]/ s|$|  CNAME   ${theAction}|" )
+
+    msg_log "info: rpz: create zonefile for ${theList}"
+
+echo "
+; Name:             ${theType} list
+; Last modified:    $(date "+%Y-%m-%d at %H.%M.%S %Z")
+;
+;   domains with actions list
+;
+${actionList}
+" > "${theZoneFile}"
+
 }
 
 ###############       Main        ###############
 
 tagName="unbound"
 
-theAction="${1}"										#	input action
-theName="${2}"											#	input RPZ name
-theURL="${3}"											#	input RPZ URL
-
-check_name "${theName}"									#	is this a valid name?
+theAction="${1}"                    #  input action
+theName="${2}"                      #  input RPZ name
+theURL="${3}"                       #  input RPZ URL
 
-rpzConfig="/etc/unbound/local.d/${theName}.rpz.conf"	#	output zone conf file
-rpzFile="/etc/unbound/zonefiles/${theName}.rpz"			#	output for RPZ file
+rpzConfig="/etc/unbound/local.d/${theName}.rpz.conf"    #  output zone conf file
+rpzFile="/etc/unbound/zonefiles/${theName}.rpz"         #  output for RPZ file
 
 case "${theAction}" in
 
-	#	add new rpz list
-	add )
-		#	does this config already exist?  If yes, then exit
-		if [[ -f "${rpzConfig}" ]] ; then
-			msg_log "info: rpz: ${rpzConfig} already exists. exit"
-			exit 1
-		fi
-
-		#	is this a valid URL?
-		regex='^https://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
-		if ! [[ "${theURL}" =~ $regex ]] ; then
-			msg_log "error: rpz: the URL is not valid: \"${theURL}\". exit."
-			exit 1
-		fi
-
-		#	create the zone config file
-		msg_log "info: rpz: add config file \"${theName}.rpz.conf\""
-		cat <<-EOF > "${rpzConfig}"
-		rpz:
-			name:					${theName}.rpz
-			zonefile:				/etc/unbound/zonefiles/${theName}.rpz
-			url:  ${theURL}
-			rpz-action-override:	nxdomain
-			rpz-log:				yes
-			rpz-log-name:			${theName}
-			rpz-signal-nxdomain-ra:	yes
-		EOF
-
-		#	set-up zone file
-		/usr/bin/touch "${rpzFile}"
-		#	unbound requires these settings for rpz files
-		/bin/chown nobody:nobody "${rpzFile}"
-		/bin/chmod 644 "${rpzFile}"
-		;;
-
-	#	trash config file & rpz file
-	remove )
-		if ! [[ -f "${rpzConfig}" ]] ; then
-			msg_log "info: rpz: ${rpzConfig} does not exist. exit"
-			exit 1
-		fi
-
-		msg_log "info: rpz: remove config file & rpz file \"${theName}\""
-		/bin/rm "${rpzConfig}"
-		/bin/rm "${rpzFile}"
-
-		check_unbound_conf
-		;;
-
-	#	make a new allow or block rpz file
-	make )
-		case "${theName}" in
-			allow )
-				make_rpz_file allow
-			;;
-
-			block )
-				make_rpz_file block
-			;;
-
-			allowblock )
-				make_rpz_file allow
-				make_rpz_file block
-			;;
-
-			* )
-				msg_log "error: rpz: the NAME is not valid: \"${theName}\". exit."
-				exit 1
-			;;
-		esac
-
-		check_unbound_conf
-		;;
-
-	*)
-		msg_log "error: rpz: missing or incorrect parameter"
-		/usr/bin/printf "Usage:  rpzConfig.sh <ACTION> <NAME> <URL>\n"
-		exit 1
-		;;
+    #  add new rpz list
+    add )
+	check_name "${theName}"             #  is this a valid name?
+        #  does this config already exist?  If yes, then exit
+        if [[ -f "${rpzConfig}" ]] ; then
+            msg_log "error: rpz: duplicate - ${rpzConfig} already exists. exit"
+            exit 104
+        fi
+
+        #  is this a valid URL?
+        regex='^https://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
+        if ! [[ "${theURL}" =~ $regex ]] ; then
+            msg_log "error: rpz: the URL is not valid: \"${theURL}\". exit."
+            exit 105
+        fi
+
+        #  create the zone config file
+        msg_log "info: rpz: add config file \"${theName}.rpz.conf\""
+echo "rpz:
+    name:                   ${theName}.rpz
+    zonefile:               ${rpzFile}
+    url:                    ${theURL}
+    rpz-action-override:    nxdomain
+    rpz-log:                yes
+    rpz-log-name:           ${theName}
+    rpz-signal-nxdomain-ra: yes
+" > "${rpzConfig}"
+        
+        #  set-up zonefile
+        #    create an empty rpz file
+        touch "${rpzFile}"
+        #  unbound requires these settings for rpz files
+        chown nobody:nobody "${rpzFile}" "${rpzConfig}"
+        chmod 644 "${rpzFile}" "${rpzConfig}"
+        ;;
+
+    #  trash config file & rpz file
+    remove )
+	check_name "${theName}"             #  is this a valid name?
+        if ! [[ -f "${rpzConfig}" ]] ; then
+            msg_log "error: rpz: cannot remove ${rpzConfig}, does not exist. exit"
+            exit 106
+        fi
+
+        msg_log "info: rpz: remove config file & rpz file \"${theName}\""
+        rm "${rpzConfig}"
+        rm "${rpzFile}"
+
+        check_unbound_conf
+        ;;
+
+    #  make a new allow or block rpz file
+    make )
+        case "${theName}" in
+            allow )
+            make_rpz_file allow
+            ;;
+
+        block )
+            make_rpz_file block
+            ;;
+
+        allowblock )
+            make_rpz_file allow
+            make_rpz_file block
+            ;;
+
+        * )
+            msg_log \
+              "error: rpz: the NAME \"${theName}\" is not valid - \"allow\" or \"block\" only.  exit."
+            exit 107
+            ;;
+        esac
+
+        check_unbound_conf
+        ;;
+        
+    list)
+        awk -F' ' '/^name:|\sname:/{ gsub(/.rpz/, "" ) ; printf $2} /\surl:|^url:/{print "="$2}' \
+          /etc/unbound/local.d/*.rpz.conf
+        exit
+        ;;    
+        
+    *)
+        msg_log "error: rpz: missing or incorrect parameter"
+        printf "Usage:  rpzConfig <ACTION> <NAME> <URL>\n"
+        printf "Version:  ${version}\n"
+        exit 108
+        ;;
 
 esac
 
-#	reload due to the changes
+#  reload due to the changes
 msg_log  "rpz: running \"unbound-control reload\""
-/usr/sbin/unbound-control reload
+unbound-control reload
 exit_code=$?
 if [[ "${exit_code}" -ne 0 ]] ; then
-	msg_log "error: rpz: unbound-control \"${theName}\". exit."
-	exit "${exit_code}"
+    msg_log "error: rpz: unbound-control \"${theName}\". exit."
+    exit 109
 fi
 
 exit
diff --git a/config/rpz/rpz-metrics b/config/rpz/rpz-metrics
index 4d932726e..d154f70b9 100644
--- a/config/rpz/rpz-metrics
+++ b/config/rpz/rpz-metrics
@@ -19,62 +19,61 @@ 
 #                                                                             #
 ###############################################################################
 
-#	v19 on 2024-07-30
+version="2024-08-16"	# v20
 
 ###############       Main        ###############
 
-weeks="${1:-2}"			#	default to two message logs
-sortBy="${2:-name}"  	#	by name or by hits
+weeks="${1:-2}"         #   default to two message logs
+sortBy="${2:-name}"     #   by name or by hits
 
-#	get the list of message logs for N weeks
-messageLogs=$( find /var/log/messages* -type f |
-	/usr/bin/sort --version-sort |
-	head -"${weeks}" )
+#   get the list of message logs for N weeks
+messageLogs=$( find /var/log/messages* -type f | sort --version-sort |
+    head -"${weeks}" )
 
-#	get the list of RPZ names & counts from the message log(s)
+#   get the list of RPZ names & counts from the message log(s)
 rpzNameCount=$( for logf in ${messageLogs} ; do
-	/usr/bin/zgrep --text --extended-regexp 'info: rpz: applied.* A IN$' "${logf}" |
-	/usr/bin/awk '$10 ~ /\[\w*]/ { print $10 }' ;
-	done | /usr/bin/sort | /usr/bin/uniq --count )
+    zgrep --text --extended-regexp 'info: rpz: applied.* A IN$' "${logf}" |
+      awk '$10 ~ /\[\w*]/ { print $10 }' ;
+    done | sort | uniq --count )
 
-#	flip results and remove brackets `[` and `]`
-rpzNameCount=$( /bin/echo "${rpzNameCount}" |
-	/usr/bin/awk '{ print $2, $1 }' |
-	/bin/sed --regexp-extended 's|^\[(.*)\]|\1|' )
+#   flip results and remove brackets `[` and `]`
+rpzNameCount=$( echo "${rpzNameCount}" |
+    awk '{ print $2, $1 }' |
+      sed --regexp-extended 's|^\[(.*)\]|\1|' )
 
-#	grab only names
-rpzNames=$( /bin/echo "${rpzNameCount}" | /usr/bin/awk '{ print $1 }' )
+#   grab only names
+rpzNames=$( echo "${rpzNameCount}" | awk '{ print $1 }' )
 
-#	get list of RPZ files
-rpzFileList=$( /bin/find /etc/unbound/zonefiles -type f -iname "*.rpz" )
+#   get list of RPZ files
+rpzFileList=$( find /etc/unbound/zonefiles -type f -iname "*.rpz" )
 
-#	get basename of those files
-rpzBaseNames=$( /bin/echo "${rpzFileList}" |
-	/bin/sed 's|/etc/unbound/zonefiles/||g ; s|\.rpz||g ;' )
+#   get basename of those files
+rpzBaseNames=$( echo "${rpzFileList}" |
+    sed 's|/etc/unbound/zonefiles/||g ; s|\.rpz||g ;' )
 
-#	add to rpzNames
+#   add to rpzNames
 rpzNames="${rpzNames}"$'\n'"${rpzBaseNames}"
 
-#	drop duplicate names
-rpzNames=$( echo "${rpzNames}" | /usr/bin/sort --unique  )
+#   drop duplicate names
+rpzNames=$( echo "${rpzNames}" | sort --unique  )
 
-#	get line count for each RPZ
-lineCount=$( /bin/echo "${rpzFileList}" | /usr/bin/xargs wc -l )
+#   get line count for each RPZ
+lineCount=$( echo "${rpzFileList}" | xargs wc -l )
 
-#	get comment line count and blank line count for each RPZ
-commentCount=$( /bin/echo "${rpzFileList}" |
-	/usr/bin/xargs /bin/grep --count -e "^$" -e "^;" )
+#   get comment line count and blank line count for each RPZ
+commentCount=$( echo "${rpzFileList}" |
+    xargs grep --count -e "^$" -e "^;" )
 
-#	get modified date each RPZ
-modDateList=$( /bin/echo "${rpzFileList}" | xargs stat -c '%.10y  %n' )
+#   get modified date each RPZ
+modDateList=$( echo "${rpzFileList}" | xargs stat -c '%.10y  %n' )
 
-ucListAuthZones=$( /usr/sbin/unbound-control list_auth_zones )
+ucListAuthZones=$( unbound-control list_auth_zones )
 
-#	get width of RPZ names
-pWidth=$( /bin/echo "${rpzNames}" | /usr/bin/awk '{ print $1"   " }' | wc -L )
+#   get width of RPZ names
+pWidth=$( echo "${rpzNames}" | awk '{ print $1"   " }' | wc -L )
 pFormat="%-${pWidth}s %-8s %-8s %-8s %10s %12s\n"
 
-#	print title line
+#   print title line
 printf "${pFormat}" "name" "hits" "active" "lines" "hits/line%" "last update"
 printf -- "--------------"
 
@@ -83,60 +82,60 @@  totalLines=0
 totalHits=0
 while read -r theName
 do
-	printf -- "-"									#	pretend progress bar
-	#	get hit count
-	theHits="0"
-	if output=$( /bin/grep "^${theName}\s" <<< "${rpzNameCount}" ) ; then
-		theHits=$( /bin/echo "${output}" |
-		/usr/bin/awk '{ print $2 }' )
-		totalHits=$(( totalHits + theHits ))
-	fi
-
-	#	is this RPZ list active?
-	theActive="disabled"
-	if /bin/grep --quiet "^${theName}\.rpz" <<< "${ucListAuthZones}"
-	then
-		theActive="enabled"
-	fi
-
-	#	get line count then subtract comment count and blank line count
-	#	  from total line count
-	theLines="n/a"
-	hitsPerLine="0"
-	if output=$( /bin/grep --fixed-strings "/${theName}.rpz" <<< "${lineCount}" ) ; then
-		theLines=$( /bin/echo "${output}" | /usr/bin/awk '{ print $1 }' )
-		totalLines=$(( totalLines + theLines ))
-
-		if [[ "${theLines}" -gt 2 ]] ; then
-			hitsPerLine=$(( 100 * theHits / theLines ))
-		fi
-	fi
-
-	#	get modification date
-	theModDate="n/a"
-	if output=$( /bin/grep --fixed-strings "/${theName}.rpz" <<< "${modDateList}" ) ; then
-		theModDate=$( /bin/echo "${output}" | /usr/bin/awk '{ print $1 }' )
-	fi
-
-	#	add to results list
-	theResults+="${theName} ${theHits} ${theActive} ${theLines} ${hitsPerLine} ${theModDate}"$'\n'
+    printf -- "-"        #   pretend progress bar
+    #   get hit count
+    theHits="0"
+    if output=$( grep "^${theName}\s" <<< "${rpzNameCount}" ) ; then
+        theHits=$( echo "${output}" |
+        awk '{ print $2 }' )
+        totalHits=$(( totalHits + theHits ))
+    fi
+
+    #   is this RPZ list active?
+    theActive="disabled"
+    if grep --quiet "^${theName}\.rpz" <<< "${ucListAuthZones}"
+    then
+        theActive="enabled"
+    fi
+
+    #   get line count
+    theLines="n/a"
+    hitsPerLine="0"
+    if output=$( grep --fixed-strings "/${theName}.rpz" <<< "${lineCount}" ) ; then
+        theLines=$( echo "${output}" | awk '{ print $1 }' )
+        totalLines=$(( totalLines + theLines ))
+
+        if [[ "${theLines}" -gt 2 ]] ; then
+            hitsPerLine=$(( 100 * theHits / theLines ))
+        fi
+    fi
+
+    #   get modification date
+    theModDate="n/a"
+    if output=$( grep --fixed-strings "/${theName}.rpz" <<< "${modDateList}" ) ; then
+        theModDate=$( echo "${output}" | awk '{ print $1 }' )
+    fi
+
+    #   add to results list
+    theResults+="${theName} ${theHits} ${theActive} ${theLines} ${hitsPerLine} ${theModDate}"$'\n'
+    
 done <<< "${rpzNames}"
 
 case "${sortBy}" in
-	names|name)	sortArg=(-k3,3r -k1,1)			;;	#	sort by "active" then by "name"
+    names|name) sortArg=(-k3,3r -k1,1)          ;;  #   sort by "active" then by "name"
 
-	hits|hit)	sortArg=(-k3,3r -k2,2nr -k1,1)	;;	#	sort by "active" then by "hits" then by "name"
+    hits|hit)   sortArg=(-k3,3r -k2,2nr -k1,1)  ;;  #   sort by "active" then by "hits" then by "name"
 
-	lines|line)	sortArg=(-k3,3r -k4,4nr -k1,1)	;;	#	sort by "active" then by "lines" then by "name"
+    lines|line) sortArg=(-k3,3r -k4,4nr -k1,1)  ;;  #   sort by "active" then by "lines" then by "name"
 esac
 
 printf -- "--------------\n"
-#	remove blank lines, sort, print as columns
-/bin/echo "${theResults}" |
-	/usr/bin/awk '!/^[[:space:]]*$/' |
-	/usr/bin/sort "${sortArg[@]}"    |
-	/usr/bin/awk --assign=width="${pWidth}" \
-		'{ printf "%-*s %-8s %-8s %-8s %10s %12s\n", width, $1, $2, $3, $4, $5, $6 }'
+#   remove blank lines, sort, print as columns
+echo "${theResults}" |
+    awk '!/^[[:space:]]*$/' |
+    sort "${sortArg[@]}"    |
+    awk --assign=width="${pWidth}" \
+        '{ printf "%-*s %-8s %-8s %-8s %10s %12s\n", width, $1, $2, $3, $4, $5, $6 }'
 
 printf "${pFormat}" "" "=======" "" "========" "" ""
 printf "${pFormat}" "Totals -->" "${totalHits}" "" "${totalLines}" "" ""
diff --git a/config/rpz/rpz-sleep b/config/rpz/rpz-sleep
index eeef1174a..dd3603599 100644
--- a/config/rpz/rpz-sleep
+++ b/config/rpz/rpz-sleep
@@ -19,38 +19,38 @@ 
 #                                                                             #
 ###############################################################################
 
-#	v04 on 2024-07-05
+version="2024-08-16"        # v05
 
 ###############     Functions     ###############
 
-#	send message to message log
+#   send message to message log
 msg_log () {
-	/usr/bin/logger --tag "${tagName}" "$*"
-	if /usr/bin/tty --silent ; then
-		echo "${tagName}:" "$*"
-	fi
+    logger --tag "${tagName}" "$*"
+    if tty --silent ; then
+        echo "${tagName}:" "$*"
+    fi
 }
 
 ###############       Main        ###############
 
 tagName="unbound"
 
-sleepTime="${1:-5m}"			#	default to sleep for 5m (5 minutes)
+sleepTime="${1:-5m}"            #  default to sleep for 5m (5 minutes)
 
-zoneList=$( /usr/sbin/unbound-control list_auth_zones | /usr/bin/awk '{print $1}' )
+zoneList=$( unbound-control list_auth_zones | awk '{print $1}' )
 
 for zone in ${zoneList} ; do
-	/usr/bin/printf "disable ${zone}\t"
-	/usr/sbin/unbound-control rpz_disable "${zone}"
+    printf "disable ${zone}\t"
+    unbound-control rpz_disable "${zone}"
 done
 
 msg_log "info: rpz: disabled all zones for ${sleepTime}"
 
-/bin/sleep "${sleepTime}"
+sleep "${sleepTime}"
 
 for zone in ${zoneList} ; do
-	/usr/bin/printf "enable ${zone}\t"
-	/usr/sbin/unbound-control rpz_enable "${zone}"
+    printf "enable ${zone}\t"
+    unbound-control rpz_enable "${zone}"
 done
 
 msg_log "info: rpz: enabled all zones"
diff --git a/lfs/rpz b/lfs/rpz
index 73f6f2b1b..16d1d0803 100644
--- a/lfs/rpz
+++ b/lfs/rpz
@@ -62,25 +62,31 @@  $(TARGET) :
 	@$(PREBUILD)
 	@rm -rf $(DIR_APP)
 
-	#	install RPZ scripts
+	# install RPZ scripts
 	install -v -m 755 \
 	  $(DIR_CONF)/rpz/{rpz-config,rpz-metrics,rpz-sleep} -t /usr/sbin
 
+	# Add conf file to /etc directory
+	cp -vf $(DIR_CONF)/rpz/00-rpz.conf /etc/unbound/local.d
+	cp -vf $(DIR_CONF)/rpz/block.rpz.conf /etc/unbound/local.d
+
 	# Install settings folder and two empty files
 	mkdir -pv /var/ipfire/dns/rpz
 	touch /var/ipfire/dns/rpz/allowlist
 	touch /var/ipfire/dns/rpz/blocklist
 
-	# Add conf file to /etc directory
-	cp -vf $(DIR_CONF)/rpz/00-rpz.conf /etc/unbound/local.d
-
-	#	create zonefiles directory for the RPZ files and add two empty RPZ
-	#	  files to avoid a unbound config error
+	# create zonefiles directory for the RPZ files and add two empty RPZ
+	#  files to avoid a unbound config error
 	mkdir -pv /etc/unbound/zonefiles
-	chown -v nobody:nobody /etc/unbound/zonefiles
 	touch /etc/unbound/zonefiles/allow.rpz
 	touch /etc/unbound/zonefiles/block.rpz
 
+	#  set owner for unbound related files
+	chown -vR nobody:nobody  \
+	  /var/ipfire/dns/rpz    \
+	  /etc/unbound/zonefiles \
+	  /etc/unbound/local.d
+
 	# Install backup definition
 	cp -vf $(DIR_CONF)/backup/includes/rpz /var/ipfire/backup/addons/includes/rpz
 
diff --git a/src/paks/rpz/uninstall.sh b/src/paks/rpz/uninstall.sh
index 4fb20e127..51edaa176 100644
--- a/src/paks/rpz/uninstall.sh
+++ b/src/paks/rpz/uninstall.sh
@@ -27,5 +27,9 @@ 
 make_backup ${NAME}
 remove_files
 
+#  delete rpz config files.  Otherwise unbound will throw error:
+#    "[1723428668] unbound-control[17117:0] error: connect: Connection refused for 127.0.0.1 port 8953"
+/bin/rm -fv /etc/unbound/local.d/*.rpz.conf
+
 #  start unbound to load unbound config file
 /etc/init.d/unbound start
diff --git a/src/paks/rpz/update.sh b/src/paks/rpz/update.sh
index 938a93a40..fd46a185a 100644
--- a/src/paks/rpz/update.sh
+++ b/src/paks/rpz/update.sh
@@ -20,6 +20,24 @@ 
 ###############################################################################
 #
 . /opt/pakfire/lib/functions.sh
+
+#  from update.sh
 extract_backup_includes
-./uninstall.sh
-./install.sh
+
+#  stop unbound to delete RPZ conf file
+/etc/init.d/unbound stop
+
+#  from uninstall.sh
+make_backup ${NAME}
+remove_files
+
+#  delete rpz config files.  Otherwise unbound will throw error:
+#    "unbound-control[nn:0] error: connect: Connection refused for 127.0.0.1 port 8953"
+/bin/rm --verbose --force /etc/unbound/local.d/*.rpz.conf
+
+#  from install.sh
+extract_files
+restore_backup ${NAME}
+
+#  restart unbound to load config files
+/etc/init.d/unbound start