banip: Added packet logging feature. Resolved shellcheck warnings. 13761/head
authorRichard Gering <rgering@dutchies.us>
Sat, 24 Oct 2020 22:09:44 +0000 (15:09 -0700)
committerRichard Gering <rg4github@dutchies.us>
Sat, 24 Oct 2020 23:20:21 +0000 (16:20 -0700)
Signed-off-by: Richard Gering <rg4github@dutchies.us>
net/banip/Makefile
net/banip/files/README.md
net/banip/files/banip.conf
net/banip/files/banip.sh

index 7a8b8a08458e161e2dedcf23bd0d8283f210d38a..20c52bee6d5e996e4f8482149e64a0c83af5e83a 100644 (file)
@@ -6,7 +6,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=banip
-PKG_VERSION:=0.3.11
+PKG_VERSION:=0.3.12
 PKG_RELEASE:=1
 PKG_LICENSE:=GPL-3.0-or-later
 PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
index b42dd5768ff0ef24dfcb8c0d65de8717ef5b3c7a..7cb716147cefd34ef991481a24f047b1fec81949 100644 (file)
@@ -27,6 +27,7 @@ IP address blocking is commonly used to protect against brute force attacks, pre
 * output comprehensive runtime information via LuCI or via 'status' init command
 * strong LuCI support
 * optional: add new banIP sources on your own
+* optional: log banned inbound and/or outbound IP to syslog.
 
 ## Prerequisites
 * [OpenWrt](https://openwrt.org), tested with the stable release series (19.07) and with the latest snapshot
@@ -45,45 +46,65 @@ IP address blocking is commonly used to protect against brute force attacks, pre
 ## banIP config options
 * usually the pre-configured banIP setup works quite well and no manual overrides are needed
 * the following options apply to the 'global' config section:
-    * ban\_enabled => main switch to enable/disable banIP service (bool/default: '0', disabled)
-    * ban\_automatic => determine the L2/L3 WAN network device automatically (bool/default: '1', enabled)
-    * ban\_iface => space separated list of WAN network interface(s)/device(s) used by banIP (default: not set, automatically detected)
-    * ban\_realtime => a small log/banIP background monitor to block SSH/LuCI brute force attacks in realtime (bool/default: 'false', disabled)
+  * ban\_enabled => main switch to enable/disable banIP service (bool/default: '0', disabled)
+  * ban\_automatic => determine the L2/L3 WAN network device automatically (bool/default: '1', enabled)
+  * ban\_iface => space separated list of WAN network interface(s)/device(s) used by banIP (default: not set, automatically detected)
+  * ban\_realtime => a small log/banIP background monitor to block SSH/LuCI brute force attacks in realtime (bool/default: 'false', disabled)
+  * ban\_target\_src => action to perform when banning inbound IPv4 packets ('DROP'/'REJECT', default: 'DROP')
+  * ban\_target\_src\_6 => action to perform when banning inbound IPv6 packets ('DROP'/'REJECT', default: 'DROP')
+  * ban\_target\_dst => action to perform when banning outbound IPv4 packets ('DROP'/'REJECT', default: 'REJECT')
+  * ban\_target\_dst\_6 => action to perform when banning outbound IPv6 packets ('DROP'/'REJECT', default: 'REJECT')
+  * ban\_log\_src => switch to enable/disable logging of banned inbound IPv4 packets (bool/default: '0', disabled)
+  * ban\_log\_dst => switch to enable/disable logging of banned outbound IPv4 packets (bool/default: '0', disabled)
 
 * the following options apply to the 'extra' config section:
-    * ban\_debug => enable/disable banIP debug output (bool/default: '0', disabled)
-    * ban\_nice => set the nice level of the banIP process and all sub-processes (int/default: '0', standard priority)
-    * ban\_triggerdelay => additional trigger delay in seconds before banIP processing begins (int/default: '2')
-    * ban\_backupdir => target directory for banIP backups (default: '/tmp')
-    * ban\_sshdaemon => select the SSH daemon for logfile parsing, 'dropbear' or 'sshd' (default: 'dropbear')
-    * ban\_starttype => select the used start type during boot, 'start', 'refresh' or 'reload' (default: 'start')
-    * ban\_maxqueue => size of the download queue to handle downloads & IPSet processing in parallel (int/default: '4')
-    * ban\_fetchutil => name of the used download utility: 'uclient-fetch', 'wget', 'curl', 'aria2c' (default: not set, automatically detected)
-    * ban\_fetchparm => special config options for the download utility (default: not set)
-    * ban\_autoblacklist => store auto-addons temporary in ipset and permanently in local blacklist as well (bool/default: '1', enabled)
-    * ban\_autowhitelist => store auto-addons temporary in ipset and permanently in local whitelist as well (bool/default: '1', enabled)
+  * ban\_debug => enable/disable banIP debug output (bool/default: '0', disabled)
+  * ban\_nice => set the nice level of the banIP process and all sub-processes (int/default: '0', standard priority)
+  * ban\_triggerdelay => additional trigger delay in seconds before banIP processing begins (int/default: '2')
+  * ban\_backupdir => target directory for banIP backups (default: '/tmp')
+  * ban\_sshdaemon => select the SSH daemon for logfile parsing, 'dropbear' or 'sshd' (default: 'dropbear')
+  * ban\_starttype => select the used start type during boot, 'start', 'refresh' or 'reload' (default: 'start')
+  * ban\_maxqueue => size of the download queue to handle downloads & IPSet processing in parallel (int/default: '4')
+  * ban\_fetchutil => name of the used download utility: 'uclient-fetch', 'wget', 'curl', 'aria2c' (default: not set, automatically detected)
+  * ban\_fetchparm => special config options for the download utility (default: not set)
+  * ban\_autoblacklist => store auto-addons temporary in ipset and permanently in local blacklist as well (bool/default: '1', enabled)
+  * ban\_autowhitelist => store auto-addons temporary in ipset and permanently in local whitelist as well (bool/default: '1', enabled)
+
+## Logging of banned packets
+* by setting ban\_log\_src=1 / ban\_log\_dst=1 in the config options, banIP will log banned inbound / outbound packets to syslog.
+* example of a logged inbound (dst) and outbound (src) packet:
+<pre><code>
+Oct  2 12:49:14 gateway kernel: [434134.855130] REJECT(dst banIP) IN=br-lan OUT=br-wan MAC=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx SRC=x.x.x.x DST=x.x.x.x LEN=100 TOS=0x00 PREC=0x00 TTL=63 ID=7938 PROTO=UDP SPT=16393 DPT=16393 LEN=80
+
+Oct  3 14:11:13 gateway kernel: [11290.429712] DROP(src banIP) IN=br-wan OUT= MAC=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx SRC=x.x.x.x DST=x.x.x.x LEN=40 TOS=0x00 PREC=0x00 TTL=235 ID=63275 PROTO=TCP SPT=48246 DPT=37860 WINDOW=1024 RES=0x00 SYN URGP=0
+</code></pre>
+* to change the default logging behavior, the following options can be added to the 'global' config section:
+  * ban\_log\_src\_opts => IPv4 iptables LOG options for banned inbound packets (default: '-m limit --limit 10/sec')
+  * ban\_log\_src\_opts\_6 => IPv6 iptables LOG options for banned inbound packets (default: '-m limit --limit 10/sec')
+  * ban\_log\_src\_prefix (default: '<ban\_target\_src>(src banIP) ', typically 'DROP(src banIP) ')
+  * ban\_log\_src\_prefix\_6 (default: '<ban\_target\_src\_6>(src banIP) ', typically 'DROP('src banIP)' )
+  * ban\_log\_dst\_opts => IPv4 iptables LOG options for banned outbound packets (default: '-m limit --limit 10/sec')
+  * ban\_log\_dst\_opts\_6 => IPv6 iptables LOG options for banned outbound packets (default: '-m limit --limit 10/sec')
+  * ban\_log\_dst\_prefix (default: '<ban\_target\_dst>(dst banIP) ', typically 'REJECT(dst banIP) ')
+  * ban\_log\_dst\_prefix\_6 (default: '<ban\_target\_dst\_6>(dst banIP) ', typically 'REJECT('dst banIP)' )
 
 ## Examples
 **receive banIP runtime information:**
 
-<pre><code>
-/etc/init.d/banip status
-::: banIP runtime information
-  + status     : enabled
-  + version    : 0.3.0
-  + util_info  : /usr/bin/aria2c, true
-  + ipset_info : 10 IPSets with overall 106729 IPs/Prefixes
-  + backup_dir : /tmp
-  + last_run   : 03.10.2019 19:15:25
-  + system     : UBNT-ERX, OpenWrt SNAPSHOT r11102-ced4c0e635
-</code></pre>
-  
+    # /etc/init.d/banip status
+    ::: banIP runtime information
+      + status     : enabled
+      + version    : 0.3.0
+      + util_info  : /usr/bin/aria2c, true
+      + ipset_info : 10 IPSets with overall 106729 IPs/Prefixes
+      + backup_dir : /tmp
+      + last_run   : 03.10.2019 19:15:25
+      + system     : UBNT-ERX, OpenWrt SNAPSHOT r11102-ced4c0e635
+
 **cronjob for a regular IPSet blocklist update (/etc/crontabs/root):**
 
-<pre><code>
-0 06 * * *    /etc/init.d/banip reload
-</code></pre>
-  
+    # Every day at 06:00, update the IPSets of banIP
+    00 06 * * *    /etc/init.d/banip reload
 
 ## Support
 Please join the banIP discussion in this [forum thread](https://forum.openwrt.org/t/banip-support-thread/16985) or contact me by mail <dev@brenken.org>  
index 68a48aad49fb52e0b81528199bce63b5d152d3c0..d3d4fc14844a6f06b105159f08302d2063713776 100644 (file)
@@ -4,6 +4,8 @@ config banip 'global'
        option ban_basever '0.3'
        option ban_automatic '1'
        option ban_realtime 'false'
+       option ban_log_src '0'
+       option ban_log_dst '0'
 
 config banip 'extra'
        option ban_debug '0'
index 14c4e838ae86c556aeacfef2437e2d771acc9f6f..b5685148d4564de7d604898460d47468117afe15 100755 (executable)
@@ -7,13 +7,13 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 
 # (s)hellcheck exceptions
-# shellcheck disable=1091 disable=2039 disable=2143 disable=2181 disable=2188
+# shellcheck disable=1091,2039,2086,2140,2143,2181,2188
 
 # set initial defaults
 #
 LC_ALL=C
 PATH="/usr/sbin:/usr/bin:/sbin:/bin"
-ban_ver="0.3.11"
+ban_ver="0.3.12"
 ban_basever=""
 ban_enabled=0
 ban_automatic="1"
@@ -42,6 +42,8 @@ ban_logservice="/etc/banip/banip.service"
 ban_sshdaemon=""
 ban_setcnt=0
 ban_cnt=0
+ban_log_src=0
+ban_log_dst=0
 
 # load environment
 #
@@ -97,6 +99,28 @@ f_envload()
        config_load banip
        config_foreach parse_config source
 
+       # setup logging
+       #
+       ban_log_chain_src="${ban_log_chain_src:-"${ban_chain}_log_src"}"
+       if [ "${ban_log_src}" -eq 1 ]
+       then
+               log_target_src="${ban_target_src:-"DROP"}"
+               ban_target_src="${ban_log_chain_src}"
+
+               log_target_src_6="${ban_target_src_6:-"DROP"}"
+               ban_target_src_6="${ban_log_chain_src}"
+       fi
+
+       ban_log_chain_dst="${ban_log_chain_dst:-"${ban_chain}_log_dst"}"
+       if [ "${ban_log_dst}" -eq 1 ]
+       then
+               log_target_dst="${ban_target_dst:-"REJECT"}"
+               ban_target_dst="${ban_log_chain_dst}"
+
+               log_target_dst_6="${ban_target_dst_6:-"REJECT"}"
+               ban_target_dst_6="${ban_log_chain_dst}"
+       fi
+
        # log daemon check
        #
        if [ "$(/etc/init.d/log running; printf "%u" "${?}")" -eq 1 ]
@@ -259,7 +283,7 @@ f_envcheck()
        fi
        case "${util}" in
                "aria2c")
-                       ban_fetchparm="${ban_fetchparm:-"--timeout=20 --allow-overwrite=true --auto-file-renaming=false --check-certificate=true --dir=" " -o"}"
+                       ban_fetchparm="${ban_fetchparm:-"--timeout=20 --allow-overwrite=true --auto-file-renaming=false --check-certificate=true --dir=/ -o"}"
                ;;
                "curl")
                        ban_fetchparm="${ban_fetchparm:-"--connect-timeout 20 -o"}"
@@ -392,15 +416,13 @@ f_iptadd()
        then
                if [ "${src_ruletype}" != "dst" ]
                then
-                       if [ "${src_name##*_}" = "6" ]
+                       f_iptrule "-I" "${wan_input} -j ${ban_chain}"
+                       f_iptrule "-I" "${wan_forward} -j ${ban_chain}"
+                       if [ "${src_name##*_}" != "6" ]
                        then
-                               # dummy, special IPv6 rules
-                               /bin/true
-                       else
-                               f_iptrule "-I" "${wan_input} -p udp --dport 67:68 --sport 67:68 -j RETURN"
+                               # special IPv4 rules
+                               f_iptrule "-A" "${ban_chain} -p udp --dport 67:68 --sport 67:68 -j RETURN"
                        fi
-                       f_iptrule "-A" "${wan_input} -j ${ban_chain}"
-                       f_iptrule "-A" "${wan_forward} -j ${ban_chain}"
                        for dev in ${ban_dev}
                        do
                                f_iptrule "${action:-"-A"}" "${ban_chain} -i ${dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} src -j ${target_src}"
@@ -408,15 +430,13 @@ f_iptadd()
                fi
                if [ "${src_ruletype}" != "src" ]
                then
-                       if [ "${src_name##*_}" = "6" ]
+                       f_iptrule "-I" "${lan_input} -j ${ban_chain}"
+                       f_iptrule "-I" "${lan_forward} -j ${ban_chain}"
+                       if [ "${src_name##*_}" != "6" ]
                        then
-                               # dummy, special IPv6 rules
-                               /bin/true
-                       else
-                               f_iptrule "-I" "${lan_input} -p udp --dport 67:68 --sport 67:68 -j RETURN"
+                               # special IPv4 rules
+                               f_iptrule "-A" "${ban_chain} -p udp --dport 67:68 --sport 67:68 -j RETURN"
                        fi
-                       f_iptrule "-A" "${lan_input} -j ${ban_chain}"
-                       f_iptrule "-A" "${lan_forward} -j ${ban_chain}"
                        for dev in ${ban_dev}
                        do
                                f_iptrule "${action:-"-A"}" "${ban_chain} -o ${dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} dst -j ${target_dst}"
@@ -434,7 +454,7 @@ f_iptadd()
 #
 f_ipset()
 {
-       local out_rc source action ruleset ruleset_6 rule cnt=0 cnt_ip=0 cnt_cidr=0 timeout="-w 5" mode="${1}" in_rc="${src_rc:-0}"
+       local out_rc source action ruleset rule cnt=0 cnt_ip=0 cnt_cidr=0 timeout="-w 5" mode="${1}" in_rc="${src_rc:-0}"
 
        if [ "${src_name%_6*}" = "whitelist" ]
        then
@@ -471,34 +491,81 @@ f_ipset()
                        return "${out_rc}"
                ;;
                "initial")
-                       if [ -x "${ban_ipt}" ] && [ -z "$("${ban_ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
-                       then
-                               "${ban_ipt}" "${timeout}" -N "${ban_chain}" 2>/dev/null
-                               out_rc="${?}"
-                       elif [ -x "${ban_ipt}" ]
-                       then
-                               src_name="ruleset"
-                               ruleset="${ban_wan_input_chain:-"input_wan_rule"} ${ban_wan_forward_chain:-"forwarding_wan_rule"} ${ban_lan_input_chain:-"input_lan_rule"} ${ban_lan_forward_chain:-"forwarding_lan_rule"}"
-                               for rule in ${ruleset}
-                               do
-                                       f_iptrule "-D" "${rule} -j ${ban_chain}"
-                               done
-                       fi
-                       if [ -x "${ban_ipt6}" ] && [ -z "$("${ban_ipt6}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
-                       then
-                               "${ban_ipt6}" "${timeout}" -N "${ban_chain}" 2>/dev/null
-                               out_rc="${?}"
-                       elif [ -x "${ban_ipt6}" ]
-                       then
-                               src_name="ruleset_6"
-                               ruleset_6="${ban_wan_input_chain_6:-"input_wan_rule"} ${ban_wan_forward_chain_6:-"forwarding_wan_rule"} ${ban_lan_input_chain_6:-"input_lan_rule"} ${ban_lan_forward_chain_6:-"forwarding_lan_rule"}"
-                               for rule in ${ruleset_6}
-                               do
-                                       f_iptrule "-D" "${rule} -j ${ban_chain}"
-                               done
-                       fi
+                       local ipt log_src_target log_src_opts log_src_prefix log_dst_target log_dst_opts log_dst_prefix
+                       for src_name in "ruleset" "ruleset_6"
+                       do
+                               if [ "${src_name##*_}" = "6" ]
+                               then
+                                       ipt="${ban_ipt6}"
+                                       ruleset="${ban_wan_input_chain_6:-"input_wan_rule"} ${ban_wan_forward_chain_6:-"forwarding_wan_rule"} ${ban_lan_input_chain_6:-"input_lan_rule"} ${ban_lan_forward_chain_6:-"forwarding_lan_rule"}"
+                                       log_src_target="${log_target_src_6}"
+                                       log_src_opts="${ban_log_src_opts_6:-"-m limit --limit 10/sec"}"
+                                       log_src_prefix="${ban_log_src_prefix_6:-"${log_target_src_6}(src banIP) "}"
+                                       log_dst_target="${log_target_dst_6}"
+                                       log_dst_opts="${ban_log_dst_opts_6:-"-m limit --limit 10/sec"}"
+                                       log_dst_prefix="${ban_log_dst_prefix_6:-"${log_target_dst_6}(dst banIP) "}"
+                               else
+                                       ipt="${ban_ipt}"
+                                       ruleset="${ban_wan_input_chain:-"input_wan_rule"} ${ban_wan_forward_chain:-"forwarding_wan_rule"} ${ban_lan_input_chain:-"input_lan_rule"} ${ban_lan_forward_chain:-"forwarding_lan_rule"}"
+                                       log_src_target="${log_target_src}"
+                                       log_src_opts="${ban_log_src_opts:-"-m limit --limit 10/sec"}"
+                                       log_src_prefix="${ban_log_src_prefix:-"${log_target_src}(src banIP) "}"
+                                       log_dst_target="${log_target_dst}"
+                                       log_dst_opts="${ban_log_dst_opts:-"-m limit --limit 10/sec"}"
+                                       log_dst_prefix="${ban_log_dst_prefix:-"${log_target_dst}(dst banIP) "}"
+                               fi
+
+                               if [ -x "${ipt}" ]
+                               then
+                                       if [ -z "$("${ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
+                                       then
+                                               "${ipt}" "${timeout}" -N "${ban_chain}" 2>/dev/null
+                                               out_rc="${?}"
+                                       else
+                                               out_rc=0
+                                               for rule in ${ruleset}
+                                               do
+                                                       f_iptrule "-D" "${rule} -j ${ban_chain}"
+                                               done
+                                       fi
+                                       f_log "debug" "f_ipset ::: name: -, mode: ${mode:-"-"}, chain: ${ban_chain:-"-"}, $src_name: ${ruleset:-"-"}, out_rc: ${out_rc}"
+
+                                       if [ "${ban_log_src}" -eq 1 ] && [ "${out_rc}" -eq 0 ]
+                                       then
+                                               if [ -z "$("${ipt}" "${timeout}" -nL "${ban_log_chain_src}" 2>/dev/null)" ]
+                                               then
+                                                       "${ipt}" "${timeout}" -N "${ban_log_chain_src}" 2>/dev/null
+                                                       out_rc="${?}"
+                                                       if [ "${out_rc}" -eq 0 ]
+                                                       then
+                                                               "${ipt}" "${timeout}" -A "${ban_log_chain_src}" -j LOG ${log_src_opts} --log-prefix "${log_src_prefix}" && \
+                                                                       "${ipt}" "${timeout}" -A "${ban_log_chain_src}" -j "${log_src_target}"
+                                                               out_rc="${?}"
+                                                       fi
+                                               fi
+                                               f_log "debug" "f_ipset ::: name: -, mode: ${mode:-"-"}, chain: ${ban_log_chain_src:-"-"}, out_rc: ${out_rc}"
+                                       fi
+
+                                       if [ "${ban_log_dst}" -eq 1 ] && [ "${out_rc}" -eq 0 ]
+                                       then
+                                               if [ -z "$("${ipt}" "${timeout}" -nL "${ban_log_chain_dst}" 2>/dev/null)" ]
+                                               then
+                                                       "${ipt}" "${timeout}" -N "${ban_log_chain_dst}" 2>/dev/null
+                                                       out_rc="${?}"
+                                                       if [ "${out_rc}" -eq 0 ]
+                                                       then
+                                                               "${ipt}" "${timeout}" -A "${ban_log_chain_dst}" -j LOG ${log_dst_opts} --log-prefix "${log_dst_prefix}" && \
+                                                                       "${ipt}" "${timeout}" -A "${ban_log_chain_dst}" -j "${log_dst_target}"
+                                                               out_rc="${?}"
+                                                       fi
+                                               fi
+                                               f_log "debug" "f_ipset ::: name: -, mode: ${mode:-"-"}, chain: ${ban_log_chain_dst:-"-"}, out_rc: ${out_rc}"
+                                       fi
+                               fi
+                       done
+
                        out_rc="${out_rc:-"${in_rc}"}"
-                       f_log "debug" "f_ipset ::: name: -, mode: ${mode:-"-"}, chain: ${ban_chain:-"-"}, ruleset: ${ruleset:-"-"}, ruleset_6: ${ruleset_6:-"-"}, out_rc: ${out_rc}"
+                       f_log "debug" "f_ipset ::: name: -, mode: ${mode:-"-"}, out_rc: ${out_rc}"
                        return "${out_rc}"
                ;;
                "create")
@@ -562,20 +629,23 @@ f_ipset()
                        f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}"
                ;;
                "destroy")
-                       if [ -x "${ban_ipt}" ] && [ -x "${ban_ipt_save}" ] && [ -x "${ban_ipt_restore}" ] && \
-                               [ -n "$("${ban_ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
-                       then
-                               "${ban_ipt_save}" | grep -v -- "-j ${ban_chain}" | "${ban_ipt_restore}"
-                               "${ban_ipt}" "${timeout}" -F "${ban_chain}" 2>/dev/null
-                               "${ban_ipt}" "${timeout}" -X "${ban_chain}" 2>/dev/null
-                       fi
-                       if [ -x "${ban_ipt6}" ] && [ -x "${ban_ipt6_save}" ] && [ -x "${ban_ipt6_restore}" ] && \
-                               [ -n "$("${ban_ipt6}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
-                       then
-                               "${ban_ipt6_save}" | grep -v -- "-j ${ban_chain}" | "${ban_ipt6_restore}"
-                               "${ban_ipt6}" "${timeout}" -F "${ban_chain}" 2>/dev/null
-                               "${ban_ipt6}" "${timeout}" -X "${ban_chain}" 2>/dev/null
-                       fi
+                       for chain in ${ban_log_chain_src} ${ban_log_chain_dst} ${ban_chain}
+                       do
+                               if [ -x "${ban_ipt}" ] && [ -x "${ban_ipt_save}" ] && [ -x "${ban_ipt_restore}" ] && \
+                                       [ -n "$("${ban_ipt}" "${timeout}" -nL "${chain}" 2>/dev/null)" ]
+                               then
+                                       "${ban_ipt_save}" | grep -v -- "-j ${chain}" | "${ban_ipt_restore}"
+                                       "${ban_ipt}" "${timeout}" -F "${chain}" 2>/dev/null
+                                       "${ban_ipt}" "${timeout}" -X "${chain}" 2>/dev/null
+                               fi
+                               if [ -x "${ban_ipt6}" ] && [ -x "${ban_ipt6_save}" ] && [ -x "${ban_ipt6_restore}" ] && \
+                                       [ -n "$("${ban_ipt6}" "${timeout}" -nL "${chain}" 2>/dev/null)" ]
+                               then
+                                       "${ban_ipt6_save}" | grep -v -- "-j ${chain}" | "${ban_ipt6_restore}"
+                                       "${ban_ipt6}" "${timeout}" -F "${chain}" 2>/dev/null
+                                       "${ban_ipt6}" "${timeout}" -X "${chain}" 2>/dev/null
+                               fi
+                       done
                        for source in ${ban_sources}
                        do
                                if [ -x "${ban_ipset}" ] && [ -n "$("${ban_ipset}" -q -n list "${source}")" ]
@@ -895,14 +965,15 @@ f_main()
 
        if [ -z "$(ls "${ban_tmpfile}".*.err 2>/dev/null)" ]
        then
-               for cnt in $(cat "${ban_tmpfile}".*.cnt 2>/dev/null)
-               do
-                       ban_cnt="$((ban_cnt+cnt))"
-               done
-               if [ "${ban_cnt}" -gt 0 ]
-               then
-                       ban_setcnt="$(ls "${ban_tmpfile}".*.cnt 2>/dev/null | wc -l)"
-               fi
+                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))"
+                       fi
+                done
                f_log "info" "${ban_setcnt} IPSets with overall ${ban_cnt} IPs/Prefixes loaded successfully (${ban_sysver})"
                f_bgserv "start"
                f_jsnup