You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							238 lines
						
					
					
						
							7.2 KiB
						
					
					
				
			
		
		
	
	
							238 lines
						
					
					
						
							7.2 KiB
						
					
					
				#!/bin/bash
 | 
						|
# info: add system IP address
 | 
						|
# options: IP NETMASK [INTERFACE] [USER] [IP_STATUS] [IP_NAME] [NAT_IP]
 | 
						|
#
 | 
						|
# example: v-add-sys-ip 203.0.113.1 255.255.255.0
 | 
						|
#
 | 
						|
# This function adds IP address into a system. It also creates rc scripts. You
 | 
						|
# can specify IP name which will be used as root domain for temporary aliases.
 | 
						|
# For example, if you set a1.myhosting.com as name, each new domain created on
 | 
						|
# this IP will automatically receive alias $domain.a1.myhosting.com. Of course
 | 
						|
# you must have wildcard record *.a1.myhosting.com pointed to IP. This feature
 | 
						|
# is very handy when customer wants to test domain before dns migration.
 | 
						|
 | 
						|
#----------------------------------------------------------#
 | 
						|
#                Variables & Functions                     #
 | 
						|
#----------------------------------------------------------#
 | 
						|
 | 
						|
# Argument definition
 | 
						|
ip="${1// /}"
 | 
						|
netmask="$2"
 | 
						|
 | 
						|
# Get interface name
 | 
						|
# First try to detect which interface the IP address resides on
 | 
						|
iface="$(ip -d -j addr show | jq --arg IP "$ip" -r '.[] | if .addr_info[].local == $IP then .ifname else empty end')"
 | 
						|
# If that fails, detect the default interface as a fallback
 | 
						|
if [ -z "$iface" ]; then
 | 
						|
	iface="$(ip -d -j route show | jq -r '.[] | if .dst == "default" then .dev else empty end')"
 | 
						|
fi
 | 
						|
 | 
						|
iface="${3-$iface}"
 | 
						|
user="${4-admin}"
 | 
						|
ip_status="${5-shared}"
 | 
						|
ip_name="$6"
 | 
						|
nat_ip="$7"
 | 
						|
 | 
						|
# Includes
 | 
						|
# shellcheck source=/etc/hestiacp/hestia.conf
 | 
						|
source /etc/hestiacp/hestia.conf
 | 
						|
# shellcheck source=/usr/local/hestia/func/main.sh
 | 
						|
source $HESTIA/func/main.sh
 | 
						|
# shellcheck source=/usr/local/hestia/func/ip.sh
 | 
						|
source $HESTIA/func/ip.sh
 | 
						|
# shellcheck source=/usr/local/hestia/func/domain.sh
 | 
						|
source $HESTIA/func/domain.sh
 | 
						|
# load config file
 | 
						|
source_conf "$HESTIA/conf/hestia.conf"
 | 
						|
 | 
						|
#----------------------------------------------------------#
 | 
						|
#                    Verifications                         #
 | 
						|
#----------------------------------------------------------#
 | 
						|
 | 
						|
check_args '2' "$#" 'IP NETMASK [INTERFACE] [USER] [STATUS] [NAME] [NATED_IP]'
 | 
						|
is_format_valid 'ip' 'netmask' 'iface' 'user' 'ip_status'
 | 
						|
is_ip_free
 | 
						|
is_object_valid 'user' 'USER' "$user"
 | 
						|
is_object_unsuspended 'user' 'USER' "$user"
 | 
						|
if [ -n "$ip_name" ]; then
 | 
						|
	is_format_valid 'ip_name'
 | 
						|
fi
 | 
						|
if [ -n "$nat_ip" ]; then
 | 
						|
	is_format_valid 'nat_ip'
 | 
						|
fi
 | 
						|
if [ "$user" != "admin" ]; then
 | 
						|
	ip_status="dedicated"
 | 
						|
fi
 | 
						|
 | 
						|
# Perform verification if read-only mode is enabled
 | 
						|
check_hestia_demo_mode
 | 
						|
 | 
						|
#----------------------------------------------------------#
 | 
						|
#                       Action                             #
 | 
						|
#----------------------------------------------------------#
 | 
						|
 | 
						|
cidr="$(convert_netmask "$netmask")"
 | 
						|
broadcast="$(get_broadcast "$ip" "$netmask")"
 | 
						|
 | 
						|
sys_ip_check="$(ip addr | grep -w "$ip")"
 | 
						|
if [ -z "$sys_ip_check" ]; then
 | 
						|
	# Adding system IP
 | 
						|
	ip addr add "$ip/$cidr" dev "$iface" broadcast "$broadcast" label "$iface"
 | 
						|
 | 
						|
	# Check if netplan is in use and generate configuration file
 | 
						|
	if [ -n "$(netplan generate --mapping "$iface" 2> /dev/null | grep networkd)" ]; then
 | 
						|
		netplan="true"
 | 
						|
	else
 | 
						|
		netplan="false"
 | 
						|
	fi
 | 
						|
 | 
						|
	if [ "$netplan" = "true" ]; then
 | 
						|
		if [ -f "/etc/netplan/60-hestia.yaml" ]; then
 | 
						|
			sys_ip="        - $ip/$cidr"
 | 
						|
		else
 | 
						|
			sys_ip="# Added by Hestia, please do not edit the file manually!"
 | 
						|
			sys_ip="$sys_ip\nnetwork:"
 | 
						|
			sys_ip="$sys_ip\n  version: 2"
 | 
						|
			sys_ip="$sys_ip\n  renderer: networkd"
 | 
						|
			sys_ip="$sys_ip\n  ethernets:"
 | 
						|
			sys_ip="$sys_ip\n    $iface:"
 | 
						|
			sys_ip="$sys_ip\n      addresses:"
 | 
						|
			sys_ip="$sys_ip\n        - $ip/$cidr"
 | 
						|
		fi
 | 
						|
		IFS='%'
 | 
						|
		echo -e "$sys_ip" >> /etc/netplan/60-hestia.yaml
 | 
						|
		unset IFS
 | 
						|
	else
 | 
						|
		sys_ip="\n# Added by Hestia Control Panel"
 | 
						|
		sys_ip="$sys_ip\nauto $iface"
 | 
						|
		sys_ip="$sys_ip\niface $iface inet static"
 | 
						|
		sys_ip="$sys_ip\naddress $ip"
 | 
						|
		sys_ip="$sys_ip\nnetmask $netmask"
 | 
						|
		echo -e $sys_ip >> /etc/network/interfaces
 | 
						|
	fi
 | 
						|
fi
 | 
						|
 | 
						|
# Generating timestamp
 | 
						|
new_timestamp
 | 
						|
 | 
						|
# Adding Hestia IP
 | 
						|
echo "OWNER='$user'
 | 
						|
STATUS='$ip_status'
 | 
						|
NAME='$ip_name'
 | 
						|
U_SYS_USERS=''
 | 
						|
U_WEB_DOMAINS='0'
 | 
						|
INTERFACE='$iface'
 | 
						|
NETMASK='$netmask'
 | 
						|
NAT='$nat_ip'
 | 
						|
TIME='$time'
 | 
						|
DATE='$date'" > $HESTIA/data/ips/$ip
 | 
						|
chmod 660 $HESTIA/data/ips/$ip
 | 
						|
 | 
						|
confd=$(get_conf_d_name "$WEB_SYSTEM")
 | 
						|
pconfd=$(get_conf_d_name "$PROXY_SYSTEM")
 | 
						|
 | 
						|
# WEB support
 | 
						|
if [ -n "$WEB_SYSTEM" ]; then
 | 
						|
	web_conf="/etc/$WEB_SYSTEM/$confd/$ip.conf"
 | 
						|
	rm -f "$web_conf"
 | 
						|
 | 
						|
	if [ "$WEB_SYSTEM" = 'httpd' ] || [ "$WEB_SYSTEM" = 'apache2' ]; then
 | 
						|
		if [ -z "$(/usr/sbin/apachectl -v | grep Apache/2.4)" ]; then
 | 
						|
			echo "NameVirtualHost $ip:$WEB_PORT" > "$web_conf"
 | 
						|
		fi
 | 
						|
		echo "Listen $ip:$WEB_PORT" >> "$web_conf"
 | 
						|
		cat $HESTIA_INSTALL_DIR/apache2/unassigned.conf >> "$web_conf"
 | 
						|
		sed -i 's/directIP/'$ip'/g' "$web_conf"
 | 
						|
		sed -i 's/directPORT/'$WEB_PORT'/g' "$web_conf"
 | 
						|
 | 
						|
	elif [ "$WEB_SYSTEM" = 'nginx' ]; then
 | 
						|
		cp -f $HESTIA_INSTALL_DIR/nginx/unassigned.inc "$web_conf"
 | 
						|
		sed -i 's/directIP/'$ip'/g' "$web_conf"
 | 
						|
		process_http2_directive "$web_conf"
 | 
						|
	fi
 | 
						|
 | 
						|
	if [ "$WEB_SSL" = 'mod_ssl' ]; then
 | 
						|
		if [ -z "$(/usr/sbin/apachectl -v | grep Apache/2.4)" ]; then
 | 
						|
			sed -i "1s/^/NameVirtualHost $ip:$WEB_SSL_PORT\n/" "$web_conf"
 | 
						|
		fi
 | 
						|
		sed -i "1s/^/Listen $ip:$WEB_SSL_PORT\n/" "$web_conf"
 | 
						|
		sed -i 's/directSSLPORT/'$WEB_SSL_PORT'/g' "$web_conf"
 | 
						|
	fi
 | 
						|
fi
 | 
						|
 | 
						|
# Proxy support
 | 
						|
if [ -n "$PROXY_SYSTEM" ]; then
 | 
						|
	cat $WEBTPL/$PROXY_SYSTEM/proxy_ip.tpl \
 | 
						|
		| sed -e "s/%ip%/$ip/g" \
 | 
						|
			-e "s/%web_port%/$WEB_PORT/g" \
 | 
						|
			-e "s/%proxy_port%/$PROXY_PORT/g" \
 | 
						|
			-e "s/%proxy_ssl_port%/$PROXY_SSL_PORT/g" \
 | 
						|
			> /etc/$PROXY_SYSTEM/$pconfd/$ip.conf
 | 
						|
 | 
						|
	process_http2_directive "/etc/$PROXY_SYSTEM/$pconfd/$ip.conf"
 | 
						|
 | 
						|
	# mod_extract_forwarded
 | 
						|
	fw_conf="/etc/$WEB_SYSTEM/$confd/mod_extract_forwarded.conf"
 | 
						|
	if [ -e "$fw_conf" ]; then
 | 
						|
		ips=$(grep 'MEFaccept ' "$fw_conf" | grep -v '#' | head -n1)
 | 
						|
		sed -i "s/$ips/$ips $ip/g" "$fw_conf"
 | 
						|
	fi
 | 
						|
 | 
						|
	# mod_rpaf
 | 
						|
	rpaf_conf="/etc/$WEB_SYSTEM/mods-enabled/rpaf.conf"
 | 
						|
	if [ -e "$rpaf_conf" ]; then
 | 
						|
		rpaf_str="$(grep RPAFproxy_ips "$rpaf_conf")"
 | 
						|
		[ -z "$rpaf_str" ] && sed -i 's|</IfModule>|RPAFproxy_ips\n</IfModule>|' "$rpaf_conf" && rpaf_str='RPAFproxy_ips'
 | 
						|
		rpaf_str="$rpaf_str $ip"
 | 
						|
		sed -i "s/.*RPAFproxy_ips.*/$rpaf_str/" "$rpaf_conf"
 | 
						|
	fi
 | 
						|
 | 
						|
	# mod_remoteip
 | 
						|
	remoteip_conf="/etc/$WEB_SYSTEM/mods-enabled/remoteip.conf"
 | 
						|
	if [ -e "$remoteip_conf" ]; then
 | 
						|
		if [ "$(grep -ic "$ip" "$remoteip_conf")" -eq "0" ]; then
 | 
						|
			sed -i "s/<\/IfModule>/RemoteIPInternalProxy $ip\n<\/IfModule>/g" "$remoteip_conf"
 | 
						|
		fi
 | 
						|
	fi
 | 
						|
fi
 | 
						|
 | 
						|
#----------------------------------------------------------#
 | 
						|
#                       Hestia                             #
 | 
						|
#----------------------------------------------------------#
 | 
						|
 | 
						|
# Updating user counters
 | 
						|
increase_user_value "$user" '$IP_OWNED'
 | 
						|
if [ "$user" = 'admin' ]; then
 | 
						|
	if [ "$ip_status" = 'shared' ]; then
 | 
						|
		for hestia_user in $($BIN/v-list-sys-users plain); do
 | 
						|
			increase_user_value "$hestia_user" '$IP_AVAIL'
 | 
						|
		done
 | 
						|
	else
 | 
						|
		increase_user_value 'admin' '$IP_AVAIL'
 | 
						|
	fi
 | 
						|
else
 | 
						|
	increase_user_value "$user" '$IP_AVAIL'
 | 
						|
	increase_user_value 'admin' '$IP_AVAIL'
 | 
						|
fi
 | 
						|
 | 
						|
# Restarting web server
 | 
						|
$BIN/v-restart-web
 | 
						|
check_result $? "Web restart failed" > /dev/null
 | 
						|
 | 
						|
# Restarting proxy server
 | 
						|
if [ -n "$PROXY_SYSTEM" ]; then
 | 
						|
	$BIN/v-restart-proxy
 | 
						|
	check_result $? "Proxy restart failed" > /dev/null
 | 
						|
fi
 | 
						|
 | 
						|
# Restarting firewall
 | 
						|
if [ -n "$FIREWALL_SYSTEM" ]; then
 | 
						|
	$BIN/v-update-firewall
 | 
						|
fi
 | 
						|
 | 
						|
# Logging
 | 
						|
$BIN/v-log-action "system" "Info" "Network" "Added new IP address to the system (IP: $ip)."
 | 
						|
log_event "$OK" "$ARGUMENTS"
 | 
						|
 | 
						|
exit
 |