Просмотр исходного кода

[Bug fix] Firewall loading failed after reboot (#3110)

* Fixed firewall loading failed after reboot

* Apply update to hestia-iptables Systemd unit
myrevery 3 лет назад
Родитель
Сommit
ce6945fd41

+ 15 - 15
bin/v-add-firewall-ipset

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: add firewall ipset
-# options: NAME [SOURCE] [IPVERSION] [AUTOUPDATE] [FORCE]
+# options: NAME [SOURCE] [IPVERSION] [AUTOUPDATE] [REFRESH]
 #
 # example: v-add-firewall-ipset country-nl 'http://ipverse.net/ipblocks/data/countries/nl.zone'
 #
@@ -14,7 +14,7 @@ ip_name=${1}
 data_source=${2}
 ip_version=${3:-v4}
 autoupdate=${4:-yes}
-force=${5:-no}
+refresh=${5:-no}
 
 # Includes
 # shellcheck source=/etc/hestiacp/hestia.conf
@@ -30,8 +30,8 @@ source_conf "$HESTIA/conf/hestia.conf"
 
 check_args '1' "$#" 'NAME [SOURCE] [IPVERSION] [AUTOUPDATE] [FORCE]'
 is_format_valid 'ip_name'
-is_boolean_format_valid "$autoupdate" 'bool (yes/no)'
-is_boolean_format_valid "$force" 'bool (yes/no)'
+is_boolean_format_valid "$autoupdate" 'Automatically update IP list (yes/no)'
+is_boolean_format_valid "$refresh" 'Refresh IP list (yes/no)'
 is_system_enabled "$FIREWALL_SYSTEM" 'FIREWALL_SYSTEM'
 
 # Perform verification if read-only mode is enabled
@@ -39,7 +39,7 @@ check_hestia_demo_mode
 
 # Define variables for ipset configuration
 ipset_hstobject='../../data/firewall/ipset'
-IPSET_BIN="$(which ipset)"
+IPSET_BIN="$(command -v ipset)"
 IPSET_PATH="$HESTIA/data/firewall/ipset"
 
 # Ensure ipset is installed
@@ -49,10 +49,10 @@ if [ -z "$IPSET_BIN" ]; then
 	else
 		apt-get --quiet --yes install ipset > /dev/null
 	fi
-	check_result $? "Installing ipset package"
+	check_result $? "Installing IPset package"
 
 	IPSET_BIN="$(which ipset)"
-	check_result $? "ipset binary not found"
+	check_result $? "IPset binary not found"
 fi
 
 # Ensure ipset configuration path and master file exist before attempting to parse
@@ -87,8 +87,8 @@ IPSET_MIN_SIZE=10
 #                       Action                             #
 #----------------------------------------------------------#
 
-# Generate ip lists file if missing or when forced
-if [ ! -f "${IPSET_PATH}/${IPSET_FILE}.iplist" ] || [ "$force" = "yes" ]; then
+# Generate ip lists file if missing or required refresh
+if [ ! -f "${IPSET_PATH}/${IPSET_FILE}.iplist" ] || [ "$refresh" = "yes" ]; then
 
 	iplist_tempfile=$(mktemp)
 
@@ -109,7 +109,6 @@ if [ ! -f "${IPSET_PATH}/${IPSET_FILE}.iplist" ] || [ "$force" = "yes" ]; then
 
 		# Generate the ip list file trough a external script
 		# ex: compiling a ip list from multiple sources on demand
-
 		if [ -x "${data_source#script:}" ]; then
 
 			setpriv --clear-groups --reuid nobody --regid nogroup -- ${data_source#script:} "$ip_name" > "$iplist_tempfile"
@@ -121,7 +120,6 @@ if [ ! -f "${IPSET_PATH}/${IPSET_FILE}.iplist" ] || [ "$force" = "yes" ]; then
 
 		# Use a external ip-list file managed by other apps
 		# ex: Using a ip list that is continously updated
-
 		[ -f "${data_source#file:}" ] && cp -f "${data_source#file:}" "$iplist_tempfile"
 
 	fi
@@ -136,7 +134,7 @@ if [ ! -f "${IPSET_PATH}/${IPSET_FILE}.iplist" ] || [ "$force" = "yes" ]; then
 
 	# Validate iplist file size
 	iplist_size=$(sed -r -e '/^#|^$/d' "$iplist_tempfile" | wc -l)
-	[[ "$iplist_size" -le "$IPSET_MIN_SIZE" ]] && check_result "$E_INVALID" "iplist file too small (<${IPSET_MIN_SIZE}), ignoring"
+	[[ "$iplist_size" -le "$IPSET_MIN_SIZE" ]] && check_result "$E_INVALID" "IP list file too small (<${IPSET_MIN_SIZE}), ignoring"
 	mv -f "$iplist_tempfile" "${IPSET_PATH}/${IPSET_FILE}.iplist"
 
 fi
@@ -168,12 +166,14 @@ if [ ! -f "${IPSET_PATH}.conf" ] || [ -z "$(get_object_value "$ipset_hstobject"
 	str="$str AUTOUPDATE='$autoupdate' SUSPENDED='no'"
 	str="$str TIME='$time' DATE='$date'"
 	echo "$str" >> $HESTIA/data/firewall/ipset.conf
+	log_type="added"
 
-elif [ "$force" = "yes" ]; then
+elif [ "$refresh" = "yes" ]; then
 
-	# update iplist last regen time
+	# Update iplist last regen time
 	update_object_value "$ipset_hstobject" 'LISTNAME' "$ip_name" '$TIME' "$time"
 	update_object_value "$ipset_hstobject" 'LISTNAME' "$ip_name" '$DATE' "$date"
+	log_type="refreshed"
 
 fi
 
@@ -192,7 +192,7 @@ fi
 #----------------------------------------------------------#
 
 # Logging
-$BIN/v-log-action "system" "Info" "Firewall" "Added new IP list (Name: $ip_name, IP version: $ip_version, Autoupdate: $autoupdate)."
+$BIN/v-log-action "system" "Info" "Firewall" "IPset IP list ${log_type:-loaded} (Name: $ip_name, IP version: $ip_version, Autoupdate: $autoupdate)."
 log_event "$OK" "$ARGUMENTS"
 
 exit

+ 14 - 14
bin/v-delete-firewall-ipset

@@ -24,22 +24,22 @@ source_conf "$HESTIA/conf/hestia.conf"
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-ipset_hstobject='../../data/firewall/ipset'
-
 check_args '1' "$#" 'NAME'
 is_format_valid 'ip_name'
 is_system_enabled "$FIREWALL_SYSTEM" 'FIREWALL_SYSTEM'
-is_object_valid "$ipset_hstobject" 'LISTNAME' "$ip_name"
 
+# Define variables for ipset configuration
+ipset_hstobject='../../data/firewall/ipset'
+is_object_valid "$ipset_hstobject" 'LISTNAME' "$ip_name"
 ip_version="$(get_object_value "$ipset_hstobject" 'LISTNAME' "$ip_name" '$IP_VERSION')"
 
-IPSET_BIN="$(which ipset)"
-IPSET_PATH="$HESTIA/data/firewall/ipset"
-IPSET_FILE="${ip_name}.${ip_version}"
-
 # Perform verification if read-only mode is enabled
 check_hestia_demo_mode
 
+IPSET_BIN="$(command -v ipset)"
+IPSET_PATH="$HESTIA/data/firewall/ipset"
+IPSET_FILE="${ip_name}.${ip_version}"
+
 # Install ipset package if missing
 if [ -z "$IPSET_BIN" ]; then
 	if [ -f '/etc/redhat-release' ]; then
@@ -47,22 +47,22 @@ if [ -z "$IPSET_BIN" ]; then
 	else
 		apt-get --quiet --yes install ipset > /dev/null
 	fi
-	check_result $? "Installing ipset package"
+	check_result $? "Installing IPset package"
 
 	IPSET_BIN="$(which ipset)"
-	check_result $? "ipset binary not found"
+	check_result $? "IPset binary not found"
 fi
 
 #----------------------------------------------------------#
 #                       Action                             #
 #----------------------------------------------------------#
 
-if $IPSET_BIN --quiet list "${ip_name}-tmp" > /dev/null; then
-	$IPSET_BIN --quiet destroy "${ip_name}-tmp"
+if $IPSET_BIN -quiet list "${ip_name}-tmp" > /dev/null; then
+	$IPSET_BIN -quiet destroy "${ip_name}-tmp"
 fi
 
-if $IPSET_BIN --quiet list "${ip_name}" > /dev/null; then
-	$IPSET_BIN --quiet destroy "${ip_name}"
+if $IPSET_BIN -quiet list "${ip_name}" > /dev/null; then
+	$IPSET_BIN -quiet destroy "${ip_name}"
 	check_result $? "ipset ${ip_name} still used by iptables. Cannot remove"
 fi
 
@@ -74,7 +74,7 @@ rm -f "${IPSET_PATH}/${IPSET_FILE}.iplist"
 #----------------------------------------------------------#
 
 # Logging
-$BIN/v-log-action "system" "Info" "Firewall" "Deleted IP list (Name: $ip_name)."
+$BIN/v-log-action "system" "Info" "Firewall" "IPset IP list deleted (Name: $ip_name)."
 log_event "$OK" "$ARGUMENTS"
 
 exit

+ 4 - 6
bin/v-stop-firewall

@@ -28,8 +28,6 @@ source_conf "$HESTIA/conf/hestia.conf"
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-#is_system_enabled "$FIREWALL_SYSTEM" 'FIREWALL_SYSTEM'
-
 # Perform verification if read-only mode is enabled
 check_hestia_demo_mode
 
@@ -83,7 +81,7 @@ else
 		echo "[Service]" >> $sd_unit
 		echo "Type=oneshot" >> $sd_unit
 		echo "RemainAfterExit=yes" >> $sd_unit
-		echo "ExecStartPre=-${HESTIA}/bin/v-update-firewall-ipset" >> $sd_unit
+		echo "ExecStartPre=-${HESTIA}/bin/v-update-firewall-ipset load" >> $sd_unit
 		if [ "$iptablesversion" = "v1.6" ]; then
 			echo "ExecStart=/sbin/iptables-restore /etc/iptables.rules" >> $sd_unit
 		else
@@ -92,12 +90,12 @@ else
 		echo "" >> $sd_unit
 		echo "[Install]" >> $sd_unit
 		echo "WantedBy=multi-user.target" >> $sd_unit
-		systemctl daemon-reload
+		systemctl -q daemon-reload
 	fi
-	systemctl is-enabled hestia-iptables > /dev/null 2>&1 && systemctl disable hestia-iptables > /dev/null 2>&1
+	systemctl -q is-enabled hestia-iptables 2> /dev/null && systemctl -q disable hestia-iptables
 	if [ -z "$FIREWALL_SYSTEM" ]; then
 		rm -f $sd_unit
-		systemctl daemon-reload
+		systemctl -q daemon-reload
 	fi
 fi
 

+ 3 - 3
bin/v-update-firewall

@@ -194,7 +194,7 @@ else
 		echo "[Service]" >> $sd_unit
 		echo "Type=oneshot" >> $sd_unit
 		echo "RemainAfterExit=yes" >> $sd_unit
-		echo "ExecStartPre=-${HESTIA}/bin/v-update-firewall-ipset" >> $sd_unit
+		echo "ExecStartPre=-${HESTIA}/bin/v-update-firewall-ipset load" >> $sd_unit
 		if [ "$iptablesversion" = "v1.6" ]; then
 			echo "ExecStart=/sbin/iptables-restore /etc/iptables.rules" >> $sd_unit
 		else
@@ -203,9 +203,9 @@ else
 		echo "" >> $sd_unit
 		echo "[Install]" >> $sd_unit
 		echo "WantedBy=multi-user.target" >> $sd_unit
-		systemctl daemon-reload
+		systemctl -q daemon-reload
 	fi
-	systemctl is-enabled hestia-iptables > /dev/null 2>&1 || systemctl enable hestia-iptables > /dev/null 2>&1
+	systemctl -q is-enabled hestia-iptables 2> /dev/null || systemctl -q enable hestia-iptables
 fi
 
 #----------------------------------------------------------#

+ 7 - 7
bin/v-update-firewall-ipset

@@ -10,8 +10,7 @@
 #                Variables & Functions                     #
 #----------------------------------------------------------#
 
-# Force refresh
-force=${1:-no}
+refresh=${1:-no}
 
 # Includes
 source /etc/profile.d/hestia.sh
@@ -26,7 +25,7 @@ source_conf "$HESTIA/conf/hestia.conf"
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-is_boolean_format_valid "$force" 'bool (yes/no)'
+is_refresh_ipset_format_valid "$refresh" 'Refresh IP lists (load/yes/no)'
 is_system_enabled "$FIREWALL_SYSTEM" 'FIREWALL_SYSTEM'
 
 # Perform verification if read-only mode is enabled
@@ -40,8 +39,9 @@ for ipset_name in $(search_objects "$ipset_hstobject" 'SUSPENDED' 'no' 'LISTNAME
 	ipset_date="$(get_object_value "$ipset_hstobject" 'LISTNAME' "$ipset_name" '$DATE')"
 	ipset_au="$(get_object_value "$ipset_hstobject" 'LISTNAME' "$ipset_name" '$AUTOUPDATE')"
 
-	if [ "$ipset_au" = 'no' ]; then
-		# load existing ip list files in the kernel but don't auto update them
+	if [ "$ipset_au" = 'no' ] || [ "$refresh" = 'load' ]; then
+		# Load existing ip list files in the kernel but don't auto update them
+		# The "load" refresh option is only used by hestia-iptables systemd service
 		$BIN/v-add-firewall-ipset "$ipset_name"
 		continue
 	fi
@@ -50,8 +50,8 @@ for ipset_name in $(search_objects "$ipset_hstobject" 'SUSPENDED' 'no' 'LISTNAME
 	now=$(date +%s)
 	hours_since_update=$(((now - last_updated_ts) / (60 * 60)))
 
-	if [[ "$hours_since_update" -lt 24 ]] && [ "$force" = 'no' ]; then
-		# load existing ip list files in the kernel but don't auto update them
+	if [[ "$hours_since_update" -lt 24 ]] && [ "$refresh" = 'no' ]; then
+		# Load existing ip list files in the kernel but don't auto update them
 		$BIN/v-add-firewall-ipset "$ipset_name"
 		continue
 	fi

+ 7 - 0
func/main.sh

@@ -859,6 +859,13 @@ is_boolean_format_valid() {
 	fi
 }
 
+# Refresh IPset format validator
+is_refresh_ipset_format_valid() {
+	if [ "$1" != 'load' ] && [ "$1" != 'yes' ] && [ "$1" != 'no' ]; then
+		check_result "$E_INVALID" "invalid $2 format :: $1"
+	fi
+}
+
 # Common format validator
 is_common_format_valid() {
 	exclude="[!|#|$|^|&|(|)|+|=|{|}|:|<|>|?|/|\|\"|'|;|%|\`| ]"

+ 7 - 0
install/upgrade/versions/1.6.12.sh

@@ -24,3 +24,10 @@ upgrade_config_set_value 'UPGRADE_UPDATE_FILEMANAGER_CONFIG' 'false'
 if [ -f "/etc/fail2ban/jail.local" ]; then
 	sed -i "s|/var/log/mysql.log|/var/log/mysql/error.log|g" /etc/fail2ban/jail.local
 fi
+
+# Fixed firewall loading failed after reboot, applying update to hestia-iptables Systemd unit.
+if [ "$FIREWALL_SYSTEM" = "iptables" ]; then
+	echo "[ * ] Update loading firewall rules service..."
+	$BIN/v-delete-sys-firewall
+	$BIN/v-add-sys-firewall
+fi