Selaa lähdekoodia

IPV6: Universal shell scripts for add/delete sys ip

bin/v-add-sys-ip

bin/v-delete-sys-ip
asmcc 3 vuotta sitten
vanhempi
sitoutus
8607ebea13
3 muutettua tiedostoa jossa 83 lisäystä ja 57 poistoa
  1. 2 2
      bin/v-add-sys-ip
  2. 64 27
      bin/v-delete-sys-ip
  3. 17 28
      func/ip.sh

+ 2 - 2
bin/v-add-sys-ip

@@ -76,7 +76,7 @@ if [ -n "$ip_format" ]; then
 		if [ -n "$ip_cidr" ]; then
 			cidr=${ip_cidr}
 		else
-			[ -z "$cidr" ] && cidr="/31"
+			[ -z "$cidr" ] && cidr="/32"
 		fi
 		if [ -z "$netmask" ]; then 
 			is_ip_format_valid "${cidr}" 'cidr'	# check for correct cidr
@@ -133,7 +133,7 @@ check_hestia_demo_mode
 
 check_ip_par=""
 [ -n "$ip_format" ] && [ $ip_format -eq 4 -o $ip_format -eq 6 ] && check_ip_par=" -${ip_format}"
-sys_ip_check=$(/sbin/ip$check_ip_par addr | grep "${ip46}")
+sys_ip_check=$(/sbin/ip$check_ip_par addr | sed -ne "/inet[6]*[ \t]${ip46}\//p")
 if [ -z "$sys_ip_check" ]; then
 	# Adding sys ip
 	if [ -n "$ip_format" ] && [ $ip_format -eq 6 ]; then

+ 64 - 27
bin/v-delete-sys-ip

@@ -1,8 +1,10 @@
 #!/bin/bash
 # info: delete system ip
+#       both kind of IP addresses, ipv4 and ipv6 are allowed
 # options: IP
 #
 # example: v-delete-sys-ip 212.42.76.210
+# example: v-delete-sys-ip 1234:5678:abcd:ef90::1
 #
 # This function for deleting a system ip. It does not allow to delete first ip
 # on interface and do not allow to delete ip which is used by a web domain.
@@ -12,7 +14,7 @@
 #----------------------------------------------------------#
 
 # Argument definition
-ip=$1
+ip46=${1%/*}	# clean ip address without cidr/prefix_length
 
 # Includes
 # shellcheck source=/etc/hestiacp/hestia.conf
@@ -31,10 +33,29 @@ source_conf "$HESTIA/conf/hestia.conf"
 #----------------------------------------------------------#
 
 check_args '1' "$#" 'IP'
-is_format_valid 'ip'
-is_ip_valid "$ip"
-is_ip_key_empty '$U_WEB_DOMAINS'
-is_ip_key_empty '$U_SYS_USERS'
+ip_format="$(get_ip_format ${ip46})"	#	ip verification and format identification
+retval=$?
+check_ip_par=""
+add_cap_string_ipv6=""
+[ -n "$ip_format" ] && [ $ip_format -eq 4 -o $ip_format -eq 6 ] && check_ip_par=" -${ip_format}"
+if [ -n "$ip_format" ]; then
+	if [ $ip_format -eq 6 ]; then
+		ip=""
+		ipv6="${ip46}"
+		add_cap_string_ipv6="V6"
+		is_format_valid 'ipv6'
+		is_ipv6_valid "$ipv6"
+	else
+		ip="${ip46}"
+		ipv6=""
+		is_format_valid 'ip'
+		is_ip_valid "$ip"
+	fi
+else
+	check_result $retval "${ip46} is not a valid IPV4/IPV6 address!"
+fi
+is_ip_key_empty '$U_WEB_DOMAINS' ${ip46}
+is_ip_key_empty '$U_SYS_USERS' ${ip46}
 
 # Perform verification if read-only mode is enabled
 check_hestia_demo_mode
@@ -44,13 +65,22 @@ check_hestia_demo_mode
 #----------------------------------------------------------#
 
 # Import ip variables
-source $HESTIA/data/ips/$ip
-cidr=$(convert_netmask "$NETMASK")
-main_ip=$(hostname -i)
+source $HESTIA/data/ips/${ip46}
+if [ $ip_format -eq 6 ]; then
+	prefix_length=${NETMASK}
+	is_format_valid 'prefix_length'
+	cidr_prefixlen=${prefix_length}
+else
+	netmask=${NETMASK}
+	is_format_valid 'netmask'
+	cidr_prefixlen=$(convert_netmask "$netmask")
+fi
+
+host_ip_check=$(hostname -i | sed -ne "/$ip46/p") # check, if IP address is main (listed in /etc/hosts)
+interface=$($BIN/v-list-network plain | sed -ne "/$ip46/s/$ip46[ \t]*[0-9]*[ \t]*\(.*\)/\1/p") # interface for IP address
+number_of_ips=$(/sbin/ip${check_ip_par} addr | grep -c global) # number of global system IP addresses
 
-# Checking main ip on the interface
-interface=$(/sbin/ip addr | grep "$ip$cidr" | awk '{print $NF}')
-if [ -n "$interface" ] && [ "$ip" = "$main_ip" ]; then
+if [[ ( -n "$host_ip_check" && -n "$interface" ) || ( $number_of_ips -eq 1 ) ]]; then
 	echo "Error: can't delete main IP address"
 	log_event "$E_FORBIDEN" "$ARGUMENTS"
 	exit "$E_FORBIDEN"
@@ -58,7 +88,7 @@ fi
 
 # Deleting system ip
 if [ -n "$interface" ]; then
-	/sbin/ip addr del "$ip$cidr" dev "$INTERFACE"
+	/sbin/ip addr del "$ip46$cidr_prefixlen" dev ${INTERFACE%:*}
 	if [ "$?" -ne 0 ]; then
 		echo "Error: can't delete system ip"
 		log_event "$E_FORBIDEN" "$ARGUMENTS"
@@ -73,36 +103,43 @@ fi
 
 # Deleting startup conf on Debian/Ubuntu
 if [ -f "/etc/netplan/60-hestia.yaml" ]; then
-	sed -i "/$ip/d" /etc/netplan/60-hestia.yaml
+	sed -i "/$ip46/d" /etc/netplan/60-hestia.yaml
 	if ! grep -q '-' /etc/netplan/60-hestia.yaml; then
 		rm /etc/netplan/60-hestia.yaml
 	fi
 elif [ -e "/etc/network/interfaces" ]; then
-	ip_str=$(grep -n $ip$ /etc/network/interfaces | cut -f1 -d:)
+	if [ $ip_format -eq 6 ]; then
+		filter_ip="${ip46}${cidr_prefixlen}"
+		lines_after=0	# ipv6 is defined using prefix length in one line
+	else
+		filter_ip="${ip46}"
+		lines_after=1	# ipv4 is defined using netmask in a separate line
+	fi
+	ip_str=$(grep -n $filter_ip$ /etc/network/interfaces | cut -f1 -d:)
 	if [ -n "$ip_str" ]; then
-		first_str=$((ip_str - 3))
-		last_str=$((ip_str + 1))
+		first_str=$((ip_str - 4))
+		last_str=$((ip_str + $lines_after))
 		sed -i "$first_str,$last_str d" /etc/network/interfaces
 	fi
 fi
 
 # Deleting hestia ip
-rm -f $HESTIA/data/ips/$ip
+rm -f $HESTIA/data/ips/${ip46}
 
 # Deleting web config
 if [ -n "$WEB_SYSTEM" ]; then
-	rm -f /etc/$WEB_SYSTEM/conf.d/$ip.conf
+	rm -f /etc/$WEB_SYSTEM/conf.d/${ip46}.conf
 fi
 
 # Deleting proxy config
 if [ -n "$PROXY_SYSTEM" ]; then
-	rm -f /etc/$PROXY_SYSTEM/conf.d/$ip.conf
+	rm -f /etc/$PROXY_SYSTEM/conf.d/${ip46}.conf
 
 	# mod_extract_forwarded
 	fw_conf="/etc/$WEB_SYSTEM/conf.d/mod_extract_forwarded.conf"
 	if [ -e "$fw_conf" ]; then
 		ips=$(grep 'MEFaccept 127.0.0.1' $fw_conf)
-		new_ips=$(echo "$ips" | sed "s/$ip//")
+		new_ips=$(echo "$ips" | sed "s/$ip46//")
 		sed -i "s/$ips/$new_ips/g" $fw_conf
 	fi
 
@@ -110,7 +147,7 @@ if [ -n "$PROXY_SYSTEM" ]; then
 	rpaf_conf="/etc/$WEB_SYSTEM/mods-enabled/rpaf.conf"
 	if [ -e "$rpaf_conf" ]; then
 		ips=$(grep RPAFproxy_ips "$rpaf_conf")
-		new_ips=$(echo "$ips" | sed "s/ $ip//")
+		new_ips=$(echo "$ips" | sed "s/ $ip46//")
 		sed -i "s/$ips/$new_ips/g" "$rpaf_conf"
 
 		# Remove RPAFproxy_ips line when ip list is empty
@@ -120,7 +157,7 @@ if [ -n "$PROXY_SYSTEM" ]; then
 	#mod_remoteip
 	remoteip_conf="/etc/$WEB_SYSTEM/mods-enabled/remoteip.conf"
 	if [ -e "$remoteip_conf" ]; then
-		sed -i "/RemoteIPInternalProxy $ip\$/d" "$remoteip_conf"
+		sed -i "/RemoteIPInternalProxy $ip46\$/d" "$remoteip_conf"
 	fi
 fi
 
@@ -130,19 +167,19 @@ fi
 
 # Updating user conf
 if [ -n "$OWNER" ]; then
-	decrease_user_value "$OWNER" '$IP_OWNED'
+	decrease_user_value "$OWNER" '$IP'$add_cap_string_ipv6'_OWNED'
 fi
 
 if [ "$OWNER" = 'admin' ]; then
 	if [ "$STATUS" = 'shared' ]; then
 		for hestia_user in $($BIN/v-list-sys-users plain); do
-			decrease_user_value "$hestia_user" '$IP_AVAIL'
+			decrease_user_value "$hestia_user" '$IP'$add_cap_string_ipv6'_AVAIL'
 		done
 	else
-		decrease_user_value "$OWNER" '$IP_AVAIL'
+		decrease_user_value "$OWNER" '$IP'$add_cap_string_ipv6'_AVAIL'
 	fi
 else
-	decrease_user_value "$OWNER" '$IP_AVAIL'
+	decrease_user_value "$OWNER" '$IP'$add_cap_string_ipv6'_AVAIL'
 fi
 
 # Restarting web server
@@ -161,7 +198,7 @@ if [ -n "$FIREWALL_SYSTEM" ]; then
 fi
 
 # Logging
-$BIN/v-log-action "system" "Info" "System" "IP address deleted (IP: $ip)."
+$BIN/v-log-action "system" "Info" "System" "IP address deleted (IP: $ip46)."
 log_event "$OK" "$ARGUMENTS"
 
 exit

+ 17 - 28
func/ip.sh

@@ -13,14 +13,17 @@ REGEX_IPV4="^((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9
 
 # Check ip ownership
 is_ip_owner() {
-	owner=$(grep 'OWNER=' $HESTIA/data/ips/$ip | cut -f 2 -d \')
+	# ip address (ipv4/ipv6) as first parameter, otherwise $ip (ipv4)
+	ip_for_test="${1-$ip}"
+	owner=$(grep 'OWNER=' $HESTIA/data/ips/$ip_for_test | cut -f 2 -d \')
 	if [ "$owner" != "$user" ]; then
-		check_result "$E_FORBIDEN" "$ip is not owned by $user"
+		check_result "$E_FORBIDEN" "$ip_for_test is not owned by $user"
 	fi
 }
 
 # Check if ip address is free
 is_ip_free() {
+	# ip address (ipv4/ipv6) as first parameter, otherwise $ip (ipv4)
 	ip_for_test="${1-$ip}"
 	if [ -e "$HESTIA/data/ips/$ip_for_test" ]; then
 		check_result "$E_EXISTS" "$ip_for_test is already exists"
@@ -30,12 +33,18 @@ is_ip_free() {
 # Check ip address specific value
 is_ip_key_empty() {
 	key="$1"
-	string=$(cat $HESTIA/data/ips/$ip)
-	eval $string
-	eval value="$key"
-	if [ -n "$value" ] && [ "$value" != '0' ]; then
-		key="$(echo $key | sed -e "s/\$U_//")"
-		check_result "$E_EXISTS" "IP is in use / $key = $value"
+	# ip address (ipv4/ipv6) as second parameter, otherwise $ip (ipv4)
+	ip_for_test="${2-$ip}"
+	if [ -n "$ip_for_test" ]; then
+		string=$(cat $HESTIA/data/ips/$ip_for_test)
+		eval $string
+		eval value="$key"
+		if [ -n "$value" ] && [ "$value" != '0' ]; then
+			key="$(echo $key | sed -e "s/\$U_//")"
+			check_result "$E_EXISTS" "IP is in use / $key = $value"
+		fi
+	else
+		check_result 1 "is_ip_key_empty(): IP address is empty!"
 	fi
 }
 
@@ -291,14 +300,6 @@ is_ip_valid() {
 
 # === IPV6 specific functions ===
 
-# Check ipv6 ownership
-is_ipv6_owner() {
-    owner=$(grep 'OWNER=' $HESTIA/data/ips/$ipv6 |cut -f 2 -d \')
-    if [ "$owner" != "$user" ]; then
-        check_result $E_FORBIDEN "$ipv6 is not owned by $user"
-    fi
-}
-
 # Get full interface name
 get_ipv6_iface() {
     i=$(/sbin/ip addr |grep -w $interface |\
@@ -311,18 +312,6 @@ get_ipv6_iface() {
     echo "$interface:$n"
 }
 
-# Check ipv6 address speciefic value
-is_ipv6_key_empty() {
-    key="$1"
-    string=$(cat $HESTIA/data/ips/$ipv6)
-    eval $string
-    eval value="$key"
-    if [ ! -z "$value" ] && [ "$value" != '0' ]; then
-        key="$(echo $key|sed -e "s/\$U_//")"
-        check_result $E_EXISTS "IP6 is in use / $key = $value"
-    fi
-}
-
 # Update ipv6 address value
 update_ipv6_value() {
     key="$1"