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
|