Procházet zdrojové kódy

Add separated ipv4 and ipv6 cidr validator for firewall

Robert-Jan de Dreu před 1 rokem
rodič
revize
6981f86fdd

+ 10 - 10
bin/v-add-firewall-ban

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: add firewall blocking rule
-# options: IP CHAIN
+# options: IPV4_CIDR CHAIN
 #
 # example: v-add-firewall-ban 37.120.129.20 MAIL
 #
@@ -11,7 +11,7 @@
 #----------------------------------------------------------#
 
 # Argument definition
-ip=$1
+ipv4_cidr=$1
 chain=$(echo $2 | tr '[:lower:]' '[:upper:]')
 
 # Defining absolute path for iptables and modprobe
@@ -31,8 +31,8 @@ source_conf "$HESTIA/conf/hestia.conf"
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-check_args '2' "$#" 'IP CHAIN'
-is_format_valid 'ip' 'chain'
+check_args '2' "$#" 'IPV4_CIDR CHAIN'
+is_format_valid 'ipv4_cidr' 'chain'
 is_system_enabled "$FIREWALL_SYSTEM" 'FIREWALL_SYSTEM'
 
 # Perform verification if read-only mode is enabled
@@ -46,20 +46,20 @@ check_hestia_demo_mode
 heal_iptables_links
 
 # Checking server ip
-if [ -e "$HESTIA/data/ips/$ip" ] || [ "$ip" = '127.0.0.1' ]; then
+if [ -e "$HESTIA/data/ips/$ipv4_cidr" ] || [ "$ipv4_cidr" = '127.0.0.1' ]; then
 	exit
 fi
 
 # Checking ip exclusions
 excludes="$HESTIA/data/firewall/excludes.conf"
-check_excludes=$(grep "^$ip$" $excludes 2> /dev/null)
+check_excludes=$(grep "^$ipv4_cidr$" $excludes 2> /dev/null)
 if [ -n "$check_excludes" ]; then
 	exit
 fi
 
 # Checking ip in banlist
 conf="$HESTIA/data/firewall/banlist.conf"
-check_ip=$(grep "IP='$ip' CHAIN='$chain'" $conf 2> /dev/null)
+check_ip=$(grep "IP='$ipv4_cidr' CHAIN='$chain'" $conf 2> /dev/null)
 if [ -n "$check_ip" ]; then
 	exit
 fi
@@ -73,8 +73,8 @@ time=$(echo "$time_n_date" | cut -f 1 -d \ )
 date=$(echo "$time_n_date" | cut -f 2 -d \ )
 
 # Adding ip to banlist
-echo "IP='$ip' CHAIN='$chain' TIME='$time' DATE='$date'" >> $conf
-$iptables -I fail2ban-$chain 1 -s $ip \
+echo "IP='$ipv4_cidr' CHAIN='$chain' TIME='$time' DATE='$date'" >> $conf
+$iptables -I fail2ban-$chain 1 -s $ipv4_cidr \
 	-j REJECT --reject-with icmp-port-unreachable 2> /dev/null
 
 # Changing permissions
@@ -85,7 +85,7 @@ chmod 660 $conf
 #----------------------------------------------------------#
 
 # Logging
-$BIN/v-log-action "system" "Warning" "Firewall" "Banned IP address $ip."
+$BIN/v-log-action "system" "Warning" "Firewall" "Banned IP address $ipv4_cidr."
 log_event "$OK" "$ARGUMENTS"
 
 exit

+ 7 - 7
bin/v-add-firewall-rule

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: add firewall rule
-# options: ACTION IP PORT [PROTOCOL] [COMMENT] [RULE]
+# options: ACTION IPV4_CIDR PORT [PROTOCOL] [COMMENT] [RULE]
 #
 # example: v-add-firewall-rule DROP 185.137.111.77 25
 #
@@ -12,7 +12,7 @@
 
 # Argument definition
 action=$(echo $1 | tr '[:lower:]' '[:upper:]')
-ip=$2
+ipv4_cidr=$2
 port_ext=$3
 protocol=${4-TCP}
 protocol=$(echo $protocol | tr '[:lower:]' '[:upper:]')
@@ -47,7 +47,7 @@ sort_fw_rules() {
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-check_args '3' "$#" 'ACTION IP PORT [PROTOCOL] [COMMENT] [RULE]'
+check_args '3' "$#" 'ACTION IPV4_CIDR PORT [PROTOCOL] [COMMENT] [RULE]'
 is_format_valid 'action' 'protocol' 'port_ext'
 is_system_enabled "$FIREWALL_SYSTEM" 'FIREWALL_SYSTEM'
 get_next_fw_rule
@@ -56,12 +56,12 @@ is_object_new '../../../data/firewall/rules' 'RULE' "$rule"
 if [ -n "$comment" ]; then
 	is_format_valid 'comment'
 fi
-if [[ "$ip" =~ ^ipset: ]]; then
-	ipset_name="${ip#ipset:}"
+if [[ "$ipv4_cidr" =~ ^ipset: ]]; then
+	ipset_name="${ipv4_cidr#ipset:}"
 	$BIN/v-list-firewall-ipset plain | grep "^$ipset_name\s" > /dev/null
 	check_result $? 'ipset object not found' "$E_NOTEXIST"
 else
-	is_format_valid 'ip'
+	is_format_valid 'ipv4_cidr'
 fi
 
 # Perform verification if read-only mode is enabled
@@ -78,7 +78,7 @@ date=$(echo "$time_n_date" | cut -f 2 -d \ )
 
 # Concatenating rule
 str="RULE='$rule' ACTION='$action' PROTOCOL='$protocol' PORT='$port_ext'"
-str="$str IP='$ip' COMMENT='$comment' SUSPENDED='no'"
+str="$str IP='$ipv4_cidr' COMMENT='$comment' SUSPENDED='no'"
 str="$str TIME='$time' DATE='$date'"
 
 # Adding to config

+ 7 - 7
bin/v-change-firewall-rule

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: change firewall rule
-# options: RULE ACTION IP PORT [PROTOCOL] [COMMENT]
+# options: RULE ACTION IPV4_CIDR PORT [PROTOCOL] [COMMENT]
 #
 # example: v-change-firewall-rule 3 ACCEPT 5.188.123.17 443
 #
@@ -14,7 +14,7 @@
 # Argument definition
 rule=$1
 action=$(echo $2 | tr '[:lower:]' '[:upper:]')
-ip=$3
+ipv4_cidr=$3
 port_ext=$4
 protocol=${5-TCP}
 protocol=$(echo $protocol | tr '[:lower:]' '[:upper:]')
@@ -40,7 +40,7 @@ sort_fw_rules() {
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-check_args '4' "$#" 'RULE ACTION IP PORT [PROTOCOL] [COMMENT]'
+check_args '4' "$#" 'RULE ACTION IPV4_CIDR PORT [PROTOCOL] [COMMENT]'
 is_format_valid 'rule' 'action' 'protocol' 'port_ext'
 if [ ! -z "$comment" ]; then
 	is_format_valid 'comment'
@@ -48,12 +48,12 @@ fi
 is_system_enabled "$FIREWALL_SYSTEM" 'FIREWALL_SYSTEM'
 is_object_valid '../../../data/firewall/rules' 'RULE' "$rule"
 
-if [[ "$ip" =~ ^ipset: ]]; then
-	ipset_name="${ip#ipset:}"
+if [[ "$ipv4_cidr" =~ ^ipset: ]]; then
+	ipset_name="${ipv4_cidr#ipset:}"
 	$BIN/v-list-firewall-ipset plain | grep "^$ipset_name\s" > /dev/null
 	check_result $? 'ipset object not found' "$E_NOTEXIST"
 else
-	is_format_valid 'ip'
+	is_format_valid 'ipv4_cidr'
 fi
 
 # Perform verification if read-only mode is enabled
@@ -70,7 +70,7 @@ date=$(echo "$time_n_date" | cut -f 2 -d \ )
 
 # Concatenating firewall rule
 str="RULE='$rule' ACTION='$action' PROTOCOL='$protocol' PORT='$port_ext'"
-str="$str IP='$ip' COMMENT='$comment' SUSPENDED='no'"
+str="$str IP='$ipv4_cidr' COMMENT='$comment' SUSPENDED='no'"
 str="$str TIME='$time' DATE='$date'"
 
 # Deleting old rule

+ 11 - 11
bin/v-delete-firewall-ban

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: delete firewall blocking rule
-# options: IP CHAIN
+# options: IPV4_CIDR CHAIN
 #
 # example: v-delete-firewall-ban 198.11.130.250 MAIL
 #
@@ -11,7 +11,7 @@
 #----------------------------------------------------------#
 
 # Argument definition
-ip=$1
+ipv4_cidr=$1
 chain=$(echo $2 | tr '[:lower:]' '[:upper:]')
 
 # Defining absolute path for iptables and modprobe
@@ -31,8 +31,8 @@ source_conf "$HESTIA/conf/hestia.conf"
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-check_args '2' "$#" 'IP CHAIN'
-is_format_valid 'ip' 'chain'
+check_args '2' "$#" 'IPV4_CIDR CHAIN'
+is_format_valid 'ipv4_cidr' 'chain'
 is_system_enabled "$FIREWALL_SYSTEM" 'FIREWALL_SYSTEM'
 
 # Perform verification if read-only mode is enabled
@@ -47,30 +47,30 @@ heal_iptables_links
 
 conf="$HESTIA/data/firewall/banlist.conf"
 if [ "$chain" == "ALL" ]; then
-	check_ip=$(grep "IP='$ip' CHAIN='*'" $conf)
+	check_ip=$(grep "IP='$ipv4_cidr' CHAIN='*'" $conf)
 	if [ -z "$check_ip" ]; then
 		exit
 	fi
-	grep "IP='$ip' CHAIN='*'" $conf | while read -r line; do
+	grep "IP='$ipv4_cidr' CHAIN='*'" $conf | while read -r line; do
 		parse_object_kv_list $line
 
 		# Deleting ip from banlist
 		sip=$(echo "$IP" | sed "s|/|\\\/|g")
 		sed -i "/IP='$sip' CHAIN='$CHAIN'/d" $conf
-		b=$($iptables -L fail2ban-$CHAIN --line-number -n | grep -w $ip | awk '{print $1}')
+		b=$($iptables -L fail2ban-$CHAIN --line-number -n | grep -w $ipv4_cidr | awk '{print $1}')
 		$iptables -D fail2ban-$CHAIN $b 2> /dev/null
 	done
 else
 	# Checking ip in banlist
-	check_ip=$(grep "IP='$ip' CHAIN='$chain'" $conf 2> /dev/null)
+	check_ip=$(grep "IP='$ipv4_cidr' CHAIN='$chain'" $conf 2> /dev/null)
 	if [ -z "$check_ip" ]; then
 		exit
 	fi
 
 	# Deleting ip from banlist
-	sip=$(echo "$ip" | sed "s|/|\\\/|g")
+	sip=$(echo "$ipv4_cidr" | sed "s|/|\\\/|g")
 	sed -i "/IP='$sip' CHAIN='$chain'/d" $conf
-	b=$($iptables -L fail2ban-$chain --line-number -n | grep -w $ip | awk '{print $1}')
+	b=$($iptables -L fail2ban-$chain --line-number -n | grep -w $ipv4_cidr | awk '{print $1}')
 	$iptables -D fail2ban-$chain $b 2> /dev/null
 fi
 
@@ -82,7 +82,7 @@ chmod 660 $conf
 #----------------------------------------------------------#
 
 # Logging
-$BIN/v-log-action "system" "Info" "Firewall" "Removed IP from ban list (IP: $ip, Service: $chain)."
+$BIN/v-log-action "system" "Info" "Firewall" "Removed IP from ban list (IP: $ipv4_cidr, Service: $chain)."
 log_event "$OK" "$ARGUMENTS"
 
 exit

+ 18 - 0
func/main.sh

@@ -814,6 +814,22 @@ is_ip46_format_valid() {
     fi
 }
 
+is_ipv4_cidr_format_valid() {
+    object_name=${2-ip}
+    valid=$($HESTIA_PHP -r '$cidr="$argv[1]"; list($ip, $netmask) = [...explode("/", $cidr), 32]; echo ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && $netmask <= 32) ? 0 : 1);' $1);
+    if [ "$valid" -ne 0 ]; then
+        check_result "$E_INVALID" "invalid $object_name :: $1"
+    fi
+}
+
+is_ipv6_cidr_format_valid() {
+    object_name=${2-ipv6}
+    valid=$($HESTIA_PHP -r '$cidr="$argv[1]"; list($ip, $netmask) = [...explode("/", $cidr), 128]; echo ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && $netmask <= 128) ? 0 : 1);' $1);
+    if [ "$valid" -ne 0 ]; then
+        check_result "$E_INVALID" "invalid $object_name :: $1"
+    fi
+}
+
 is_netmask_format_valid() {
     object_name=${2-netmask}
     valid=$($HESTIA_PHP -r '$netmask="$argv[1]"; echo (preg_match("/^(128|192|224|240|248|252|254|255)\.(0|128|192|224|240|248|252|254|255)\.(0|128|192|224|240|248|252|254|255)\.(0|128|192|224|240|248|252|254|255)/", $netmask) ? 0 : 1);' $1);
@@ -1213,6 +1229,8 @@ is_format_valid() {
 				ip) is_ip_format_valid "$arg" ;;
 				ipv6) is_ipv6_format_valid "$arg" ;;
 				ip46) is_ip46_format_valid "$arg" ;;
+				ipv4_cidr) is_ipv4_cidr_format_valid "$arg" ;;
+				ipv6_cidr) is_ipv6_cidr_format_valid "$arg" ;;
 				ip_name) is_domain_format_valid "$arg" 'IP name' ;;
 				ip_status) is_ip_status_format_valid "$arg" ;;
 				job) is_int_format_valid "$arg" 'job' ;;