diff --git a/net/banip/Makefile b/net/banip/Makefile index 1e7f59caa5..b0aef6acd9 100644 --- a/net/banip/Makefile +++ b/net/banip/Makefile @@ -6,8 +6,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=banip -PKG_VERSION:=0.7.9 -PKG_RELEASE:=2 +PKG_VERSION:=0.7.10 +PKG_RELEASE:=1 PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Dirk Brenken diff --git a/net/banip/files/banip.dns b/net/banip/files/banip.dns index 198a501cc2..5cf5d2693c 100755 --- a/net/banip/files/banip.dns +++ b/net/banip/files/banip.dns @@ -1,122 +1,67 @@ #!/bin/sh # helper script to resolve domains for adding to banIP-related IPSets -# written by Dirk Brenken (dev@brenken.org) -# +# Copyright (c) 2020-2021 Dirk Brenken (dev@brenken.org) # This is free software, licensed under the GNU General Public License v3. -# + # (s)hellcheck exceptions -# shellcheck disable=1091,2030,2031,2034,2039,2086,2129,2140,2143,2154,2181,2183,2188 +# shellcheck disable=1091,3040 export LC_ALL=C export PATH="/usr/sbin:/usr/bin:/sbin:/bin" set -o pipefail -if [ -r "/lib/functions.sh" ] -then - . "/lib/functions.sh" - ban_debug="$(uci_get banip global ban_debug "0")" - ban_tmpbase="$(uci_get banip global ban_tmpbase "/tmp")" - ban_backupdir="$(uci_get banip global ban_backupdir "${ban_tmpbase}/banIP-Backup")" - ban_proto4_enabled="$(uci_get banip global ban_proto4_enabled "0")" - ban_proto6_enabled="$(uci_get banip global ban_proto6_enabled "0")" -else - exit 1 -fi -ban_ver="${1}" -ban_action="${2}" -ban_src_name="${3}" -ban_src_file="${4}" +. "/lib/functions.sh" + +ban_action="${1}" +ban_src_name="${2}" +ban_src_file="${3}" +ban_tmpbase="$(uci_get banip global ban_tmpbase "/tmp")" +ban_backupdir="$(uci_get banip global ban_backupdir "${ban_tmpbase}/banIP-Backup")" +ban_proto4_enabled="$(uci_get banip global ban_proto4_enabled "0")" +ban_proto6_enabled="$(uci_get banip global ban_proto6_enabled "0")" ban_ipset_cmd="$(command -v ipset)" ban_lookup_cmd="$(command -v nslookup)" ban_logger_cmd="$(command -v logger)" -ban_rc=1 -f_log() -{ - local class="${1}" log_msg="${2}" - - if [ -n "${log_msg}" ] && { [ "${class}" != "debug" ] || [ "${ban_debug}" = "1" ]; } - then - if [ -x "${ban_logger_cmd}" ] - then - "${ban_logger_cmd}" -p "${class}" -t "banIP-${ban_ver%-*}[${$}]" "${log_msg}" - else - printf "%s %s %s\n" "${class}" "banIP-${ban_ver%-*}[${$}]" "${log_msg}" - fi - fi -} - -if [ "${ban_action}" = "start" ] || [ "${ban_action}" = "refresh" ] -then - for proto in "4" "6" - do - if [ -s "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}.gz" ] - then - gzip -df "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}.gz" - if [ "${?}" = "0" ] - then - ban_rc=0 - else - ban_rc=1 - break - fi +if [ "${ban_action}" = "start" ] || [ "${ban_action}" = "refresh" ]; then + for proto in "4" "6"; do + if { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ]; } || + { [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ]; }; then + gzip -df "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}.gz" 2>/dev/null fi done fi -if [ "${ban_rc}" = "1" ] -then - > "${ban_backupdir}/banIP.${ban_src_name}_addon_4" - > "${ban_backupdir}/banIP.${ban_src_name}_addon_6" - while read -r domain - do - update_ips="" - result="$("${ban_lookup_cmd}" "${domain}" 2>/dev/null; printf "%s" "${?}")" - if [ "$(printf "%s" "${result}" | tail -1)" = "0" ] - then +if { [ "${ban_proto4_enabled}" = "1" ] && [ ! -s "${ban_backupdir}/banIP.${ban_src_name}_addon_4" ]; } || + { [ "${ban_proto6_enabled}" = "1" ] && [ ! -s "${ban_backupdir}/banIP.${ban_src_name}_addon_6" ]; }; then + [ -s "${ban_backupdir}/banIP.${ban_src_name}_addon_4" ] && : > "${ban_backupdir}/banIP.${ban_src_name}_addon_4" + [ -s "${ban_backupdir}/banIP.${ban_src_name}_addon_6" ] && : > "${ban_backupdir}/banIP.${ban_src_name}_addon_6" + while read -r domain; do + result="$( + "${ban_lookup_cmd}" "${domain}" 2>/dev/null + printf "%s" "${?}" + )" + if [ "$(printf "%s" "${result}" | tail -1)" = "0" ]; then ips="$(printf "%s" "${result}" | awk '/^Address[ 0-9]*: /{ORS=" ";print $NF}')" - for ip in ${ips} - do - for proto in "4" "6" - do - if { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ] && \ - [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] && \ - [ -n "$(printf "%s" "${ip}" | awk '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print $1}')" ]; } || \ - { [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ] && \ - [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] && \ - [ -z "$(printf "%s" "${ip}" | awk '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print $1}')" ]; } - then - printf "%s\n" "add ${ban_src_name}_${proto} ${ip}" >> "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" - if [ -z "${update_ips}" ] - then - update_ips="${ip}" - else - update_ips="${update_ips}, ${ip}" - fi + for ip in ${ips}; do + for proto in "4" "6"; do + if { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] && + [ -n "$(printf "%s" "${ip}" | awk '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print $1}')" ]; } || + { [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] && + [ -n "$(printf "%s" "${ip}" | awk '/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{print $1}')" ]; }; then + printf "%s\n" "add ${ban_src_name}_${proto} ${ip}" >>"${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" fi done done - if [ -n "${update_ips}" ] - then - ban_rc=0 - f_log "debug" "dns_imp ::: source '${ban_src_name}' supplemented by '${domain}' (${update_ips})" - fi fi - done < "${ban_src_file}" + done <"${ban_src_file}" fi -if [ "${ban_rc}" = "0" ] -then - for proto in "4" "6" - do - if [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] && [ -s "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" ] - then - "${ban_ipset_cmd}" -q -! restore < "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" - gzip -f "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" - fi - rm -f "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" - done -fi -f_log "info" "banIP domain import for source '${ban_src_name}' has been finished with rc '${ban_rc}'" +for proto in "4" "6"; do + if [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] && [ -s "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" ]; then + "${ban_ipset_cmd}" -q -! restore <"${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" + gzip -f "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" + fi +done +"${ban_logger_cmd}" -p "info" -t "banIP-resolve [${$}]" "banIP domain import for source '${ban_src_name}' has been finished" 2>/dev/null rm -f "${ban_src_file}" -exit "${ban_rc}" diff --git a/net/banip/files/banip.hotplug b/net/banip/files/banip.hotplug index 9b9469ebfe..436a3a63c7 100644 --- a/net/banip/files/banip.hotplug +++ b/net/banip/files/banip.hotplug @@ -1,14 +1,10 @@ #!/bin/sh -# -ban_pidfile="/var/run/banip.pid" -ban_enabled="$(/etc/init.d/banip enabled; printf "%u" "${?}")" +# firewall hotplug script for banIP +# Copyright (c) 2019-2021 Dirk Brenken (dev@brenken.org) +# This is free software, licensed under the GNU General Public License v3. -if [ "${ban_enabled}" = "0" ] && [ "${ACTION}" = "add" ] && [ -n "${INTERFACE}" ] -then - ban_ifaces="$(uci_get banip global ban_ifaces)" - if [ ! -s "${ban_pidfile}" ] && [ -n "$(printf "%s\n" "${ban_ifaces}" | grep -F "${INTERFACE}")" ] - then +if /etc/init.d/banip enabled && [ "${ACTION}" = "add" ] && [ -n "${INTERFACE}" ]; then + if [ ! -s "/var/run/banip.pid" ] && uci_get banip global ban_ifaces | grep -q "${INTERFACE}"; then /etc/init.d/banip refresh fi fi -exit 0 diff --git a/net/banip/files/banip.init b/net/banip/files/banip.init index 05e380ba4d..08405e608c 100755 --- a/net/banip/files/banip.init +++ b/net/banip/files/banip.init @@ -1,16 +1,14 @@ #!/bin/sh /etc/rc.common -# written by Dirk Brenken (dev@brenken.org) -# +# Copyright (c) 2018-2021 Dirk Brenken (dev@brenken.org) # This is free software, licensed under the GNU General Public License v3. -# + # (s)hellcheck exceptions -# shellcheck disable=1091,2030,2031,2034,2039,2086,2129,2140,2143,2154,2181,2183,2188 +# shellcheck disable=1091,2034,3043,3057,3060 START=30 USE_PROCD=1 -if [ -n "$(type -t extra_command)" ] -then +if type extra_command >/dev/null 2>&1; then extra_command "refresh" "Refresh ipsets without new list downloads" extra_command "suspend" "Suspend banIP processing" extra_command "resume" "Resume banIP processing" @@ -18,7 +16,6 @@ then extra_command "report" "[|||] Print banIP related IPset statistics" extra_command "list" "[|||||] List/Edit available sources" extra_command "timer" "[ [] []]|[ ] List/Edit cron update intervals" - extra_command "version" "Print version information" else EXTRA_COMMANDS="status refresh suspend resume query report list timer version" EXTRA_HELP=" status Service status @@ -28,34 +25,28 @@ else query Query active banIP IPSets for a specific IP address report [|||] Print banIP related IPset statistics list [|||||] List/Edit available sources - timer [ [] []]|[ ] List/Edit cron update intervals - version Print version information" + timer [ [] []]|[ ] List/Edit cron update intervals" fi ban_init="/etc/init.d/banip" ban_script="/usr/bin/banip.sh" ban_pidfile="/var/run/banip.pid" -if [ -s "${ban_pidfile}" ] && { [ "${action}" = "start" ] || [ "${action}" = "stop" ] || \ - [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "refresh" ] || \ - [ "${action}" = "suspend" ] || [ "${action}" = "resume" ] || [ "${action}" = "query" ] || \ - { [ "${action}" = "list" ] && [ -n "${1}" ]; } || { [ "${action}" = "report" ] && [ "${1}" != "json" ]; }; } -then +if [ -s "${ban_pidfile}" ] && { [ "${action}" = "start" ] || [ "${action}" = "stop" ] || + [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "refresh" ] || + [ "${action}" = "suspend" ] || [ "${action}" = "resume" ] || [ "${action}" = "query" ] || + { [ "${action}" = "list" ] && [ -n "${1}" ]; } || { [ "${action}" = "report" ] && [ "${1}" != "json" ]; }; }; then exit 0 fi -boot() -{ - > "${ban_pidfile}" +boot() { + : >"${ban_pidfile}" rc_procd start_service } -start_service() -{ - if [ "$("${ban_init}" enabled; printf "%u" ${?})" = "0" ] - then - if [ "${action}" = "boot" ] - then +start_service() { + if "${ban_init}" enabled; then + if [ "${action}" = "boot" ]; then return 0 fi procd_open_instance "banip" @@ -68,102 +59,84 @@ start_service() fi } -version() -{ +version() { rc_procd "${ban_script}" version } -refresh() -{ +refresh() { rc_procd start_service refresh } -reload_service() -{ +reload_service() { rc_procd start_service reload } -stop_service() -{ +stop_service() { rc_procd "${ban_script}" stop } -restart() -{ +restart() { rc_procd start_service restart } -suspend() -{ +suspend() { rc_procd start_service suspend } -resume() -{ +resume() { rc_procd start_service resume } -query() -{ +query() { rc_procd "${ban_script}" query "${1}" } -list() -{ - local src_archive src_file src_enabled key name enabled focus url_4 rule_4 url_6 rule_6 action="${1}" +list() { + local src_archive src_file src_enabled key name enabled focus descurl url_4 rule_4 url_6 rule_6 action="${1}" - if [ "${action%_*}" = "add" ] || [ "${action%_*}" = "remove" ] - then + if [ "${action%_*}" = "add" ] || [ "${action%_*}" = "remove" ]; then shift - for name in "${@}" - do + for name in "${@}"; do case "${action}" in "add") - if [ -z "$(uci_get banip global ban_sources | grep -Fo "${name}")" ] - then + if ! uci_get banip global ban_sources | grep -q "${name}"; then uci_add_list banip global ban_sources "${name}" printf "%s\n" "::: banIP source '${name}' added to config" fi - ;; + ;; "remove") - if [ -n "$(uci_get banip global ban_sources | grep -Fo "${name}")" ] - then + if uci_get banip global ban_sources | grep -q "${name}"; then uci_remove_list banip global ban_sources "${name}" printf "%s\n" "::: banIP source '${name}' removed from config" fi - ;; + ;; "add_asn") - if [ -z "$(uci_get banip global ban_asns | grep -Fo "${name}")" ] - then + if ! uci_get banip global ban_asns | grep -q "${name}"; then uci_add_list banip global ban_asns "${name}" printf "%s\n" "::: banIP asn '${name}' added to config" fi - ;; + ;; "remove_asn") - if [ -n "$(uci_get banip global ban_asns | grep -Fo "${name}")" ] - then + if uci_get banip global ban_asns | grep -q "${name}"; then uci_remove_list banip global ban_asns "${name}" printf "%s\n" "::: banIP asn '${name}' removed from config" fi - ;; + ;; "add_country") - if [ -z "$(uci_get banip global ban_countries | grep -Fo "${name}")" ] - then + if ! uci_get banip global ban_countries | grep -q "${name}"; then uci_add_list banip global ban_countries "${name}" printf "%s\n" "::: banIP country '${name}' added to config" fi - ;; + ;; "remove_country") - if [ -n "$(uci_get banip global ban_countries | grep -Fo "${name}")" ] - then + if uci_get banip global ban_countries | grep -q "${name}"; then uci_remove_list banip global ban_countries "${name}" printf "%s\n" "::: banIP country '${name}' removed from config" fi - ;; + ;; esac done - if [ -n "$(uci -q changes banip)" ] - then + if [ -n "$(uci -q changes banip)" ]; then uci_commit banip "${ban_init}" start fi @@ -171,24 +144,21 @@ list() src_archive="$(uci_get banip global ban_srcarc "/etc/banip/banip.sources.gz")" src_file="$(uci_get banip global ban_srcfile "/tmp/ban_sources.json")" src_enabled="$(uci -q show banip.global.ban_sources)" - if [ -r "${src_archive}" ] - then - zcat "${src_archive}" > "${src_file}" + if [ -r "${src_archive}" ]; then + zcat "${src_archive}" >"${src_file}" else printf "%s\n" "::: banIP source archive '${src_archive}' not found" fi - if [ -r "${src_file}" ] - then + if [ -r "${src_file}" ]; then src_enabled="${src_enabled#*=}" - src_enabled="${src_enabled//\'}" + src_enabled="${src_enabled//\'/}" printf "%s\n" "::: Available banIP sources" printf "%s\n" ":::" printf "%-25s%-10s%-36s%s\n" " Name" "Enabled" "Focus" "Info URL" printf "%s\n" " ---------------------------------------------------------------------------" json_load_file "${src_file}" json_get_keys keylist - for key in ${keylist} - do + for key in ${keylist}; do json_select "${key}" json_get_var focus "focus" json_get_var descurl "descurl" @@ -196,15 +166,13 @@ list() json_get_var rule_4 "rule_4" json_get_var url_6 "url_6" json_get_var rule_6 "rule_6" - if { [ -n "${url_4}" ] && [ -n "${rule_4}" ]; } || { [ -n "${url_6}" ] && [ -n "${rule_6}" ]; } - then - if [ -n "$(printf "%s" "${src_enabled}" | grep -Fo "${key}")" ] - then + if { [ -n "${url_4}" ] && [ -n "${rule_4}" ]; } || { [ -n "${url_6}" ] && [ -n "${rule_6}" ]; }; then + if printf "%s" "${src_enabled}" | grep -q "${key}"; then enabled="x" else enabled=" " fi - src_enabled="${src_enabled/${key}}" + src_enabled="${src_enabled/${key}/}" printf " + %-21s%-10s%-36s%s\n" "${key:0:20}" "${enabled}" "${focus:0:35}" "${descurl:0:50}" else src_enabled="${src_enabled} ${key}" @@ -217,13 +185,11 @@ list() printf " * %s\n" "Configured ASNs: ${asn_list// /, }" printf " * %s\n" "Configured Countries: ${country_list// /, }" - if [ -n "${src_enabled// }" ] - then + if [ -n "${src_enabled// /}" ]; then printf "%s\n" " ---------------------------------------------------------------------------" printf "%s\n" " Sources without valid configuration" printf "%s\n" " ---------------------------------------------------------------------------" - for key in ${src_enabled} - do + for key in ${src_enabled}; do printf " - %s\n" "${key:0:20}" done fi @@ -233,41 +199,34 @@ list() fi } -status() -{ +status() { status_service } -status_service() -{ - local key keylist value index_value values rtfile +status_service() { + local key keylist type value index_value values rtfile rtfile="$(uci_get banip global ban_rtfile "/tmp/ban_runtime.json")" json_load_file "${rtfile}" >/dev/null 2>&1 json_get_keys keylist - if [ -n "${keylist}" ] - then + if [ -n "${keylist}" ]; then printf "%s\n" "::: banIP runtime information" - for key in ${keylist} - do + for key in ${keylist}; do json_get_var value "${key}" >/dev/null 2>&1 - if [ "${key%_*}" = "active" ] - then + if [ "${key%_*}" = "active" ]; then printf " + %-15s : " "${key}" json_select "${key}" >/dev/null 2>&1 values="" index=1 - while json_get_type type "${index}" && [ "${type}" = "object" ] - do + while json_get_type type "${index}" && [ "${type}" = "object" ]; do json_get_values index_value "${index}" >/dev/null 2>&1 - if [ "${index}" = "1" ] - then + if [ "${index}" = "1" ]; then values="${index_value}" else values="${values}, ${index_value}" fi - index=$((index+1)) + index=$((index + 1)) done values="$(printf "%s" "${values}" | awk '{NR=1;max=98;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max)}else{printf"%-22s%s\n","",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')" printf "%s\n" "${values:-"-"}" @@ -281,64 +240,53 @@ status_service() fi } -report() -{ +report() { rc_procd "${ban_script}" report "${1:-"cli"}" } -timer() -{ +timer() { local cron_file cron_content cron_lineno action="${1:-"list"}" cron_tasks="${2}" hour="${3}" minute="${4:-0}" weekday="${5:-"*"}" cron_file="/etc/crontabs/root" - if [ -s "${cron_file}" ] && [ "${action}" = "list" ] - then + if [ -s "${cron_file}" ] && [ "${action}" = "list" ]; then awk '{print NR "> " $0}' "${cron_file}" - elif [ "${action}" = "add" ] - then + elif [ "${action}" = "add" ]; then hour="${hour//[[:alpha:]]/}" minute="${minute//[[:alpha:]]/}" - if [ -n "${cron_tasks}" ] && [ -n "${hour}" ] && [ -n "${minute}" ] && [ -n "${weekday}" ] && \ - [ "${hour}" -ge 0 ] && [ "${hour}" -le 23 ] && \ - [ "${minute}" -ge 0 ] && [ "${minute}" -le 59 ] - then - printf "%02d %02d %s\n" "${minute}" "${hour}" "* * ${weekday} ${ban_init} ${cron_tasks}" >> "${cron_file}" + if [ -n "${cron_tasks}" ] && [ -n "${hour}" ] && [ -n "${minute}" ] && [ -n "${weekday}" ] && + [ "${hour}" -ge 0 ] && [ "${hour}" -le 23 ] && + [ "${minute}" -ge 0 ] && [ "${minute}" -le 59 ]; then + printf "%02d %02d %s\n" "${minute}" "${hour}" "* * ${weekday} ${ban_init} ${cron_tasks}" >>"${cron_file}" /etc/init.d/cron restart fi - elif [ -s "${cron_file}" ] && [ "${action}" = "remove" ] - then + elif [ -s "${cron_file}" ] && [ "${action}" = "remove" ]; then cron_tasks="${cron_tasks//[[:alpha:]]/}" cron_lineno="$(awk 'END{print NR}' "${cron_file}")" cron_content="$(awk '{print $0}' "${cron_file}")" - if [ "${cron_tasks:-"0"}" -le "${cron_lineno:-"1"}" ] && [ -n "${cron_content}" ] - then - printf "%s\n" "${cron_content}" | awk "NR!~/^${cron_tasks}$/" > "${cron_file}" + if [ "${cron_tasks:-"0"}" -le "${cron_lineno:-"1"}" ] && [ -n "${cron_content}" ]; then + printf "%s\n" "${cron_content}" | awk "NR!~/^${cron_tasks}$/" >"${cron_file}" /etc/init.d/cron restart fi fi } -service_triggers() -{ +service_triggers() { local iface delay iface="$(uci_get banip global ban_trigger)" delay="$(uci_get banip global ban_triggerdelay "5")" - PROCD_RELOAD_DELAY=$((delay*1000)) + PROCD_RELOAD_DELAY=$((delay * 1000)) - if [ -z "${iface}" ] - then + if [ -z "${iface}" ]; then . "/lib/functions/network.sh" network_find_wan iface - if [ -n "${iface}" ] - then + if [ -n "${iface}" ]; then uci_set banip global ban_trigger "${iface}" uci_commit "banip" fi fi - if [ -n "${iface}" ] - then + if [ -n "${iface}" ]; then procd_add_interface_trigger "interface.*.up" "${iface}" "${ban_init}" "start" fi procd_add_reload_trigger "banip" diff --git a/net/banip/files/banip.mail b/net/banip/files/banip.mail index 0b639757a3..a89b92df36 100755 --- a/net/banip/files/banip.mail +++ b/net/banip/files/banip.mail @@ -1,52 +1,35 @@ #!/bin/sh # send mail script for banIP notifications -# written by Dirk Brenken (dev@brenken.org) -# +# Copyright (c) 2020-2021 Dirk Brenken (dev@brenken.org) # This is free software, licensed under the GNU General Public License v3. -# + # (s)hellcheck exceptions -# shellcheck disable=1091,2030,2031,2034,2039,2086,2129,2140,2143,2154,2181,2183,2188 +# shellcheck disable=1091,3040 + +# Please note: you have to setup the package 'msmtp' before using this script export LC_ALL=C export PATH="/usr/sbin:/usr/bin:/sbin:/bin" set -o pipefail -if [ -r "/lib/functions.sh" ] -then - . "/lib/functions.sh" - ban_debug="$(uci_get banip global ban_debug "0")" - ban_loglimit="$(uci_get banip global ban_loglimit "100")" - ban_mailsender="$(uci_get banip global ban_mailsender "no-reply@banIP")" - ban_mailreceiver="$(uci_get banip global ban_mailreceiver)" - ban_mailtopic="$(uci_get banip global ban_mailtopic "banIP notification")" - ban_mailprofile="$(uci_get banip global ban_mailprofile "ban_notify")" -fi -ban_ver="${1}" +. "/lib/functions.sh" +ban_debug="$(uci_get banip global ban_debug "0")" +ban_loglimit="$(uci_get banip global ban_loglimit "100")" +ban_mailsender="$(uci_get banip global ban_mailsender "no-reply@banIP")" +ban_mailreceiver="$(uci_get banip global ban_mailreceiver)" +ban_mailtopic="$(uci_get banip global ban_mailtopic "banIP notification")" +ban_mailprofile="$(uci_get banip global ban_mailprofile "ban_notify")" + ban_mail="$(command -v msmtp)" ban_logger="$(command -v logger)" ban_logread="$(command -v logread)" -ban_rc=1 -f_log() -{ - local class="${1}" log_msg="${2}" - - if [ -x "${ban_logger}" ] - then - "${ban_logger}" -p "${class}" -t "banIP-${ban_ver%-*}[${$}]" "${log_msg}" - else - printf "%s %s %s\n" "${class}" "banIP-${ban_ver%-*}[${$}]" "${log_msg}" - fi -} - -if [ -z "${ban_mailreceiver}" ] -then +if [ -z "${ban_mailreceiver}" ]; then f_log "err" "please set the mail receiver with the 'ban_mailreceiver' option" - exit ${ban_rc} + exit 1 fi -if [ "${ban_debug}" = "1" ] -then +if [ "${ban_debug}" = "1" ]; then msmtp_debug="--debug" fi @@ -54,9 +37,12 @@ ban_mailhead="From: ${ban_mailsender}\nTo: ${ban_mailreceiver}\nSubject: ${ban_m # info preparation # -sys_info="$(strings /etc/banner 2>/dev/null)" +sys_info="$( + strings /etc/banner 2>/dev/null + ubus call system board | awk 'BEGIN{FS="[{}\"]"}{if($2=="kernel"||$2=="hostname"||$2=="system"||$2=="model"||$2=="description")printf " + %-12s: %s\n",$2,$4}' +)" ban_info="$(/etc/init.d/banip "status" 2>/dev/null)" -rep_info="${2}" +rep_info="${1}" log_info="$("${ban_logread}" -l "${ban_loglimit}" -e "banIP-" 2>/dev/null | awk '{NR=1;max=120;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max)}else{print substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')" # mail body @@ -64,8 +50,7 @@ log_info="$("${ban_logread}" -l "${ban_loglimit}" -e "banIP-" 2>/dev/null | awk ban_mailtext="
"
 ban_mailtext="${ban_mailtext}\n++\n++ System Information ++\n++\n${sys_info}"
 ban_mailtext="${ban_mailtext}\n\n++\n++ banIP Status ++\n++\n${ban_info}"
-if [ -n "${rep_info}" ]
-then
+if [ -n "${rep_info}" ]; then
 	ban_mailtext="${ban_mailtext}\n\n++\n++ banIP Report ++\n++\n${rep_info}"
 fi
 ban_mailtext="${ban_mailtext}\n\n++\n++ Logfile Information ++\n++\n${log_info}"
@@ -73,12 +58,5 @@ ban_mailtext="${ban_mailtext}
" # send mail # -if [ -x "${ban_mail}" ] -then - printf "%b" "${ban_mailhead}${ban_mailtext}" 2>/dev/null | "${ban_mail}" ${msmtp_debug} -a "${ban_mailprofile}" "${ban_mailreceiver}" >/dev/null 2>&1 - ban_rc=${?} - f_log "info" "mail sent to '${ban_mailreceiver}' with rc '${ban_rc}'" -else - f_log "err" "msmtp mail daemon not found" -fi -exit ${ban_rc} +printf "%b" "${ban_mailhead}${ban_mailtext}" 2>/dev/null | "${ban_mail}" ${msmtp_debug} -a "${ban_mailprofile}" "${ban_mailreceiver}" >/dev/null 2>&1 +"${ban_logger}" -p "info" -t "banIP-mail [${$}]" "mail sent to '${ban_mailreceiver}' with rc '${?}'" 2>/dev/null diff --git a/net/banip/files/banip.service b/net/banip/files/banip.service index 45e2babb67..12e7bda2fc 100755 --- a/net/banip/files/banip.service +++ b/net/banip/files/banip.service @@ -1,36 +1,28 @@ #!/bin/sh -# log service to trace failed ssh/luci logins and conditionally refresh banIP -# written by Dirk Brenken (dev@brenken.org) -# +# log service to trace suspicious logins and conditionally refresh banIP +# Copyright (c) 2019-2021 Dirk Brenken (dev@brenken.org) # This is free software, licensed under the GNU General Public License v3. -# + # (s)hellcheck exceptions -# shellcheck disable=1091,2030,2031,2034,2039,2086,2129,2140,2143,2154,2181,2183,2188 +# shellcheck disable=3040 export LC_ALL=C export PATH="/usr/sbin:/usr/bin:/sbin:/bin" set -o pipefail -ban_ver="${1}" -ban_search="${2}" -ban_logger="$(command -v logger)" -ban_logread="$(command -v logread)" -f_log() -{ - local class="${1}" log_msg="${2}" +ban_search="${1}" +ban_logger_cmd="$(command -v logger)" +ban_logread_cmd="$(command -v logread)" - if [ -x "${ban_logger}" ] - then - "${ban_logger}" -p "${class}" -t "banIP-${ban_ver%-*}[${$}]" "${log_msg}" - else - printf "%s %s %s\n" "${class}" "banIP-${ban_ver%-*}[${$}]" "${log_msg}" - fi -} - -if [ -x "${ban_logread}" ] -then - f_log "info" "log/banIP service started" - "${ban_logread}" -f | { grep -qE "${ban_search}"; [ "${?}" = "0" ] && { /etc/init.d/banip refresh; exit 0; }; } +if [ -x "${ban_logread_cmd}" ]; then + "${ban_logger_cmd}" -p "info" -t "banIP-service [${$}]" "log/banIP service started" 2>/dev/null + "${ban_logread_cmd}" -f | + { + grep -qE "${ban_search}" && { + /etc/init.d/banip refresh + exit 0 + } + } else - f_log "err" "can't start log/banIP service" + "${ban_logger_cmd}" -p "err" -t "banIP-service [${$}]" "can't start log/banIP service" 2>/dev/null fi diff --git a/net/banip/files/banip.sh b/net/banip/files/banip.sh index 31662e159b..814a83a487 100755 --- a/net/banip/files/banip.sh +++ b/net/banip/files/banip.sh @@ -1,18 +1,18 @@ #!/bin/sh # banIP - ban incoming and outgoing ip adresses/subnets via ipset -# written by Dirk Brenken (dev@brenken.org) -# +# Copyright (c) 2018-2021 Dirk Brenken (dev@brenken.org) # This is free software, licensed under the GNU General Public License v3. -# + # (s)hellcheck exceptions -# shellcheck disable=1091,2030,2031,2034,2039,2086,2129,2140,2143,2154,2181,2183,2188 +# shellcheck disable=1091,2030,2031,2086,2183,3040,3043,3060 # set initial defaults # export LC_ALL=C export PATH="/usr/sbin:/usr/bin:/sbin:/bin" set -o pipefail -ban_ver="0.7.9" +ban_ver="0.7.10" +ban_status="" ban_enabled="0" ban_mail_enabled="0" ban_proto4_enabled="0" @@ -36,6 +36,7 @@ ban_ifaces="" ban_debug="0" ban_maxqueue="4" ban_fetchutil="" +ban_fetchinsecure="0" ban_ip_cmd="$(command -v ip)" ban_ipt4_cmd="$(command -v iptables)" ban_ipt4_savecmd="$(command -v iptables-save)" @@ -47,6 +48,7 @@ ban_ipset_cmd="$(command -v ipset)" ban_logger_cmd="$(command -v logger)" ban_logread_cmd="$(command -v logread)" ban_allsources="" +ban_extrasources="" ban_sources="" ban_asns="" ban_countries="" @@ -81,21 +83,12 @@ ban_cnt="0" # load environment # -f_load() -{ - # get system information - # - ban_sysver="$(ubus -S call system board 2>/dev/null | jsonfilter -e '@.model' -e '@.release.description' | \ - awk 'BEGIN{ORS=", "}{print $0}' | awk '{print substr($0,1,length($0)-2)}')" +f_load() { + ban_sysver="$(ubus -S call system board 2>/dev/null | jsonfilter -q -e '@.model' -e '@.release.description' | + awk 'BEGIN{RS="";FS="\n"}{printf "%s, %s",$1,$2}')" - # load config - # f_conf - - # check status - # - if [ "${ban_enabled}" = "0" ] - then + if [ "${ban_enabled}" = "0" ]; then f_bgsrv "stop" f_ipset "destroy" f_jsnup "disabled" @@ -104,108 +97,77 @@ f_load() f_log "info" "banIP is currently disabled, please set the config option 'ban_enabled' to '1' to use this service" exit 0 fi - f_dir "${ban_backupdir}" f_dir "${ban_reportdir}" } # check/create directories # -f_dir() -{ +f_dir() { local dir="${1}" - if [ ! -d "${dir}" ] - then - mkdir -p "${dir}" - if [ "${?}" = "0" ] - then - f_log "debug" "directory '${dir}' created" - else - f_log "err" "directory '${dir}' could not be created" - fi - else + if [ -d "${dir}" ]; then f_log "debug" "directory '${dir}' is used" + else + rm -f "${dir}" + mkdir -p "${dir}" + f_log "debug" "directory '${dir}' created" fi } # load banIP config # -f_conf() -{ - if [ ! -r "/etc/config/banip" ] || [ -z "$(uci -q show banip.global.ban_autodetect)" ] - then +f_conf() { + if [ ! -r "/etc/config/banip" ] || [ -z "$(uci -q show banip.global.ban_autodetect)" ]; then f_log "err" "no valid banIP config found, please re-install the package via opkg with the '--force-reinstall --force-maintainer' options" fi - config_cb() - { - option_cb() - { + config_cb() { + option_cb() { local option="${1}" local value="${2}" eval "${option}=\"${value}\"" } - list_cb() - { + list_cb() { local option="${1}" local value="${2}" - if [ "${option}" = "ban_ifaces" ] - then + if [ "${option}" = "ban_ifaces" ]; then eval "${option}=\"$(printf "%s" "${ban_ifaces}")${value} \"" - elif [ "${option}" = "ban_sources" ] - then + elif [ "${option}" = "ban_sources" ]; then eval "${option}=\"$(printf "%s" "${ban_sources}")${value} \"" - elif [ "${option}" = "ban_localsources" ] - then + elif [ "${option}" = "ban_localsources" ]; then eval "${option}=\"$(printf "%s" "${ban_localsources}")${value} \"" - elif [ "${option}" = "ban_extrasources" ] - then + elif [ "${option}" = "ban_extrasources" ]; then eval "${option}=\"$(printf "%s" "${ban_extrasources}")${value} \"" - elif [ "${option}" = "ban_settype_src" ] - then + elif [ "${option}" = "ban_settype_src" ]; then eval "${option}=\"$(printf "%s" "${ban_settype_src}")${value} \"" - elif [ "${option}" = "ban_settype_dst" ] - then + elif [ "${option}" = "ban_settype_dst" ]; then eval "${option}=\"$(printf "%s" "${ban_settype_dst}")${value} \"" - elif [ "${option}" = "ban_settype_all" ] - then + elif [ "${option}" = "ban_settype_all" ]; then eval "${option}=\"$(printf "%s" "${ban_settype_all}")${value} \"" - elif [ "${option}" = "ban_mailactions" ] - then + elif [ "${option}" = "ban_mailactions" ]; then eval "${option}=\"$(printf "%s" "${ban_mailactions}")${value} \"" - elif [ "${option}" = "ban_logterms" ] - then + elif [ "${option}" = "ban_logterms" ]; then eval "${option}=\"$(printf "%s" "${ban_logterms}")${value} \"" - elif [ "${option}" = "ban_countries" ] - then + elif [ "${option}" = "ban_countries" ]; then eval "${option}=\"$(printf "%s" "${ban_countries}")${value} \"" - elif [ "${option}" = "ban_asns" ] - then + elif [ "${option}" = "ban_asns" ]; then eval "${option}=\"$(printf "%s" "${ban_asns}")${value} \"" - elif [ "${option}" = "ban_lan_inputchains_4" ] - then + elif [ "${option}" = "ban_lan_inputchains_4" ]; then eval "${option}=\"$(printf "%s" "${ban_lan_inputchains_4}")${value} \"" - elif [ "${option}" = "ban_lan_inputchains_6" ] - then + elif [ "${option}" = "ban_lan_inputchains_6" ]; then eval "${option}=\"$(printf "%s" "${ban_lan_inputchains_6}")${value} \"" - elif [ "${option}" = "ban_lan_forwardchains_4" ] - then + elif [ "${option}" = "ban_lan_forwardchains_4" ]; then eval "${option}=\"$(printf "%s" "${ban_lan_forwardchains_4}")${value} \"" - elif [ "${option}" = "ban_lan_forwardchains_6" ] - then + elif [ "${option}" = "ban_lan_forwardchains_6" ]; then eval "${option}=\"$(printf "%s" "${ban_lan_forwardchains_6}")${value} \"" - elif [ "${option}" = "ban_wan_inputchains_4" ] - then + elif [ "${option}" = "ban_wan_inputchains_4" ]; then eval "${option}=\"$(printf "%s" "${ban_wan_inputchains_4}")${value} \"" - elif [ "${option}" = "ban_wan_inputchains_6" ] - then + elif [ "${option}" = "ban_wan_inputchains_6" ]; then eval "${option}=\"$(printf "%s" "${ban_wan_inputchains_6}")${value} \"" - elif [ "${option}" = "ban_wan_forwardchains_4" ] - then + elif [ "${option}" = "ban_wan_forwardchains_4" ]; then eval "${option}=\"$(printf "%s" "${ban_wan_forwardchains_4}")${value} \"" - elif [ "${option}" = "ban_wan_forwardchains_6" ] - then + elif [ "${option}" = "ban_wan_forwardchains_6" ]; then eval "${option}=\"$(printf "%s" "${ban_wan_forwardchains_6}")${value} \"" fi } @@ -228,14 +190,12 @@ f_conf() ban_logchain_dst="${ban_logchain_dst:-"${ban_chain}_log_dst"}" ban_logtarget_src="${ban_target_src}" ban_logtarget_dst="${ban_target_dst}" - if [ "${ban_logsrc_enabled}" = "1" ] - then + if [ "${ban_logsrc_enabled}" = "1" ]; then ban_logprefix_src="${ban_logprefix_src:-"[banIP-${ban_ver%-*}, src/${ban_target_src}] "}" ban_logopts_src="${ban_logopts_src:-"-m limit --limit 2/sec"}" ban_target_src="${ban_logchain_src}" fi - if [ "${ban_logdst_enabled}" = "1" ] - then + if [ "${ban_logdst_enabled}" = "1" ]; then ban_logprefix_dst="${ban_logprefix_dst:-"[banIP-${ban_ver%-*}, dst/${ban_target_dst}] "}" ban_logopts_dst="${ban_logopts_dst:-"-m limit --limit 2/sec"}" ban_target_dst="${ban_logchain_dst}" @@ -249,53 +209,41 @@ f_conf() # check environment # -f_env() -{ +f_env() { local util utils packages iface insecure tmp cnt="0" cnt_max="10" ban_starttime="$(date "+%s")" f_jsnup "running" f_log "info" "start banIP processing (${ban_action})" - # create temp directory & files - # f_tmp - # get wan devices and wan subnets - # - if [ "${ban_autodetect}" = "1" ] && [ -z "${ban_ifaces}" ] - then - while [ "${cnt}" -le "${cnt_max}" ] - do + if [ "${ban_autodetect}" = "1" ] && [ -z "${ban_ifaces}" ]; then + while [ "${cnt}" -le "${cnt_max}" ]; do network_find_wan iface - if [ -n "${iface}" ] && [ -z "$(printf "%s\n" "${ban_ifaces}" | grep -F "${iface}")" ] - then + if [ -n "${iface}" ] && ! printf "%s\n" "${ban_ifaces}" | grep -q "${iface}"; then ban_proto4_enabled="1" ban_ifaces="${ban_ifaces}${iface} " uci_set banip global ban_proto4_enabled "1" uci_add_list banip global ban_ifaces "${iface}" fi network_find_wan6 iface - if [ -n "${iface}" ] && [ -z "$(printf "%s\n" "${ban_ifaces}" | grep -F "${iface}")" ] - then + if [ -n "${iface}" ] && ! printf "%s\n" "${ban_ifaces}" | grep -q "${iface}"; then ban_proto6_enabled="1" ban_ifaces="${ban_ifaces}${iface} " uci_set banip global ban_proto6_enabled "1" uci_add_list banip global ban_ifaces "${iface}" fi - if [ -z "${ban_ifaces}" ] - then - if [ "${cnt}" -le "${cnt_max}" ] - then + if [ -z "${ban_ifaces}" ]; then + if [ "${cnt}" -le "${cnt_max}" ]; then network_flush_cache - cnt=$((cnt+1)) + cnt=$((cnt + 1)) sleep 1 else break fi else - if [ -n "$(uci -q changes "banip")" ] - then + if [ -n "$(uci -q changes "banip")" ]; then uci_commit "banip" fi break @@ -303,38 +251,30 @@ f_env() done fi - while [ "${cnt}" -le "${cnt_max}" ] - do - for iface in ${ban_ifaces} - do + while [ "${cnt}" -le "${cnt_max}" ]; do + for iface in ${ban_ifaces}; do network_get_device tmp "${iface}" - if [ -n "${tmp}" ] && [ -z "$(printf "%s\n" "${ban_devs}" | grep -F "${tmp}")" ] - then + if [ -n "${tmp}" ] && ! printf "%s\n" "${ban_devs}" | grep -q "${tmp}"; then ban_devs="${ban_devs} ${tmp}" else network_get_physdev tmp "${iface}" - if [ -n "${tmp}" ] && [ -z "$(printf "%s\n" "${ban_devs}" | grep -F "${tmp}")" ] - then + if [ -n "${tmp}" ] && ! printf "%s\n" "${ban_devs}" | grep -q "${tmp}"; then ban_devs="${ban_devs} ${tmp}" fi fi network_get_subnet tmp "${iface}" - if [ -n "${tmp}" ] && [ -z "$(printf "%s\n" "${ban_subnets}" | grep -F "${tmp}")" ] - then + if [ -n "${tmp}" ] && ! printf "%s\n" "${ban_subnets}" | grep -q "${tmp}"; then ban_subnets="${ban_subnets} ${tmp}" fi network_get_subnet6 tmp "${iface}" - if [ -n "${tmp}" ] && [ -z "$(printf "%s\n" "${ban_subnets}" | grep -F "${tmp}")" ] - then + if [ -n "${tmp}" ] && ! printf "%s\n" "${ban_subnets}" | grep -q "${tmp}"; then ban_subnets="${ban_subnets} ${tmp}" fi done - if [ -z "${ban_devs}" ] || [ -z "${ban_subnets}" ] - then - if [ "${cnt}" -le "${cnt_max}" ] - then + if [ -z "${ban_devs}" ] || [ -z "${ban_subnets}" ]; then + if [ "${cnt}" -le "${cnt_max}" ]; then network_flush_cache - cnt=$((cnt+1)) + cnt=$((cnt + 1)) sleep 1 else break @@ -345,50 +285,36 @@ f_env() done ban_ipdevs="$("${ban_ip_cmd}" link show 2>/dev/null | awk 'BEGIN{FS="[@: ]"}/^[0-9:]/{if($3!="lo"){ORS=" ";print $3}}')" - if [ -z "${ban_ifaces}" ] || [ -z "${ban_devs}" ] || [ -z "${ban_ipdevs}" ] - then + if [ -z "${ban_ifaces}" ] || [ -z "${ban_devs}" ] || [ -z "${ban_ipdevs}" ]; then f_log "err" "logical wan interface(s)/device(s) '${ban_ifaces:-"-"}/${ban_devs:-"-"}' not found, please please check your configuration" - elif [ -z "${ban_ipdevs}" ] - then + elif [ -z "${ban_ipdevs}" ]; then f_log "err" "ip device(s) '${ban_ipdevs:-"-"}' not found, please please check your configuration" fi - # check ipset/iptables utility - # - if [ ! -x "${ban_ipset_cmd}" ] - then + if [ ! -x "${ban_ipset_cmd}" ]; then f_log "err" "ipset utility '${ban_ipset_cmd:-"-"}' not executable, please install package 'ipset'" fi - if { [ "${ban_proto4_enabled}" = "1" ] && { [ ! -x "${ban_ipt4_cmd}" ] || [ ! -x "${ban_ipt4_savecmd}" ] || [ ! -x "${ban_ipt4_restorecmd}" ]; }; } || \ - { [ "${ban_proto6_enabled}" = "1" ] && { [ ! -x "${ban_ipt6_cmd}" ] || [ ! -x "${ban_ipt6_savecmd}" ] || [ ! -x "${ban_ipt6_restorecmd}" ]; }; } - then + if { [ "${ban_proto4_enabled}" = "1" ] && { [ ! -x "${ban_ipt4_cmd}" ] || [ ! -x "${ban_ipt4_savecmd}" ] || [ ! -x "${ban_ipt4_restorecmd}" ]; }; } || + { [ "${ban_proto6_enabled}" = "1" ] && { [ ! -x "${ban_ipt6_cmd}" ] || [ ! -x "${ban_ipt6_savecmd}" ] || [ ! -x "${ban_ipt6_restorecmd}" ]; }; }; then f_log "err" "iptables utilities '${ban_ipt4_cmd:-"-"}, ${ban_ipt4_savecmd:-"-"}, ${ban_ipt4_restorecmd:-"-"}/${ban_ipt6_cmd:-"-"}', ${ban_ipt6_savecmd:-"-"}, ${ban_ipt6_restorecmd:-"-"} not executable, please install the relevant iptables packages" fi - # check download utility - # - if [ -z "${ban_fetchutil}" ] - then - while [ -z "${packages}" ] && [ "${cnt}" -le "${cnt_max}" ] - do + if [ -z "${ban_fetchutil}" ]; then + while [ -z "${packages}" ] && [ "${cnt}" -le "${cnt_max}" ]; do packages="$(opkg list-installed 2>/dev/null)" - cnt=$((cnt+1)) + cnt=$((cnt + 1)) sleep 1 done - if [ -z "${packages}" ] - then + if [ -z "${packages}" ]; then f_log "err" "local opkg package repository is not available, please set 'ban_fetchutil' manually" fi utils="aria2c curl wget uclient-fetch" - for util in ${utils} - do - if { [ "${util}" = "uclient-fetch" ] && [ -n "$(printf "%s" "${packages}" | grep "^libustream-")" ]; } || \ - { [ "${util}" = "wget" ] && [ -n "$(printf "%s" "${packages}" | grep "^wget -")" ]; } || \ - [ "${util}" = "curl" ] || [ "${util}" = "aria2c" ] - then - if [ -x "$(command -v "${util}")" ] - then + for util in ${utils}; do + if { [ "${util}" = "uclient-fetch" ] && printf "%s" "${packages}" | grep -q "^libustream-"; } || + { [ "${util}" = "wget" ] && printf "%s" "${packages}" | grep -q "^wget -"; } || + [ "${util}" = "curl" ] || [ "${util}" = "aria2c" ]; then + if [ -x "$(command -v "${util}")" ]; then ban_fetchutil="${util}" uci_set banip global ban_fetchutil "${util}" uci_commit "banip" @@ -396,60 +322,50 @@ f_env() fi fi done - elif [ ! -x "$(command -v "${ban_fetchutil}")" ] - then + elif [ ! -x "$(command -v "${ban_fetchutil}")" ]; then unset ban_fetchutil fi case "${ban_fetchutil}" in "aria2c") - if [ "${ban_fetchinsecure}" = "1" ] - then + if [ "${ban_fetchinsecure}" = "1" ]; then insecure="--check-certificate=false" fi ban_fetchparm="${ban_fetchparm:-"${insecure} --timeout=20 --allow-overwrite=true --auto-file-renaming=false --log-level=warn --dir=/ -o"}" - ;; + ;; "curl") - if [ "${ban_fetchinsecure}" = "1" ] - then + if [ "${ban_fetchinsecure}" = "1" ]; then insecure="--insecure" fi ban_fetchparm="${ban_fetchparm:-"${insecure} --connect-timeout 20 --silent --show-error --location -o"}" - ;; + ;; "uclient-fetch") - if [ "${ban_fetchinsecure}" = "1" ] - then + if [ "${ban_fetchinsecure}" = "1" ]; then insecure="--no-check-certificate" fi ban_fetchparm="${ban_fetchparm:-"${insecure} --timeout=20 -O"}" - ;; + ;; "wget") - if [ "${ban_fetchinsecure}" = "1" ] - then + if [ "${ban_fetchinsecure}" = "1" ]; then insecure="--no-check-certificate" fi ban_fetchparm="${ban_fetchparm:-"${insecure} --no-cache --no-cookies --max-redirect=0 --timeout=20 -O"}" - ;; + ;; esac - if [ -n "${ban_fetchutil}" ] && [ -n "${ban_fetchparm}" ] - then + if [ -n "${ban_fetchutil}" ] && [ -n "${ban_fetchparm}" ]; then ban_fetchutil="$(command -v "${ban_fetchutil}")" else f_log "err" "download utility with SSL support not found, please install 'uclient-fetch' with a 'libustream-*' variant or another download utility like 'wget', 'curl' or 'aria2'" fi - # load JSON source file - # - if [ ! -r "${ban_srcfile}" ] - then - if [ -r "${ban_srcarc}" ] - then - zcat "${ban_srcarc}" > "${ban_srcfile}" + if [ ! -r "${ban_srcfile}" ]; then + if [ -r "${ban_srcarc}" ]; then + zcat "${ban_srcarc}" >"${ban_srcfile}" else f_log "err" "banIP source archive not found" fi fi - if [ -r "${ban_srcfile}" ] - then + if [ -r "${ban_srcfile}" ]; then + json_init json_load_file "${ban_srcfile}" json_get_keys ban_allsources ban_allsources="${ban_allsources} maclist blacklist whitelist" @@ -461,51 +377,43 @@ f_env() # create temporary files and directories # -f_tmp() -{ +f_tmp() { f_dir "${ban_tmpbase}" ban_tmpdir="$(mktemp -p "${ban_tmpbase}" -d)" ban_tmpfile="$(mktemp -p "${ban_tmpdir}" -tu)" - if [ ! -f "${ban_pidfile}" ] || [ ! -s "${ban_pidfile}" ] - then - printf "%s" "${$}" > "${ban_pidfile}" + if [ ! -f "${ban_pidfile}" ] || [ ! -s "${ban_pidfile}" ]; then + printf "%s" "${$}" >"${ban_pidfile}" fi f_log "debug" "f_tmp ::: tmp_base: ${ban_tmpbase:-"-"}, tmp_dir: ${ban_tmpdir:-"-"}, pid_file: ${ban_pidfile:-"-"}" } # remove temporary files and directories # -f_rmtmp() -{ - if [ -d "${ban_tmpdir}" ] - then +f_rmtmp() { + if [ -d "${ban_tmpdir}" ]; then rm -rf "${ban_tmpdir}" fi rm -f "${ban_srcfile}" - > "${ban_pidfile}" + : >"${ban_pidfile}" f_log "debug" "f_rmtmp ::: tmp_base: ${ban_tmpbase:-"-"}, tmp_dir: ${ban_tmpdir:-"-"}, pid_file: ${ban_pidfile:-"-"}" } # remove backup files # -f_rmbckp() -{ - if [ -d "${ban_backupdir}" ] - then +f_rmbckp() { + if [ -d "${ban_backupdir}" ]; then rm -f "${ban_backupdir}/banIP."*".gz" fi } # status helper function # -f_char() -{ +f_char() { local result input="${1}" - if [ "${input}" = "1" ] - then + if [ "${input}" = "1" ]; then result="✔" else result="✘" @@ -515,56 +423,51 @@ f_char() # apply iptables rules # -f_iptrule() -{ +f_iptrule() { local rc timeout="-w 5" action="${1}" chain="${2}" rule="${3}" pos="${4}" - if [ "${ban_proto4_enabled}" = "1" ] && { [ "${src_name}" = "maclist" ] || [ "${src_name##*_}" = "4" ]; } - then - rc="$("${ban_ipt4_cmd}" "${timeout}" -C ${chain} ${rule} 2>/dev/null; printf "%u" ${?})" - if { [ "${rc}" != "0" ] && { [ "${action}" = "-A" ] || [ "${action}" = "-I" ]; }; } || \ - { [ "${rc}" = "0" ] && [ "${action}" = "-D" ]; } - then + if [ "${ban_proto4_enabled}" = "1" ] && { [ "${src_name}" = "maclist" ] || [ "${src_name##*_}" = "4" ]; }; then + rc="$( + "${ban_ipt4_cmd}" "${timeout}" -C ${chain} ${rule} 2>/dev/null + printf "%u" ${?} + )" + if { [ "${rc}" != "0" ] && { [ "${action}" = "-A" ] || [ "${action}" = "-I" ]; }; } || + { [ "${rc}" = "0" ] && [ "${action}" = "-D" ]; }; then "${ban_ipt4_cmd}" "${timeout}" "${action}" ${chain} ${pos} ${rule} 2>/dev/null rc="${?}" else rc=0 fi fi - if [ "${ban_proto6_enabled}" = "1" ] && { [ "${src_name}" = "maclist" ] || [ "${src_name##*_}" = "6" ]; } - then - rc="$("${ban_ipt6_cmd}" "${timeout}" -C ${chain} ${rule} 2>/dev/null; printf "%u" ${?})" - if { [ "${rc}" != "0" ] && { [ "${action}" = "-A" ] || [ "${action}" = "-I" ]; }; } || \ - { [ "${rc}" = "0" ] && [ "${action}" = "-D" ]; } - then + if [ "${ban_proto6_enabled}" = "1" ] && { [ "${src_name}" = "maclist" ] || [ "${src_name##*_}" = "6" ]; }; then + rc="$( + "${ban_ipt6_cmd}" "${timeout}" -C ${chain} ${rule} 2>/dev/null + printf "%u" ${?} + )" + if { [ "${rc}" != "0" ] && { [ "${action}" = "-A" ] || [ "${action}" = "-I" ]; }; } || + { [ "${rc}" = "0" ] && [ "${action}" = "-D" ]; }; then "${ban_ipt6_cmd}" "${timeout}" "${action}" ${chain} ${pos} ${rule} 2>/dev/null rc="${?}" else rc=0 fi fi - if [ -n "${rc}" ] && [ "${rc}" != "0" ] - then - > "${tmp_err}" + if [ -n "${rc}" ] && [ "${rc}" != "0" ]; then + : >"${tmp_err}" f_log "info" "${src_name}: iptables action '${action:-"-"}' failed with '${chain}, ${pos:-"-"}, ${rule:-"-"}'" fi } # iptables controller # -f_iptables() -{ +f_iptables() { local ipt_cmd chain chainsets dev pos timeout="-w 5" destroy="${1}" - if [ "${ban_action}" != "refresh" ] && [ "${ban_action}" != "resume" ] - then - for dev in ${ban_ipdevs} - do - if [ "${src_name}" = "maclist" ] - then + if [ "${ban_action}" != "refresh" ] && [ "${ban_action}" != "resume" ]; then + for dev in ${ban_ipdevs}; do + if [ "${src_name}" = "maclist" ]; then f_iptrule "-D" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} src -j RETURN" - elif [ "${src_name%_*}" = "whitelist" ] - then + elif [ "${src_name%_*}" = "whitelist" ]; then f_iptrule "-D" "${ban_chain}" "-i ${dev} -m set ! --match-set ${src_name} src -j ${ban_logtarget_src}" f_iptrule "-D" "${ban_chain}" "-o ${dev} -m set ! --match-set ${src_name} dst -j ${ban_logtarget_dst}" f_iptrule "-D" "${ban_chain}" "-i ${dev} -m set ! --match-set ${src_name} src -j ${ban_logchain_src}" @@ -579,31 +482,24 @@ f_iptables() fi done fi - if [ -z "${destroy}" ] && { [ "${cnt}" -gt "0" ] || [ "${src_name%_*}" = "blacklist" ] || [ "${src_name%_*}" = "whitelist" ]; } - then - if [ "${src_name##*_}" = "4" ] - then + if [ -z "${destroy}" ] && { [ "${cnt}" -gt "0" ] || [ "${src_name%_*}" = "blacklist" ] || [ "${src_name%_*}" = "whitelist" ]; }; then + if [ "${src_name##*_}" = "4" ]; then ipt_cmd="${ban_ipt4_cmd}" - if [ ! -f "${ban_tmpfile}.${src_name##*_}.chains" ] - then - > "${ban_tmpfile}.${src_name##*_}.chains" + if [ ! -f "${ban_tmpfile}.${src_name##*_}.chains" ]; then + : >"${ban_tmpfile}.${src_name##*_}.chains" chainsets="${ban_lan_inputchains_4} ${ban_wan_inputchains_4} ${ban_lan_forwardchains_4} ${ban_wan_forwardchains_4}" - for chain in ${chainsets} - do + for chain in ${chainsets}; do f_iptrule "-I" "${chain}" "-j ${ban_chain}" done f_iptrule "-A" "${ban_chain}" "-p udp --dport 67:68 --sport 67:68 -j RETURN" f_iptrule "-A" "${ban_chain}" "-m conntrack ! --ctstate NEW -j RETURN" fi - elif [ "${src_name##*_}" = "6" ] - then + elif [ "${src_name##*_}" = "6" ]; then ipt_cmd="${ban_ipt6_cmd}" - if [ ! -f "${ban_tmpfile}.${src_name##*_}.chains" ] - then - > "${ban_tmpfile}.${src_name##*_}.chains" + if [ ! -f "${ban_tmpfile}.${src_name##*_}.chains" ]; then + : >"${ban_tmpfile}.${src_name##*_}.chains" chainsets="${ban_lan_inputchains_6} ${ban_wan_inputchains_6} ${ban_lan_forwardchains_6} ${ban_wan_forwardchains_6}" - for chain in ${chainsets} - do + for chain in ${chainsets}; do f_iptrule "-I" "${chain}" "-j ${ban_chain}" done f_iptrule "-A" "${ban_chain}" "-p ipv6-icmp -s fe80::/10 -d fe80::/10 -j RETURN" @@ -611,18 +507,13 @@ f_iptables() f_iptrule "-A" "${ban_chain}" "-m conntrack ! --ctstate NEW -j RETURN" fi fi - if [ "${src_settype}" != "dst" ] - then - for dev in ${ban_devs} - do - if [ "${src_name}" = "maclist" ] - then + if [ "${src_settype}" != "dst" ]; then + for dev in ${ban_devs}; do + if [ "${src_name}" = "maclist" ]; then f_iptrule "-I" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} src -j RETURN" "1" - elif [ "${src_name%_*}" = "whitelist" ] - then - pos="$(( $("${ipt_cmd}" "${timeout}" -vnL "${ban_chain}" --line-numbers | grep -cF "RETURN")+1))" - if [ "${ban_whitelistonly}" = "1" ] - then + elif [ "${src_name%_*}" = "whitelist" ]; then + pos="$(($("${ipt_cmd}" "${timeout}" -vnL "${ban_chain}" --line-numbers | grep -cF "RETURN") + 1))" + if [ "${ban_whitelistonly}" = "1" ]; then f_iptrule "-I" "${ban_chain}" "-i ${dev} -m set ! --match-set ${src_name} src -j ${ban_target_src}" "${pos}" else f_iptrule "-I" "${ban_chain}" "-i ${dev} -m set --match-set ${src_name} src -j RETURN" "${pos}" @@ -632,21 +523,16 @@ f_iptables() fi done fi - if [ "${src_settype}" != "src" ] - then - for dev in ${ban_devs} - do - if [ "${src_name%_*}" = "whitelist" ] - then - pos="$(( $("${ipt_cmd}" "${timeout}" -vnL "${ban_chain}" --line-numbers | grep -cF "RETURN")+1))" - if [ "${ban_whitelistonly}" = "1" ] - then + if [ "${src_settype}" != "src" ]; then + for dev in ${ban_devs}; do + if [ "${src_name%_*}" = "whitelist" ]; then + pos="$(($("${ipt_cmd}" "${timeout}" -vnL "${ban_chain}" --line-numbers | grep -cF "RETURN") + 1))" + if [ "${ban_whitelistonly}" = "1" ]; then f_iptrule "-I" "${ban_chain}" "-o ${dev} -m set ! --match-set ${src_name} dst -j ${ban_target_dst}" "${pos}" else f_iptrule "-I" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} dst -j RETURN" "${pos}" fi - elif [ "${src_name}" != "maclist" ] - then + elif [ "${src_name}" != "maclist" ]; then f_iptrule "${action:-"-A"}" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} dst -j ${ban_target_dst}" fi done @@ -658,31 +544,28 @@ f_iptables() # ipset controller # -f_ipset() -{ +f_ipset() { local src src_list action rule ipt_cmd out_rc max="0" cnt="0" cnt_ip="0" cnt_cidr="0" cnt_mac="0" timeout="-w 5" mode="${1}" in_rc="4" case "${mode}" in "backup") - gzip -cf "${tmp_load}" 2>/dev/null > "${ban_backupdir}/banIP.${src_name}.gz" + gzip -cf "${tmp_load}" 2>/dev/null >"${ban_backupdir}/banIP.${src_name}.gz" out_rc="${?}" f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, out_rc: ${out_rc}" return "${out_rc}" - ;; + ;; "restore") - if [ -f "${ban_backupdir}/banIP.${src_name}.gz" ] - then - zcat "${ban_backupdir}/banIP.${src_name}.gz" 2>/dev/null > "${tmp_load}" + if [ -f "${ban_backupdir}/banIP.${src_name}.gz" ]; then + zcat "${ban_backupdir}/banIP.${src_name}.gz" 2>/dev/null >"${tmp_load}" out_rc="${?}" else out_rc="${in_rc}" fi f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, out_rc: ${out_rc}" return "${out_rc}" - ;; + ;; "remove") - if [ -f "${ban_backupdir}/banIP.${src_name}.gz" ] - then + if [ -f "${ban_backupdir}/banIP.${src_name}.gz" ]; then rm -f "${ban_backupdir}/banIP.${src_name}.gz" out_rc="${?}" else @@ -690,46 +573,37 @@ f_ipset() fi f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, out_rc: ${out_rc}" return "${out_rc}" - ;; + ;; "initial") - for proto in "4" "6" - do - if [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ] - then + for proto in "4" "6"; do + if [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ]; then ipt_cmd="${ban_ipt4_cmd}" chainsets="${ban_lan_inputchains_4} ${ban_lan_forwardchains_4} ${ban_wan_inputchains_4} ${ban_wan_forwardchains_4}" - elif [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ] - then + elif [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ]; then ipt_cmd="${ban_ipt6_cmd}" chainsets="${ban_lan_inputchains_6} ${ban_lan_forwardchains_6} ${ban_wan_inputchains_6} ${ban_wan_forwardchains_6}" fi - if { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ]; } || \ - { [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ]; } - then - if [ -z "$("${ipt_cmd}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ] - then + if { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ]; } || + { [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ]; }; then + if [ -z "$("${ipt_cmd}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]; then "${ipt_cmd}" "${timeout}" -N "${ban_chain}" 2>/dev/null out_rc="${?}" f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, chain: ${ban_chain:-"-"}, out_rc: ${out_rc}" else out_rc=0 - for chain in ${chainsets} - do + for chain in ${chainsets}; do f_iptrule "-D" "${chain}" "-j ${ban_chain}" done fi - if [ "${ban_logsrc_enabled}" = "1" ] && [ "${out_rc}" = "0" ] && [ -z "$("${ipt_cmd}" "${timeout}" -nL "${ban_logchain_src}" 2>/dev/null)" ] - then + if [ "${ban_logsrc_enabled}" = "1" ] && [ "${out_rc}" = "0" ] && [ -z "$("${ipt_cmd}" "${timeout}" -nL "${ban_logchain_src}" 2>/dev/null)" ]; then "${ipt_cmd}" "${timeout}" -N "${ban_logchain_src}" 2>/dev/null out_rc="${?}" - if [ "${out_rc}" = "0" ] - then + if [ "${out_rc}" = "0" ]; then "${ipt_cmd}" "${timeout}" -A "${ban_logchain_src}" -j LOG ${ban_logopts_src} --log-prefix "${ban_logprefix_src}" out_rc="${?}" - if [ "${out_rc}" = "0" ] - then + if [ "${out_rc}" = "0" ]; then "${ipt_cmd}" "${timeout}" -A "${ban_logchain_src}" -j "${ban_logtarget_src}" out_rc="${?}" fi @@ -737,16 +611,13 @@ f_ipset() f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, logchain_src: ${ban_logchain_src:-"-"}, out_rc: ${out_rc}" fi - if [ "${ban_logdst_enabled}" = "1" ] && [ "${out_rc}" = "0" ] && [ -z "$("${ipt_cmd}" "${timeout}" -nL "${ban_logchain_dst}" 2>/dev/null)" ] - then + if [ "${ban_logdst_enabled}" = "1" ] && [ "${out_rc}" = "0" ] && [ -z "$("${ipt_cmd}" "${timeout}" -nL "${ban_logchain_dst}" 2>/dev/null)" ]; then "${ipt_cmd}" "${timeout}" -N "${ban_logchain_dst}" 2>/dev/null out_rc="${?}" - if [ "${out_rc}" = "0" ] - then + if [ "${out_rc}" = "0" ]; then "${ipt_cmd}" "${timeout}" -A "${ban_logchain_dst}" -j LOG ${ban_logopts_dst} --log-prefix "${ban_logprefix_dst}" out_rc="${?}" - if [ "${out_rc}" = "0" ] - then + if [ "${out_rc}" = "0" ]; then "${ipt_cmd}" "${timeout}" -A "${ban_logchain_dst}" -j "${ban_logtarget_dst}" out_rc="${?}" fi @@ -758,177 +629,151 @@ f_ipset() out_rc="${out_rc:-"${in_rc}"}" f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, out_rc: ${out_rc}" return "${out_rc}" - ;; + ;; "create") - if [ -z "$("${ban_ipset_cmd}" -q -n list "${src_name}")" ] && \ - { [ -s "${tmp_file}" ] || [ "${src_name%_*}" = "whitelist" ] || [ "${src_name%_*}" = "blacklist" ]; } - then + if [ -z "$("${ban_ipset_cmd}" -q -n list "${src_name}")" ] && + { [ -s "${tmp_file}" ] || [ "${src_name%_*}" = "whitelist" ] || [ "${src_name%_*}" = "blacklist" ]; }; then max="$(awk 'END{print NR}' "${tmp_file}" 2>/dev/null)" - max=$((max+262144)) - if [ "${src_name}" = "maclist" ] - then + max=$((max + 262144)) + if [ "${src_name}" = "maclist" ]; then "${ban_ipset_cmd}" create "${src_name}" hash:mac hashsize 64 maxelem "${max}" counters timeout "${ban_maclist_timeout:-"0"}" out_rc="${?}" - elif [ "${src_name%_*}" = "whitelist" ] - then + elif [ "${src_name%_*}" = "whitelist" ]; then "${ban_ipset_cmd}" create "${src_name}" hash:net hashsize 64 maxelem "${max}" family "${src_ipver}" counters timeout "${ban_whitelist_timeout:-"0"}" out_rc="${?}" - elif [ "${src_name%_*}" = "blacklist" ] - then + elif [ "${src_name%_*}" = "blacklist" ]; then "${ban_ipset_cmd}" create "${src_name}" hash:net hashsize 64 maxelem "${max}" family "${src_ipver}" counters timeout "${ban_blacklist_timeout:-"0"}" out_rc="${?}" else "${ban_ipset_cmd}" create "${src_name}" hash:net hashsize 64 maxelem "${max}" family "${src_ipver}" counters out_rc="${?}" fi - elif [ -n "$("${ban_ipset_cmd}" -q -n list "${src_name}")" ] - then + elif [ -n "$("${ban_ipset_cmd}" -q -n list "${src_name}")" ]; then "${ban_ipset_cmd}" -q flush "${src_name}" out_rc="${?}" fi - if [ -s "${tmp_file}" ] && [ "${out_rc}" = "0" ] - then - "${ban_ipset_cmd}" -q -! restore < "${tmp_file}" + if [ -s "${tmp_file}" ] && [ "${out_rc}" = "0" ]; then + "${ban_ipset_cmd}" -q -! restore <"${tmp_file}" out_rc="${?}" - if [ "${out_rc}" = "0" ] - then + if [ "${out_rc}" = "0" ]; then src_list="$("${ban_ipset_cmd}" -q list "${src_name}")" cnt="$(printf "%s\n" "${src_list}" | awk '/^Number of entries:/{print $4}')" cnt_mac="$(printf "%s\n" "${src_list}" | grep -cE "^(([0-9A-Z][0-9A-Z]:){5}[0-9A-Z]{2} )")" cnt_cidr="$(printf "%s\n" "${src_list}" | grep -cE "(/[0-9]{1,3} )")" - cnt_ip=$((cnt-cnt_cidr-cnt_mac)) - printf "%s\n" "${cnt}" > "${tmp_cnt}" + cnt_ip=$((cnt - cnt_cidr - cnt_mac)) + printf "%s\n" "${cnt}" >"${tmp_cnt}" fi fi f_iptables end_ts="$(date +%s)" out_rc="${out_rc:-"${in_rc}"}" - f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, ipver: ${src_ipver:-"-"}, settype: ${src_settype:-"-"}, count(sum/ip/cidr/mac): ${cnt}/${cnt_ip}/${cnt_cidr}/${cnt_mac}, time: $((end_ts-start_ts)), out_rc: ${out_rc}" + f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, ipver: ${src_ipver:-"-"}, settype: ${src_settype:-"-"}, count(sum/ip/cidr/mac): ${cnt}/${cnt_ip}/${cnt_cidr}/${cnt_mac}, time: $((end_ts - start_ts)), out_rc: ${out_rc}" return "${out_rc}" - ;; + ;; "refresh") - if [ -n "$("${ban_ipset_cmd}" -q -n list "${src_name}")" ] - then + if [ -n "$("${ban_ipset_cmd}" -q -n list "${src_name}")" ]; then out_rc=0 src_list="$("${ban_ipset_cmd}" -q list "${src_name}")" cnt="$(printf "%s\n" "${src_list}" | awk '/^Number of entries:/{print $4}')" cnt_mac="$(printf "%s\n" "${src_list}" | grep -cE "^(([0-9A-Z][0-9A-Z]:){5}[0-9A-Z]{2} )")" cnt_cidr="$(printf "%s\n" "${src_list}" | grep -cE "(/[0-9]{1,3} )")" - cnt_ip=$((cnt-cnt_cidr-cnt_mac)) - printf "%s\n" "${cnt}" > "${tmp_cnt}" + cnt_ip=$((cnt - cnt_cidr - cnt_mac)) + printf "%s\n" "${cnt}" >"${tmp_cnt}" f_iptables fi end_ts="$(date +%s)" out_rc="${out_rc:-"${in_rc}"}" - f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, count(sum/ip/cidr/mac): ${cnt}/${cnt_ip}/${cnt_cidr}/${cnt_mac}, time: $((end_ts-start_ts)), out_rc: ${out_rc}" + f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, count(sum/ip/cidr/mac): ${cnt}/${cnt_ip}/${cnt_cidr}/${cnt_mac}, time: $((end_ts - start_ts)), out_rc: ${out_rc}" return "${out_rc}" - ;; + ;; "suspend") - for src in ${ban_sources} ${ban_localsources} - do - if [ "${src}" = "maclist" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${src}")" ] - then + for src in ${ban_sources} ${ban_localsources}; do + if [ "${src}" = "maclist" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${src}")" ]; then tmp_file="${ban_backupdir}/${src}.file" - "${ban_ipset_cmd}" -q save "${src}" | tail -n +2 > "${tmp_file}" + "${ban_ipset_cmd}" -q save "${src}" | tail -n +2 >"${tmp_file}" "${ban_ipset_cmd}" -q flush "${src}" else - for proto in "4" "6" - do - if [ -n "$("${ban_ipset_cmd}" -q -n list "${src}_${proto}")" ] - then + for proto in "4" "6"; do + if [ -n "$("${ban_ipset_cmd}" -q -n list "${src}_${proto}")" ]; then tmp_file="${ban_backupdir}/${src}_${proto}.file" - "${ban_ipset_cmd}" -q save "${src}_${proto}" | tail -n +2 > "${tmp_file}" + "${ban_ipset_cmd}" -q save "${src}_${proto}" | tail -n +2 >"${tmp_file}" "${ban_ipset_cmd}" -q flush "${src}_${proto}" fi done fi done f_log "debug" "f_ipset ::: name: ${src:-"-"}, mode: ${mode:-"-"}" - ;; + ;; "resume") - if [ -f "${ban_backupdir}/${src_name}.file" ] - then - "${ban_ipset_cmd}" -q -! restore < "${ban_backupdir}/${src_name}.file" + if [ -f "${ban_backupdir}/${src_name}.file" ]; then + "${ban_ipset_cmd}" -q -! restore <"${ban_backupdir}/${src_name}.file" out_rc="${?}" - if [ "${out_rc}" = "0" ] - then + if [ "${out_rc}" = "0" ]; then rm -f "${ban_backupdir}/${src_name}.file" src_list="$("${ban_ipset_cmd}" -q list "${src_name}")" cnt="$(printf "%s\n" "${src_list}" | awk '/^Number of entries:/{print $4}')" cnt_mac="$(printf "%s\n" "${src_list}" | grep -cE "^(([0-9A-Z][0-9A-Z]:){5}[0-9A-Z]{2} )")" cnt_cidr="$(printf "%s\n" "${src_list}" | grep -cE "(/[0-9]{1,3} )")" - cnt_ip=$((cnt-cnt_cidr-cnt_mac)) - printf "%s\n" "${cnt}" > "${tmp_cnt}" + cnt_ip=$((cnt - cnt_cidr - cnt_mac)) + printf "%s\n" "${cnt}" >"${tmp_cnt}" fi f_iptables fi end_ts="$(date +%s)" out_rc="${out_rc:-"${in_rc}"}" - f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, ipver: ${src_ipver:-"-"}, settype: ${src_settype:-"-"}, count(sum/ip/cidr/mac): ${cnt}/${cnt_ip}/${cnt_cidr}/${cnt_mac}, time: $((end_ts-start_ts)), out_rc: ${out_rc}" + f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, ipver: ${src_ipver:-"-"}, settype: ${src_settype:-"-"}, count(sum/ip/cidr/mac): ${cnt}/${cnt_ip}/${cnt_cidr}/${cnt_mac}, time: $((end_ts - start_ts)), out_rc: ${out_rc}" return "${out_rc}" - ;; + ;; "flush") - if [ -n "$("${ban_ipset_cmd}" -q -n list "${src_name}")" ] - then + if [ -n "$("${ban_ipset_cmd}" -q -n list "${src_name}")" ]; then f_iptables "destroy" out_rc=0 fi out_rc="${out_rc:-"${in_rc}"}" f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, out_rc: ${out_rc}" return "${out_rc}" - ;; + ;; "destroy") - for chain in ${ban_chain} ${ban_logchain_src} ${ban_logchain_dst} - do - if [ -n "$("${ban_ipt4_cmd}" "${timeout}" -nL "${chain}" 2>/dev/null)" ] - then + for chain in ${ban_chain} ${ban_logchain_src} ${ban_logchain_dst}; do + if [ -n "$("${ban_ipt4_cmd}" "${timeout}" -nL "${chain}" 2>/dev/null)" ]; then "${ban_ipt4_savecmd}" | grep -v -- "-j ${chain}" | "${ban_ipt4_restorecmd}" "${ban_ipt4_cmd}" "${timeout}" -F "${chain}" 2>/dev/null "${ban_ipt4_cmd}" "${timeout}" -X "${chain}" 2>/dev/null fi - if [ -n "$("${ban_ipt6_cmd}" "${timeout}" -nL "${chain}" 2>/dev/null)" ] - then + if [ -n "$("${ban_ipt6_cmd}" "${timeout}" -nL "${chain}" 2>/dev/null)" ]; then "${ban_ipt6_savecmd}" | grep -v -- "-j ${chain}" | "${ban_ipt6_restorecmd}" "${ban_ipt6_cmd}" "${timeout}" -F "${chain}" 2>/dev/null "${ban_ipt6_cmd}" "${timeout}" -X "${chain}" 2>/dev/null fi done - for src in ${ban_sources} maclist blacklist whitelist - do - if [ "${src}" = "maclist" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${src}")" ] - then + for src in ${ban_sources} maclist blacklist whitelist; do + if [ "${src}" = "maclist" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${src}")" ]; then "${ban_ipset_cmd}" -q destroy "${src}" else - for proto in "4" "6" - do - if [ -n "$("${ban_ipset_cmd}" -q -n list "${src}_${proto}")" ] - then + for proto in "4" "6"; do + if [ -n "$("${ban_ipset_cmd}" -q -n list "${src}_${proto}")" ]; then "${ban_ipset_cmd}" -q destroy "${src}_${proto}" fi done fi done f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}" - ;; + ;; esac } # write to syslog # -f_log() -{ +f_log() { local class="${1}" log_msg="${2}" - if [ -n "${log_msg}" ] && { [ "${class}" != "debug" ] || [ "${ban_debug}" = "1" ]; } - then - if [ -x "${ban_logger_cmd}" ] - then + if [ -n "${log_msg}" ] && { [ "${class}" != "debug" ] || [ "${ban_debug}" = "1" ]; }; then + if [ -x "${ban_logger_cmd}" ]; then "${ban_logger_cmd}" -p "${class}" -t "banIP-${ban_ver%-*}[${$}]" "${log_msg}" else printf "%s %s %s\n" "${class}" "banIP-${ban_ver%-*}[${$}]" "${log_msg}" fi - if [ "${class}" = "err" ] - then + if [ "${class}" = "err" ]; then f_jsnup "error" f_ipset "destroy" f_rmbckp @@ -940,50 +785,41 @@ f_log() # kill all relevant background processes # -f_pidx() -{ +f_pidx() { local pids ppid="${1}" pids="$(pgrep -P "${ppid}" 2>/dev/null | awk '{ORS=" ";print $0}')" kill -HUP "${ppid}" "${pids}" 2>/dev/null - > "${ban_bgpidfile}" + : >"${ban_bgpidfile}" } # start log service to trace failed ssh/luci logins # -f_bgsrv() -{ +f_bgsrv() { local bg_pid action="${1}" bg_pid="$(cat "${ban_bgpidfile}" 2>/dev/null)" - if [ "${action}" = "start" ] && [ -x "${ban_logservice}" ] && [ "${ban_monitor_enabled}" = "1" ] && [ "${ban_whitelistonly}" = "0" ] - then - if [ -n "${bg_pid}" ] - then + if [ "${action}" = "start" ] && [ -x "${ban_logservice}" ] && [ "${ban_monitor_enabled}" = "1" ] && [ "${ban_whitelistonly}" = "0" ]; then + if [ -n "${bg_pid}" ]; then f_pidx "${bg_pid}" fi - if [ -n "$(printf "%s\n" "${ban_logterms}" | grep -F "dropbear")" ] - then + if printf "%s\n" "${ban_logterms}" | grep -q "dropbear"; then ban_search="Exit before auth from|" fi - if [ -n "$(printf "%s\n" "${ban_logterms}" | grep -F "sshd")" ] - then + if printf "%s\n" "${ban_logterms}" | grep -q "sshd"; then ban_search="${ban_search}error: maximum authentication attempts exceeded|sshd.*Connection closed by.*\[preauth\]|" fi - if [ -n "$(printf "%s\n" "${ban_logterms}" | grep -F "luci")" ] - then + if printf "%s\n" "${ban_logterms}" | grep -q "luci"; then ban_search="${ban_search}luci: failed login|" fi - if [ -n "$(printf "%s\n" "${ban_logterms}" | grep -F "nginx")" ] - then + if printf "%s\n" "${ban_logterms}" | grep -q "nginx"; then ban_search="${ban_search}nginx\[[0-9]+\]:.*\[error\].*open().*client: [[:alnum:].:]+|" fi ( - "${ban_logservice}" "${ban_ver}" "${ban_search%?}" & - printf "%s" "${!}" > "${ban_bgpidfile}" + "${ban_logservice}" "${ban_search%?}" & + printf "%s" "${!}" >"${ban_bgpidfile}" ) - elif { [ "${action}" = "stop" ] || [ "${ban_monitor_enabled}" = "0" ]; } && [ -n "${bg_pid}" ] - then + elif { [ "${action}" = "stop" ] || [ "${ban_monitor_enabled}" = "0" ]; } && [ -n "${bg_pid}" ]; then f_pidx "${bg_pid}" fi f_log "debug" "f_bgsrv ::: action: ${action:-"-"}, bg_pid (old/new): ${bg_pid}/$(cat "${ban_bgpidfile}" 2>/dev/null), monitor_enabled: ${ban_monitor_enabled:-"-"}, log_service: ${ban_logservice:-"-"}" @@ -991,20 +827,16 @@ f_bgsrv() # download controller # -f_down() -{ +f_down() { local src_name="${1}" proto="${2}" src_ipver="${3}" src_url="${4}" src_rule="${5}" src_comp="${6}" local ip start_ts end_ts src_settype src_log src_rc tmp_load tmp_file tmp_raw tmp_cnt tmp_err start_ts="$(date +%s)" - if [ -n "$(printf "%s\n" "${ban_settype_src}" | grep -F "${src_name}")" ] - then + if printf "%s\n" "${ban_settype_src}" | grep -q "${src_name}"; then src_settype="src" - elif [ -n "$(printf "%s\n" "${ban_settype_dst}" | grep -F "${src_name}")" ] - then + elif printf "%s\n" "${ban_settype_dst}" | grep -q "${src_name}"; then src_settype="dst" - elif [ -n "$(printf "%s\n" "${ban_settype_all}" | grep -F "${src_name}")" ] - then + elif printf "%s\n" "${ban_settype_all}" | grep -q "${src_name}"; then src_settype="src+dst" else src_settype="${ban_global_settype}" @@ -1018,16 +850,13 @@ f_down() # 'resume' mode # - if [ "${ban_action}" = "resume" ] - then - if [ "${src_name%_*}" = "maclist" ] - then + if [ "${ban_action}" = "resume" ]; then + if [ "${src_name%_*}" = "maclist" ]; then src_name="maclist" fi f_ipset "resume" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then + if [ "${src_rc}" = "0" ]; then return fi fi @@ -1035,23 +864,20 @@ f_down() # handle local downloads # case "${src_name%_*}" in - "blacklist"|"whitelist") - printf "%s\n" "0" > "${tmp_cnt}" - awk "${src_rule}" "${src_url}" > "${tmp_file}" + "blacklist" | "whitelist") + printf "%s\n" "0" >"${tmp_cnt}" + awk "${src_rule}" "${src_url}" >"${tmp_file}" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then + if [ "${src_rc}" = "0" ]; then f_ipset "create" - if [ ! -f "${tmp_dns}" ] && { { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ]; } || \ - { [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ] && [ "${ban_proto4_enabled}" = "0" ]; }; } - then + if [ ! -f "${tmp_dns}" ] && { { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ]; } || + { [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ] && [ "${ban_proto4_enabled}" = "0" ]; }; }; then tmp_dns="${ban_tmpbase}/${src_name%_*}.dns" src_rule="/^([[:alnum:]_-]{1,63}\\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}" - awk "${src_rule}" "${src_url}" > "${tmp_dns}" + awk "${src_rule}" "${src_url}" >"${tmp_dns}" src_rc="${?}" - if [ "${src_rc}" = "0" ] && [ -s "${tmp_dns}" ] - then - ( "${ban_dnsservice}" "${ban_ver}" "${ban_action}" "${src_name%_*}" "${tmp_dns}" & ) + if [ "${src_rc}" = "0" ] && [ -s "${tmp_dns}" ]; then + ("${ban_dnsservice}" "${ban_action}" "${src_name%_*}" "${tmp_dns}" &) else rm -f "${tmp_dns}" fi @@ -1060,53 +886,46 @@ f_down() f_log "debug" "f_down ::: name: ${src_name}, url: ${src_url}, rule: ${src_rule}, rc: ${src_rc}" fi return - ;; + ;; "maclist") src_name="${src_name%_*}" tmp_file="${ban_tmpfile}.${src_name}.file" tmp_cnt="${tmp_file}.cnt" tmp_err="${tmp_file}.err" - awk "${src_rule}" "${src_url}" > "${tmp_file}" + awk "${src_rule}" "${src_url}" >"${tmp_file}" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then + if [ "${src_rc}" = "0" ]; then f_ipset "create" else f_log "debug" "f_down ::: name: ${src_name}, url: ${src_url}, rule: ${src_rule}, rc: ${src_rc}" fi return - ;; + ;; esac # 'refresh' mode # - if [ "${ban_action}" = "refresh" ] - then + if [ "${ban_action}" = "refresh" ]; then f_ipset "refresh" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then + if [ "${src_rc}" = "0" ]; then return fi fi # 'start' mode # - if [ "${ban_action}" = "start" ] - then + if [ "${ban_action}" = "start" ]; then f_ipset "restore" fi src_rc="${?}" - if [ "${src_rc}" = "0" ] - then - awk "${src_rule}" "${tmp_load}" 2>/dev/null > "${tmp_file}" + if [ "${src_rc}" = "0" ]; then + awk "${src_rule}" "${tmp_load}" 2>/dev/null >"${tmp_file}" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then + if [ "${src_rc}" = "0" ]; then f_ipset "create" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then + if [ "${src_rc}" = "0" ]; then return fi fi @@ -1114,15 +933,12 @@ f_down() # handle country related downloads # - if [ "${src_name%_*}" = "country" ] - then - for country in ${ban_countries} - do + if [ "${src_name%_*}" = "country" ]; then + for country in ${ban_countries}; do src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}${country}-aggregated.zone" 2>&1)" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then - cat "${tmp_raw}" 2>/dev/null >> "${tmp_load}" + if [ "${src_rc}" = "0" ]; then + cat "${tmp_raw}" 2>/dev/null >>"${tmp_load}" else continue fi @@ -1130,15 +946,12 @@ f_down() # handle asn related downloads # - elif [ "${src_name%_*}" = "asn" ] - then - for asn in ${ban_asns} - do + elif [ "${src_name%_*}" = "asn" ]; then + for asn in ${ban_asns}; do src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}AS${asn}" 2>&1)" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then - cat "${tmp_raw}" 2>/dev/null >> "${tmp_load}" + if [ "${src_rc}" = "0" ]; then + cat "${tmp_raw}" 2>/dev/null >>"${tmp_load}" else continue fi @@ -1146,18 +959,16 @@ f_down() # handle compressed downloads # - elif [ -n "${src_comp}" ] - then + elif [ -n "${src_comp}" ]; then case "${src_comp}" in "gz") src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}" 2>&1)" src_rc="${?}" - if [ "${src_rc}" -eq 0 ] - then - zcat "${tmp_raw}" 2>/dev/null > "${tmp_load}" + if [ "${src_rc}" -eq 0 ]; then + zcat "${tmp_raw}" 2>/dev/null >"${tmp_load}" src_rc="${?}" fi - ;; + ;; esac # handle normal downloads @@ -1167,34 +978,28 @@ f_down() src_rc="${?}" fi - # download post-processing (backup, restore, regex) + # download post-processing # - if [ "${src_rc}" = "0" ] - then + if [ "${src_rc}" = "0" ]; then f_ipset "backup" src_rc="${?}" - elif [ "${ban_action}" != "start" ] && [ "${ban_action}" != "refresh" ] - then + elif [ "${ban_action}" != "start" ] && [ "${ban_action}" != "refresh" ]; then f_ipset "restore" src_rc="${?}" fi - if [ "${src_rc}" = "0" ] - then - awk "${src_rule}" "${tmp_load}" 2>/dev/null > "${tmp_file}" + if [ "${src_rc}" = "0" ]; then + awk "${src_rule}" "${tmp_load}" 2>/dev/null >"${tmp_file}" src_rc="${?}" - if [ "${src_rc}" = "0" ] - then + if [ "${src_rc}" = "0" ]; then f_ipset "create" src_rc="${?}" - elif [ "${ban_action}" != "refresh" ] - then + elif [ "${ban_action}" != "refresh" ]; then f_ipset "refresh" src_rc="${?}" fi else src_log="$(printf "%s" "${src_log}" | awk '{ORS=" ";print $0}')" - if [ "${ban_action}" != "refresh" ] - then + if [ "${ban_action}" != "refresh" ]; then f_ipset "refresh" src_rc="${?}" fi @@ -1204,63 +1009,49 @@ f_down() # main controller # -f_main() -{ +f_main() { local src_name src_url_4 src_rule_4 src_url_6 src_rule_6 src_comp src_rc src_ts log_raw log_merge log_ips log_count hold err_file cnt_file cnt=0 - # prepare logfile excerpts (dropbear, sshd, luci) + # prepare logfile excerpts # - if [ "${ban_autoblacklist}" = "1" ] || [ "${ban_monitor_enabled}" = "1" ] - then + if [ "${ban_autoblacklist}" = "1" ] || [ "${ban_monitor_enabled}" = "1" ]; then log_raw="$(${ban_logread_cmd} -l "${ban_loglimit}")" - if [ -n "$(printf "%s\n" "${ban_logterms}" | grep -F "dropbear")" ] - then - log_ips="$(printf "%s\n" "${log_raw}" | grep -E "Exit before auth from" | \ - awk 'match($0,/<[0-9A-f:\.]+:/){printf "%s\n",substr($0,RSTART+1,RLENGTH-2)}' | awk '!seen[$NF]++' | awk '{ORS=" ";print $NF}')" - for ip in ${log_ips} - do + if printf "%s\n" "${ban_logterms}" | grep -q "dropbear"; then + log_ips="$(printf "%s\n" "${log_raw}" | grep -E "Exit before auth from" | + awk 'match($0,/<[0-9A-f:\.]+:/){printf "%s\n",substr($0,RSTART+1,RLENGTH-2)}' | awk '!seen[$NF]++' | awk '{ORS=" ";print $NF}')" + for ip in ${log_ips}; do log_count="$(printf "%s\n" "${log_raw}" | grep -cE "Exit before auth from <${ip}")" - if [ "${log_count}" -ge "${ban_ssh_logcount}" ] - then + if [ "${log_count}" -ge "${ban_ssh_logcount}" ]; then log_merge="${log_merge} ${ip}" fi done fi - if [ -n "$(printf "%s\n" "${ban_logterms}" | grep -F "sshd")" ] - then - log_ips="$(printf "%s\n" "${log_raw}" | grep -E "error: maximum authentication attempts exceeded|sshd.*Connection closed by.*\[preauth\]" | \ - awk 'match($0,/[0-9A-f:\.]+ port/){printf "%s\n",substr($0,RSTART,RLENGTH-5)}' | awk '!seen[$NF]++' | awk '{ORS=" ";print $NF}')" - for ip in ${log_ips} - do + if printf "%s\n" "${ban_logterms}" | grep -q "sshd"; then + log_ips="$(printf "%s\n" "${log_raw}" | grep -E "error: maximum authentication attempts exceeded|sshd.*Connection closed by.*\[preauth\]" | + awk 'match($0,/[0-9A-f:\.]+ port/){printf "%s\n",substr($0,RSTART,RLENGTH-5)}' | awk '!seen[$NF]++' | awk '{ORS=" ";print $NF}')" + for ip in ${log_ips}; do log_count="$(printf "%s\n" "${log_raw}" | grep -cE "error: maximum authentication attempts exceeded.*${ip}|sshd.*Connection closed by.*${ip}.*\[preauth\]")" - if [ "${log_count}" -ge "${ban_ssh_logcount}" ] - then + if [ "${log_count}" -ge "${ban_ssh_logcount}" ]; then log_merge="${log_merge} ${ip}" fi done fi - if [ -n "$(printf "%s\n" "${ban_logterms}" | grep -F "luci")" ] - then - log_ips="$(printf "%s\n" "${log_raw}" | grep -E "luci: failed login on " | \ - awk 'match($0,/[0-9A-f:\.]+$/){printf "%s\n",substr($0,RSTART,RLENGTH)}' | awk '!seen[$NF]++' | awk '{ORS=" ";print $NF}')" - for ip in ${log_ips} - do + if printf "%s\n" "${ban_logterms}" | grep -q "luci"; then + log_ips="$(printf "%s\n" "${log_raw}" | grep -E "luci: failed login on " | + awk 'match($0,/[0-9A-f:\.]+$/){printf "%s\n",substr($0,RSTART,RLENGTH)}' | awk '!seen[$NF]++' | awk '{ORS=" ";print $NF}')" + for ip in ${log_ips}; do log_count="$(printf "%s\n" "${log_raw}" | grep -cE "luci: failed login on .*from ${ip}")" - if [ "${log_count}" -ge "${ban_luci_logcount}" ] - then + if [ "${log_count}" -ge "${ban_luci_logcount}" ]; then log_merge="${log_merge} ${ip}" fi done fi - if [ -n "$(printf "%s\n" "${ban_logterms}" | grep -F "nginx")" ] - then - log_ips="$(printf "%s\n" "${log_raw}" | grep -oE "nginx(\[[0-9]+\])?:.*\[error\].*open\(\).*client: [[:alnum:].:]+" | \ - awk '!seen[$NF]++' | awk '{ORS=" ";print $NF}')" - for ip in ${log_ips} - do + if printf "%s\n" "${ban_logterms}" | grep -q "nginx"; then + log_ips="$(printf "%s\n" "${log_raw}" | grep -oE "nginx(\[[0-9]+\])?:.*\[error\].*open\(\).*client: [[:alnum:].:]+" | + awk '!seen[$NF]++' | awk '{ORS=" ";print $NF}')" + for ip in ${log_ips}; do log_count="$(printf "%s\n" "${log_raw}" | grep -cE "nginx(\[[0-9]+\])?:.*\[error\].*open\(\).*client: ${ip}")" - if [ "${log_count}" -ge "${ban_nginx_logcount}" ] - then + if [ "${log_count}" -ge "${ban_nginx_logcount}" ]; then log_merge="${log_merge} ${ip}" fi done @@ -1269,26 +1060,20 @@ f_main() # prepare new black- and whitelist entries # - if [ "${ban_autowhitelist}" = "1" ] && [ -f "${ban_whitelist}" ] - then - for ip in ${ban_subnets} - do - if [ -z "$(grep -F "${ip}" "${ban_whitelist}")" ] - then + if [ "${ban_autowhitelist}" = "1" ] && [ -f "${ban_whitelist}" ]; then + for ip in ${ban_subnets}; do + if ! grep -q "${ip}" "${ban_whitelist}"; then src_ts="# added on $(date "+%d.%m.%Y %H:%M:%S")" - printf "%-42s%s\n" "${ip}" "${src_ts}" >> "${ban_whitelist}" + printf "%-42s%s\n" "${ip}" "${src_ts}" >>"${ban_whitelist}" f_log "info" "IP address '${ip}' added to whitelist" fi done fi - if [ "${ban_autoblacklist}" = "1" ] && [ -f "${ban_blacklist}" ] - then - for ip in ${log_merge} - do - if [ -z "$(grep -F "${ip}" "${ban_blacklist}")" ] - then + if [ "${ban_autoblacklist}" = "1" ] && [ -f "${ban_blacklist}" ]; then + for ip in ${log_merge}; do + if ! grep -q "${ip}" "${ban_blacklist}"; then src_ts="# added on $(date "+%d.%m.%Y %H:%M:%S")" - printf "%-42s%s\n" "${ip}" "${src_ts}" >> "${ban_blacklist}" + printf "%-42s%s\n" "${ip}" "${src_ts}" >>"${ban_blacklist}" f_log "info" "IP address '${ip}' added to blacklist" fi done @@ -1296,124 +1081,104 @@ f_main() # initial ipset/iptables creation # - f_ipset "initial" - if [ "${?}" != "0" ] - then + if ! f_ipset "initial"; then f_log "err" "banIP processing failed, fatal error during ipset/iptables creation (${ban_sysver})" fi # load local source files (maclist, blacklist, whitelist) # - for src_name in ${ban_localsources} - do - if [ "${src_name}" = "maclist" ] && [ -s "${ban_maclist}" ] - then + for src_name in ${ban_localsources}; do + if [ "${src_name}" = "maclist" ] && [ -s "${ban_maclist}" ]; then ( src_rule_4="/^([0-9A-z][0-9A-z]:){5}[0-9A-z]{2}([[:space:]]|$)/{print \"add ${src_name} \"toupper(\$1)}" f_down "${src_name}" "mac" "mac" "${ban_maclist}" "${src_rule_4}" - )& + ) & fi - if [ "${ban_proto4_enabled}" = "1" ] - then - if [ "${src_name}" = "blacklist" ] && [ -s "${ban_blacklist}" ] && [ "${ban_whitelistonly}" = "0" ] - then + if [ "${ban_proto4_enabled}" = "1" ]; then + if [ "${src_name}" = "blacklist" ] && [ -s "${ban_blacklist}" ] && [ "${ban_whitelistonly}" = "0" ]; then ( src_rule_4="/^(([0-9]{1,3}\\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]|$)/{print \"add ${src_name}_4 \"\$1}" f_down "${src_name}" "4" "inet" "${ban_blacklist}" "${src_rule_4}" - )& - elif [ "${src_name}" = "whitelist" ] && [ -s "${ban_whitelist}" ] - then + ) & + elif [ "${src_name}" = "whitelist" ] && [ -s "${ban_whitelist}" ]; then ( src_rule_4="/^(([0-9]{1,3}\\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]|$)/{print \"add ${src_name}_4 \"\$1}" f_down "${src_name}" "4" "inet" "${ban_whitelist}" "${src_rule_4}" - )& + ) & fi else ( src_name="${src_name}_4" f_ipset "flush" - )& + ) & fi - if [ "${ban_proto6_enabled}" = "1" ] - then - if [ "${src_name}" = "blacklist" ] && [ -s "${ban_blacklist}" ] && [ "${ban_whitelistonly}" = "0" ] - then + if [ "${ban_proto6_enabled}" = "1" ]; then + if [ "${src_name}" = "blacklist" ] && [ -s "${ban_blacklist}" ] && [ "${ban_whitelistonly}" = "0" ]; then ( src_rule_6="/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{print \"add ${src_name}_6 \"\$1}" f_down "${src_name}" "6" "inet6" "${ban_blacklist}" "${src_rule_6}" - )& - elif [ "${src_name}" = "whitelist" ] && [ -s "${ban_whitelist}" ] - then + ) & + elif [ "${src_name}" = "whitelist" ] && [ -s "${ban_whitelist}" ]; then ( src_rule_6="/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{print \"add ${src_name}_6 \"\$1}" f_down "${src_name}" "6" "inet6" "${ban_whitelist}" "${src_rule_6}" - )& + ) & fi else ( src_name="${src_name}_6" f_ipset "flush" - )& + ) & fi done wait # loop over all external sources # - if [ "${ban_whitelistonly}" = "0" ] - then - for src_name in ${ban_sources} - do + if [ "${ban_whitelistonly}" = "0" ]; then + for src_name in ${ban_sources}; do # get source data from JSON file # - json_select "${src_name}" >/dev/null 2>&1 - if [ "${?}" != "0" ] - then + if ! json_select "${src_name}" >/dev/null 2>&1; then continue fi json_objects="url_4 rule_4 url_6 rule_6 comp" - for object in ${json_objects} - do - eval json_get_var src_${object} "\${object}" >/dev/null 2>&1 + for object in ${json_objects}; do + eval json_get_var src_${object} '${object}' >/dev/null 2>&1 done json_select .. # handle external IPv4 source downloads in a subshell # - if [ "${ban_proto4_enabled}" = "1" ] && [ -n "${src_url_4}" ] && [ -n "${src_rule_4}" ] - then + if [ "${ban_proto4_enabled}" = "1" ] && [ -n "${src_url_4}" ] && [ -n "${src_rule_4}" ]; then ( f_down "${src_name}" "4" "inet" "${src_url_4}" "${src_rule_4}" "${src_comp}" - )& + ) & fi # handle external IPv6 source downloads in a subshell # - if [ "${ban_proto6_enabled}" = "1" ] && [ -n "${src_url_6}" ] && [ -n "${src_rule_6}" ] - then + if [ "${ban_proto6_enabled}" = "1" ] && [ -n "${src_url_6}" ] && [ -n "${src_rule_6}" ]; then ( f_down "${src_name}" "6" "inet6" "${src_url_6}" "${src_rule_6}" "${src_comp}" - )& + ) & fi # control/limit download queues # - hold=$((cnt%ban_maxqueue)) - if [ "${hold}" = "0" ] - then + hold=$((cnt % ban_maxqueue)) + if [ "${hold}" = "0" ]; then wait fi - cnt=$((cnt+1)) + cnt=$((cnt + 1)) done wait fi # error out # - for err_file in "${ban_tmpfile}."*".err" - do - if [ -f "${err_file}" ] - then + for err_file in "${ban_tmpfile}."*".err"; do + if [ -f "${err_file}" ]; then f_log "err" "banIP processing failed, fatal iptables errors during subshell processing (${ban_sysver})" fi done @@ -1421,34 +1186,27 @@ f_main() # finish processing # ban_sources="" - for cnt_file in "${ban_tmpfile}."*".cnt" - do - if [ -f "${cnt_file}" ] - then - read -r cnt < "${cnt_file}" - ban_cnt=$((ban_cnt+cnt)) - ban_setcnt=$((ban_setcnt+1)) + for cnt_file in "${ban_tmpfile}."*".cnt"; do + if [ -f "${cnt_file}" ]; then + read -r cnt <"${cnt_file}" + ban_cnt=$((ban_cnt + cnt)) + ban_setcnt=$((ban_setcnt + 1)) src_name="$(printf "%s" "${cnt_file}" | grep -Eo "[a-z0-9_]+.file.cnt")" src_name="${src_name%%.*}" - if [ -z "$(printf "%s" "${ban_sources}" | grep -F "${src_name%_*}")" ] - then + if ! printf "%s" "${ban_sources}" | grep -q "${src_name%_*}"; then ban_sources="${ban_sources} ${src_name%_*}" ban_allsources="${ban_allsources//${src_name%_*}/}" fi fi done - for src_name in ${ban_allsources} - do - if [ "${src_name}" = "maclist" ] - then + for src_name in ${ban_allsources}; do + if [ "${src_name}" = "maclist" ]; then f_ipset "flush" else - for proto in "4" "6" - do + for proto in "4" "6"; do src_name="${src_name%_*}_${proto}" f_ipset "flush" - if [ "${src_name%_*}" != "blacklist" ] && [ "${src_name%_*}" != "whitelist" ] - then + if [ "${src_name%_*}" != "blacklist" ] && [ "${src_name%_*}" != "whitelist" ]; then f_ipset "remove" fi done @@ -1462,36 +1220,34 @@ f_main() # query ipsets for certain IP # -f_query() -{ +f_query() { local src proto result query_start query_end query_timeout="30" match="0" search="${1}" - if [ -z "${search}" ] - then + if [ -z "${search}" ]; then printf "%s\n" "::: missing search term, please submit a single ip or mac address :::" else query_start="$(date "+%s")" printf "%s\n%s\n%s\n" ":::" "::: search '${search}' in banIP related IPSets" ":::" - for src in ${ban_localsources} ${ban_sources} ${ban_extrasources} - do - if [ "${src}" = "maclist" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${src}")" ] - then - result="$(ipset -q test ${src} ${search} >/dev/null 2>&1; printf "%u" "${?}")" - if [ "${result}" = "0" ] - then + for src in ${ban_localsources} ${ban_sources} ${ban_extrasources}; do + if [ "${src}" = "maclist" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${src}")" ]; then + result="$( + ipset -q test ${src} ${search} >/dev/null 2>&1 + printf "%u" "${?}" + )" + if [ "${result}" = "0" ]; then match="1" printf "%s\n" " - found in IPSet '${src}'" break fi else - for proto in "4" "6" - do - if [ -n "$("${ban_ipset_cmd}" -q -n list "${src}_${proto}")" ] - then - result="$(ipset -q test ${src}_${proto} ${search} >/dev/null 2>&1; printf "%u" "${?}")" - if [ "${result}" = "0" ] - then + for proto in "4" "6"; do + if [ -n "$("${ban_ipset_cmd}" -q -n list "${src}_${proto}")" ]; then + result="$( + ipset -q test ${src}_${proto} ${search} >/dev/null 2>&1 + printf "%u" "${?}" + )" + if [ "${result}" = "0" ]; then match="1" printf "%s\n" " - found in IPSet '${src}_${proto}'" fi @@ -1499,14 +1255,12 @@ f_query() done fi query_end="$(date "+%s")" - if [ "$((query_end-query_start))" -gt "${query_timeout}" ] - then + if [ "$((query_end - query_start))" -gt "${query_timeout}" ]; then printf "%s\n\n" " - [...]" break fi done - if [ "${match}" = "0" ] - then + if [ "${match}" = "0" ]; then printf "%s\n\n" " - no match" fi fi @@ -1514,190 +1268,184 @@ f_query() # generate statistics # -f_report() -{ - local report_json report_txt bg_pid content proto src src_list cnt cnt_mac cnt_cidr cnt_ip cnt_acc cnt_sum="0" cnt_set_sum="1" cnt_acc_sum="0" cnt_mac_sum="0" cnt_ip_sum="0" cnt_cidr_sum="0" cnt_set_sum="0" action="${1}" +f_report() { + local report_json report_txt bg_pid content proto src src_list detaillist type jsnval jsnvals jsnval1 jsnval2 jsnval3 jsnval4 jsnval5 jsnval6 jsnval7 + local cnt cnt_mac cnt_cidr cnt_ip cnt_acc cnt_sum="0" cnt_set_sum="1" cnt_acc_sum="0" cnt_mac_sum="0" cnt_ip_sum="0" cnt_cidr_sum="0" cnt_set_sum="0" action="${1}" report_json="${ban_reportdir}/ban_report.json" report_txt="${ban_reportdir}/ban_mailreport.txt" # build json file # - if [ "${action}" != "json" ] && { [ -n "$("${ban_ipt4_savecmd}" | grep " ${ban_chain} ")" ] || [ -n "$("${ban_ipt6_savecmd}" | grep " ${ban_chain} ")" ]; } - then - > "${report_json}" - > "${report_txt}" - printf "%s\n" "{" >> "${report_json}" - printf "\t%s\n" "\"ipsets\": {" >> "${report_json}" - for src in ${ban_localsources} ${ban_sources} ${ban_extrasources} - do - if [ -n "$(printf "%s" "${ban_extrasources}" | grep -F "${src}")" ] - then + if [ "${action}" != "json" ] && { "${ban_ipt4_savecmd}" | grep -q " ${ban_chain} " || "${ban_ipt6_savecmd}" | grep -q " ${ban_chain} "; }; then + : >"${report_json}" + printf "%s\n" "{" >>"${report_json}" + printf "%s\n" '"ipsets": {' >>"${report_json}" + for src in ${ban_localsources} ${ban_sources} ${ban_extrasources}; do + if printf "%s" "${ban_extrasources}" | grep -q "${src}"; then set_type="n/a" else - if [ -n "$(printf "%s\n" "${ban_settype_src}" | grep -F "${src}")" ] - then + if printf "%s\n" "${ban_settype_src}" | grep -q "${src}"; then set_type="src" - elif [ -n "$(printf "%s\n" "${ban_settype_dst}" | grep -F "${src}")" ] - then + elif printf "%s\n" "${ban_settype_dst}" | grep -q "${src}"; then set_type="dst" - elif [ -n "$(printf "%s\n" "${ban_settype_all}" | grep -F "${src}")" ] - then + elif printf "%s\n" "${ban_settype_all}" | grep -q "${src}"; then set_type="src+dst" else set_type="${ban_global_settype}" fi fi - if [ "${src}" = "maclist" ] - then + if [ "${src}" = "maclist" ]; then src_list="$("${ban_ipset_cmd}" -q list "${src}")" - if [ -n "${src_list}" ] - then + if [ -n "${src_list}" ]; then cnt="$(printf "%s" "${src_list}" | awk '/^Number of entries:/{print $4}')" cnt_acc="$(printf "%s" "${src_list}" | grep -cE "packets [1-9]+")" - cnt_acc_sum=$((cnt_acc_sum+cnt_acc)) + cnt_acc_sum=$((cnt_acc_sum + cnt_acc)) cnt_mac_sum="${cnt}" - cnt_sum=$((cnt_sum+cnt)) - if [ "${cnt_set_sum}" != "0" ] - then - printf "%s\n" "," >> "${report_json}" - fi - printf "\t\t%s\n" "\"${src}\": {" >> "${report_json}" - printf "\t\t\t%s\n" "\"type\": \"${set_type}\"," >> "${report_json}" - printf "\t\t\t%s\n" "\"count\": \"${cnt}\"," >> "${report_json}" - printf "\t\t\t%s\n" "\"count_ip\": \"0\"," >> "${report_json}" - printf "\t\t\t%s\n" "\"count_cidr\": \"0\"," >> "${report_json}" - printf "\t\t\t%s\n" "\"count_mac\": \"${cnt}\"," >> "${report_json}" - printf "\t\t\t%s" "\"count_acc\": \"${cnt_acc}\"" >> "${report_json}" - printf ",\n\t\t\t%s" "\"member_acc\": [" >> "${report_json}" - printf "%s" "${src_list}" | awk 'match($0,/ packets [1-9]+/){printf "%s %s\n",$1,substr($0,RSTART+9,RLENGTH-9)}' | \ - awk 'BEGIN{i=0};{i=i+1;if(i==1){printf "\n\t\t\t\t\t{\n\t\t\t\t\t\t\"member\": \"%s\",\n\t\t\t\t\t\t\"packets\": \"%s\"\n\t\t\t\t\t}",$1,$2}else{printf ",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"member\": \"%s\",\n\t\t\t\t\t\t\t\"packets\": \"%s\"\n\t\t\t\t\t\t}",$1,$2}}' >> "${report_json}" - printf "\n\t\t\t%s\n" "]" >> "${report_json}" - printf "\t\t%s" "}" >> "${report_json}" - cnt_set_sum=$((cnt_set_sum+1)) + cnt_sum=$((cnt_sum + cnt)) + { + if [ "${cnt_set_sum}" != "0" ]; then + printf "%s\n" "," + fi + printf "\t%s\n" "\"${src}\": {" + printf "\t\t%s\n" "\"type\": \"${set_type}\"," + printf "\t\t%s\n" "\"count\": \"${cnt}\"," + printf "\t\t%s\n" '"count_ip": "0",' + printf "\t\t%s\n" '"count_cidr": "0",' + printf "\t\t%s\n" "\"count_mac\": \"${cnt}\"," + printf "\t\t%s" "\"count_acc\": \"${cnt_acc}\"" + printf ",\n\t\t%s" '"member_acc": [' + printf "%s" "${src_list}" | awk 'match($0,/ packets [1-9]+/){printf "%s %s\n",$1,substr($0,RSTART+9,RLENGTH-9)}' | + awk 'BEGIN{i=0};{i=i+1;if(i==1){printf "{\n\t\t\t\"member\": \"%s\",\n\t\t\t\"packets\": \"%s\"\n\t\t}",$1,$2} + else{printf ",\n\t\t{\n\t\t\t\"member\": \"%s\",\n\t\t\t\"packets\": \"%s\"\n\t\t}",$1,$2}}' + printf "%s\n" "]" + printf "\t%s" "}" + } >>"${report_json}" + cnt_set_sum=$((cnt_set_sum + 1)) fi else - for proto in "4" "6" - do + for proto in "4" "6"; do src_list="$("${ban_ipset_cmd}" -q list "${src}_${proto}")" - if [ -n "${src_list}" ] - then + if [ -n "${src_list}" ]; then cnt="$(printf "%s\n" "${src_list}" | awk '/^Number of entries:/{print $4}')" cnt_cidr="$(printf "%s\n" "${src_list}" | grep -cE "/[0-9]{1,3} ")" - cnt_ip=$((cnt-cnt_cidr-cnt_mac)) + cnt_ip=$((cnt - cnt_cidr - cnt_mac)) cnt_acc="$(printf "%s\n" "${src_list}" | grep -cE "packets [1-9]+")" - cnt_cidr_sum=$((cnt_cidr_sum+cnt_cidr)) - cnt_ip_sum=$((cnt_ip_sum+cnt_ip)) - cnt_acc_sum=$((cnt_acc_sum+cnt_acc)) - cnt_sum=$((cnt_sum+cnt)) - if [ "${cnt_set_sum}" != "0" ] - then - printf "%s\n" "," >> "${report_json}" - fi - printf "\t\t%s\n" "\"${src}_${proto}\": {" >> "${report_json}" - printf "\t\t\t%s\n" "\"type\": \"${set_type}\"," >> "${report_json}" - printf "\t\t\t%s\n" "\"count\": \"${cnt}\"," >> "${report_json}" - printf "\t\t\t%s\n" "\"count_ip\": \"${cnt_ip}\"," >> "${report_json}" - printf "\t\t\t%s\n" "\"count_cidr\": \"${cnt_cidr}\"," >> "${report_json}" - printf "\t\t\t%s\n" "\"count_mac\": \"0\"," >> "${report_json}" - printf "\t\t\t%s" "\"count_acc\": \"${cnt_acc}\"" >> "${report_json}" - printf ",\n\t\t\t%s" "\"member_acc\": [" >> "${report_json}" - printf "%s" "${src_list}" | awk 'match($0,/ packets [1-9]+/){printf "%s %s\n",$1,substr($0,RSTART+9,RLENGTH-9)}' | \ - awk 'BEGIN{i=0};{i=i+1;if(i==1){printf "\n\t\t\t\t\t{\n\t\t\t\t\t\t\"member\": \"%s\",\n\t\t\t\t\t\t\"packets\": \"%s\"\n\t\t\t\t\t}",$1,$2}else{printf ",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"member\": \"%s\",\n\t\t\t\t\t\t\t\"packets\": \"%s\"\n\t\t\t\t\t\t}",$1,$2}}' >> "${report_json}" - printf "\n\t\t\t%s\n" "]" >> "${report_json}" - printf "\t\t%s" "}" >> "${report_json}" - cnt_set_sum=$((cnt_set_sum+1)) + cnt_cidr_sum=$((cnt_cidr_sum + cnt_cidr)) + cnt_ip_sum=$((cnt_ip_sum + cnt_ip)) + cnt_acc_sum=$((cnt_acc_sum + cnt_acc)) + cnt_sum=$((cnt_sum + cnt)) + { + if [ "${cnt_set_sum}" != "0" ]; then + printf "%s\n" "," + fi + printf "\t%s\n" "\"${src}_${proto}\": {" + printf "\t\t%s\n" "\"type\": \"${set_type}\"," + printf "\t\t%s\n" "\"count\": \"${cnt}\"," + printf "\t\t%s\n" "\"count_ip\": \"${cnt_ip}\"," + printf "\t\t%s\n" "\"count_cidr\": \"${cnt_cidr}\"," + printf "\t\t%s\n" '"count_mac": "0",' + printf "\t\t%s" "\"count_acc\": \"${cnt_acc}\"" + printf ",\n\t\t%s" '"member_acc": [' + printf "%s" "${src_list}" | awk 'match($0,/ packets [1-9]+/){printf "%s %s\n",$1,substr($0,RSTART+9,RLENGTH-9)}' | + awk 'BEGIN{i=0};{i=i+1;if(i==1){printf "{\n\t\t\t\"member\": \"%s\",\n\t\t\t\"packets\": \"%s\"\n\t\t}",$1,$2} + else{printf ",\n\t\t{\n\t\t\t\"member\": \"%s\",\n\t\t\t\"packets\": \"%s\"\n\t\t}",$1,$2}}' + printf "%s\n" "]" + printf "\t%s" "}" + } >>"${report_json}" + cnt_set_sum=$((cnt_set_sum + 1)) fi done fi done - printf "\n\t%s" "}" >> "${report_json}" - printf ",\n\t%s\n" "\"timestamp\": \"$(date "+%d.%m.%Y %H:%M:%S")\"," >> "${report_json}" - printf "\t%s\n" "\"cnt_set_sum\": \"${cnt_set_sum}\"," >> "${report_json}" - printf "\t%s\n" "\"cnt_ip_sum\": \"${cnt_ip_sum}\"," >> "${report_json}" - printf "\t%s\n" "\"cnt_cidr_sum\": \"${cnt_cidr_sum}\"," >> "${report_json}" - printf "\t%s\n" "\"cnt_mac_sum\": \"${cnt_mac_sum}\"," >> "${report_json}" - printf "\t%s\n" "\"cnt_sum\": \"${cnt_sum}\"," >> "${report_json}" - printf "\t%s\n" "\"cnt_acc_sum\": \"${cnt_acc_sum}\"" >> "${report_json}" - printf "%s\n" "}" >> "${report_json}" + { + printf "\n%s" "}" + printf ",\n%s\n" "\"timestamp\": \"$(date "+%d.%m.%Y %H:%M:%S")\"," + printf "%s\n" "\"cnt_set_sum\": \"${cnt_set_sum}\"," + printf "%s\n" "\"cnt_ip_sum\": \"${cnt_ip_sum}\"," + printf "%s\n" "\"cnt_cidr_sum\": \"${cnt_cidr_sum}\"," + printf "%s\n" "\"cnt_mac_sum\": \"${cnt_mac_sum}\"," + printf "%s\n" "\"cnt_sum\": \"${cnt_sum}\"," + printf "%s\n" "\"cnt_acc_sum\": \"${cnt_acc_sum}\"" + printf "%s\n" "}" + } >>"${report_json}" fi # output preparation # - if [ -s "${report_json}" ] && { [ "${action}" = "cli" ] || [ "${action}" = "mail" ]; } - then - printf "%s\n%s\n%s\n" ":::" "::: report on all banIP related IPSets" ":::" >> "${report_txt}" - json_load_file "${report_json}" >/dev/null 2>&1 - json_get_var value "timestamp" >/dev/null 2>&1 - printf " + %s\n" "Report timestamp ::: ${value}" >> "${report_txt}" - json_get_var value "cnt_set_sum" >/dev/null 2>&1 - printf " + %s\n" "Number of all IPSets ::: ${value:-"0"}" >> "${report_txt}" - json_get_var value "cnt_sum" >/dev/null 2>&1 - printf " + %s\n" "Number of all entries ::: ${value:-"0"}" >> "${report_txt}" - json_get_var value "cnt_ip_sum" >/dev/null 2>&1 - printf " + %s\n" "Number of IP entries ::: ${value:-"0"}" >> "${report_txt}" - json_get_var value "cnt_cidr_sum" >/dev/null 2>&1 - printf " + %s\n" "Number of CIDR entries ::: ${value:-"0"}" >> "${report_txt}" - json_get_var value "cnt_mac_sum" >/dev/null 2>&1 - printf " + %s\n" "Number of MAC entries ::: ${value:-"0"}" >> "${report_txt}" - json_get_var value "cnt_acc_sum" >/dev/null 2>&1 - printf " + %s\n" "Number of accessed entries ::: ${value:-"0"}" >> "${report_txt}" - json_select "ipsets" - json_get_keys ipsetlist - if [ -n "${ipsetlist}" ] - then - printf "%s\n%s\n%s\n" ":::" "::: IPSet details" ":::" >> "${report_txt}" - printf "%-25s%-12s%-11s%-10s%-10s%-10s%-10s%s\n" " Name" "Type" "Count" "Cnt_IP" "Cnt_CIDR" "Cnt_MAC" "Cnt_ACC" "Entry details (Entry/Count)" >> "${report_txt}" - printf "%s\n" " --------------------------------------------------------------------------------------------------------------------" >> "${report_txt}" - fi - for ipset in ${ipsetlist} - do - set_info="${ipset}" - acc_info="" - json_select "${ipset}" - json_get_keys detaillist - for detail in ${detaillist} - do - if [ "${detail}" != "member_acc" ] - then - json_get_var value "${detail}" >/dev/null 2>&1 - set_info="${set_info} ${value}" - elif [ "${detail}" = "member_acc" ] - then - index=1 - json_select "${detail}" - while json_get_type type "${index}" && [ "${type}" = "object" ] - do - json_get_values values "${index}" >/dev/null 2>&1 - acc_info="${acc_info} ${values}" - index=$((index+1)) - done - json_select ".." - fi - done - printf " %-21s%-12s%-11s%-10s%-10s%-10s%s\n" ${set_info} >> "${report_txt}" - if [ -n "${acc_info}" ] - then - printf " %-25s%s\n" ${acc_info} >> "${report_txt}" + if [ -s "${report_json}" ] && { [ "${action}" = "cli" ] || [ "${action}" = "mail" ]; }; then + : >"${report_txt}" + json_init + if json_load_file "${report_json}" >/dev/null 2>&1; then + json_get_var jsnval1 "timestamp" >/dev/null 2>&1 + json_get_var jsnval2 "cnt_set_sum" >/dev/null 2>&1 + json_get_var jsnval3 "cnt_sum" >/dev/null 2>&1 + json_get_var jsnval4 "cnt_ip_sum" >/dev/null 2>&1 + json_get_var jsnval5 "cnt_cidr_sum" >/dev/null 2>&1 + json_get_var jsnval6 "cnt_mac_sum" >/dev/null 2>&1 + json_get_var jsnval7 "cnt_acc_sum" >/dev/null 2>&1 + { + printf "%s\n%s\n%s\n" ":::" "::: report on all banIP related IPSets" ":::" + printf " + %s\n" "Report timestamp ::: ${jsnval1:-"-"}" + printf " + %s\n" "Number of all IPSets ::: ${jsnval2:-"0"}" + printf " + %s\n" "Number of all entries ::: ${jsnval3:-"0"}" + printf " + %s\n" "Number of IP entries ::: ${jsnval4:-"0"}" + printf " + %s\n" "Number of CIDR entries ::: ${jsnval5:-"0"}" + printf " + %s\n" "Number of MAC entries ::: ${jsnval6:-"0"}" + printf " + %s\n" "Number of accessed entries ::: ${jsnval7:-"0"}" + } >>"${report_txt}" + + json_select "ipsets" + json_get_keys ipsetlist + if [ -n "${ipsetlist}" ]; then + { + printf "%s\n%s\n%s\n" ":::" "::: IPSet details" ":::" + printf "%-25s%-12s%-11s%-10s%-10s%-10s%-10s%s\n" " Name" "Type" "Count" "Cnt_IP" "Cnt_CIDR" "Cnt_MAC" "Cnt_ACC" "Entry details (Entry/Count)" + printf "%s\n" " --------------------------------------------------------------------------------------------------------------------" + } >>"${report_txt}" fi - printf "%s\n" " --------------------------------------------------------------------------------------------------------------------" >> "${report_txt}" - json_select ".." - done - content="$(cat "${report_txt}" 2>/dev/null)" - rm -f "${report_txt}" + for ipset in ${ipsetlist}; do + set_info="${ipset}" + acc_info="" + json_select "${ipset}" + json_get_keys detaillist + for detail in ${detaillist}; do + if [ "${detail}" != "member_acc" ]; then + json_get_var jsnval "${detail}" >/dev/null 2>&1 + set_info="${set_info} ${jsnval}" + elif [ "${detail}" = "member_acc" ]; then + index=1 + json_select "${detail}" + while json_get_type type "${index}" && [ "${type}" = "object" ]; do + json_get_values jsnvals "${index}" >/dev/null 2>&1 + acc_info="${acc_info} ${jsnvals}" + index=$((index + 1)) + done + json_select ".." + fi + done + { + printf " %-21s%-12s%-11s%-10s%-10s%-10s%s\n" ${set_info} + if [ -n "${acc_info}" ]; then + printf " %-25s%s\n" ${acc_info} + fi + printf "%s\n" " --------------------------------------------------------------------------------------------------------------------" + } >>"${report_txt}" + json_select ".." + done + content="$(cat "${report_txt}" 2>/dev/null)" + rm -f "${report_txt}" + fi fi # report output # - if [ "${action}" = "cli" ] - then + if [ "${action}" = "cli" ]; then printf "%s\n" "${content}" - elif [ "${action}" = "json" ] - then + elif [ "${action}" = "json" ]; then cat "${ban_reportdir}/ban_report.json" - elif [ "${action}" = "mail" ] && [ "${ban_mail_enabled}" = "1" ] && [ -x "${ban_mailservice}" ] - then - ( "${ban_mailservice}" "${ban_ver}" "${content}" >/dev/null 2>&1 )& + elif [ "${action}" = "mail" ] && [ "${ban_mail_enabled}" = "1" ] && [ -x "${ban_mailservice}" ]; then + ("${ban_mailservice}" "${content}" >/dev/null 2>&1) & bg_pid="${!}" fi f_log "debug" "f_report ::: action: ${action}, report_json: ${report_json}, report_txt: ${report_txt}, bg_pid: ${bg_pid:-"-"}" @@ -1705,38 +1453,33 @@ f_report() # update runtime information # -f_jsnup() -{ +f_jsnup() { local memory entry runtime cnt_info status="${1:-"enabled"}" - if [ "${status}" = "enabled" ] || [ "${status}" = "error" ] - then + if [ "${status}" = "enabled" ] || [ "${status}" = "error" ]; then ban_endtime="$(date "+%s")" cnt_info="${ban_setcnt} IPSets with ${ban_cnt} IPs/Prefixes" memory="$(awk '/^MemTotal|^MemFree|^MemAvailable/{ORS="/"; print int($2/1000)}' "/proc/meminfo" 2>/dev/null | awk '{print substr($0,1,length($0)-1)}')" - if [ "$(( (ban_endtime-ban_starttime)/60 ))" -lt "60" ] - then - runtime="${ban_action}, $(( (ban_endtime-ban_starttime)/60 ))m $(( (ban_endtime-ban_starttime)%60 ))s, ${memory:-0}, $(date "+%d.%m.%Y %H:%M:%S")" + if [ "$(((ban_endtime - ban_starttime) / 60))" -lt "60" ]; then + runtime="${ban_action}, $(((ban_endtime - ban_starttime) / 60))m $(((ban_endtime - ban_starttime) % 60))s, ${memory:-0}, $(date "+%d.%m.%Y %H:%M:%S")" else runtime="${ban_action}, n/a, ${memory:-0}, $(date "+%d.%m.%Y %H:%M:%S")" fi fi - > "${ban_rtfile}" - json_load_file "${ban_rtfile}" >/dev/null 2>&1 + : >"${ban_rtfile}" json_init + json_load_file "${ban_rtfile}" >/dev/null 2>&1 json_add_string "status" "${status}" json_add_string "version" "${ban_ver}" json_add_string "ipset_info" "${cnt_info:-"-"}" json_add_array "active_sources" - if [ "${status}" = "running" ] || [ "${status}" = "error" ] - then + if [ "${status}" = "running" ] || [ "${status}" = "error" ]; then json_add_object json_add_string "source" "-" json_close_object else - for entry in ${ban_sources} - do + for entry in ${ban_sources}; do json_add_object json_add_string "source" "${entry}" json_close_object @@ -1744,32 +1487,28 @@ f_jsnup() fi json_close_array json_add_array "active_devs" - for entry in ${ban_devs} - do + for entry in ${ban_devs}; do json_add_object json_add_string "dev" "${entry}" json_close_object done json_close_array json_add_array "active_ifaces" - for entry in ${ban_ifaces} - do + for entry in ${ban_ifaces}; do json_add_object json_add_string "iface" "${entry}" json_close_object done json_close_array json_add_array "active_logterms" - for entry in ${ban_logterms} - do + for entry in ${ban_logterms}; do json_add_object json_add_string "term" "${entry}" json_close_object done json_close_array json_add_array "active_subnets" - for entry in ${ban_subnets} - do + for entry in ${ban_subnets}; do json_add_object json_add_string "subnet" "${entry}" json_close_object @@ -1779,12 +1518,11 @@ f_jsnup() json_add_string "run_flags" "protocols (4/6): $(f_char ${ban_proto4_enabled})/$(f_char ${ban_proto6_enabled}), log (src/dst): $(f_char ${ban_logsrc_enabled})/$(f_char ${ban_logdst_enabled}), monitor: $(f_char ${ban_monitor_enabled}), mail: $(f_char ${ban_mail_enabled}), whitelist only: $(f_char ${ban_whitelistonly})" json_add_string "last_run" "${runtime:-"-"}" json_add_string "system" "${ban_sysver}" - json_dump > "${ban_rtfile}" + json_dump >"${ban_rtfile}" - if [ "${ban_mail_enabled}" = "1" ] && [ -x "${ban_mailservice}" ] && { [ "${status}" = "error" ] || \ - { [ "${status}" = "enabled" ] && { [ -z "${ban_mailactions}" ] || [ -n "$(printf "%s\n" "${ban_mailactions}" | grep -F "${ban_action}")" ]; }; }; } - then - ( "${ban_mailservice}" "${ban_ver}" >/dev/null 2>&1 )& + if [ "${ban_mail_enabled}" = "1" ] && [ -x "${ban_mailservice}" ] && { [ "${status}" = "error" ] || + { [ "${status}" = "enabled" ] && { [ -z "${ban_mailactions}" ] || printf "%s\n" "${ban_mailactions}" | grep -q "${ban_action}"; }; }; }; then + ("${ban_mailservice}" "${ban_ver}" >/dev/null 2>&1) & bg_pid="${!}" fi f_log "debug" "f_jsnup ::: status: ${status:-"-"}, action: ${ban_action}, mail_enabled: ${ban_mail_enabled}, mail_actions: ${ban_mailactions}, mail_service: ${ban_mailservice}, mail_pid: ${bg_pid:-"-"}" @@ -1792,8 +1530,7 @@ f_jsnup() # source required system libraries # -if [ -r "/lib/functions.sh" ] && [ -r "/lib/functions/network.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ] -then +if [ -r "/lib/functions.sh" ] && [ -r "/lib/functions/network.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]; then . "/lib/functions.sh" . "/lib/functions/network.sh" . "/usr/share/libubox/jshn.sh" @@ -1801,21 +1538,13 @@ else f_log "err" "system libraries not found" fi -if [ "${ban_action}" = "suspend" ] || [ "${ban_action}" = "resume" ] || \ - [ "${ban_action}" = "report" ] || [ "${ban_action}" = "query" ] -then +if [ "${ban_action}" = "suspend" ] || [ "${ban_action}" = "resume" ] || + [ "${ban_action}" = "report" ] || [ "${ban_action}" = "query" ]; then + json_init json_load_file "${ban_rtfile}" >/dev/null 2>&1 json_get_var ban_status "status" fi -# version information -# -if [ "${ban_action}" = "version" ] -then - printf "%s\n" "${ban_ver}" - exit 0 -fi - # handle different banIP actions # f_load @@ -1825,46 +1554,42 @@ case "${ban_action}" in f_ipset "destroy" f_jsnup "stopped" f_rmbckp - ;; + ;; "restart") f_ipset "destroy" f_rmbckp f_env f_main - ;; + ;; "suspend") - if [ "${ban_status}" = "enabled" ] && [ "${ban_whitelistonly}" = "0" ] - then + if [ "${ban_status}" = "enabled" ] && [ "${ban_whitelistonly}" = "0" ]; then f_bgsrv "stop" f_jsnup "running" f_ipset "suspend" f_jsnup "paused" fi f_rmtmp - ;; + ;; "resume") - if [ "${ban_status}" = "paused" ] && [ "${ban_whitelistonly}" = "0" ] - then + if [ "${ban_status}" = "paused" ] && [ "${ban_whitelistonly}" = "0" ]; then f_env f_main else f_rmtmp fi - ;; + ;; "query") - if [ "${ban_status}" = "enabled" ] - then + if [ "${ban_status}" = "enabled" ]; then f_query "${2}" fi - ;; + ;; "report") - if [ "${ban_status}" = "enabled" ] || [ "${2}" = "json" ] - then + if [ "${ban_status}" = "enabled" ] || [ "${2}" = "json" ]; then f_report "${2}" fi - ;; - "start"|"reload"|"refresh") + ;; + "start" | "reload" | "refresh") f_env f_main - ;; + ;; esac diff --git a/net/banip/files/banip.sources b/net/banip/files/banip.sources index 9dce5ae35c..1d8afd07c6 100644 --- a/net/banip/files/banip.sources +++ b/net/banip/files/banip.sources @@ -16,12 +16,12 @@ "descurl": "https://team-cymru.com" }, "country": { - "url_4": "https://www.ipdeny.com/ipblocks/data/aggregated/", - "url_6": "https://www.ipdeny.com/ipv6/ipaddresses/aggregated/", + "url_4": "http://www.ipdeny.com/ipblocks/data/aggregated/", + "url_6": "http://www.ipdeny.com/ipv6/ipaddresses/aggregated/", "rule_4": "/^(([0-9]{1,3}\\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]|$)/{print \"add country_4 \"$1}", "rule_6": "/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{print \"add country_6 \"$1}", "focus": "Country blocks", - "descurl": "https://www.ipdeny.com/ipblocks" + "descurl": "http://www.ipdeny.com/ipblocks" }, "darklist": { "url_4": "https://darklist.de/raw.php",