diff --git a/net/banip/Makefile b/net/banip/Makefile index 9f0a86540..b7fc044c8 100644 --- a/net/banip/Makefile +++ b/net/banip/Makefile @@ -6,8 +6,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=banip -PKG_VERSION:=0.7.6 -PKG_RELEASE:=2 +PKG_VERSION:=0.7.7 +PKG_RELEASE:=1 PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Dirk Brenken diff --git a/net/banip/files/README.md b/net/banip/files/README.md index c9aadb32f..df9563835 100644 --- a/net/banip/files/README.md +++ b/net/banip/files/README.md @@ -50,6 +50,7 @@ IP address blocking is commonly used to protect against brute force attacks, pre * auto-add unsuccessful LuCI, nginx or ssh login attempts via 'dropbear'/'sshd' to local blacklist * auto-add the uplink subnet to local whitelist * black- and whitelist also accept domain names as input to allow IP filtering based on these names +* supports a 'whitelist only' mode, this option allows to restrict Internet access from/to a small number of secure websites/IPs * provides a small background log monitor to ban unsuccessful login attempts in real-time * per source configuration of SRC (incoming) and DST (outgoing) * integrated IPSet-Lookup @@ -122,6 +123,7 @@ Available commands: | ban_logdst_enabled | option | 0 | enable the dst-related logchain | | ban_autoblacklist | option | 1 | add suspicious IPs automatically to the local blacklist | | ban_autowhitelist | option | 1 | add wan IPs/subnets automatically to the local whitelist | +| ban_whitelistonly | option | 0 | allow to restrict Internet access from/to a small number of secure websites/IPs | | ban_maxqueue | option | 4 | size of the download queue to handle downloads and processing in parallel | | ban_reportdir | option | /tmp/banIP-Report | directory where banIP stores the report files | | ban_backupdir | option | /tmp/banIP-Backup | directory where banIP stores the compressed backup files | @@ -206,18 +208,17 @@ Available commands: ~# /etc/init.d/banip status ::: banIP runtime information + status : enabled - + version : 0.7.5 - + ipset_info : 27 IPSets with 280704 IPs/Prefixes - + active_sources : blacklist, country, darklist, debl, doh, drop, dshield, feodo, firehol1, greensnow, iblockspy, nix - spam, sslbl, talos, threat, tor, uceprotect1, voip, whitelist, yoyo - + active_devs : eth3 - + active_ifaces : wan, wan6 - + active_logterms : dropbear, luci - + active_subnets : xxx.xxx.x.xxx/24, xxxx:xxxx:xxxx:0:xxxx:xxxx:xxxx:xxxx/64 - + run_infos : settype: src+dst, backup_dir: /mnt/data/banIP/backup, report_dir: /mnt/data/banIP/report - + run_flags : protocols (4/6): ✔/✔, log (src/dst): ✔/✘, monitor: ✔, mail: ✔ - + last_run : refresh, 0m 15s, 4019/3743/3784, 15.03.2021 09:28:01 - + system : PC Engines apu4, OpenWrt SNAPSHOT r16186-bf4aa0c6a2 + + version : 0.7.7 + + ipset_info : 2 IPSets with 30 IPs/Prefixes + + active_sources : whitelist + + active_devs : wlan0 + + active_ifaces : trm_wwan, trm_wwan6 + + active_logterms : dropbear, sshd, luci, nginx + + active_subnets : xxx.xxx.xxx.xxx/24, xxxx:xxxx:xxxx:xx::xxx/128 + + run_infos : settype: src+dst, backup_dir: /tmp/banIP-Backup, report_dir: /tmp/banIP-Report + + run_flags : protocols (4/6): ✔/✔, log (src/dst): ✔/✘, monitor: ✔, mail: ✘, whitelist only: ✔ + + last_run : restart, 0m 3s, 122/30/14, 21.04.2021 20:14:36 + + system : TP-Link RE650 v1, OpenWrt SNAPSHOT r16574-f7e00d81bc **black-/whitelist handling:** @@ -225,6 +226,9 @@ banIP supports a local black & whitelist (IPv4, IPv6, CIDR notation or domain na Unsuccessful LuCI logins, suspicious nginx request or ssh login attempts via 'dropbear'/'sshd' could be tracked and automatically added to the local blacklist (see the 'ban_autoblacklist' option). Furthermore the uplink subnet could be automatically added to local whitelist (see 'ban_autowhitelist' option). The list behaviour could be further tweaked with different timeout and counter options (see the config options section above). Last but not least, both lists also accept domain names as input to allow IP filtering based on these names. The corresponding IPs (IPv4 & IPv6) will be resolved in a detached background process and added to the IPsets. The detached name lookup takes place only during 'restart' or 'reload' action, 'start' and 'refresh' actions are using an auto-generated backup instead. +**whitelist-only mode:** +banIP supports a "whitelist only" mode. This option allows to restrict the internet access from/to a small number of secure websites/IPs, and block access from/to the rest of the internet. All IPs and Domains which are _not_ listed in the whitelist are blocked. Please note: suspend/resume does not work in this mode. + **generate an IPSet report:**

 ~# /etc/init.d/banip report
diff --git a/net/banip/files/banip.sh b/net/banip/files/banip.sh
index 5e80ee291..ed808529d 100755
--- a/net/banip/files/banip.sh
+++ b/net/banip/files/banip.sh
@@ -12,7 +12,7 @@
 export LC_ALL=C
 export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
 set -o pipefail
-ban_ver="0.7.6"
+ban_ver="0.7.7"
 ban_enabled="0"
 ban_mail_enabled="0"
 ban_proto4_enabled="0"
@@ -23,6 +23,7 @@ ban_monitor_enabled="0"
 ban_autodetect="1"
 ban_autoblacklist="1"
 ban_autowhitelist="1"
+ban_whitelistonly="0"
 ban_logterms=""
 ban_loglimit="100"
 ban_ssh_logcount="3"
@@ -240,7 +241,7 @@ f_conf()
 	fi
 	ban_localsources="${ban_localsources:-"maclist whitelist blacklist"}"
 	ban_logterms="${ban_logterms:-"dropbear sshd luci nginx"}"
-	f_log "debug" "f_conf  ::: ifaces: ${ban_ifaces:-"-"}, chain: ${ban_chain}, set_type: ${ban_global_settype}, log_chains (src/dst): ${ban_logchain_src}/${ban_logchain_dst}, targets (src/dst): ${ban_target_src}/${ban_target_dst}"
+	f_log "debug" "f_conf  ::: ifaces: ${ban_ifaces:-"-"}, chain: ${ban_chain}, set_type: ${ban_global_settype}, log_chains (src/dst): ${ban_logchain_src}/${ban_logchain_dst}, targets (src/dst): ${ban_target_src}/${ban_target_dst}, whitelist_only: ${ban_whitelistonly}"
 	f_log "debug" "f_conf  ::: lan_inputs (4/6): ${ban_lan_inputchains_4}/${ban_lan_inputchains_6}, lan_forwards (4/6): ${ban_lan_forwardchains_4}/${ban_lan_forwardchains_6}, wan_inputs (4/6): ${ban_wan_inputchains_4}/${ban_wan_inputchains_6}, wan_forwards (4/6): ${ban_wan_forwardchains_4}/${ban_wan_forwardchains_6}"
 	f_log "debug" "f_conf  ::: local_sources: ${ban_localsources:-"-"}, extra_sources: ${ban_extrasources:-"-"}, log_terms: ${ban_logterms:-"-"}, log_prefixes (src/dst): ${ban_logprefix_src}/${ban_logprefix_dst}, log_options (src/dst): ${ban_logopts_src}/${ban_logopts_dst}"
 }
@@ -547,8 +548,14 @@ f_iptables()
 				f_iptrule "-D" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} src -j RETURN"
 			elif [ "${src_name%_*}" = "whitelist" ]
 			then
-				f_iptrule "-D" "${ban_chain}" "-i ${dev} -m set --match-set ${src_name} src -j RETURN"
-				f_iptrule "-D" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} dst -j RETURN"
+				if [ "${ban_whitelistonly}" = "1" ]
+				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}"
+				else
+					f_iptrule "-D" "${ban_chain}" "-i ${dev} -m set --match-set ${src_name} src -j RETURN"
+					f_iptrule "-D" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} dst -j RETURN"
+				fi
 			else
 				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}"
@@ -599,7 +606,12 @@ f_iptables()
 				elif [ "${src_name%_*}" = "whitelist" ]
 				then
 					pos="$(( $("${ipt_cmd}" "${timeout}" -vnL "${ban_chain}" --line-numbers | grep -cF "RETURN")+1))"
-					f_iptrule "-I" "${ban_chain}" "-i ${dev} -m set --match-set ${src_name} src -j RETURN" "${pos}"
+					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}"
+					fi
 				else
 					f_iptrule "${action:-"-A"}" "${ban_chain}" "-i ${dev} -m set --match-set ${src_name} src -j ${ban_target_src}"
 				fi
@@ -612,7 +624,12 @@ f_iptables()
 				if [ "${src_name%_*}" = "whitelist" ]
 				then
 					pos="$(( $("${ipt_cmd}" "${timeout}" -vnL "${ban_chain}" --line-numbers | grep -cF "RETURN")+1))"
-					f_iptrule "-I" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} dst -j RETURN" "${pos}"
+					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
 					f_iptrule "${action:-"-A"}" "${ban_chain}" "-o ${dev} -m set --match-set ${src_name} dst -j ${ban_target_dst}"
@@ -913,7 +930,7 @@ f_bgsrv()
 	local bg_pid action="${1}"
 
 	bg_pid="$(pgrep -f "^/bin/sh ${ban_logservice}|${ban_logread_cmd}|^grep -qE Exit before auth|^grep -qE error: maximum|^grep -qE luci: failed|^grep -qE nginx" | awk '{ORS=" "; print $1}')"
-	if [ "${action}" = "start" ] && [ -x "${ban_logservice}" ] && [ "${ban_monitor_enabled}" = "1" ]
+	if [ "${action}" = "start" ] && [ -x "${ban_logservice}" ] && [ "${ban_monitor_enabled}" = "1" ] && [ "${ban_whitelistonly}" = "0" ]
 	then
 		if [ -n "${bg_pid}" ]
 		then
@@ -1269,7 +1286,7 @@ f_main()
 		fi
 		if [ "${ban_proto4_enabled}" = "1" ]
 		then
-			if [ "${src_name}" = "blacklist" ] && [ -s "${ban_blacklist}" ]
+			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}"
@@ -1290,7 +1307,7 @@ f_main()
 		fi
 		if [ "${ban_proto6_enabled}" = "1" ]
 		then
-			if [ "${src_name}" = "blacklist" ] && [ -s "${ban_blacklist}" ]
+			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}"
@@ -1314,50 +1331,53 @@ f_main()
 
 	# loop over all external sources
 	#
-	for src_name in ${ban_sources}
-	do
-		# get source data from JSON file
-		#
-		json_select "${src_name}" >/dev/null 2>&1
-		if [ "${?}" != "0" ]
-		then
-			continue
-		fi
-		json_objects="url_4 rule_4 url_6 rule_6 comp"
-		for object in ${json_objects}
+	if [ "${ban_whitelistonly}" = "0" ]
+	then
+		for src_name in ${ban_sources}
 		do
-			eval json_get_var src_${object} "\${object}" >/dev/null 2>&1
-		done
-		json_select ..
+			# get source data from JSON file
+			#
+			json_select "${src_name}" >/dev/null 2>&1
+			if [ "${?}" != "0" ]
+			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
+			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
-			(
-				f_down "${src_name}" "4" "inet" "${src_url_4}" "${src_rule_4}" "${src_comp}"
-			)&
-		fi
+			# handle external IPv4 source downloads in a subshell
+			#
+			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
-			(
-				f_down "${src_name}" "6" "inet6" "${src_url_6}" "${src_rule_6}" "${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
+				(
+					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
-			wait
-		fi
-		cnt=$((cnt+1))
-	done
-	wait
+			# control/limit download queues
+			#
+			hold=$((cnt%ban_maxqueue))
+			if [ "${hold}" = "0" ]
+			then
+				wait
+			fi
+			cnt=$((cnt+1))
+		done
+		wait
+	fi
 
 	# error out
 	#
@@ -1635,6 +1655,7 @@ f_report()
 			json_select ".."
 		done
 		content="$(cat "${report_txt}" 2>/dev/null)"
+		rm -f "${report_txt}"
 	fi
 
 	# report output
@@ -1726,7 +1747,7 @@ f_jsnup()
 	done
 	json_close_array
 	json_add_string "run_infos" "settype: ${ban_global_settype}, backup_dir: ${ban_backupdir}, report_dir: ${ban_reportdir}"
-	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})"
+	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}"
@@ -1783,7 +1804,7 @@ case "${ban_action}" in
 		f_main
 	;;
 	"suspend")
-		if [ "${ban_status}" = "enabled" ]
+		if [ "${ban_status}" = "enabled" ] && [ "${ban_whitelistonly}" = "0" ]
 		then
 			f_bgsrv "stop"
 			f_jsnup "running"
@@ -1793,7 +1814,7 @@ case "${ban_action}" in
 		f_rmtmp
 	;;
 	"resume")
-		if [ "${ban_status}" = "paused" ]
+		if [ "${ban_status}" = "paused" ] && [ "${ban_whitelistonly}" = "0" ]
 		then
 			f_env
 			f_main