#!/bin/bash # ======================================================== # # # Hestia Control Panel Installer for RHEL based OS # https://hestiadocs.brepo.ru/ # # Currently Supported Versions: # Red Hat Enterprise Linux based distros # # ======================================================== # #----------------------------------------------------------# # Variables&Functions # #----------------------------------------------------------# export PATH=$PATH:/sbin VERSION='rhel' HESTIA='/usr/local/hestia' LOG="/root/hst_install_backups/hst_install-$(date +%d%m%Y%H%M).log" memory=$(grep 'MemTotal' /proc/meminfo | tr ' ' '\n' | grep [0-9]) hst_backups="/root/hst_install_backups/$(date +%d%m%Y%H%M)" spinner="/-\|" os='rhel' arch="$(arch)" type=$(grep "^ID=" /etc/os-release | cut -f 2 -d '"') VERSION=$type # TODO: Not sure if condition below is required if [[ "$type" =~ ^(rhel|almalinux|eurolinux|ol|rocky|centos|msvsphere)$ ]]; then release=$(rpm --eval='%rhel') fi if [ "$release" -lt 8 ]; then echo "Unsupported version of OS" fi HESTIA_INSTALL_DIR="$HESTIA/install/rpm" HESTIA_COMMON_DIR="$HESTIA/install/common" VERBOSE='no' # Define software versions HESTIA_INSTALL_VER='1.9.4.rpm~alpha' # Dependencies mariadb_v="10.11" multiphp_v=("74" "80" "81" "82" "83") # default PHP version php_v="82" php_modules_install="mysqlnd mysqli pdo_mysql pgsql pdo sqlite pdo_sqlite pdo_pgsql imap ldap zip opcache xmlwriter xmlreader gd intl pspell" php_modules_disable="" mod_php="enable" software="nginx httpd.${arch} httpd-tools httpd-itk mod_fcgid mod_suphp mod_ssl MariaDB-client MariaDB-common MariaDB-server mysql.${arch} mysql-common mysql-server postgresql-server postgresql sqlite.${arch} vsftpd proftpd bind exim clamd clamav spamassassin dovecot dovecot-pigeonhole hestia hestia-nginx hestia-php rrdtool quota e2fsprogs fail2ban dnsutils util-linux cronie expect perl-Mail-DKIM unrar vim acl sysstat rsyslog openssh-clients util-linux ipset zstd systemd-timesyncd jq awstats perl-Switch net-tools mc flex whois git idn2 unzip zip sudo bc ftp lsof" installer_dependencies="gnupg2 policycoreutils wget ca-certificates" # Defining help function help() { echo "Usage: $0 [OPTIONS] -a, --apache Install Apache [yes|no] default: yes -w, --phpfpm Install PHP-FPM [yes|no] default: yes -o, --multiphp Install Multi-PHP [yes|no] default: no -v, --vsftpd Install Vsftpd [yes|no] default: yes -j, --proftpd Install ProFTPD [yes|no] default: no -k, --named Install Bind [yes|no] default: yes -m, --mysql Install MariaDB [yes|no] default: yes -M, --mysql-classic Install MySQL 8 [yes|no] default: no -g, --postgresql Install PostgreSQL [yes|no] default: no -x, --exim Install Exim [yes|no] default: yes -z, --dovecot Install Dovecot [yes|no] default: yes -Z, --sieve Install Sieve [yes|no] default: no -c, --clamav Install ClamAV [yes|no] default: no -t, --spamassassin Install SpamAssassin [yes|no] default: yes -i, --iptables Install Iptables [yes|no] default: yes -b, --fail2ban Install Fail2ban [yes|no] default: yes -q, --quota Filesystem Quota [yes|no] default: no -d, --api Activate API [yes|no] default: yes -r, --port Change Backend Port default: 8083 -l, --lang Default language default: en -y, --interactive Interactive install [yes|no] default: yes -I, --nopublicip Use local ip [yes|no] default: yes -u, --uselocalphp Use PHP from local repo [yes|no] default: yes -s, --hostname Set hostname -e, --email Set admin email -p, --password Set admin password -R, --with-rpms Path to Hestia rpms -f, --force Force installation -h, --help Print this help Example: bash $0 -e demo@hestiacp.com -p p4ssw0rd --multiphp yes" exit 1 } # Defining file download function download_file() { wget $1 -q --show-progress --progress=bar:force } # Defining password-gen function gen_pass() { matrix=$1 length=$2 if [ -z "$matrix" ]; then matrix="A-Za-z0-9" fi if [ -z "$length" ]; then length=16 fi head /dev/urandom | tr -dc $matrix | head -c$length } # Defining return code check function check_result() { if [ $1 -ne 0 ]; then echo "Error: $2" exit $1 fi } # Defining function to set default value set_default_value() { eval variable=\$$1 if [ -z "$variable" ]; then eval $1=$2 fi if [ "$variable" != 'yes' ] && [ "$variable" != 'no' ]; then eval $1=$2 fi } # Defining function to set default language value set_default_lang() { if [ -z "$lang" ]; then eval lang=$1 fi lang_list="ar az bg bn bs ca cs da de el en es fa fi fr hr hu id it ja ka ku ko nl no pl pt pt-br ro ru sk sr sv th tr uk ur vi zh-cn zh-tw" if ! (echo $lang_list | grep -w $lang > /dev/null 2>&1); then eval lang=$1 fi } # Define the default backend port set_default_port() { if [ -z "$port" ]; then eval port=$1 fi } # Write configuration KEY/VALUE pair to $HESTIA/conf/hestia.conf write_config_value() { local key="$1" local value="$2" echo "$key='$value'" >> $HESTIA/conf/hestia.conf } # Sort configuration file values # Write final copy to $HESTIA/conf/hestia.conf for active usage # Duplicate file to $HESTIA/conf/defaults/hestia.conf to restore known good installation values sort_config_file() { sort $HESTIA/conf/hestia.conf -o /tmp/updconf mv $HESTIA/conf/hestia.conf $HESTIA/conf/hestia.conf.bak mv /tmp/updconf $HESTIA/conf/hestia.conf rm -f $HESTIA/conf/hestia.conf.bak if [ ! -d "$HESTIA/conf/defaults/" ]; then mkdir -p "$HESTIA/conf/defaults/" fi cp $HESTIA/conf/hestia.conf $HESTIA/conf/defaults/hestia.conf } # Validate hostname according to RFC1178 validate_hostname() { # remove extra . servername=$(echo "$servername" | sed -e "s/[.]*$//g") servername=$(echo "$servername" | sed -e "s/^[.]*//") if [[ $(echo "$servername" | grep -o "\." | wc -l) -gt 1 ]] && [[ ! $servername =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then # Hostname valid return 1 else # Hostname invalid return 0 fi } validate_email() { if [[ ! "$email" =~ ^[A-Za-z0-9._%+-]+@[[:alnum:].-]+\.[A-Za-z]{2,63}$ ]]; then # Email invalid return 0 else # Email valid return 1 fi } get_link_name(){ str_result="" ext_name=$1 pattern=("01-ioncube.ini" "10-opcache.ini" "20-bcmath.ini" "20-bz2.ini" "20-calendar.ini" "20-ctype.ini" "20-curl.ini" "20-dba.ini" "20-dom.ini" "20-enchant.ini" "20-exif.ini" "20-ffi.ini" "20-fileinfo.ini" "20-ftp.ini" "20-gd.ini" "20-gettext.ini" "20-gmp.ini" "20-iconv.ini" "20-imap.ini" "20-intl.ini" "20-ldap.ini" "20-mbstring.ini" "20-mysqlnd.ini" "20-odbc.ini" "20-pdo.ini" "20-phar.ini" "20-posix.ini" "20-pspell.ini" "20-shmop.ini" "20-simplexml.ini" "20-sockets.ini" "20-sqlite3.ini" "20-sysvmsg.ini" "20-sysvsem.ini" "20-sysvshm.ini" "20-tokenizer.ini" "20-xml.ini" "20-xmlwriter.ini" "20-xsl.ini" "30-mysqli.ini" "30-pdo_dblib.ini" "30-pdo_firebird.ini" "30-pdo_mysql.ini" "30-pdo_odbc.ini" "30-pdo_sqlite.ini" "30-xmlreader.ini" "30-zip.ini" "40-apcu.ini" "40-ast.ini" "40-bolt.ini" "40-brotli.ini" "40-geos.ini" "40-imagick.ini" "40-libvirt-php.ini" "40-lz4.ini" "40-pdlib.ini") check="^[0-9]+-${ext_name}.ini" for str in ${pattern[@]}; do if [[ $str =~ $check ]]; then str_result="$str" break fi done if [ -z "$str_result" ]; then echo "50-${ext_name}.ini" else echo "$str_result" fi } enable_local_php_extension(){ vers=$1 ext_name=$2 ext_nm=$(get_link_name "$ext_name") if [ -e "/opt/brepo/php${vers}/etc/php.d/" ]; then if [ ! -e "/opt/brepo/php${vers}/etc/php.d/${ext_nm}" -a -e "/opt/brepo/php${vers}/etc/mod-installed/${ext_name}.ini" ]; then pushd "/opt/brepo/php${vers}/etc/php.d/" ln -s ../mod-installed/${ext_name}.ini /opt/brepo/php${vers}/etc/php.d/${ext_nm} popd fi fi } disable_local_php_extension(){ vers=$1 ext_name=$2 ext_nm=$(get_link_name "$ext_name") if [ -e "/opt/brepo/php${vers}/etc/php.d/" ]; then if [ -e "/opt/brepo/php${vers}/etc/php.d/${ext_nm}" ]; then rm -f "/opt/brepo/php${vers}/etc/php.d/${ext_nm}" fi fi } enable_mod_php(){ vers=$1 if [ -e "/etc/httpd/conf.d.prep/php${vers}.conf" ]; then ln -s /etc/httpd/conf.d.prep/php${vers}.conf /etc/httpd/conf.h.d/mod_php${vers}.conf fi } #----------------------------------------------------------# # Verifications # #----------------------------------------------------------# # Creating temporary file tmpfile=$(mktemp -p /tmp) # Translating argument to --gnu-long-options for arg; do delim="" case "$arg" in --apache) args="${args}-a " ;; --phpfpm) args="${args}-w " ;; --vsftpd) args="${args}-v " ;; --proftpd) args="${args}-j " ;; --named) args="${args}-k " ;; --mysql) args="${args}-m " ;; --mysql-classic) args="${args}-M " ;; --postgresql) args="${args}-g " ;; --exim) args="${args}-x " ;; --dovecot) args="${args}-z " ;; --sieve) args="${args}-Z " ;; --clamav) args="${args}-c " ;; --spamassassin) args="${args}-t " ;; --iptables) args="${args}-i " ;; --fail2ban) args="${args}-b " ;; --multiphp) args="${args}-o " ;; --quota) args="${args}-q " ;; --port) args="${args}-r " ;; --lang) args="${args}-l " ;; --interactive) args="${args}-y " ;; --api) args="${args}-d " ;; --hostname) args="${args}-s " ;; --email) args="${args}-e " ;; --password) args="${args}-p " ;; --force) args="${args}-f " ;; --with-debs) args="${args}-D " ;; --help) args="${args}-h " ;; --nopublicip) args="${args}-I " ;; --uselocalphp) args="${args}-u" ;; *) [[ "${arg:0:1}" == "-" ]] || delim="\"" args="${args}${delim}${arg}${delim} " ;; esac done eval set -- "$args" # Parsing arguments while getopts "u:I:a:w:v:j:k:m:M:g:d:x:z:Z:c:t:i:b:r:o:q:l:y:s:e:p:R:fh" Option; do case $Option in a) apache=$OPTARG ;; # Apache w) phpfpm=$OPTARG ;; # PHP-FPM o) multiphp=$OPTARG ;; # Multi-PHP v) vsftpd=$OPTARG ;; # Vsftpd j) proftpd=$OPTARG ;; # Proftpd k) named=$OPTARG ;; # Named m) mysql=$OPTARG ;; # MariaDB M) mysqlclassic=$OPTARG ;; # MySQL g) postgresql=$OPTARG ;; # PostgreSQL x) exim=$OPTARG ;; # Exim z) dovecot=$OPTARG ;; # Dovecot Z) sieve=$OPTARG ;; # Sieve c) clamd=$OPTARG ;; # ClamAV t) spamd=$OPTARG ;; # SpamAssassin i) iptables=$OPTARG ;; # Iptables b) fail2ban=$OPTARG ;; # Fail2ban q) quota=$OPTARG ;; # FS Quota r) port=$OPTARG ;; # Backend Port l) lang=$OPTARG ;; # Language d) api=$OPTARG ;; # Activate API y) interactive=$OPTARG ;; # Interactive install s) servername=$OPTARG ;; # Hostname e) email=$OPTARG ;; # Admin email p) vpass=$OPTARG ;; # Admin password R) withrpms=$OPTARG ;; # Hestia rpms path f) force='yes' ;; # Force install h) help ;; # Help I) nopublicip=$OPTARG ;; # NoPublicIP u) uselocalphp=$OPTARG ;; # UseLocalPHP *) help ;; # Print help (default) esac done # Defining default software stack set_default_value 'nginx' 'yes' set_default_value 'apache' 'yes' set_default_value 'phpfpm' 'yes' set_default_value 'multiphp' 'no' set_default_value 'vsftpd' 'yes' set_default_value 'proftpd' 'no' set_default_value 'named' 'yes' set_default_value 'mysql' 'yes' set_default_value 'mysql8' 'no' set_default_value 'postgresql' 'no' set_default_value 'exim' 'yes' set_default_value 'dovecot' 'yes' set_default_value 'sieve' 'no' if [ $memory -lt 1500000 ]; then set_default_value 'clamd' 'no' set_default_value 'spamd' 'no' elif [ $memory -lt 3000000 ]; then set_default_value 'clamd' 'no' set_default_value 'spamd' 'yes' else set_default_value 'clamd' 'no' set_default_value 'spamd' 'yes' fi set_default_value 'iptables' 'yes' set_default_value 'fail2ban' 'yes' set_default_value 'quota' 'no' set_default_value 'interactive' 'yes' set_default_value 'api' 'yes' set_default_value 'nopublicip' 'yes' set_default_port '8083' set_default_lang 'en' set_default_value 'uselocalphp' 'yes' # Checking software conflicts if [ "$proftpd" = 'yes' ]; then vsftpd='no' fi if [ "$exim" = 'no' ]; then clamd='no' spamd='no' dovecot='no' fi if [ "$dovecot" = 'no' ]; then sieve='no' fi if [ "$iptables" = 'no' ]; then fail2ban='no' fi if [ "$apache" = 'no' ]; then phpfpm='yes' fi if [ "$mysql" = 'yes' ] && [ "$mysql8" = 'yes' ]; then mysql='no' fi # Checking root permissions if [ "x$(id -u)" != 'x0' ]; then check_result 1 "Script can be run executed only by root" fi if [ -d "/usr/local/hestia" ] && [ "$force" = "no" ]; then check_result 1 "Hestia install detected. Unable to continue" fi # Checking admin user account if [ -n "$(grep ^admin: /etc/passwd /etc/group)" ] && [ -z "$force" ]; then echo 'Please remove admin user account before proceeding.' echo 'If you want to do it automatically run installer with -f option:' echo -e "Example: bash $0 --force\n" check_result 1 "User admin exists" fi # Clear the screen once launch permissions have been verified clear # Welcome message echo "Welcome to the Hestia Control Panel installer!" echo echo "Please wait, the installer is now checking for missing dependencies..." echo # DNF config-manager plugin isn't installed by defaut dnf -qy install dnf-plugins-core # enable dev repo if [ $release -eq 8 ]; then dnf config-manager --set-enabled powertools else dnf config-manager --set-enabled crb fi # Install EPEL Repo dnf install -y epel-release # Creating backup directory mkdir -p "$hst_backups" # Pre-install packages echo "[ * ] Installing dependencies..." dnf -y install $installer_dependencies >> $LOG check_result $? "Package installation failed, check log file for more details." # Disable SELinux if [ -e /etc/selinux/config ]; then sed 's/^SELINUX=.*/SELINUX=disabled/' -i /etc/selinux/config grubby --update-kernel ALL --args selinux=0 fi setenforce 0 # Check installed packages tmpfile=$(mktemp -p /tmp) dnf list installed > $tmpfile conflicts_pkg="exim mariadb-server httpd nginx hestia postfix" # Drop postfix from the list if exim should not be installed if [ "$exim" = 'no' ]; then conflicts_pkg=$(echo $conflicts_pkg | sed 's/postfix//g' | xargs) fi for pkg in $conflicts_pkg; do if [ -n "$(grep $pkg $tmpfile)" ]; then conflicts="$pkg* $conflicts" fi done rm -f $tmpfile if [ -n "$conflicts" ] && [ -z "$force" ]; then echo '!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!' echo echo 'WARNING: The following packages are already installed' echo "$conflicts" echo echo 'It is highly recommended that you remove them before proceeding.' echo echo '!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!' echo read -p 'Would you like to remove the conflicting packages? [y/n] ' answer if [ "$answer" = 'y' ] || [ "$answer" = 'Y' ]; then dnf remove $conflicts -y check_result $? 'dnf remove failed' unset $answer else check_result 1 "Hestia Control Panel should be installed on a clean server." fi fi case $arch in x86_64) ARCH="amd64" ;; aarch64) ARCH="arm64" ;; *) echo echo -e "\e[91mInstallation aborted\e[0m" echo "====================================================================" echo -e "\e[33mERROR: $arch is currently not supported!\e[0m" echo -e "\e[33mPlease verify the achitecture used is currenlty supported\e[0m" echo "" echo -e "\e[33mhttps://github.com/hestiacp/hestiacp/blob/main/README.md\e[0m" echo "" check_result 1 "Installation aborted" ;; esac #----------------------------------------------------------# # Brief Info # #----------------------------------------------------------# install_welcome_message() { DISPLAY_VER=$(echo $HESTIA_INSTALL_VER | sed "s|~alpha||g" | sed "s|~beta||g") echo echo ' _ _ _ _ ____ ____ ' echo ' | | | | ___ ___| |_(_) __ _ / ___| _ \ _ _ . . ' echo ' | |_| |/ _ \/ __| __| |/ _` | | | |_) | | \| \|\/| ' echo ' | _ | __/\__ \ |_| | (_| | |___| __/ |_/|_/| | ' echo ' |_| |_|\___||___/\__|_|\__,_|\____|_| | \| | | ' echo " " echo " Hestia Control Panel(rpm edition) " if [[ "$HESTIA_INSTALL_VER" =~ "beta" ]]; then echo " BETA RELEASE " fi if [[ "$HESTIA_INSTALL_VER" =~ "alpha" ]]; then echo " DEVELOPMENT SNAPSHOT " echo " USE AT YOUR OWN RISK " fi echo " ${DISPLAY_VER} " echo " hestiadocs.brepo.ru " echo " Original: www.hestiacp.com " echo echo "========================================================================" echo echo "Thank you for downloading Hestia Control Panel! In a few moments," echo "we will begin installing the following components on your server:" echo } # Printing nice ASCII logo clear install_welcome_message # Web stack echo ' - NGINX Web / Proxy Server' if [ "$apache" = 'yes' ]; then echo ' - Apache Web Server (as backend)' fi if [ "$phpfpm" = 'yes' ] && [ "$multiphp" = 'no' ]; then echo ' - PHP-FPM Application Server' fi if [ "$multiphp" = 'yes' ]; then phpfpm='yes' echo ' - Multi-PHP Environment' fi # DNS stack if [ "$named" = 'yes' ]; then echo ' - Bind DNS Server' # RHEL 8 hack for bind9.16 conflict if [ "$release" = "8" ]; then dnf remove -y bind-utils fi fi # Mail stack if [ "$exim" = 'yes' ]; then echo -n ' - Exim Mail Server' if [ "$clamd" = 'yes' ] || [ "$spamd" = 'yes' ]; then echo -n ' + ' if [ "$clamd" = 'yes' ]; then echo -n 'ClamAV ' fi if [ "$spamd" = 'yes' ]; then if [ "$clamd" = 'yes' ]; then echo -n '+ ' fi echo -n 'SpamAssassin' fi fi echo if [ "$dovecot" = 'yes' ]; then echo -n ' - Dovecot POP3/IMAP Server' if [ "$sieve" = 'yes' ]; then echo -n '+ Sieve' fi fi fi echo # Database stack if [ "$mysql" = 'yes' ]; then echo ' - MariaDB Database Server' fi if [ "$mysql8" = 'yes' ]; then echo ' - MySQL8 Database Server' fi if [ "$postgresql" = 'yes' ]; then echo ' - PostgreSQL Database Server' fi # FTP stack if [ "$vsftpd" = 'yes' ]; then echo ' - Vsftpd FTP Server' fi if [ "$proftpd" = 'yes' ]; then echo ' - ProFTPD FTP Server' fi # Firewall stack if [ "$iptables" = 'yes' ]; then echo -n ' - Firewall (iptables)' fi if [ "$iptables" = 'yes' ] && [ "$fail2ban" = 'yes' ]; then echo -n ' + Fail2Ban Access Monitor' fi echo -e "\n" echo "========================================================================" echo -e "\n" # Asking for confirmation to proceed if [ "$interactive" = 'yes' ]; then read -p 'Would you like to continue with the installation? [Y/N]: ' answer if [ "$answer" != 'y' ] && [ "$answer" != 'Y' ]; then echo 'Goodbye' exit 1 fi fi # Validate Email / Hostname even when interactive = no # Asking for contact email if [ -z "$email" ]; then while validate_email; do echo -e "\nPlease use a valid emailadress (ex. info@domain.tld)." read -p 'Please enter admin email address: ' email done else if validate_email; then echo "Please use a valid emailadress (ex. info@domain.tld)." exit 1 fi fi # Asking to set FQDN hostname if [ -z "$servername" ]; then # Ask and validate FQDN hostname. read -p "Please enter FQDN hostname [$(hostname -f)]: " servername # Set hostname if it wasn't set if [ -z "$servername" ]; then servername=$(hostname -f) fi # Validate Hostname, go to loop if the validation fails. while validate_hostname; do echo -e "\nPlease use a valid hostname according to RFC1178 (ex. hostname.domain.tld)." read -p "Please enter FQDN hostname [$(hostname -f)]: " servername done else # Validate FQDN hostname if it is preset if validate_hostname; then echo "Please use a valid hostname according to RFC1178 (ex. hostname.domain.tld)." exit 1 fi fi # Generating admin password if it wasn't set displaypass="The password you chose during installation." if [ -z "$vpass" ]; then vpass=$(gen_pass) displaypass=$vpass fi # Set FQDN if it wasn't set mask1='(([[:alnum:]](-?[[:alnum:]])*)\.)' mask2='*[[:alnum:]](-?[[:alnum:]])+\.[[:alnum:]]{2,}' if ! [[ "$servername" =~ ^${mask1}${mask2}$ ]]; then if [[ -n "$servername" ]]; then servername="$servername.example.com" else servername="example.com" fi echo "127.0.0.1 $servername" >> /etc/hosts fi if [[ -z $(grep -i "$servername" /etc/hosts) ]]; then echo "127.0.0.1 $servername" >> /etc/hosts fi # Set email if it wasn't set if [[ -z "$email" ]]; then email="admin@$servername" fi # Defining backup directory echo -e "Installation backup directory: $hst_backups" # Print Log File Path echo "Installation log file: $LOG" # Print new line echo #----------------------------------------------------------# # Checking swap # #----------------------------------------------------------# # Checking swap on small instances if [ -z "$(swapon -s)" ] && [ "$memory" -lt 1000000 ]; then fallocate -l 1G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo "/swapfile none swap sw 0 0" >> /etc/fstab fi #----------------------------------------------------------# # Install repository # #----------------------------------------------------------# # Create new folder if not all-ready exists mkdir -p /root/.gnupg/ && chmod 700 /root/.gnupg/ # Updating system echo "Adding required repositories to proceed with installation:" echo # Installing Nginx repo echo "[ * ] NGINX" #dnf config-manager --add-repo https://dev.brepo.ru/bayrepo/hestiacp/raw/branch/master/install/rpm/nginx/nginx.repo #nginx will be installed from hestia.repo # Installing Remi PHP repo echo "[ * ] PHP" php_pkgs_lst="" if [ "$uselocalphp" == "yes" ]; then write_config_value "LOCAL_PHP" "yes" php_pkgs_lst="brepo-php${php_v} brepo-php${php_v}-mod-apache" else write_config_value "LOCAL_PHP" "no" php_pkgs_lst="php${php_v}-php.${arch} php${php_v}-php-cgi.${arch} php${php_v}-php-mysqlnd.${arch} php${php_v}-php-pgsql.${arch} php${php_v}-php-pdo php${php_v}-php-common php${php_v}-php-pecl-imagick php${php_v}-php-imap php${php_v}-php-ldap php${php_v}-php-pecl-apcu php${php_v}-php-pecl-zip php${php_v}-php-cli php${php_v}-php-opcache php${php_v}-php-xml php${php_v}-php-gd php${php_v}-php-intl php${php_v}-php-mbstring php${php_v}-php-pspell php${php_v}-php-readline" dnf install -y https://rpms.remirepo.net/enterprise/remi-release-$release.rpm fi software="$software $php_pkgs_lst" # Installing MariaDB repo if [ "$mysql" = 'yes' ]; then echo "[ * ] MariaDB" dnf config-manager --add-repo https://dev.brepo.ru/bayrepo/hestiacp/raw/branch/master/install/rpm/mysql/mariadb-$(arch).repo fi # Enabling MySQL module if [ "$mysql8" = 'yes' ]; then echo "[ * ] MySQL 8" if [ "$release" -eq 8 ]; then dnf -y module enable mysql:8.0 fi fi # Installing HestiaCP repo echo "[ * ] Hestia Control Panel" dnf config-manager --add-repo https://dev.brepo.ru/bayrepo/hestiacp/raw/branch/master/install/rpm/hestia/hestia.repo rpm --import https://repo.brepo.ru/hestia/brepo_projects-gpg-key check_result $? "rpm import brepo.ru GPG key failed" mkdir /var/cache/hestia-nginx/ # Installing PostgreSQL repo if [ "$postgresql" = 'yes' ]; then echo "[ * ] PostgreSQL" dnf -y module enable postgresql:15 fi # Echo for a new line echo # Updating system echo -ne "Updating currently installed packages, please wait... " dnf -y upgrade >> $LOG & BACK_PID=$! # Check if package installation is done, print a spinner spin_i=1 while kill -0 $BACK_PID > /dev/null 2>&1; do printf "\b${spinner:spin_i++%${#spinner}:1}" sleep 0.5 done # Do a blank echo to get the \n back echo # Check Installation result wait $BACK_PID check_result $? 'dnf upgrade failed' #----------------------------------------------------------# # Backup # #----------------------------------------------------------# # Creating backup directory tree mkdir -p $hst_backups cd $hst_backups mkdir nginx httpd php vsftpd proftpd bind exim dovecot clamd mkdir spamassassin mysql postgresql hestia # Backup nginx configuration systemctl stop nginx > /dev/null 2>&1 cp -r /etc/nginx/* $hst_backups/nginx > /dev/null 2>&1 # Backup Apache configuration systemctl stop httpd > /dev/null 2>&1 cp -r /etc/httpd/* $hst_backups/httpd > /dev/null 2>&1 rm -f /etc/httpd/conf.h.d/* > /dev/null 2>&1 # Backup PHP-FPM configuration systemctl stop php*-fpm > /dev/null 2>&1 cp -r /etc/php/* $hst_backups/php/ > /dev/null 2>&1 # Backup Bind configuration systemctl stop named > /dev/null 2>&1 cp -r /etc/named/* $hst_backups/named > /dev/null 2>&1 # Backup Vsftpd configuration systemctl stop vsftpd > /dev/null 2>&1 cp /etc/vsftpd.conf $hst_backups/vsftpd > /dev/null 2>&1 # Backup ProFTPD configuration systemctl stop proftpd > /dev/null 2>&1 cp /etc/proftpd/* $hst_backups/proftpd > /dev/null 2>&1 # Backup Exim configuration systemctl stop exim > /dev/null 2>&1 cp -r /etc/exim/* $hst_backups/exim > /dev/null 2>&1 # Backup ClamAV configuration systemctl stop clamav-daemon > /dev/null 2>&1 cp -r /etc/clamav/* $hst_backups/clamav > /dev/null 2>&1 # Backup SpamAssassin configuration systemctl stop spamassassin > /dev/null 2>&1 cp -r /etc/spamassassin/* $hst_backups/spamassassin > /dev/null 2>&1 # Backup Dovecot configuration systemctl stop dovecot > /dev/null 2>&1 cp /etc/dovecot.conf $hst_backups/dovecot > /dev/null 2>&1 cp -r /etc/dovecot/* $hst_backups/dovecot > /dev/null 2>&1 # Backup MySQL/MariaDB configuration and data systemctl stop mysql > /dev/null 2>&1 killall -9 mysqld > /dev/null 2>&1 mv /var/lib/mysql $hst_backups/mysql/mysql_datadir > /dev/null 2>&1 cp -r /etc/mysql/* $hst_backups/mysql > /dev/null 2>&1 mv -f /root/.my.cnf $hst_backups/mysql > /dev/null 2>&1 # Backup Hestia systemctl stop hestia > /dev/null 2>&1 cp -r $HESTIA/* $hst_backups/hestia > /dev/null 2>&1 dnf -y remove hestia hestia-nginx hestia-php > /dev/null 2>&1 rm -rf $HESTIA > /dev/null 2>&1 #----------------------------------------------------------# # Package Includes # #----------------------------------------------------------# if [ "$phpfpm" = 'yes' ]; then if [ "$uselocalphp" == "yes" ]; then fpm="brepo-php${php_v}-fpm" else fpm="php${php_v}-php-fpm php${php_v}-php-cgi.${arch} php${php_v}-php-mysqlnd.${arch} php${php_v}-php-pgsql.${arch} php${php_v}-php-pdo php${php_v}-php-common php${php_v}-php-pecl-imagick php${php_v}-php-imap php${php_v}-php-ldap php${php_v}-php-pecl-apcu php${php_v}-php-pecl-zip php${php_v}-php-cli php${php_v}-php-opcache php${php_v}-php-xml php${php_v}-php-gd php${php_v}-php-intl php${php_v}-php-mbstring php${php_v}-php-pspell php${php_v}-php-readline" fi software="$software $fpm" fi #----------------------------------------------------------# # Package Excludes # #----------------------------------------------------------# # Excluding packages if [ "$apache" = 'no' ]; then software=$(echo "$software" | sed -e "s/httpd.${arch}//") software=$(echo "$software" | sed -e "s/httpd-tools//") software=$(echo "$software" | sed -e "s/httpd-itk//") software=$(echo "$software" | sed -e "s/mod_suphp//") software=$(echo "$software" | sed -e "s/mod_fcgid//") software=$(echo "$software" | sed -e "s/mod_ssl//") software=$(echo "$software" | sed -e "s/php${php_v}-php.${arch}//") software=$(echo "$software" | sed -e "s/brepo-php${php_v}-mod-apache//") mod_php="disable" fi if [ "$vsftpd" = 'no' ]; then software=$(echo "$software" | sed -e "s/vsftpd//") fi if [ "$proftpd" = 'no' ]; then software=$(echo "$software" | sed -e "s/proftpd//") fi if [ "$named" = 'no' ]; then software=$(echo "$software" | sed -e "s/bind//") fi if [ "$exim" = 'no' ]; then software=$(echo "$software" | sed -e "s/exim//") software=$(echo "$software" | sed -e "s/dovecot//") software=$(echo "$software" | sed -e "s/clamd//") software=$(echo "$software" | sed -e "s/clamav//") software=$(echo "$software" | sed -e "s/spamassassin//") software=$(echo "$software" | sed -e "s/dovecot-pigeonhole//") fi if [ "$clamd" = 'no' ]; then software=$(echo "$software" | sed -e "s/clamd//") software=$(echo "$software" | sed -e "s/clamav//") fi if [ "$spamd" = 'no' ]; then software=$(echo "$software" | sed -e "s/spamassassin//") fi if [ "$dovecot" = 'no' ]; then software=$(echo "$software" | sed -e "s/dovecot//") fi if [ "$sieve" = 'no' ]; then software=$(echo "$software" | sed -e "s/dovecot-pigeonhole//") fi if [ "$mysql" = 'no' ]; then software=$(echo "$software" | sed -e "s/MariaDB-server//") software=$(echo "$software" | sed -e "s/MariaDB-client//") software=$(echo "$software" | sed -e "s/MariaDB-common//") fi if [ "$mysql8" = 'no' ]; then software=$(echo "$software" | sed -e "s/mysql.${arch}//") software=$(echo "$software" | sed -e "s/mysql-server//") software=$(echo "$software" | sed -e "s/mysql-common//") fi if [ "$mysql" = 'no' ] && [ "$mysql8" = 'no' ]; then software=$(echo "$software" | sed -e "s/php${php_v}-php-mysql.${arch}//") fi if [ "$postgresql" = 'no' ]; then software=$(echo "$software" | sed -e "s/postgresql-server//") software=$(echo "$software" | sed -e "s/php${php_v}-php-pgsql.${arch}//") software=$(echo "$software" | sed -e "s/phppgadmin//") php_modules_install=$(echo "$php_modules_install" | sed -e "s/pgsql//") php_modules_install=$(echo "$php_modules_install" | sed -e "s/pdo_pgsql//") php_modules_disable="$php_modules_disable pgsql pdo_pgsql" fi if [ "$fail2ban" = 'no' ]; then software=$(echo "$software" | sed -e "s/fail2ban//") fi if [ "$iptables" = 'no' ]; then software=$(echo "$software" | sed -e "s/ipset//") software=$(echo "$software" | sed -e "s/fail2ban//") fi if [ "$phpfpm" = 'yes' ]; then software=$(echo "$software" | sed -e "s/php${php_v}-php-cgi.${arch}//") software=$(echo "$software" | sed -e "s/httpd-itk//") software=$(echo "$software" | sed -e "s/mod_ruid2 //") software=$(echo "$software" | sed -e "s/mod_suphp//") software=$(echo "$software" | sed -e "s/mod_fcgid//") software=$(echo "$software" | sed -e "s/php${php_v}-php.${arch}//") software=$(echo "$software" | sed -e "s/brepo-php${php_v}-mod-apache//") mod_php="disable" fi if [ -d "$withrpms" ]; then software=$(echo "$software" | sed -e "s/hestia-nginx//") software=$(echo "$software" | sed -e "s/hestia-php//") software=$(echo "$software" | sed -e "s/hestia//") fi #----------------------------------------------------------# # Install packages # #----------------------------------------------------------# if [ "$iptables" = 'yes' ]; then if [ -f /etc/redhat-release ]; then dnf install iptables-nft -y systemctl stop firewalld systemctl disable firewalld systemctl enable nftables --now fi fi # Installing rpm packages echo "The installer is now downloading and installing all required packages." echo -ne "NOTE: This process may take 10 to 15 minutes to complete, please wait... " echo dnf -y install $software >> $LOG & BACK_PID=$! # Check if package installation is done, print a spinner spin_i=1 while kill -0 $BACK_PID > /dev/null 2>&1; do printf "\b${spinner:spin_i++%${#spinner}:1}" sleep 0.5 done # Do a blank echo to get the \n back echo # Check Installation result wait $BACK_PID check_result $? "dnf install failed" echo echo "========================================================================" echo # Create PHP symlink if [ "$uselocalphp" == "yes" ]; then alternatives --install /usr/bin/php php /opt/brepo/php${php_v}/bin/php 1 echo "[ * ] Configuring php settings..." for mod in $php_modules_install; do enable_local_php_extension "${php_v}" "$mod" done for mod in $php_modules_disable; do disable_local_php_extension "${php_v}" "$mod" done if [ "$mod_php" == "enable" ]; then enable_mod_php "${php_v}" fi else alternatives --install /usr/bin/php php /opt/remi/php${php_v}/root/usr/bin/php 1 fi # Install Hestia packages from local folder if [ -n "$withrpms" ] && [ -d "$withrpms" ]; then echo "[ * ] Installing local package files..." echo " - hestia core package" rpm -i $withrpms/hestia_*.rpm > /dev/null 2>&1 if [ -z $(ls $withrpms/hestia-php_*.rpm 2> /dev/null) ]; then echo " - hestia-php backend package (from dnf)" dnf -y install hestia-php > /dev/null 2>&1 else echo " - hestia-php backend package" rpm -i $withrpms/hestia-php_*.rpm > /dev/null 2>&1 fi if [ -z $(ls $withrpms/hestia-nginx_*.deb 2> /dev/null) ]; then echo " - hestia-nginx backend package (from dnf)" dnf -y install hestia-nginx > /dev/null 2>&1 else echo " - hestia-nginx backend package" rpm -i $withrpms/hestia-nginx_*.rpm > /dev/null 2>&1 fi fi #----------------------------------------------------------# # Configure system # #----------------------------------------------------------# echo "[ * ] Configuring system settings..." # Enable SFTP subsystem for SSH sftp_subsys_enabled=$(grep -iE "^#?.*subsystem.+(sftp )?sftp-server" /etc/ssh/sshd_config) if [ -n "$sftp_subsys_enabled" ]; then sed -i -E "s/^#?.*Subsystem.+(sftp )?sftp-server/Subsystem sftp internal-sftp/g" /etc/ssh/sshd_config fi # Reduce SSH login grace time sed -i "s/[#]LoginGraceTime [[:digit:]]m/LoginGraceTime 1m/g" /etc/ssh/sshd_config # Restart SSH daemon systemctl restart sshd # Disable AWStats cron rm -f /etc/cron.d/awstats # Replace awstatst function mkdir -p /etc/logrotate.d/httpd-prerotate cp -f $HESTIA_INSTALL_DIR/logrotate/httpd-prerotate/* /etc/logrotate.d/httpd-prerotate/ # Set directory color if [ -z "$(grep 'LS_COLORS="$LS_COLORS:di=00;33"' /etc/profile)" ]; then echo 'LS_COLORS="$LS_COLORS:di=00;33"' >> /etc/profile fi # Register /sbin/nologin and /usr/sbin/nologin if [ -z "$(grep ^/sbin/nologin /etc/shells)" ]; then echo "/sbin/nologin" >> /etc/shells fi if [ -z "$(grep ^/usr/sbin/nologin /etc/shells)" ]; then echo "/usr/sbin/nologin" >> /etc/shells fi # Configuring NTP sed -i 's/#NTP=/NTP=pool.ntp.org/' /etc/systemd/timesyncd.conf systemctl enable systemd-timesyncd systemctl start systemd-timesyncd # Restrict access to /proc fs # - Prevent unpriv users from seeing each other running processes mount -o remount,defaults,hidepid=2 /proc > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Info: Cannot remount /proc (LXC containers require additional perm added to host apparmor profile)" else echo "@reboot root sleep 5 && mount -o remount,defaults,hidepid=2 /proc" > /etc/cron.d/hestia-proc fi #----------------------------------------------------------# # Configure Hestia # #----------------------------------------------------------# echo "[ * ] Configuring Hestia Control Panel..." # Installing sudo configuration mkdir -p /etc/sudoers.d cp -f $HESTIA_INSTALL_DIR/sudo/admin /etc/sudoers.d/ chmod 440 /etc/sudoers.d/admin # Add Hestia global config if [[ ! -e /etc/hestiacp/hestia.conf ]]; then mkdir -p /etc/hestiacp echo -e "# Do not edit this file, will get overwritten on next upgrade, use /etc/hestiacp/local.conf instead\n\nexport HESTIA='/usr/local/hestia'\n\n[[ -f /etc/hestiacp/local.conf ]] && source /etc/hestiacp/local.conf" > /etc/hestiacp/hestia.conf fi # Configuring system env echo "export HESTIA='$HESTIA'" > /etc/profile.d/hestia.sh echo 'PATH=$PATH:'$HESTIA'/bin' >> /etc/profile.d/hestia.sh echo 'export PATH' >> /etc/profile.d/hestia.sh chmod 755 /etc/profile.d/hestia.sh source /etc/profile.d/hestia.sh # Configuring logrotate for Hestia logs cp -f $HESTIA_INSTALL_DIR/logrotate/hestia /etc/logrotate.d/hestia # Create log path and symbolic link rm -f /var/log/hestia mkdir -p /var/log/hestia ln -s /var/log/hestia $HESTIA/log # Building directory tree and creating some blank files for Hestia mkdir -p $HESTIA/conf $HESTIA/ssl $HESTIA/data/ips \ $HESTIA/data/queue $HESTIA/data/users $HESTIA/data/firewall \ $HESTIA/data/sessions touch $HESTIA/data/queue/backup.pipe $HESTIA/data/queue/disk.pipe \ $HESTIA/data/queue/webstats.pipe $HESTIA/data/queue/restart.pipe \ $HESTIA/data/queue/traffic.pipe $HESTIA/data/queue/daily.pipe $HESTIA/log/system.log \ $HESTIA/log/nginx-error.log $HESTIA/log/auth.log $HESTIA/log/backup.log chmod 750 $HESTIA/conf $HESTIA/data/users $HESTIA/data/ips $HESTIA/log chmod -R 750 $HESTIA/data/queue chmod 660 /var/log/hestia/* chmod 770 $HESTIA/data/sessions # Generating Hestia configuration rm -f $HESTIA/conf/hestia.conf > /dev/null 2>&1 touch $HESTIA/conf/hestia.conf chmod 660 $HESTIA/conf/hestia.conf # Write default port value to hestia.conf # If a custom port is specified it will be set at the end of the installation process. write_config_value "BACKEND_PORT" "8083" if [ "$uselocalphp" == "yes" ]; then write_config_value "LOCAL_PHP" "yes" else write_config_value "LOCAL_PHP" "no" fi # Web stack if [ "$apache" = 'yes' ]; then write_config_value "WEB_SYSTEM" "httpd" write_config_value "WEB_RGROUPS" "apache" write_config_value "WEB_PORT" "8080" write_config_value "WEB_SSL_PORT" "8443" write_config_value "WEB_SSL" "mod_ssl" write_config_value "PROXY_SYSTEM" "nginx" write_config_value "PROXY_PORT" "80" write_config_value "PROXY_SSL_PORT" "443" write_config_value "STATS_SYSTEM" "awstats" fi if [ "$apache" = 'no' ]; then write_config_value "WEB_SYSTEM" "nginx" write_config_value "WEB_PORT" "80" write_config_value "WEB_SSL_PORT" "443" write_config_value "WEB_SSL" "openssl" write_config_value "STATS_SYSTEM" "awstats" fi if [ "$phpfpm" = 'yes' ]; then write_config_value "WEB_BACKEND" "php-fpm" fi # Database stack if [ "$mysql" = 'yes' ] || [ "$mysql8" = 'yes' ]; then installed_db_types='mysql' fi if [ "$postgresql" = 'yes' ]; then installed_db_types="$installed_db_types,pgsql" fi if [ -n "$installed_db_types" ]; then db=$(echo "$installed_db_types" \ | sed "s/,/\n/g" \ | sort -r -u \ | sed "/^$/d" \ | sed ':a;N;$!ba;s/\n/,/g') write_config_value "DB_SYSTEM" "$db" fi # FTP stack if [ "$vsftpd" = 'yes' ]; then write_config_value "FTP_SYSTEM" "vsftpd" fi if [ "$proftpd" = 'yes' ]; then write_config_value "FTP_SYSTEM" "proftpd" fi # DNS stack if [ "$named" = 'yes' ]; then write_config_value "DNS_SYSTEM" "named" fi # Mail stack if [ "$exim" = 'yes' ]; then write_config_value "MAIL_SYSTEM" "exim" if [ "$clamd" = 'yes' ]; then write_config_value "ANTIVIRUS_SYSTEM" "clamav-daemon" fi if [ "$spamd" = 'yes' ]; then write_config_value "ANTISPAM_SYSTEM" "spamassassin" fi if [ "$dovecot" = 'yes' ]; then write_config_value "IMAP_SYSTEM" "dovecot" fi if [ "$sieve" = 'yes' ]; then write_config_value "SIEVE_SYSTEM" "yes" fi fi # Cron daemon write_config_value "CRON_SYSTEM" "crond" # Firewall stack if [ "$iptables" = 'yes' ]; then write_config_value "FIREWALL_SYSTEM" "iptables" fi if [ "$iptables" = 'yes' ] && [ "$fail2ban" = 'yes' ]; then write_config_value "FIREWALL_EXTENSION" "fail2ban" fi # Disk quota if [ "$quota" = 'yes' ]; then write_config_value "DISK_QUOTA" "yes" else write_config_value "DISK_QUOTA" "no" fi # Backups write_config_value "BACKUP_SYSTEM" "local" write_config_value "BACKUP_GZIP" "4" write_config_value "BACKUP_MODE" "zstd" # Language write_config_value "LANGUAGE" "$lang" # Login in screen write_config_value "LOGIN_STYLE" "default" # Theme write_config_value "THEME" "dark" # Inactive session timeout write_config_value "INACTIVE_SESSION_TIMEOUT" "60" # Version & Release Branch write_config_value "VERSION" "${HESTIA_INSTALL_VER}" write_config_value "RELEASE_BRANCH" "release" # Email notifications after upgrade write_config_value "UPGRADE_SEND_EMAIL" "true" write_config_value "UPGRADE_SEND_EMAIL_LOG" "false" # Installing hosting packages cp -rf $HESTIA_COMMON_DIR/packages $HESTIA/data/ # Update nameservers in hosting package IFS='.' read -r -a domain_elements <<< "$servername" if [ -n "${domain_elements[-2]}" ] && [ -n "${domain_elements[-1]}" ]; then serverdomain="${domain_elements[-2]}.${domain_elements[-1]}" sed -i s/"domain.tld"/"$serverdomain"/g $HESTIA/data/packages/*.pkg fi # Installing templates cp -rf $HESTIA_INSTALL_DIR/templates $HESTIA/data/ cp -rf $HESTIA_COMMON_DIR/templates/web/ $HESTIA/data/templates cp -rf $HESTIA_COMMON_DIR/templates/dns/ $HESTIA/data/templates mkdir -p /var/www/html mkdir -p /var/www/document_errors # Install default success page cp -rf $HESTIA_COMMON_DIR/templates/web/unassigned/index.html /var/www/html/ cp -rf $HESTIA_COMMON_DIR/templates/web/skel/document_errors/* /var/www/document_errors/ # Installing firewall rules cp -rf $HESTIA_COMMON_DIR/firewall $HESTIA/data/ rm -f $HESTIA/data/firewall/ipset/blacklist.sh $HESTIA/data/firewall/ipset/blacklist.ipv6.sh # Installing apis cp -rf $HESTIA_COMMON_DIR/api $HESTIA/data/ # Configuring server hostname $HESTIA/bin/v-change-sys-hostname $servername > /dev/null 2>&1 # Generating SSL certificate echo "[ * ] Generating default self-signed SSL certificate..." $HESTIA/bin/v-generate-ssl-cert $(hostname) '' 'RU' 'Moscow' \ 'Moscow' 'Hestia Control Panel' 'IT' > /tmp/hst.pem # Parsing certificate file crt_end=$(grep -n "END CERTIFICATE-" /tmp/hst.pem | cut -f 1 -d:) key_start=$(grep -n "BEGIN PRIVATE KEY" /tmp/hst.pem | cut -f 1 -d:) key_end=$(grep -n "END PRIVATE KEY" /tmp/hst.pem | cut -f 1 -d:) # Adding SSL certificate echo "[ * ] Adding SSL certificate to Hestia Control Panel..." cd $HESTIA/ssl sed -n "1,${crt_end}p" /tmp/hst.pem > certificate.crt sed -n "$key_start,${key_end}p" /tmp/hst.pem > certificate.key chown root:mail $HESTIA/ssl/* chmod 660 $HESTIA/ssl/* rm /tmp/hst.pem # Install dhparam.pem cp -f $HESTIA_INSTALL_DIR/ssl/dhparam.pem /etc/pki/tls/ # Deleting old admin user if [ -n "$(grep ^admin: /etc/passwd)" ] && [ "$force" = 'yes' ]; then chattr -i /home/admin/conf > /dev/null 2>&1 userdel -f admin > /dev/null 2>&1 chattr -i /home/admin/conf > /dev/null 2>&1 mv -f /home/admin $hst_backups/home/ > /dev/null 2>&1 rm -f /tmp/sess_* > /dev/null 2>&1 fi if [ -n "$(grep ^admin: /etc/group)" ] && [ "$force" = 'yes' ]; then groupdel admin > /dev/null 2>&1 fi # Enabling sftp jail echo "[ * ] Enable SFTP jail..." $HESTIA/bin/v-add-sys-sftp-jail > /dev/null 2>&1 check_result $? "can't enable sftp jail" # Adding Hestia admin account echo "[ * ] Create default admin account..." $HESTIA/bin/v-add-user admin $vpass $email "system" "System Administrator" check_result $? "can't create admin user" $HESTIA/bin/v-change-user-shell admin nologin $HESTIA/bin/v-change-user-role admin admin $HESTIA/bin/v-change-user-language admin $lang $HESTIA/bin/v-change-sys-config-value 'POLICY_SYSTEM_PROTECTED_ADMIN' 'yes' chown admin:admin /var/cache/hestia-nginx/ locale-gen "en_US.utf8" > /dev/null 2>&1 #----------------------------------------------------------# # Configure Nginx # #----------------------------------------------------------# echo "[ * ] Configuring NGINX..." rm -f /etc/nginx/conf.d/*.conf cp -f $HESTIA_INSTALL_DIR/nginx/nginx.conf /etc/nginx/ cp -f $HESTIA_INSTALL_DIR/nginx/status.conf /etc/nginx/conf.d/ cp -f $HESTIA_INSTALL_DIR/nginx/0rtt-anti-replay.conf /etc/nginx/conf.d/ cp -f $HESTIA_INSTALL_DIR/nginx/agents.conf /etc/nginx/conf.d/ cp -f $HESTIA_INSTALL_DIR/nginx/phpmyadmin.inc /etc/nginx/conf.d/ cp -f $HESTIA_INSTALL_DIR/nginx/phppgadmin.inc /etc/nginx/conf.d/ cp -f $HESTIA_INSTALL_DIR/logrotate/nginx /etc/logrotate.d/ mkdir -p /etc/nginx/conf.d/domains mkdir -p /etc/nginx/modules-enabled mkdir -p /var/log/nginx/domains mkdir -p /etc/nginx/conf.d/main # Update dns servers in nginx.conf for nameserver in $(grep -is '^nameserver' /etc/resolv.conf | cut -d' ' -f2 | tr '\r\n' ' ' | xargs); do if [[ "$nameserver" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then if [ -z "$resolver" ]; then resolver="$nameserver" else resolver="$resolver $nameserver" fi fi done if [ -n "$resolver" ]; then sed -i "s/1.1.1.1 8.8.8.8/$resolver/g" /etc/nginx/nginx.conf fi # https://github.com/ergin/nginx-cloudflare-real-ip/ CLOUDFLARE_FILE_PATH='/etc/nginx/conf.d/cloudflare.inc' echo "#Cloudflare" > $CLOUDFLARE_FILE_PATH echo "" >> $CLOUDFLARE_FILE_PATH echo "# - IPv4" >> $CLOUDFLARE_FILE_PATH for i in $(curl -s -L https://www.cloudflare.com/ips-v4); do echo "set_real_ip_from $i;" >> $CLOUDFLARE_FILE_PATH done echo "" >> $CLOUDFLARE_FILE_PATH echo "# - IPv6" >> $CLOUDFLARE_FILE_PATH for i in $(curl -s -L https://www.cloudflare.com/ips-v6); do echo "set_real_ip_from $i;" >> $CLOUDFLARE_FILE_PATH done echo "" >> $CLOUDFLARE_FILE_PATH echo "real_ip_header CF-Connecting-IP;" >> $CLOUDFLARE_FILE_PATH systemctl enable nginx --now >> $LOG check_result $? "nginx start failed" #----------------------------------------------------------# # Configure Apache # #----------------------------------------------------------# if [ "$apache" = 'yes' ]; then echo "[ * ] Configuring Apache Web Server..." mkdir -p /etc/httpd/conf.h.d mkdir -p /etc/httpd/conf.h.d/domains # Copy configuration files cp -f $HESTIA_INSTALL_DIR/httpd/httpd.conf /etc/httpd/conf/ cp -f $HESTIA_INSTALL_DIR/httpd/status.conf /etc/httpd/conf.h.d/hestia-status.conf cp -f $HESTIA_INSTALL_DIR/logrotate/httpd /etc/logrotate.d/ cp -f $HESTIA_INSTALL_DIR/httpd/hestiacp-httpd.conf /usr/lib/systemd/system/httpd.service.d/ # Enable needed modules if [ "$nginx" = "no" ]; then dnf install -y mod_ssl mod_http2 fi # IDK why those modules still here, but ok. if they are disabled by default if [ -e /etc/httpd/conf.modules.d/01-suexec.conf ]; then sed 's/^LoadModule suexec_module/#LoadModule suexec_module/' -i /etc/httpd/conf.modules.d/01-suexec.conf fi if [ -e /etc/httpd/conf.modules.d/10-fcgid.conf ]; then sed 's/^LoadModule fcgid_module/#LoadModule fcgid_module/' -i /etc/httpd/conf.modules.d/10-fcgid.conf fi # Switch status loader to custom one if [ -e /etc/httpd/conf.modules.d/00-base.conf ]; then sed 's/^LoadModule status_module/#LoadModule status_module/' -i /etc/httpd/conf.modules.d/00-base.conf fi echo 'LoadModule status_module modules/mod_status.so' > /etc/httpd/conf.modules.d/00-hestia-status.conf if [ "$phpfpm" = 'yes' ]; then # Disable prefork and php, enable event sed 's/LoadModule mpm_prefork_module/#LoadModule mpm_prefork_module/' -i /etc/httpd/conf.modules.d/00-mpm.conf sed 's/#LoadModule mpm_event_module/LoadModule mpm_event_module/' -i /etc/httpd/conf.modules.d/00-mpm.conf cp -f $HESTIA_INSTALL_DIR/httpd/hestia-event.conf /etc/httpd/conf.h.d/ fi if [ ! -d /etc/httpd/sites-available ]; then mkdir -p /etc/httpd/sites-available fi echo "# Powered by hestia" > /etc/httpd/sites-available/default echo "# Powered by hestia" > /etc/httpd/sites-available/default-ssl echo "# Powered by hestia" > /etc/httpd/conf/ports.conf # echo -e "/home\npublic_html/cgi-bin" > /etc/httpd/suexec/www-data touch /var/log/httpd/access.log /var/log/httpd/error.log mkdir -p /var/log/httpd/domains chmod a+x /var/log/httpd chmod 640 /var/log/httpd/access.log /var/log/httpd/error.log chmod 751 /var/log/httpd/domains systemctl enable httpd --now >> $LOG check_result $? "httpd start failed" else systemctl disable httpd --now > /dev/null 2>&1 fi #----------------------------------------------------------# # Configure PHP-FPM # #----------------------------------------------------------# if [ "$phpfpm" = "yes" ]; then if [ "$multiphp" = 'yes' ]; then for v in "${multiphp_v[@]}"; do echo "[ * ] Installing PHP $v..." $HESTIA/bin/v-add-web-php "$v" > /dev/null 2>&1 done else echo "[ * ] Installing PHP $php_v..." $HESTIA/bin/v-add-web-php "$php_v" > /dev/null 2>&1 fi echo "[ * ] Configuring PHP $php_v..." # Create www.conf for webmail and php(*)admin if [ "$uselocalphp" == "yes" ]; then cp -f $HESTIA_INSTALL_DIR/php-fpm/www.conf /opt/brepo/php${php_v}/etc/php-fpm.d systemctl enable brepo-php-fpm${php_v}.service --now >> $LOG check_result $? "php-fpm start failed" # Set default php version to $php_v alternatives --install /usr/bin/php php /opt/brepo/php${php_v}/bin/php 1 > /dev/null 2>&1 alternatives --set php /opt/brepo/php${php_v}/bin/php > /dev/null 2>&1 else cp -f $HESTIA_INSTALL_DIR/php-fpm/www.conf /etc/opt/remi/php${php_v}/php-fpm.d systemctl enable php${php_v}-php-fpm --now >> $LOG check_result $? "php-fpm start failed" # Set default php version to $php_v alternatives --install /usr/bin/php php /usr/bin/php$php_v 1 > /dev/null 2>&1 alternatives --set php /usr/bin/php$php_v > /dev/null 2>&1 fi fi #----------------------------------------------------------# # Configure PHP # #----------------------------------------------------------# echo "[ * ] Configuring PHP..." # Set system php for selector hestiacp-php-admin system "$php_v" ZONE=$(timedatectl > /dev/null 2>&1 | grep Timezone | awk '{print $2}') if [ -z "$ZONE" ]; then ZONE='UTC' fi if [ "$uselocalphp" == "yes" ]; then for pconf in $(find /opt/brepo/php* -name php.ini); do sed -i "s%;date.timezone =%date.timezone = $ZONE%g" $pconf sed -i 's%_open_tag = Off%_open_tag = On%g' $pconf done else for pconf in $(find /etc/opt/remi/php* -name php.ini); do sed -i "s%;date.timezone =%date.timezone = $ZONE%g" $pconf sed -i 's%_open_tag = Off%_open_tag = On%g' $pconf done fi # Cleanup php session files not changed in the last 7 days (60*24*7 minutes) echo '#!/bin/sh' > /etc/cron.daily/php-session-cleanup echo "find -O3 /home/*/tmp/ -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin '+10080' -delete > /dev/null 2>&1" >> /etc/cron.daily/php-session-cleanup echo "find -O3 $HESTIA/data/sessions/ -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin '+10080' -delete > /dev/null 2>&1" >> /etc/cron.daily/php-session-cleanup chmod 755 /etc/cron.daily/php-session-cleanup #----------------------------------------------------------# # Configure Vsftpd # #----------------------------------------------------------# if [ "$vsftpd" = 'yes' ]; then echo "[ * ] Configuring Vsftpd server..." cp -f $HESTIA_INSTALL_DIR/vsftpd/vsftpd.conf /etc/ touch /var/log/vsftpd.log chown root:adm /var/log/vsftpd.log chmod 640 /var/log/vsftpd.log touch /var/log/xferlog chown root:adm /var/log/xferlog chmod 640 /var/log/xferlog systemctl enable vsftpd --now check_result $? "vsftpd start failed" fi #----------------------------------------------------------# # Configure ProFTPD # #----------------------------------------------------------# if [ "$proftpd" = 'yes' ]; then echo "[ * ] Configuring ProFTPD server..." echo "127.0.0.1 $servername" >> /etc/hosts cp -f $HESTIA_INSTALL_DIR/proftpd/proftpd.conf /etc/proftpd/ cp -f $HESTIA_INSTALL_DIR/proftpd/tls.conf /etc/proftpd/ systemctl enable proftpd --now >> $LOG check_result $? "proftpd start failed" fi #----------------------------------------------------------# # Configure MariaDB / MySQL # #----------------------------------------------------------# if [ "$mysql" = 'yes' ] || [ "$mysql8" = 'yes' ]; then [ "$mysql" = 'yes' ] && mysql_type="MariaDB" || mysql_type="MySQL" echo "[ * ] Configuring $mysql_type database server..." mycnf="my-small.cnf" if [ $memory -gt 1200000 ]; then mycnf="my-medium.cnf" fi if [ $memory -gt 3900000 ]; then mycnf="my-large.cnf" fi if [ "$mysql_type" = 'MariaDB' ]; then # Run mysql_install_db mysql_install_db >> $LOG fi mkdir /var/log/mysql/ chown mysql:mysql /var/log/mysql/ # Remove symbolic link rm -f /etc/my.cnf # Configuring MariaDB cp -f $HESTIA_INSTALL_DIR/mysql/$mycnf /etc/my.cnf # Switch MariaDB inclusions to the MySQL if [ "$mysql_type" = 'MySQL' ]; then sed -i '/query_cache_size/d' /etc/my.cnf sed -i 's|mariadb.conf.d|mysql.conf.d|g' /etc/my.cnf fi # MariaDB-server package has a compatibility symlink, so there is no need for conditions systemctl enable mysqld --now >> $LOG check_result $? "${mysql_type,,} start failed" # Securing MariaDB/MySQL installation mpass=$(gen_pass) echo -e "[client]\npassword='$mpass'\n" > /root/.my.cnf chmod 600 /root/.my.cnf # Alter root password mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$mpass'; FLUSH PRIVILEGES;" if [ "$mysql_type" = 'MariaDB' ]; then # Allow mysql access via socket for startup mysql -e "UPDATE mysql.global_priv SET priv=json_set(priv, '$.password_last_changed', UNIX_TIMESTAMP(), '$.plugin', 'mysql_native_password', '$.authentication_string', 'invalid', '$.auth_or', json_array(json_object(), json_object('plugin', 'unix_socket'))) WHERE User='root';" # Disable anonymous users mysql -e "DELETE FROM mysql.global_priv WHERE User='';" else mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '$mpass';" mysql -e "DELETE FROM mysql.user WHERE User='';" mysql -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" fi # Drop test database mysql -e "DROP DATABASE IF EXISTS test" mysql -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'" # Flush privileges mysql -e "FLUSH PRIVILEGES;" fi #----------------------------------------------------------# # Configure phpMyAdmin # #----------------------------------------------------------# # Source upgrade.conf with phpmyadmin versions # shellcheck source=/usr/local/hestia/install/upgrade/upgrade.conf source $HESTIA/install/upgrade/upgrade.conf if [ "$mysql" = 'yes' ] || [ "$mysql8" = 'yes' ]; then # Display upgrade information echo "[ * ] Installing phpMyAdmin version v$pma_v..." # Download latest phpmyadmin release wget --quiet --retry-connrefused https://files.phpmyadmin.net/phpMyAdmin/$pma_v/phpMyAdmin-$pma_v-all-languages.tar.gz # Unpack files tar xzf phpMyAdmin-$pma_v-all-languages.tar.gz # Create folders mkdir -p /usr/share/phpmyadmin mkdir -p /etc/phpmyadmin mkdir -p /etc/phpmyadmin/conf.d/ mkdir /usr/share/phpmyadmin/tmp # Configuring Apache2 for PHPMYADMIN if [ "$apache" = 'yes' ]; then touch /etc/httpd/conf.h.d/phpmyadmin.inc fi # Overwrite old files cp -rf phpMyAdmin-$pma_v-all-languages/* /usr/share/phpmyadmin # Create copy of config file cp -f $HESTIA_COMMON_DIR/phpmyadmin/config.inc.php /etc/phpmyadmin/ mkdir -p /var/lib/phpmyadmin/tmp chmod 770 /var/lib/phpmyadmin/tmp chown root:apache /usr/share/phpmyadmin/tmp # Set config and log directory sed -i "s|'configFile' => ROOT_PATH . 'config.inc.php',|'configFile' => '/etc/phpmyadmin/config.inc.php',|g" /usr/share/phpmyadmin/libraries/vendor_config.php # Create temporary folder and change permission chmod 770 /usr/share/phpmyadmin/tmp chown root:apache /usr/share/phpmyadmin/tmp # Generate blow fish blowfish=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32) sed -i "s|%blowfish_secret%|$blowfish|" /etc/phpmyadmin/config.inc.php # Clean Up rm -fr phpMyAdmin-$pma_v-all-languages rm -f phpMyAdmin-$pma_v-all-languages.tar.gz write_config_value "DB_PMA_ALIAS" "phpmyadmin" $HESTIA/bin/v-change-sys-db-alias 'pma' "phpmyadmin" # Special thanks to Pavel Galkin (https://skurudo.ru) # https://github.com/skurudo/phpmyadmin-fixer # shellcheck source=/usr/local/hestia/install/deb/phpmyadmin/pma.sh source $HESTIA_COMMON_DIR/phpmyadmin/pma.sh > /dev/null 2>&1 # limit access to /etc/phpmyadmin/ chown -R root:apache /etc/phpmyadmin/ chmod -R 640 /etc/phpmyadmin/* chmod 750 /etc/phpmyadmin/conf.d/ fi #----------------------------------------------------------# # Configure PostgreSQL # #----------------------------------------------------------# if [ "$postgresql" = 'yes' ]; then echo "[ * ] Configuring PostgreSQL database server..." ppass=$(gen_pass) cp -f $HESTIA_INSTALL_DIR/postgresql/pg_hba.conf /etc/postgresql/*/main/ systemctl restart postgresql sudo -iu postgres psql -c "ALTER USER postgres WITH PASSWORD '$ppass'" > /dev/null 2>&1 mkdir -p /etc/phppgadmin/ mkdir -p /usr/share/phppgadmin/ wget --retry-connrefused --quiet https://github.com/hestiacp/phppgadmin/releases/download/v$pga_v/phppgadmin-v$pga_v.tar.gz tar xzf phppgadmin-v$pga_v.tar.gz -C /usr/share/phppgadmin/ cp -f $HESTIA_INSTALL_DIR/pga/config.inc.php /etc/phppgadmin/ ln -s /etc/phppgadmin/config.inc.php /usr/share/phppgadmin/conf/ # Configuring phpPgAdmin if [ "$apache" = 'yes' ]; then cp -f $HESTIA_INSTALL_DIR/pga/phppgadmin.conf /etc/httpd/conf.h.d/phppgadmin.inc fi cp -f $HESTIA_INSTALL_DIR/pga/config.inc.php /etc/phppgadmin/ rm phppgadmin-v$pga_v.tar.gz write_config_value "DB_PGA_ALIAS" "phppgadmin" $HESTIA/bin/v-change-sys-db-alias 'pga' "phppgadmin" fi #----------------------------------------------------------# # Configure Bind # #----------------------------------------------------------# if [ "$named" = 'yes' ]; then echo "[ * ] Configuring Bind DNS server..." cp -f $HESTIA_INSTALL_DIR/bind/named.conf /etc/named/ cp -f $HESTIA_INSTALL_DIR/bind/named.conf.options /etc/named/ chown root:named /etc/named/named.conf chown root:named /etc/named/named.conf.options chmod 640 /etc/named/named.conf chmod 640 /etc/named/named.conf.options systemctl enable named --now check_result $? "bind start failed" # Workaround for OpenVZ/Virtuozzo if [ -e "/proc/vz/veinfo" ] && [ -e "/etc/rc.local" ]; then sed -i "s/^exit 0/systemctl restart named\nexit 0/" /etc/rc.local fi fi #----------------------------------------------------------# # Configure Exim # #----------------------------------------------------------# if [ "$exim" = 'yes' ]; then echo "[ * ] Configuring Exim mail server..." exim_version=$(exim --version | head -1 | awk '{print $3}' | cut -f -2 -d .) cp -f $HESTIA_INSTALL_DIR/exim/exim.conf.template /etc/exim/ cp -f $HESTIA_INSTALL_DIR/exim/dnsbl.conf /etc/exim/ cp -f $HESTIA_INSTALL_DIR/exim/spam-blocks.conf /etc/exim/ cp -f $HESTIA_INSTALL_DIR/exim/limit.conf /etc/exim/ cp -f $HESTIA_INSTALL_DIR/exim/system.filter /etc/exim/ touch /etc/exim/white-blocks.conf if [ "$spamd" = 'yes' ]; then sed -i "s/#SPAM/SPAM/g" /etc/exim/exim.conf.template fi if [ "$clamd" = 'yes' ]; then sed -i "s/#CLAMD/CLAMD/g" /etc/exim/exim.conf.template fi chmod 640 /etc/exim/exim.conf.template rm -rf /etc/exim/domains mkdir -p /etc/exim/domains alternatives --install /usr/sbin/sendmail mta /usr/sbin/exim 1 alternatives --set mta /usr/sbin/exim systemctl disable sendmail --now > /dev/null 2>&1 systemctl disable postfix --now > /dev/null 2>&1 systemctl enable exim --now check_result $? "exim start failed" fi #----------------------------------------------------------# # Configure Dovecot # #----------------------------------------------------------# if [ "$dovecot" = 'yes' ]; then echo "[ * ] Configuring Dovecot POP/IMAP mail server..." gpasswd -a dovecot mail > /dev/null 2>&1 cp -rf $HESTIA_INSTALL_DIR/dovecot /etc/ cp -f $HESTIA_INSTALL_DIR/logrotate/dovecot /etc/logrotate.d/ chown -R root:root /etc/dovecot* rm -f /etc/dovecot/conf.d/15-mailboxes.conf systemctl enable dovecot --now check_result $? "dovecot start failed" fi #----------------------------------------------------------# # Configure ClamAV # #----------------------------------------------------------# if [ "$clamd" = 'yes' ]; then useradd clamav -m -d /var/lib/clamavnew -r -s /sbin/nologin gpasswd -a clamav mail > /dev/null 2>&1 gpasswd -a clamav exim > /dev/null 2>&1 cp -f $HESTIA_INSTALL_DIR/clamav/clamd.conf /etc/clamd.d/daemon.conf cp -f $HESTIA_INSTALL_DIR/clamav/clamd.tmpfiles /etc/tmpfiles.d/clamav.conf cp -f $HESTIA_INSTALL_DIR/clamav/freshclam.conf /etc/freshclam.conf touch /var/log/freshclam.log chown clamav:clamav /var/log/freshclam.log rm -f /var/lib/clamav/freshclam.dat mkdir -p /var/log/clamav systemd-tmpfiles --create echo -ne "[ * ] Installing ClamAV anti-virus definitions... " /usr/bin/freshclam >> $LOG & BACK_PID=$! spin_i=1 while kill -0 $BACK_PID > /dev/null 2>&1; do printf "\b${spinner:spin_i++%${#spinner}:1}" sleep 0.5 done echo systemctl enable clamd@daemon --now check_result $? "clamav-daemon start failed" fi #----------------------------------------------------------# # Configure SpamAssassin # #----------------------------------------------------------# if [ "$spamd" = 'yes' ]; then echo "[ * ] Configuring SpamAssassin..." systemctl enable spamassassin --now >> $LOG check_result $? "spamassassin start failed" fi #----------------------------------------------------------# # Configure Fail2Ban # #----------------------------------------------------------# if [ "$fail2ban" = 'yes' ]; then echo "[ * ] Configuring fail2ban access monitor..." cp -rf $HESTIA_INSTALL_DIR/fail2ban /etc/ if [ "$dovecot" = 'no' ]; then fline=$(cat /etc/fail2ban/jail.local | grep -n dovecot-iptables -A 2) fline=$(echo "$fline" | grep enabled | tail -n1 | cut -f 1 -d -) sed -i "${fline}s/true/false/" /etc/fail2ban/jail.local fi if [ "$exim" = 'no' ]; then fline=$(cat /etc/fail2ban/jail.local | grep -n exim-iptables -A 2) fline=$(echo "$fline" | grep enabled | tail -n1 | cut -f 1 -d -) sed -i "${fline}s/true/false/" /etc/fail2ban/jail.local fi if [ "$vsftpd" = 'yes' ]; then #Create vsftpd Log File if [ ! -f "/var/log/vsftpd.log" ]; then touch /var/log/vsftpd.log fi fline=$(cat /etc/fail2ban/jail.local | grep -n vsftpd-iptables -A 2) fline=$(echo "$fline" | grep enabled | tail -n1 | cut -f 1 -d -) sed -i "${fline}s/false/true/" /etc/fail2ban/jail.local fi if [ -f /etc/fail2ban/jail.d/00-firewalld.conf ]; then cat /dev/null > /etc/fail2ban/jail.d/00-firewalld.conf fi sed -i "s/^backend[ ]*=[ ]*auto/backend = systemd/gi" /etc/fail2ban/jail.conf systemctl enable fail2ban --now check_result $? "fail2ban start failed" fi # Configuring MariaDB/MySQL host if [ "$mysql" = 'yes' ] || [ "$mysql8" = 'yes' ]; then $HESTIA/bin/v-add-database-host mysql localhost root $mpass fi # Configuring PostgreSQL host if [ "$postgresql" = 'yes' ]; then $HESTIA/bin/v-add-database-host pgsql localhost postgres $ppass fi #----------------------------------------------------------# # Install Roundcube # #----------------------------------------------------------# # Min requirements Dovecot + Exim + Mysql if ([ "$mysql" == 'yes' ] || [ "$mysql8" == 'yes' ]) && [ "$dovecot" == "yes" ]; then echo "[ * ] Install Roundcube..." $HESTIA/bin/v-add-sys-roundcube write_config_value "WEBMAIL_ALIAS" "webmail" else write_config_value "WEBMAIL_ALIAS" "" write_config_value "WEBMAIL_SYSTEM" "" fi #----------------------------------------------------------# # Install Sieve # #----------------------------------------------------------# # Min requirements Dovecot + Exim + Mysql + Roundcube if [ "$sieve" = 'yes' ]; then # Folder paths RC_INSTALL_DIR="/var/lib/roundcube" RC_CONFIG_DIR="/etc/roundcube" echo "[ * ] Install Sieve..." # dovecot.conf install sed -i "s/namespace/service stats \{\n unix_listener stats-writer \{\n group = mail\n mode = 0660\n user = dovecot\n \}\n\}\n\nnamespace/g" /etc/dovecot/dovecot.conf # Dovecot conf files # 10-master.conf sed -i -E -z "s/ }\n user = dovecot\n}/ \}\n unix_listener auth-master \{\n group = mail\n mode = 0660\n user = dovecot\n \}\n user = dovecot\n\}/g" /etc/dovecot/conf.d/10-master.conf # 15-lda.conf sed -i "s/\#mail_plugins = \\\$mail_plugins/mail_plugins = \$mail_plugins quota sieve\n auth_socket_path = \/run\/dovecot\/auth-master/g" /etc/dovecot/conf.d/15-lda.conf # 20-imap.conf sed -i "s/mail_plugins = quota imap_quota/mail_plugins = quota imap_quota imap_sieve/g" /etc/dovecot/conf.d/20-imap.conf # Replace dovecot-sieve config files cp -f $HESTIA_COMMON_DIR/dovecot/sieve/* /etc/dovecot/conf.d # Dovecot default file install echo -e "require [\"fileinto\"];\n# rule:[SPAM]\nif header :contains \"X-Spam-Flag\" \"YES\" {\n fileinto \"INBOX.Spam\";\n}\n" > /etc/dovecot/sieve/default # exim install sed -i "s/\stransport = local_delivery/ transport = dovecot_virtual_delivery/" /etc/exim/exim.conf.template sed -i "s/address_pipe:/dovecot_virtual_delivery:\n driver = pipe\n command = \/usr\/libexec\/dovecot\/dovecot-lda -e -d \${extract{1}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/accounts}}}}@\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\n delivery_date_add\n envelope_to_add\n return_path_add\n log_output = true\n log_defer_output = true\n user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n group = mail\n return_output\n\naddress_pipe:/g" /etc/exim4/exim4.conf.template if [ -d "/var/lib/roundcube" ]; then # Modify Roundcube config mkdir -p $RC_CONFIG_DIR/plugins/managesieve cp -f $HESTIA_COMMON_DIR/roundcube/plugins/config_managesieve.inc.php $RC_CONFIG_DIR/plugins/managesieve/config.inc.php ln -s $RC_CONFIG_DIR/plugins/managesieve/config.inc.php $RC_INSTALL_DIR/plugins/managesieve/config.inc.php chown -R root:apache $RC_CONFIG_DIR/ chmod 751 -R $RC_CONFIG_DIR chmod 644 $RC_CONFIG_DIR/*.php chmod 644 $RC_CONFIG_DIR/plugins/managesieve/config.inc.php sed -i "s/\"archive\"/\"archive\", \"managesieve\"/g" $RC_CONFIG_DIR/config.inc.php fi # Restart Dovecot and exim systemctl restart dovecot > /dev/null 2>&1 systemctl restart exim > /dev/null 2>&1 fi #----------------------------------------------------------# # Configure API # #----------------------------------------------------------# if [ "$api" = "yes" ]; then # Keep legacy api enabled until transition is complete write_config_value "API" "yes" write_config_value "API_SYSTEM" "1" write_config_value "API_ALLOWED_IP" "" else write_config_value "API" "no" write_config_value "API_SYSTEM" "0" write_config_value "API_ALLOWED_IP" "" $HESTIA/bin/v-change-sys-api disable fi #----------------------------------------------------------# # Configure File Manager # #----------------------------------------------------------# echo "[ * ] Configuring File Manager..." $HESTIA/bin/v-add-sys-filemanager quiet #----------------------------------------------------------# # Configure dependencies # #----------------------------------------------------------# echo "[ * ] Configuring PHP dependencies..." $HESTIA/bin/v-add-sys-dependencies quiet echo "[ * ] Installing Rclone" curl -s https://rclone.org/install.sh | bash > /dev/null 2>&1 #----------------------------------------------------------# # Configure IP # #----------------------------------------------------------# # Configuring system IPs echo "[ * ] Configuring System IP..." if [ "$nopublicip" = 'yes' ]; then touch $HESTIA/conf/nopublickip fi $HESTIA/bin/v-update-sys-ip > /dev/null 2>&1 # Get primary IP default_nic="$(ip -d -j route show | jq -r '.[] | if .dst == "default" then .dev else empty end')" # IPv4 primary_ipv4="$(ip -4 -d -j addr show "$default_nic" | jq -r '.[] | select(length > 0) | .addr_info[] | if .scope == "global" then .local else empty end' | head -n1)" # IPv6 #primary_ipv6="$(ip -6 -d -j addr show "$default_nic" | jq -r '.[] | select(length > 0) | .addr_info[] | if .scope == "global" then .local else empty end' | head -n1)" ip="$primary_ipv4" local_ip="$primary_ipv4" # Configuring firewall if [ "$iptables" = 'yes' ]; then $HESTIA/bin/v-update-firewall fi # Get public IP pub_ip=$ip if [ "$nopublicip" = 'no' ]; then pub_ip=$(curl -fsLm5 --retry 2 --ipv4 -H "Simple-Hestiacp: yes" https://hestiaip.brepo.ru/) if [ -n "$pub_ip" ] && [ "$pub_ip" != "$ip" ]; then $HESTIA/bin/v-change-sys-ip-nat $ip $pub_ip > /dev/null 2>&1 ip=$pub_ip fi fi # Configuring mod_remoteip if [ "$apache" = 'yes' ] && [ "$nginx" = 'yes' ]; then cd /etc/httpd/conf.modules.d echo "" > remoteip.conf echo " RemoteIPHeader X-Real-IP" >> remoteip.conf if [ "$local_ip" != "127.0.0.1" ] && [ "$pub_ip" != "127.0.0.1" ]; then echo " RemoteIPInternalProxy 127.0.0.1" >> remoteip.conf fi if [ -n "$local_ip" ] && [ "$local_ip" != "$pub_ip" ]; then echo " RemoteIPInternalProxy $local_ip" >> remoteip.conf fi if [ -n "$pub_ip" ]; then echo " RemoteIPInternalProxy $pub_ip" >> remoteip.conf fi echo "" >> remoteip.conf sed -i "s/LogFormat \"%h/LogFormat \"%a/g" /etc/httpd/conf/httpd.conf systemctl restart httpd fi #install oneshot service for hestia echo "[ * ] Configuring One Shot Service..." $HESTIA/bin/v-oneshot-service if [ ! -e /etc/systemd/system/hestiacp-prepare.service ]; then cp -f $HESTIA_INSTALL_DIR/oneshot/hestiacp-prepare.service /etc/systemd/system/ systemctl enable hestiacp-prepare.service --now fi # Adding default domain $HESTIA/bin/v-add-web-domain admin $servername $ip check_result $? "can't create $servername domain" # Adding cron jobs export SCHEDULED_RESTART="yes" command="sudo $HESTIA/bin/v-update-sys-queue restart" $HESTIA/bin/v-add-cron-job 'admin' '*/2' '*' '*' '*' '*' "$command" systemctl restart crond command="sudo $HESTIA/bin/v-update-sys-queue daily" $HESTIA/bin/v-add-cron-job 'admin' '10' '00' '*' '*' '*' "$command" command="sudo $HESTIA/bin/v-update-sys-queue disk" $HESTIA/bin/v-add-cron-job 'admin' '15' '02' '*' '*' '*' "$command" command="sudo $HESTIA/bin/v-update-sys-queue traffic" $HESTIA/bin/v-add-cron-job 'admin' '10' '00' '*' '*' '*' "$command" command="sudo $HESTIA/bin/v-update-sys-queue webstats" $HESTIA/bin/v-add-cron-job 'admin' '30' '03' '*' '*' '*' "$command" command="sudo $HESTIA/bin/v-update-sys-queue backup" $HESTIA/bin/v-add-cron-job 'admin' '*/5' '*' '*' '*' '*' "$command" command="sudo $HESTIA/bin/v-backup-users" $HESTIA/bin/v-add-cron-job 'admin' '10' '05' '*' '*' '*' "$command" command="sudo $HESTIA/bin/v-update-user-stats" $HESTIA/bin/v-add-cron-job 'admin' '20' '00' '*' '*' '*' "$command" command="sudo $HESTIA/bin/v-update-sys-rrd" $HESTIA/bin/v-add-cron-job 'admin' '*/5' '*' '*' '*' '*' "$command" command="sudo $HESTIA/bin/v-update-letsencrypt-ssl" min=$(gen_pass '012345' '2') hour=$(gen_pass '1234567' '1') $HESTIA/bin/v-add-cron-job 'admin' "$min" "$hour" '*' '*' '*' "$command" # Enable automatic updates $HESTIA/bin/v-add-cron-hestia-autoupdate apt # Building initital rrd images $HESTIA/bin/v-update-sys-rrd # Enabling file system quota if [ "$quota" = 'yes' ]; then $HESTIA/bin/v-add-sys-quota fi # Set backend port $HESTIA/bin/v-change-sys-port $port > /dev/null 2>&1 # Create default configuration files $HESTIA/bin/v-update-sys-defaults # Update remaining packages since repositories have changed echo -ne "[ * ] Installing remaining software updates..." dnf clean all dnf makecache dnf -y upgrade >> $LOG & BACK_PID=$! # Check if package installation is done, print a spinner spin_i=1 while kill -0 $BACK_PID > /dev/null 2>&1; do printf "\b${spinner:spin_i++%${#spinner}:1}" sleep 0.5 done # Do a blank echo to get the \n back echo # Check Installation result wait $BACK_PID check_result $? "dnf upgrade failed" # Starting Hestia service systemctl enable hestia --now check_result $? "hestia start failed" chown admin:admin $HESTIA/data/sessions # Create backup folder and set correct permission mkdir -p /backup/ chmod 755 /backup/ # Create cronjob to generate ssl echo "@reboot root sleep 10 && rm /etc/cron.d/hestia-ssl && PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:' && /usr/local/hestia/bin/v-add-letsencrypt-host" > /etc/cron.d/hestia-ssl #----------------------------------------------------------# # Set hestia.conf default values # #----------------------------------------------------------# echo "[ * ] Updating configuration files..." write_config_value "PHPMYADMIN_KEY" "" write_config_value "POLICY_USER_VIEW_SUSPENDED" "no" write_config_value "POLICY_USER_VIEW_LOGS" "yes" write_config_value "POLICY_USER_EDIT_WEB_TEMPLATES" "true" write_config_value "POLICY_USER_EDIT_DNS_TEMPLATES" "yes" write_config_value "POLICY_USER_EDIT_DETAILS" "yes" write_config_value "POLICY_USER_DELETE_LOGS" "yes" write_config_value "POLICY_USER_CHANGE_THEME" "yes" write_config_value "POLICY_SYSTEM_PROTECTED_ADMIN" "no" write_config_value "POLICY_SYSTEM_PASSWORD_RESET" "yes" write_config_value "POLICY_SYSTEM_HIDE_SERVICES" "no" write_config_value "POLICY_SYSTEM_ENABLE_BACON" "no" write_config_value "PLUGIN_APP_INSTALLER" "true" write_config_value "DEBUG_MODE" "no" write_config_value "ENFORCE_SUBDOMAIN_OWNERSHIP" "yes" write_config_value "USE_SERVER_SMTP" "false" write_config_value "SERVER_SMTP_PORT" "" write_config_value "SERVER_SMTP_HOST" "" write_config_value "SERVER_SMTP_SECURITY" "" write_config_value "SERVER_SMTP_USER" "" write_config_value "SERVER_SMTP_PASSWD" "" write_config_value "SERVER_SMTP_ADDR" "" write_config_value "POLICY_CSRF_STRICTNESS" "1" write_config_value "DISABLE_IP_CHECK" "no" write_config_value "DNS_CLUSTER_SYSTEM" "hestia" # Add /usr/local/hestia/bin/ to path variable echo 'if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then . /etc/profile.d/hestia.sh fi' >> /root/.bashrc #----------------------------------------------------------# # Hestia Access Info # #----------------------------------------------------------# # Comparing hostname and IP host_ip=$(host $servername | head -n 1 | awk '{print $NF}') if [ "$host_ip" = "$ip" ]; then ip="$servername" fi echo -e "\n" echo "====================================================================" echo -e "\n" # Sending notification to admin email echo -e "Congratulations! You have successfully installed Hestia Control Panel on your server. Ready to get started? Log in using the following credentials: Admin URL: https://$servername:$port" > $tmpfile if [ "$host_ip" != "$ip" ]; then echo " Backup URL: https://$ip:$port" >> $tmpfile fi echo -e -n " Username: admin Password: $displaypass Thank you for choosing Hestia Control Panel(RPM edition) to power your full stack web server, we hope that you enjoy using it as much as we do! Documentation: https://hestiadocs.brepo.ru/ Forum: https://forum.hestiacp.com/ GitHub: https://github.com/bayrepo/hestiacp-rpm or development storage https://dev.brepo.ru/bayrepo/hestiacp Note: Automatic updates are enabled by default. If you would like to disable them, please log in and navigate to Server > Updates to turn them off. -- Sincerely yours, The Hestia Control Panel(RPM edition) development team Made with love & pride by the open-source community around the world. " >> $tmpfile send_mail="$HESTIA/web/inc/mail-wrapper.php" cat $tmpfile | $send_mail -s "Hestia Control Panel" $email # Congrats echo cat $tmpfile rm -f $tmpfile # Add welcome message to notification panel $HESTIA/bin/v-add-user-notification admin 'Добро пожаловать в HestiaCP' '

Перйдите по ссылке для добавления пользователя и домена. Для получения информации ознакомтесь с документацией.

Желаем удачного дня!

Команда разработчиков HestiaCP

' # Clean-up # Sort final configuration file sort_config_file if [ "$interactive" = 'yes' ]; then echo "[ ! ] IMPORTANT: The system will now reboot to complete the installation process." read -n 1 -s -r -p "Press any key to continue" reboot else echo "[ ! ] IMPORTANT: You must restart the system before continuing!" fi # EOF