From patchwork Fri Aug 23 21:39:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: jon X-Patchwork-Id: 8047 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mail01.haj.ipfire.org", Issuer "R11" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4WrD4237VJz3x41 for ; Fri, 23 Aug 2024 21:39:30 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature ECDSA (secp384r1) client-digest SHA384) (Client CN "mail02.haj.ipfire.org", Issuer "E5" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4WrD3z2JS9z5M4; Fri, 23 Aug 2024 21:39:27 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4WrD3z0sYyz343B; Fri, 23 Aug 2024 21:39:27 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mail01.haj.ipfire.org", Issuer "R11" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4WrD3w6ZNvz32wS for ; Fri, 23 Aug 2024 21:39:24 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4WrD3v46VHz1VG; Fri, 23 Aug 2024 21:39:23 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1724449164; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=7Yc//rI4UcvQN+F+U8lGmsuFNQmxrESyTJWy8ilX3VQ=; b=uXXkuLtGGscM9Wmypi6eovmGC0LzjMHc+n+H0jbK7/RmGND82Of2wW6nqUtcyOAeYoGGme vDjM0P+DPJ0c6cCw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1724449164; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=7Yc//rI4UcvQN+F+U8lGmsuFNQmxrESyTJWy8ilX3VQ=; b=OqYJAT75TUnuwrCISPEYlMzwT3EwimJZhWDNyKuIBV6Er6XWw+YMcyZrcBC5Wc6ua14PEM PPFe7fRTpf/48y+nz6bWmkey5Kb5Vn+hoFrVZccVs29O+D5QXTvmHqVSNMubh7BICM66st N9i/9aWnZxwqN0MuPWPCbRRrNmEcY/iDmRUsnys8z4lDiIbEYfsa/vN5kw4gEusfVw8CMI JFXmuFiCkLJKPHzDdAYbz0sPiewNdghdikUGflSUSitiMS/ETM5IUKfkk1p7mVrRDaywgA Q5B+wFghtOFa6EohbDZfsH2IvnfGpGLfm5Et3lieEJhuvKMXmtD3pUdPqEzvuw== From: Jon Murphy To: development@lists.ipfire.org Subject: [PATCH] RPZ: code updates and bug fixes #2 Date: Fri, 23 Aug 2024 16:39:07 -0500 Message-Id: <20240823213907.3528222-1-jon.murphy@ipfire.org> MIME-Version: 1.0 Message-ID-Hash: K3IBGXSSZGT72XIBPNMYVLIVDJ5I5YKJ X-Message-ID-Hash: K3IBGXSSZGT72XIBPNMYVLIVDJ5I5YKJ X-MailFrom: jon.murphy@ipfire.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: IPFire development talk Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: - 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 --- 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 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 ." 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 ." 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 \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 \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