hst-install-ubuntu.sh 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375
  1. #!/bin/bash
  2. # ======================================================== #
  3. #
  4. # Hestia Control Panel Installer for Ubuntu
  5. # https://www.hestiacp.com/
  6. #
  7. # Currently Supported Versions:
  8. # Ubuntu 20.04, 22.04 LTS
  9. #
  10. # ======================================================== #
  11. #----------------------------------------------------------#
  12. # Variables&Functions #
  13. #----------------------------------------------------------#
  14. export PATH=$PATH:/sbin
  15. export DEBIAN_FRONTEND=noninteractive
  16. RHOST='apt.hestiacp.com'
  17. VERSION='ubuntu'
  18. HESTIA='/usr/local/hestia'
  19. LOG="/root/hst_install_backups/hst_install-$(date +%d%m%Y%H%M).log"
  20. memory=$(grep 'MemTotal' /proc/meminfo | tr ' ' '\n' | grep [0-9])
  21. hst_backups="/root/hst_install_backups/$(date +%d%m%Y%H%M)"
  22. spinner="/-\|"
  23. os='ubuntu'
  24. release="$(lsb_release -s -r)"
  25. codename="$(lsb_release -s -c)"
  26. architecture="$(arch)"
  27. HESTIA_INSTALL_DIR="$HESTIA/install/deb"
  28. HESTIA_COMMON_DIR="$HESTIA/install/common"
  29. VERBOSE='no'
  30. # Define software versions
  31. HESTIA_INSTALL_VER='1.9.0~alpha'
  32. # Dependencies
  33. multiphp_v=("5.6" "7.0" "7.1" "7.2" "7.3" "7.4" "8.0" "8.1" "8.2")
  34. fpm_v="8.2"
  35. mariadb_v="10.11"
  36. # Defining software pack for all distros
  37. software="acl apache2 apache2.2-common apache2-suexec-custom apache2-utils apparmor-utils awstats bc bind9 bsdmainutils bsdutils
  38. clamav-daemon cron curl dnsutils dovecot-imapd dovecot-managesieved dovecot-pop3d dovecot-sieve e2fslibs e2fsprogs
  39. exim4 exim4-daemon-heavy expect fail2ban flex ftp git hestia=${HESTIA_INSTALL_VER} hestia-nginx hestia-php hestia-web-terminal
  40. idn2 imagemagick ipset jq libapache2-mod-fcgid libapache2-mod-php$fpm_v libapache2-mod-rpaf libonig5 libzip4 lsb-release
  41. lsof mariadb-client mariadb-common mariadb-server mc mysql-client mysql-common mysql-server nginx nodejs openssh-server
  42. php$fpm_v php$fpm_v-apcu php$fpm_v-bz2 php$fpm_v-cgi php$fpm_v-cli php$fpm_v-common php$fpm_v-curl php$fpm_v-gd
  43. php$fpm_v-imagick php$fpm_v-imap php$fpm_v-intl php$fpm_v-ldap php$fpm_v-mbstring php$fpm_v-mysql php$fpm_v-opcache
  44. php$fpm_v-pgsql php$fpm_v-pspell php$fpm_v-readline php$fpm_v-xml php$fpm_v-zip postgresql postgresql-contrib
  45. proftpd-basic quota rrdtool rsyslog setpriv spamassassin sudo sysstat unzip vim-common vsftpd whois zip zstd"
  46. installer_dependencies="apt-transport-https ca-certificates curl dirmngr gnupg openssl software-properties-common wget"
  47. # Defining help function
  48. help() {
  49. echo "Usage: $0 [OPTIONS]
  50. -a, --apache Install Apache [yes|no] default: yes
  51. -w, --phpfpm Install PHP-FPM [yes|no] default: yes
  52. -o, --multiphp Install MultiPHP [yes|no] default: no
  53. -v, --vsftpd Install VSFTPD [yes|no] default: yes
  54. -j, --proftpd Install ProFTPD [yes|no] default: no
  55. -k, --named Install BIND [yes|no] default: yes
  56. -m, --mysql Install MariaDB [yes|no] default: yes
  57. -M, --mysql8 Install MySQL 8 [yes|no] default: no
  58. -g, --postgresql Install PostgreSQL [yes|no] default: no
  59. -x, --exim Install Exim [yes|no] default: yes
  60. -z, --dovecot Install Dovecot [yes|no] default: yes
  61. -Z, --sieve Install Sieve [yes|no] default: no
  62. -c, --clamav Install ClamAV [yes|no] default: yes
  63. -t, --spamassassin Install SpamAssassin [yes|no] default: yes
  64. -i, --iptables Install iptables [yes|no] default: yes
  65. -b, --fail2ban Install Fail2Ban [yes|no] default: yes
  66. -q, --quota Filesystem Quota [yes|no] default: no
  67. -W, --webterminal Web Terminal [yes|no] default: no
  68. -d, --api Activate API [yes|no] default: yes
  69. -r, --port Change Backend Port default: 8083
  70. -l, --lang Default language default: en
  71. -y, --interactive Interactive install [yes|no] default: yes
  72. -s, --hostname Set hostname
  73. -e, --email Set admin email
  74. -u, --username Set admin user
  75. -p, --password Set admin password
  76. -D, --with-debs Path to Hestia debs
  77. -f, --force Force installation
  78. -h, --help Print this help
  79. Example: bash $0 -e [email protected] -p p4ssw0rd --multiphp yes"
  80. exit 1
  81. }
  82. # Defining file download function
  83. download_file() {
  84. wget $1 -q --show-progress --progress=bar:force
  85. }
  86. # Defining password-gen function
  87. gen_pass() {
  88. matrix=$1
  89. length=$2
  90. if [ -z "$matrix" ]; then
  91. matrix="A-Za-z0-9"
  92. fi
  93. if [ -z "$length" ]; then
  94. length=16
  95. fi
  96. head /dev/urandom | tr -dc $matrix | head -c$length
  97. }
  98. # Defining return code check function
  99. check_result() {
  100. if [ $1 -ne 0 ]; then
  101. echo "Error: $2"
  102. exit $1
  103. fi
  104. }
  105. # Source conf in installer
  106. source_conf() {
  107. while IFS='= ' read -r lhs rhs; do
  108. if [[ ! $lhs =~ ^\ *# && -n $lhs ]]; then
  109. rhs="${rhs%%^\#*}" # Del in line right comments
  110. rhs="${rhs%%*( )}" # Del trailing spaces
  111. rhs="${rhs%\'*}" # Del opening string quotes
  112. rhs="${rhs#\'*}" # Del closing string quotes
  113. declare -g $lhs="$rhs"
  114. fi
  115. done < $1
  116. }
  117. # Defining function to set default value
  118. set_default_value() {
  119. eval variable=\$$1
  120. if [ -z "$variable" ]; then
  121. eval $1=$2
  122. fi
  123. if [ "$variable" != 'yes' ] && [ "$variable" != 'no' ]; then
  124. eval $1=$2
  125. fi
  126. }
  127. # Defining function to set default language value
  128. set_default_lang() {
  129. if [ -z "$lang" ]; then
  130. eval lang=$1
  131. fi
  132. 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 sq sr sv th tr uk ur vi zh-cn zh-tw"
  133. if ! (echo $lang_list | grep -w $lang > /dev/null 2>&1); then
  134. eval lang=$1
  135. fi
  136. }
  137. # Define the default backend port
  138. set_default_port() {
  139. if [ -z "$port" ]; then
  140. eval port=$1
  141. fi
  142. }
  143. # Write configuration KEY/VALUE pair to $HESTIA/conf/hestia.conf
  144. write_config_value() {
  145. local key="$1"
  146. local value="$2"
  147. echo "$key='$value'" >> $HESTIA/conf/hestia.conf
  148. }
  149. # Sort configuration file values
  150. # Write final copy to $HESTIA/conf/hestia.conf for active usage
  151. # Duplicate file to $HESTIA/conf/defaults/hestia.conf to restore known good installation values
  152. sort_config_file() {
  153. sort $HESTIA/conf/hestia.conf -o /tmp/updconf
  154. mv $HESTIA/conf/hestia.conf $HESTIA/conf/hestia.conf.bak
  155. mv /tmp/updconf $HESTIA/conf/hestia.conf
  156. rm -f $HESTIA/conf/hestia.conf.bak
  157. if [ ! -d "$HESTIA/conf/defaults/" ]; then
  158. mkdir -p "$HESTIA/conf/defaults/"
  159. fi
  160. cp $HESTIA/conf/hestia.conf $HESTIA/conf/defaults/hestia.conf
  161. }
  162. # todo add check for usernames that are blocked
  163. validate_username() {
  164. if [[ "$username" =~ ^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$ ]]; then
  165. # Username valid
  166. return 1
  167. else
  168. return 0
  169. fi
  170. }
  171. validate_password() {
  172. if [ -z "$vpass" ]; then
  173. return 0
  174. else
  175. return 1
  176. fi
  177. }
  178. # Validate hostname according to RFC1178
  179. validate_hostname() {
  180. # remove extra .
  181. servername=$(echo "$servername" | sed -e "s/[.]*$//g")
  182. servername=$(echo "$servername" | sed -e "s/^[.]*//")
  183. if [[ $(echo "$servername" | grep -o "\." | wc -l) -gt 1 ]] && [[ ! $servername =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  184. # Hostname valid
  185. return 1
  186. else
  187. # Hostname invalid
  188. return 0
  189. fi
  190. }
  191. validate_email() {
  192. if [[ ! "$email" =~ ^[A-Za-z0-9._%+-]+@[[:alnum:].-]+\.[A-Za-z]{2,63}$ ]]; then
  193. # Email invalid
  194. return 0
  195. else
  196. # Email valid
  197. return 1
  198. fi
  199. }
  200. version_ge() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1" -o -n "$1" -a "$1" = "$2"; }
  201. #----------------------------------------------------------#
  202. # Verifications #
  203. #----------------------------------------------------------#
  204. # Creating temporary file
  205. tmpfile=$(mktemp -p /tmp)
  206. # Translating argument to --gnu-long-options
  207. for arg; do
  208. delim=""
  209. case "$arg" in
  210. --apache) args="${args}-a " ;;
  211. --phpfpm) args="${args}-w " ;;
  212. --vsftpd) args="${args}-v " ;;
  213. --proftpd) args="${args}-j " ;;
  214. --named) args="${args}-k " ;;
  215. --mysql) args="${args}-m " ;;
  216. --mariadb) args="${args}-m " ;;
  217. --mysql-classic) args="${args}-M " ;;
  218. --mysql8) args="${args}-M " ;;
  219. --postgresql) args="${args}-g " ;;
  220. --exim) args="${args}-x " ;;
  221. --dovecot) args="${args}-z " ;;
  222. --sieve) args="${args}-Z " ;;
  223. --clamav) args="${args}-c " ;;
  224. --spamassassin) args="${args}-t " ;;
  225. --iptables) args="${args}-i " ;;
  226. --fail2ban) args="${args}-b " ;;
  227. --multiphp) args="${args}-o " ;;
  228. --quota) args="${args}-q " ;;
  229. --webterminal) args="${args}-W " ;;
  230. --port) args="${args}-r " ;;
  231. --lang) args="${args}-l " ;;
  232. --interactive) args="${args}-y " ;;
  233. --api) args="${args}-d " ;;
  234. --hostname) args="${args}-s " ;;
  235. --email) args="${args}-e " ;;
  236. --username) args="${args}-u " ;;
  237. --password) args="${args}-p " ;;
  238. --force) args="${args}-f " ;;
  239. --with-debs) args="${args}-D " ;;
  240. --help) args="${args}-h " ;;
  241. *)
  242. [[ "${arg:0:1}" == "-" ]] || delim="\""
  243. args="${args}${delim}${arg}${delim} "
  244. ;;
  245. esac
  246. done
  247. eval set -- "$args"
  248. # Parsing arguments
  249. while getopts "a:w:v:j:k:m:M:g:d:x:z:Z:c:t:i:b:r:o:q:l:y:s:u:e:p:W:D:fh" Option; do
  250. case $Option in
  251. a) apache=$OPTARG ;; # Apache
  252. w) phpfpm=$OPTARG ;; # PHP-FPM
  253. o) multiphp=$OPTARG ;; # Multi-PHP
  254. v) vsftpd=$OPTARG ;; # Vsftpd
  255. j) proftpd=$OPTARG ;; # Proftpd
  256. k) named=$OPTARG ;; # Named
  257. m) mysql=$OPTARG ;; # MariaDB
  258. M) mysql8=$OPTARG ;; # MySQL
  259. g) postgresql=$OPTARG ;; # PostgreSQL
  260. x) exim=$OPTARG ;; # Exim
  261. z) dovecot=$OPTARG ;; # Dovecot
  262. Z) sieve=$OPTARG ;; # Sieve
  263. c) clamd=$OPTARG ;; # ClamAV
  264. t) spamd=$OPTARG ;; # SpamAssassin
  265. i) iptables=$OPTARG ;; # Iptables
  266. b) fail2ban=$OPTARG ;; # Fail2ban
  267. q) quota=$OPTARG ;; # FS Quota
  268. W) webterminal=$OPTARG ;; # Web Terminal
  269. r) port=$OPTARG ;; # Backend Port
  270. l) lang=$OPTARG ;; # Language
  271. d) api=$OPTARG ;; # Activate API
  272. y) interactive=$OPTARG ;; # Interactive install
  273. s) servername=$OPTARG ;; # Hostname
  274. e) email=$OPTARG ;; # Admin email
  275. u) username=$OPTARG ;; # Admin username
  276. p) vpass=$OPTARG ;; # Admin password
  277. D) withdebs=$OPTARG ;; # Hestia debs path
  278. f) force='yes' ;; # Force install
  279. h) help ;; # Help
  280. *) help ;; # Print help (default)
  281. esac
  282. done
  283. # Defining default software stack
  284. set_default_value 'nginx' 'yes'
  285. set_default_value 'apache' 'yes'
  286. set_default_value 'phpfpm' 'yes'
  287. set_default_value 'multiphp' 'no'
  288. set_default_value 'vsftpd' 'yes'
  289. set_default_value 'proftpd' 'no'
  290. set_default_value 'named' 'yes'
  291. set_default_value 'mysql' 'yes'
  292. set_default_value 'mysql8' 'no'
  293. set_default_value 'postgresql' 'no'
  294. set_default_value 'exim' 'yes'
  295. set_default_value 'dovecot' 'yes'
  296. set_default_value 'sieve' 'no'
  297. if [ $memory -lt 1500000 ]; then
  298. set_default_value 'clamd' 'no'
  299. set_default_value 'spamd' 'no'
  300. elif [ $memory -lt 3000000 ]; then
  301. set_default_value 'clamd' 'no'
  302. set_default_value 'spamd' 'yes'
  303. else
  304. set_default_value 'clamd' 'yes'
  305. set_default_value 'spamd' 'yes'
  306. fi
  307. set_default_value 'iptables' 'yes'
  308. set_default_value 'fail2ban' 'yes'
  309. set_default_value 'quota' 'no'
  310. set_default_value 'webterminal' 'no'
  311. set_default_value 'interactive' 'yes'
  312. set_default_value 'api' 'yes'
  313. set_default_port '8083'
  314. set_default_lang 'en'
  315. # Checking software conflicts
  316. if [ "$proftpd" = 'yes' ]; then
  317. vsftpd='no'
  318. fi
  319. if [ "$exim" = 'no' ]; then
  320. clamd='no'
  321. spamd='no'
  322. dovecot='no'
  323. fi
  324. if [ "$dovecot" = 'no' ]; then
  325. sieve='no'
  326. fi
  327. if [ "$iptables" = 'no' ]; then
  328. fail2ban='no'
  329. fi
  330. if [ "$apache" = 'no' ]; then
  331. phpfpm='yes'
  332. fi
  333. if [ "$mysql" = 'yes' ] && [ "$mysql8" = 'yes' ]; then
  334. mysql='no'
  335. fi
  336. # Checking root permissions
  337. if [ "x$(id -u)" != 'x0' ]; then
  338. check_result 1 "Script can be run executed only by root"
  339. fi
  340. if [ -d "/usr/local/hestia" ]; then
  341. check_result 1 "Hestia install detected. Unable to continue"
  342. fi
  343. # Checking admin user account
  344. if [ -n "$(grep ^admin: /etc/passwd /etc/group)" ] && [ -z "$force" ]; then
  345. echo 'Please remove admin user account before proceeding.'
  346. echo 'If you want to do it automatically run installer with -f option:'
  347. echo -e "Example: bash $0 --force\n"
  348. check_result 1 "User admin exists"
  349. fi
  350. # Clear the screen once launch permissions have been verified
  351. clear
  352. # Configure apt to retry downloading on error
  353. if [ ! -f /etc/apt/apt.conf.d/80-retries ]; then
  354. echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
  355. fi
  356. # Welcome message
  357. echo "Welcome to the Hestia Control Panel installer!"
  358. echo
  359. echo "Please wait, the installer is now checking for missing dependencies..."
  360. echo
  361. # Update apt repository
  362. apt-get -qq update
  363. # Creating backup directory
  364. mkdir -p "$hst_backups"
  365. # Pre-install packages
  366. echo "[ * ] Installing dependencies..."
  367. apt-get -y install $installer_dependencies >> $LOG
  368. check_result $? "Package installation failed, check log file for more details."
  369. # Check repository availability
  370. wget --quiet "https://$RHOST" -O /dev/null
  371. check_result $? "Unable to connect to the Hestia APT repository"
  372. # Check installed packages
  373. tmpfile=$(mktemp -p /tmp)
  374. dpkg --get-selections > $tmpfile
  375. conflicts_pkg="exim4 mariadb-server apache2 nginx hestia postfix ufw"
  376. # Drop postfix from the list if exim should not be installed
  377. if [ "$exim" = 'no' ]; then
  378. conflicts_pkg=$(echo $conflicts_pkg | sed 's/postfix//g' | xargs)
  379. fi
  380. for pkg in $conflicts_pkg; do
  381. if [ -n "$(grep $pkg $tmpfile)" ]; then
  382. conflicts="$pkg* $conflicts"
  383. fi
  384. done
  385. rm -f $tmpfile
  386. if [ -n "$conflicts" ] && [ -z "$force" ]; then
  387. echo '!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!'
  388. echo
  389. echo 'WARNING: The following packages are already installed'
  390. echo "$conflicts"
  391. echo
  392. echo 'It is highly recommended that you remove them before proceeding.'
  393. echo
  394. echo '!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!'
  395. echo
  396. read -p 'Would you like to remove the conflicting packages? [y/n] ' answer
  397. if [ "$answer" = 'y' ] || [ "$answer" = 'Y' ]; then
  398. apt-get -qq purge $conflicts -y
  399. check_result $? 'apt-get remove failed'
  400. unset $answer
  401. else
  402. check_result 1 "Hestia Control Panel should be installed on a clean server."
  403. fi
  404. fi
  405. # Check network configuration
  406. if [ -d /etc/netplan ] && [ -z "$force" ]; then
  407. if [ -z "$(ls -A /etc/netplan)" ]; then
  408. echo '!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!'
  409. echo
  410. echo 'WARNING: Your network configuration may not be set up correctly.'
  411. echo 'Details: The netplan configuration directory is empty.'
  412. echo ''
  413. echo 'You may have a network configuration file that was created using'
  414. echo 'systemd-networkd.'
  415. echo ''
  416. echo 'It is strongly recommended to migrate to netplan, which is now the'
  417. echo 'default network configuration system in newer releases of Ubuntu.'
  418. echo ''
  419. echo 'While you can leave your configuration as-is, please note that you'
  420. echo 'will not be able to use additional IPs properly.'
  421. echo ''
  422. echo 'If you wish to continue and force the installation,'
  423. echo 'run this script with -f option:'
  424. echo "Example: bash $0 --force"
  425. echo
  426. echo '!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!'
  427. echo
  428. check_result 1 "Unable to detect netplan configuration."
  429. fi
  430. fi
  431. # Validate whether installation script matches release version before continuing with install
  432. if [ -z "$withdebs" ] || [ ! -d "$withdebs" ]; then
  433. release_branch_ver=$(curl -s https://raw.githubusercontent.com/hestiacp/hestiacp/release/src/deb/hestia/control | grep "Version:" | awk '{print $2}')
  434. if [ "$HESTIA_INSTALL_VER" != "$release_branch_ver" ]; then
  435. echo
  436. echo -e "\e[91mInstallation aborted\e[0m"
  437. echo "===================================================================="
  438. echo -e "\e[33mERROR: Install script version does not match package version!\e[0m"
  439. echo -e "\e[33mPlease download the installer from the release branch in order to continue:\e[0m"
  440. echo ""
  441. echo -e "\e[33mhttps://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh\e[0m"
  442. echo ""
  443. echo -e "\e[33mTo test pre-release versions, build the .deb packages and re-run the installer:\e[0m"
  444. echo -e " \e[33m./hst_autocompile.sh \e[1m--hestia branchname no\e[21m\e[0m"
  445. echo -e " \e[33m./hst-install.sh .. \e[1m--with-debs /tmp/hestiacp-src/debs\e[21m\e[0m"
  446. echo ""
  447. check_result 1 "Installation aborted"
  448. fi
  449. fi
  450. case $architecture in
  451. x86_64)
  452. ARCH="amd64"
  453. ;;
  454. aarch64)
  455. ARCH="arm64"
  456. ;;
  457. *)
  458. echo
  459. echo -e "\e[91mInstallation aborted\e[0m"
  460. echo "===================================================================="
  461. echo -e "\e[33mERROR: $architecture is currently not supported!\e[0m"
  462. echo -e "\e[33mPlease verify the achitecture used is currenlty supported\e[0m"
  463. echo ""
  464. echo -e "\e[33mhttps://github.com/hestiacp/hestiacp/blob/main/README.md\e[0m"
  465. echo ""
  466. check_result 1 "Installation aborted"
  467. ;;
  468. esac
  469. #----------------------------------------------------------#
  470. # Brief Info #
  471. #----------------------------------------------------------#
  472. install_welcome_message() {
  473. DISPLAY_VER=$(echo $HESTIA_INSTALL_VER | sed "s|~alpha||g" | sed "s|~beta||g")
  474. echo
  475. echo ' _ _ _ _ ____ ____ '
  476. echo ' | | | | ___ ___| |_(_) __ _ / ___| _ \ '
  477. echo ' | |_| |/ _ \/ __| __| |/ _` | | | |_) | '
  478. echo ' | _ | __/\__ \ |_| | (_| | |___| __/ '
  479. echo ' |_| |_|\___||___/\__|_|\__,_|\____|_| '
  480. echo " "
  481. echo " Hestia Control Panel "
  482. if [[ "$HESTIA_INSTALL_VER" =~ "beta" ]]; then
  483. echo " BETA RELEASE "
  484. fi
  485. if [[ "$HESTIA_INSTALL_VER" =~ "alpha" ]]; then
  486. echo " DEVELOPMENT SNAPSHOT "
  487. echo " NOT INTENDED FOR PRODUCTION USE "
  488. echo " USE AT YOUR OWN RISK "
  489. fi
  490. echo " ${DISPLAY_VER} "
  491. echo " www.hestiacp.com "
  492. echo
  493. echo "========================================================================"
  494. echo
  495. echo "Thank you for downloading Hestia Control Panel! In a few moments,"
  496. echo "we will begin installing the following components on your server:"
  497. echo
  498. }
  499. # Printing nice ASCII logo
  500. clear
  501. install_welcome_message
  502. # Web stack
  503. echo ' - NGINX Web / Proxy Server'
  504. if [ "$apache" = 'yes' ]; then
  505. echo ' - Apache Web Server (as backend)'
  506. fi
  507. if [ "$phpfpm" = 'yes' ] && [ "$multiphp" = 'no' ]; then
  508. echo ' - PHP-FPM Application Server'
  509. fi
  510. if [ "$multiphp" = 'yes' ]; then
  511. phpfpm='yes'
  512. echo ' - Multi-PHP Environment'
  513. fi
  514. # DNS stack
  515. if [ "$named" = 'yes' ]; then
  516. echo ' - Bind DNS Server'
  517. fi
  518. # Mail stack
  519. if [ "$exim" = 'yes' ]; then
  520. echo -n ' - Exim Mail Server'
  521. if [ "$clamd" = 'yes' ] || [ "$spamd" = 'yes' ]; then
  522. echo -n ' + '
  523. if [ "$clamd" = 'yes' ]; then
  524. echo -n 'ClamAV '
  525. fi
  526. if [ "$spamd" = 'yes' ]; then
  527. if [ "$clamd" = 'yes' ]; then
  528. echo -n '+ '
  529. fi
  530. echo -n 'SpamAssassin'
  531. fi
  532. fi
  533. echo
  534. if [ "$dovecot" = 'yes' ]; then
  535. echo -n ' - Dovecot POP3/IMAP Server'
  536. if [ "$sieve" = 'yes' ]; then
  537. echo -n '+ Sieve'
  538. fi
  539. fi
  540. fi
  541. echo
  542. # Database stack
  543. if [ "$mysql" = 'yes' ]; then
  544. echo ' - MariaDB Database Server'
  545. fi
  546. if [ "$mysql8" = 'yes' ]; then
  547. echo ' - MySQL8 Database Server'
  548. fi
  549. if [ "$postgresql" = 'yes' ]; then
  550. echo ' - PostgreSQL Database Server'
  551. fi
  552. # FTP stack
  553. if [ "$vsftpd" = 'yes' ]; then
  554. echo ' - Vsftpd FTP Server'
  555. fi
  556. if [ "$proftpd" = 'yes' ]; then
  557. echo ' - ProFTPD FTP Server'
  558. fi
  559. if [ "$webterminal" = 'yes' ]; then
  560. echo ' - Web terminal'
  561. fi
  562. # Firewall stack
  563. if [ "$iptables" = 'yes' ]; then
  564. echo -n ' - Firewall (iptables)'
  565. fi
  566. if [ "$iptables" = 'yes' ] && [ "$fail2ban" = 'yes' ]; then
  567. echo -n ' + Fail2Ban Access Monitor'
  568. fi
  569. echo -e "\n"
  570. echo "========================================================================"
  571. echo -e "\n"
  572. # Asking for confirmation to proceed
  573. if [ "$interactive" = 'yes' ]; then
  574. read -p 'Would you like to continue with the installation? [Y/N]: ' answer
  575. if [ "$answer" != 'y' ] && [ "$answer" != 'Y' ]; then
  576. echo 'Goodbye'
  577. exit 1
  578. fi
  579. fi
  580. #Validate Username / Password / Email / Hostname even when interactive = no
  581. # Asking for contact email
  582. if [ -z "$username" ]; then
  583. while validate_username; do
  584. echo -e "\nPlease use a valid username (ex. user)."
  585. read -p 'Please enter administrator username: ' username
  586. done
  587. else
  588. if validate_username; then
  589. echo "Please use a valid username (ex. user)."
  590. exit 1
  591. fi
  592. fi
  593. # Asking for contact email
  594. if [ -z "$email" ]; then
  595. while validate_email; do
  596. echo -e "\nPlease use a valid emailadress (ex. [email protected])."
  597. read -p 'Please enter admin email address: ' email
  598. done
  599. else
  600. if validate_email; then
  601. echo "Please use a valid emailadress (ex. [email protected])."
  602. exit 1
  603. fi
  604. fi
  605. # Asking to set FQDN hostname
  606. if [ -z "$servername" ]; then
  607. # Ask and validate FQDN hostname.
  608. read -p "Please enter FQDN hostname [$(hostname -f)]: " servername
  609. # Set hostname if it wasn't set
  610. if [ -z "$servername" ]; then
  611. servername=$(hostname -f)
  612. fi
  613. # Validate Hostname, go to loop if the validation fails.
  614. while validate_hostname; do
  615. echo -e "\nPlease use a valid hostname according to RFC1178 (ex. hostname.domain.tld)."
  616. read -p "Please enter FQDN hostname [$(hostname -f)]: " servername
  617. done
  618. else
  619. # Validate FQDN hostname if it is preset
  620. if validate_hostname; then
  621. echo "Please use a valid hostname according to RFC1178 (ex. hostname.domain.tld)."
  622. exit 1
  623. fi
  624. fi
  625. # Generating admin password if it wasn't set
  626. displaypass="The password you chose during installation."
  627. if [ -z "$vpass" ]; then
  628. vpass=$(gen_pass)
  629. displaypass=$vpass
  630. fi
  631. # Set FQDN if it wasn't set
  632. mask1='(([[:alnum:]](-?[[:alnum:]])*)\.)'
  633. mask2='*[[:alnum:]](-?[[:alnum:]])+\.[[:alnum:]]{2,}'
  634. if ! [[ "$servername" =~ ^${mask1}${mask2}$ ]]; then
  635. if [[ -n "$servername" ]]; then
  636. servername="$servername.example.com"
  637. else
  638. servername="example.com"
  639. fi
  640. echo "127.0.0.1 $servername" >> /etc/hosts
  641. fi
  642. if [[ -z $(grep -i "$servername" /etc/hosts) ]]; then
  643. echo "127.0.0.1 $servername" >> /etc/hosts
  644. fi
  645. # Set email if it wasn't set
  646. if [[ -z "$email" ]]; then
  647. email="admin@$servername"
  648. fi
  649. # Defining backup directory
  650. echo -e "Installation backup directory: $hst_backups"
  651. # Print Log File Path
  652. echo "Installation log file: $LOG"
  653. # Print new line
  654. echo
  655. #----------------------------------------------------------#
  656. # Checking swap #
  657. #----------------------------------------------------------#
  658. # Checking swap on small instances
  659. if [ -z "$(swapon -s)" ] && [ "$memory" -lt 1000000 ]; then
  660. fallocate -l 1G /swapfile
  661. chmod 600 /swapfile
  662. mkswap /swapfile
  663. swapon /swapfile
  664. echo "/swapfile none swap sw 0 0" >> /etc/fstab
  665. fi
  666. #----------------------------------------------------------#
  667. # Install repository #
  668. #----------------------------------------------------------#
  669. # Define apt conf location
  670. apt=/etc/apt/sources.list.d
  671. # Create new folder if not all-ready exists
  672. mkdir -p /root/.gnupg/ && chmod 700 /root/.gnupg/
  673. # Updating system
  674. echo "Adding required repositories to proceed with installation:"
  675. echo
  676. # Installing Nginx repo
  677. echo "[ * ] NGINX"
  678. echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/nginx-keyring.gpg] https://nginx.org/packages/mainline/$VERSION/ $codename nginx" > $apt/nginx.list
  679. curl -s https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-keyring.gpg > /dev/null 2>&1
  680. # Installing sury PHP repo
  681. # add-apt-repository does not yet support signed-by see: https://bugs.launchpad.net/ubuntu/+source/software-properties/+bug/1862764
  682. echo "[ * ] PHP"
  683. LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php > /dev/null 2>&1
  684. # Installing sury Apache2 repo
  685. if [ "$apache" = 'yes' ]; then
  686. echo "[ * ] Apache2"
  687. echo "deb http://ppa.launchpad.net/ondrej/apache2/ubuntu $codename main" > $apt/apache2.list
  688. fi
  689. # Installing MariaDB repo
  690. if [ "$mysql" = 'yes' ]; then
  691. echo "[ * ] MariaDB"
  692. echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/mariadb-keyring.gpg] https://dlm.mariadb.com/repo/mariadb-server/$mariadb_v/repo/$VERSION $codename main" > $apt/mariadb.list
  693. curl -s https://mariadb.org/mariadb_release_signing_key.asc | gpg --dearmor | tee /usr/share/keyrings/mariadb-keyring.gpg > /dev/null 2>&1
  694. fi
  695. # Installing HestiaCP repo
  696. echo "[ * ] Hestia Control Panel"
  697. echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/hestia-keyring.gpg] https://$RHOST/ $codename main" > $apt/hestia.list
  698. gpg --no-default-keyring --keyring /usr/share/keyrings/hestia-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys A189E93654F0B0E5 > /dev/null 2>&1
  699. # Installing NodeJS 20.x repo
  700. echo "[ * ] NodeJS 20.x"
  701. echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x $codename main" > $apt/nodesource.list
  702. echo "deb-src [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x $codename main" >> $apt/nodesource.list
  703. curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor | tee /usr/share/keyrings/nodesource.gpg > /dev/null 2>&1
  704. # Installing PostgreSQL repo
  705. if [ "$postgresql" = 'yes' ]; then
  706. echo "[ * ] PostgreSQL"
  707. echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/postgresql-keyring.gpg] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main" > $apt/postgresql.list
  708. curl -s https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/postgresql-keyring.gpg > /dev/null 2>&1
  709. fi
  710. # Echo for a new line
  711. echo
  712. # Updating system
  713. echo -ne "Updating currently installed packages, please wait... "
  714. apt-get -qq update
  715. apt-get -y upgrade >> $LOG &
  716. BACK_PID=$!
  717. # Check if package installation is done, print a spinner
  718. spin_i=1
  719. while kill -0 $BACK_PID > /dev/null 2>&1; do
  720. printf "\b${spinner:spin_i++%${#spinner}:1}"
  721. sleep 0.5
  722. done
  723. # Do a blank echo to get the \n back
  724. echo
  725. # Check Installation result
  726. wait $BACK_PID
  727. check_result $? 'apt-get upgrade failed'
  728. #----------------------------------------------------------#
  729. # Backup #
  730. #----------------------------------------------------------#
  731. # Creating backup directory tree
  732. mkdir -p $hst_backups
  733. cd $hst_backups
  734. mkdir nginx apache2 php vsftpd proftpd bind exim4 dovecot clamd
  735. mkdir spamassassin mysql postgresql openssl hestia
  736. # Backup OpenSSL configuration
  737. cp /etc/ssl/openssl.cnf $hst_backups/openssl > /dev/null 2>&1
  738. # Backup nginx configuration
  739. systemctl stop nginx > /dev/null 2>&1
  740. cp -r /etc/nginx/* $hst_backups/nginx > /dev/null 2>&1
  741. # Backup Apache configuration
  742. systemctl stop apache2 > /dev/null 2>&1
  743. cp -r /etc/apache2/* $hst_backups/apache2 > /dev/null 2>&1
  744. rm -f /etc/apache2/conf.d/* > /dev/null 2>&1
  745. # Backup PHP-FPM configuration
  746. systemctl stop php*-fpm > /dev/null 2>&1
  747. cp -r /etc/php/* $hst_backups/php > /dev/null 2>&1
  748. # Backup Bind configuration
  749. systemctl stop bind9 > /dev/null 2>&1
  750. cp -r /etc/bind/* $hst_backups/bind > /dev/null 2>&1
  751. # Backup Vsftpd configuration
  752. systemctl stop vsftpd > /dev/null 2>&1
  753. cp /etc/vsftpd.conf $hst_backups/vsftpd > /dev/null 2>&1
  754. # Backup ProFTPD configuration
  755. systemctl stop proftpd > /dev/null 2>&1
  756. cp /etc/proftpd/* $hst_backups/proftpd > /dev/null 2>&1
  757. # Backup Exim configuration
  758. systemctl stop exim4 > /dev/null 2>&1
  759. cp -r /etc/exim4/* $hst_backups/exim4 > /dev/null 2>&1
  760. # Backup ClamAV configuration
  761. systemctl stop clamav-daemon > /dev/null 2>&1
  762. cp -r /etc/clamav/* $hst_backups/clamav > /dev/null 2>&1
  763. # Backup SpamAssassin configuration
  764. systemctl stop spamassassin > /dev/null 2>&1
  765. cp -r /etc/spamassassin/* $hst_backups/spamassassin > /dev/null 2>&1
  766. # Backup Dovecot configuration
  767. systemctl stop dovecot > /dev/null 2>&1
  768. cp /etc/dovecot.conf $hst_backups/dovecot > /dev/null 2>&1
  769. cp -r /etc/dovecot/* $hst_backups/dovecot > /dev/null 2>&1
  770. # Backup MySQL/MariaDB configuration and data
  771. systemctl stop mysql > /dev/null 2>&1
  772. killall -9 mysqld > /dev/null 2>&1
  773. mv /var/lib/mysql $hst_backups/mysql/mysql_datadir > /dev/null 2>&1
  774. cp -r /etc/mysql/* $hst_backups/mysql > /dev/null 2>&1
  775. mv -f /root/.my.cnf $hst_backups/mysql > /dev/null 2>&1
  776. # Backup Hestia
  777. systemctl stop hestia > /dev/null 2>&1
  778. cp -r $HESTIA/* $hst_backups/hestia > /dev/null 2>&1
  779. apt-get -y purge hestia hestia-nginx hestia-php > /dev/null 2>&1
  780. rm -rf $HESTIA > /dev/null 2>&1
  781. #----------------------------------------------------------#
  782. # Package Includes #
  783. #----------------------------------------------------------#
  784. if [ "$phpfpm" = 'yes' ]; then
  785. fpm="php$fpm_v php$fpm_v-common php$fpm_v-bcmath php$fpm_v-cli
  786. php$fpm_v-curl php$fpm_v-fpm php$fpm_v-gd php$fpm_v-intl
  787. php$fpm_v-mysql php$fpm_v-soap php$fpm_v-xml php$fpm_v-zip
  788. php$fpm_v-mbstring php$fpm_v-bz2 php$fpm_v-pspell
  789. php$fpm_v-imagick"
  790. software="$software $fpm"
  791. fi
  792. #----------------------------------------------------------#
  793. # Package Excludes #
  794. #----------------------------------------------------------#
  795. # Excluding packages
  796. software=$(echo "$software" | sed -e "s/apache2.2-common//")
  797. if [ "$apache" = 'no' ]; then
  798. software=$(echo "$software" | sed -e "s/apache2 //")
  799. software=$(echo "$software" | sed -e "s/apache2-bin//")
  800. software=$(echo "$software" | sed -e "s/apache2-utils//")
  801. software=$(echo "$software" | sed -e "s/apache2-suexec-custom//")
  802. software=$(echo "$software" | sed -e "s/apache2.2-common//")
  803. software=$(echo "$software" | sed -e "s/libapache2-mod-rpaf//")
  804. software=$(echo "$software" | sed -e "s/libapache2-mod-fcgid//")
  805. software=$(echo "$software" | sed -e "s/libapache2-mod-php$fpm_v//")
  806. fi
  807. if [ "$vsftpd" = 'no' ]; then
  808. software=$(echo "$software" | sed -e "s/vsftpd//")
  809. fi
  810. if [ "$proftpd" = 'no' ]; then
  811. software=$(echo "$software" | sed -e "s/proftpd-basic//")
  812. software=$(echo "$software" | sed -e "s/proftpd-mod-vroot//")
  813. fi
  814. if [ "$named" = 'no' ]; then
  815. software=$(echo "$software" | sed -e "s/bind9//")
  816. fi
  817. if [ "$exim" = 'no' ]; then
  818. software=$(echo "$software" | sed -e "s/exim4 //")
  819. software=$(echo "$software" | sed -e "s/exim4-daemon-heavy//")
  820. software=$(echo "$software" | sed -e "s/dovecot-imapd//")
  821. software=$(echo "$software" | sed -e "s/dovecot-pop3d//")
  822. software=$(echo "$software" | sed -e "s/clamav-daemon//")
  823. software=$(echo "$software" | sed -e "s/spamassassin//")
  824. software=$(echo "$software" | sed -e "s/dovecot-sieve//")
  825. software=$(echo "$software" | sed -e "s/dovecot-managesieved//")
  826. fi
  827. if [ "$clamd" = 'no' ]; then
  828. software=$(echo "$software" | sed -e "s/clamav-daemon//")
  829. fi
  830. if [ "$spamd" = 'no' ]; then
  831. software=$(echo "$software" | sed -e "s/spamassassin//")
  832. fi
  833. if [ "$dovecot" = 'no' ]; then
  834. software=$(echo "$software" | sed -e "s/dovecot-imapd//")
  835. software=$(echo "$software" | sed -e "s/dovecot-pop3d//")
  836. fi
  837. if [ "$sieve" = 'no' ]; then
  838. software=$(echo "$software" | sed -e "s/dovecot-sieve//")
  839. software=$(echo "$software" | sed -e "s/dovecot-managesieved//")
  840. fi
  841. if [ "$mysql" = 'no' ]; then
  842. software=$(echo "$software" | sed -e "s/mariadb-server//")
  843. software=$(echo "$software" | sed -e "s/mariadb-client//")
  844. software=$(echo "$software" | sed -e "s/mariadb-common//")
  845. fi
  846. if [ "$mysql8" = 'no' ]; then
  847. software=$(echo "$software" | sed -e "s/mysql-server//")
  848. software=$(echo "$software" | sed -e "s/mysql-client//")
  849. software=$(echo "$software" | sed -e "s/mysql-common//")
  850. fi
  851. if [ "$mysql" = 'no' ] && [ "$mysql8" = 'no' ]; then
  852. software=$(echo "$software" | sed -e "s/php$fpm_v-mysql//")
  853. if [ "$multiphp" = 'yes' ]; then
  854. for v in "${multiphp_v[@]}"; do
  855. software=$(echo "$software" | sed -e "s/php$v-mysql//")
  856. software=$(echo "$software" | sed -e "s/php$v-bz2//")
  857. done
  858. fi
  859. fi
  860. if [ "$postgresql" = 'no' ]; then
  861. software=$(echo "$software" | sed -e "s/postgresql-contrib//")
  862. software=$(echo "$software" | sed -e "s/postgresql//")
  863. software=$(echo "$software" | sed -e "s/php$fpm_v-pgsql//")
  864. fi
  865. if [ "$fail2ban" = 'no' ]; then
  866. software=$(echo "$software" | sed -e "s/fail2ban//")
  867. fi
  868. if [ "$iptables" = 'no' ]; then
  869. software=$(echo "$software" | sed -e "s/ipset//")
  870. software=$(echo "$software" | sed -e "s/fail2ban//")
  871. fi
  872. if [ "$webterminal" = 'no' ]; then
  873. software=$(echo "$software" | sed -e "s/nodejs//")
  874. software=$(echo "$software" | sed -e "s/hestia-web-terminal//")
  875. fi
  876. if [ "$phpfpm" = 'yes' ]; then
  877. software=$(echo "$software" | sed -e "s/php$fpm_v-cgi//")
  878. software=$(echo "$software" | sed -e "s/libapache2-mod-ruid2//")
  879. software=$(echo "$software" | sed -e "s/libapache2-mod-php$fpm_v//")
  880. fi
  881. if [ -d "$withdebs" ]; then
  882. software=$(echo "$software" | sed -e "s/hestia-nginx//")
  883. software=$(echo "$software" | sed -e "s/hestia-php//")
  884. software=$(echo "$software" | sed -e "s/hestia-web-terminal//")
  885. software=$(echo "$software" | sed -e "s/hestia=${HESTIA_INSTALL_VER}//")
  886. fi
  887. if [ "$release" = '20.04' ]; then
  888. software=$(echo "$software" | sed -e "s/setpriv/util-linux/")
  889. software=$(echo "$software" | sed -e "s/libzip4/libzip5/")
  890. fi
  891. if [ "$release" = '22.04' ]; then
  892. software=$(echo "$software" | sed -e "s/setpriv/util-linux/")
  893. fi
  894. #----------------------------------------------------------#
  895. # Disable Apparmor on LXC #
  896. #----------------------------------------------------------#
  897. if grep --quiet lxc /proc/1/environ; then
  898. if [ -f /etc/init.d/apparmor ]; then
  899. systemctl stop apparmor > /dev/null 2>&1
  900. systemctl disable apparmor > /dev/null 2>&1
  901. fi
  902. fi
  903. #----------------------------------------------------------#
  904. # Install packages #
  905. #----------------------------------------------------------#
  906. # Enable en_US.UTF-8
  907. sed -i "s/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g" /etc/locale.gen
  908. locale-gen > /dev/null 2>&1
  909. # Disabling daemon autostart on apt-get install
  910. echo -e '#!/bin/sh\nexit 101' > /usr/sbin/policy-rc.d
  911. chmod a+x /usr/sbin/policy-rc.d
  912. # Installing apt packages
  913. echo "The installer is now downloading and installing all required packages."
  914. echo -ne "NOTE: This process may take 10 to 15 minutes to complete, please wait... "
  915. echo
  916. apt-get -y install $software > $LOG
  917. BACK_PID=$!
  918. # Check if package installation is done, print a spinner
  919. spin_i=1
  920. while kill -0 $BACK_PID > /dev/null 2>&1; do
  921. printf "\b${spinner:spin_i++%${#spinner}:1}"
  922. sleep 0.5
  923. done
  924. # Do a blank echo to get the \n back
  925. echo
  926. # Check Installation result
  927. wait $BACK_PID
  928. check_result $? "apt-get install failed"
  929. echo
  930. echo "========================================================================"
  931. echo
  932. # Install Hestia packages from local folder
  933. if [ -n "$withdebs" ] && [ -d "$withdebs" ]; then
  934. echo "[ * ] Installing local package files..."
  935. echo " - hestia core package"
  936. dpkg -i $withdebs/hestia_*.deb > /dev/null 2>&1
  937. if [ -z $(ls $withdebs/hestia-php_*.deb 2> /dev/null) ]; then
  938. echo " - hestia-php backend package (from apt)"
  939. apt-get -y install hestia-php > /dev/null 2>&1
  940. else
  941. echo " - hestia-php backend package"
  942. dpkg -i $withdebs/hestia-php_*.deb > /dev/null 2>&1
  943. fi
  944. if [ -z $(ls $withdebs/hestia-nginx_*.deb 2> /dev/null) ]; then
  945. echo " - hestia-nginx backend package (from apt)"
  946. apt-get -y install hestia-nginx > /dev/null 2>&1
  947. else
  948. echo " - hestia-nginx backend package"
  949. dpkg -i $withdebs/hestia-nginx_*.deb > /dev/null 2>&1
  950. fi
  951. if [ "$webterminal" = "yes" ]; then
  952. if [ -z $(ls $withdebs/hestia-web-terminal_*.deb 2> /dev/null) ]; then
  953. echo " - hestia-web-terminal package (from apt)"
  954. apt-get -y install hestia-web-terminal > /dev/null 2>&1
  955. else
  956. echo " - hestia-web-terminal"
  957. dpkg -i $withdebs/hestia-web-terminal_*.deb > /dev/null 2>&1
  958. fi
  959. fi
  960. fi
  961. # Restoring autostart policy
  962. rm -f /usr/sbin/policy-rc.d
  963. #----------------------------------------------------------#
  964. # Configure system #
  965. #----------------------------------------------------------#
  966. echo "[ * ] Configuring system settings..."
  967. # Generate a random password
  968. random_password=$(gen_pass '32')
  969. # Create the new hestiaweb user
  970. /usr/sbin/useradd "hestiaweb" -c "$email" --no-create-home
  971. # do not allow login into hestiaweb user
  972. echo hestiaweb:$random_password | sudo chpasswd -e
  973. # Create user for php-fpm configs
  974. /usr/sbin/useradd "hestiamail" -c "$email" --no-create-home
  975. # Enable SFTP subsystem for SSH
  976. sftp_subsys_enabled=$(grep -iE "^#?.*subsystem.+(sftp )?sftp-server" /etc/ssh/sshd_config)
  977. if [ -n "$sftp_subsys_enabled" ]; then
  978. sed -i -E "s/^#?.*Subsystem.+(sftp )?sftp-server/Subsystem sftp internal-sftp/g" /etc/ssh/sshd_config
  979. fi
  980. # Reduce SSH login grace time
  981. sed -i "s/[#]LoginGraceTime [[:digit:]]m/LoginGraceTime 1m/g" /etc/ssh/sshd_config
  982. # Disable SSH suffix broadcast
  983. if [ -z "$(grep "^DebianBanner no" /etc/ssh/sshd_config)" ]; then
  984. sed -i '/^[#]Banner .*/a DebianBanner no' /etc/ssh/sshd_config
  985. if [ -z "$(grep "^DebianBanner no" /etc/ssh/sshd_config)" ]; then
  986. # If first attempt fails just add it
  987. echo '' >> /etc/ssh/sshd_config
  988. echo 'DebianBanner no' >> /etc/ssh/sshd_config
  989. fi
  990. fi
  991. # Restart SSH daemon
  992. systemctl restart ssh
  993. # Disable AWStats cron
  994. rm -f /etc/cron.d/awstats
  995. # Replace awstatst function
  996. cp -f $HESTIA_INSTALL_DIR/logrotate/httpd-prerotate/* /etc/logrotate.d/httpd-prerotate/
  997. # Set directory color
  998. if [ -z "$(grep 'LS_COLORS="$LS_COLORS:di=00;33"' /etc/profile)" ]; then
  999. echo 'LS_COLORS="$LS_COLORS:di=00;33"' >> /etc/profile
  1000. fi
  1001. # Register /usr/sbin/nologin
  1002. if [ -z "$(grep nologin /etc/shells)" ]; then
  1003. echo "/usr/sbin/nologin" >> /etc/shells
  1004. fi
  1005. # Configuring NTP
  1006. sed -i 's/#NTP=/NTP=pool.ntp.org/' /etc/systemd/timesyncd.conf
  1007. systemctl enable systemd-timesyncd
  1008. systemctl start systemd-timesyncd
  1009. # Check iptables paths and add symlinks when necessary
  1010. if [ ! -e "/sbin/iptables" ]; then
  1011. if which iptables > /dev/null; then
  1012. ln -s "$(which iptables)" /sbin/iptables
  1013. elif [ -e "/usr/sbin/iptables" ]; then
  1014. ln -s /usr/sbin/iptables /sbin/iptables
  1015. elif whereis -B /bin /sbin /usr/bin /usr/sbin -f -b iptables; then
  1016. autoiptables=$(whereis -B /bin /sbin /usr/bin /usr/sbin -f -b iptables | cut -d '' -f 2)
  1017. if [ -x "$autoiptables" ]; then
  1018. ln -s "$autoiptables" /sbin/iptables
  1019. fi
  1020. fi
  1021. fi
  1022. if [ ! -e "/sbin/iptables-save" ]; then
  1023. if which iptables-save > /dev/null; then
  1024. ln -s "$(which iptables-save)" /sbin/iptables-save
  1025. elif [ -e "/usr/sbin/iptables-save" ]; then
  1026. ln -s /usr/sbin/iptables-save /sbin/iptables-save
  1027. elif whereis -B /bin /sbin /usr/bin /usr/sbin -f -b iptables-save; then
  1028. autoiptables_save=$(whereis -B /bin /sbin /usr/bin /usr/sbin -f -b iptables-save | cut -d '' -f 2)
  1029. if [ -x "$autoiptables_save" ]; then
  1030. ln -s "$autoiptables_save" /sbin/iptables-save
  1031. fi
  1032. fi
  1033. fi
  1034. if [ ! -e "/sbin/iptables-restore" ]; then
  1035. if which iptables-restore > /dev/null; then
  1036. ln -s "$(which iptables-restore)" /sbin/iptables-restore
  1037. elif [ -e "/usr/sbin/iptables-restore" ]; then
  1038. ln -s /usr/sbin/iptables-restore /sbin/iptables-restore
  1039. elif whereis -B /bin /sbin /usr/bin /usr/sbin -f -b iptables-restore; then
  1040. autoiptables_restore=$(whereis -B /bin /sbin /usr/bin /usr/sbin -f -b iptables-restore | cut -d '' -f 2)
  1041. if [ -x "$autoiptables_restore" ]; then
  1042. ln -s "$autoiptables_restore" /sbin/iptables-restore
  1043. fi
  1044. fi
  1045. fi
  1046. # Restrict access to /proc fs
  1047. # - Prevent unpriv users from seeing each other running processes
  1048. mount -o remount,defaults,hidepid=2 /proc > /dev/null 2>&1
  1049. if [ $? -ne 0 ]; then
  1050. echo "Info: Cannot remount /proc (LXC containers require additional perm added to host apparmor profile)"
  1051. else
  1052. echo "@reboot root sleep 5 && mount -o remount,defaults,hidepid=2 /proc" > /etc/cron.d/hestia-proc
  1053. fi
  1054. #----------------------------------------------------------#
  1055. # Configure Hestia #
  1056. #----------------------------------------------------------#
  1057. echo "[ * ] Configuring Hestia Control Panel..."
  1058. # Installing sudo configuration
  1059. mkdir -p /etc/sudoers.d
  1060. cp -f $HESTIA_COMMON_DIR/sudo/hestiaweb /etc/sudoers.d/
  1061. chmod 440 /etc/sudoers.d/hestiaweb
  1062. # Add Hestia global config
  1063. if [[ ! -e /etc/hestiacp/hestia.conf ]]; then
  1064. mkdir -p /etc/hestiacp
  1065. 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
  1066. fi
  1067. # Configuring system env
  1068. echo "export HESTIA='$HESTIA'" > /etc/profile.d/hestia.sh
  1069. echo 'PATH=$PATH:'$HESTIA'/bin' >> /etc/profile.d/hestia.sh
  1070. echo 'export PATH' >> /etc/profile.d/hestia.sh
  1071. chmod 755 /etc/profile.d/hestia.sh
  1072. source /etc/profile.d/hestia.sh
  1073. # Configuring logrotate for Hestia logs
  1074. cp -f $HESTIA_INSTALL_DIR/logrotate/hestia /etc/logrotate.d/hestia
  1075. # Create log path and symbolic link
  1076. rm -f /var/log/hestia
  1077. mkdir -p /var/log/hestia
  1078. ln -s /var/log/hestia $HESTIA/log
  1079. # Building directory tree and creating some blank files for Hestia
  1080. mkdir -p $HESTIA/conf $HESTIA/ssl $HESTIA/data/ips \
  1081. $HESTIA/data/queue $HESTIA/data/users $HESTIA/data/firewall \
  1082. $HESTIA/data/sessions
  1083. touch $HESTIA/data/queue/backup.pipe $HESTIA/data/queue/disk.pipe \
  1084. $HESTIA/data/queue/webstats.pipe $HESTIA/data/queue/restart.pipe \
  1085. $HESTIA/data/queue/traffic.pipe $HESTIA/data/queue/daily.pipe $HESTIA/log/system.log \
  1086. $HESTIA/log/nginx-error.log $HESTIA/log/auth.log $HESTIA/log/backup.log
  1087. chmod 750 $HESTIA/conf $HESTIA/data/users $HESTIA/data/ips $HESTIA/log
  1088. chmod -R 750 $HESTIA/data/queue
  1089. chmod 660 /var/log/hestia/*
  1090. chmod 770 $HESTIA/data/sessions
  1091. # Generating Hestia configuration
  1092. rm -f $HESTIA/conf/hestia.conf > /dev/null 2>&1
  1093. touch $HESTIA/conf/hestia.conf
  1094. chmod 660 $HESTIA/conf/hestia.conf
  1095. # Write default port value to hestia.conf
  1096. # If a custom port is specified it will be set at the end of the installation process.
  1097. write_config_value "BACKEND_PORT" "8083"
  1098. # Web stack
  1099. if [ "$apache" = 'yes' ]; then
  1100. write_config_value "WEB_SYSTEM" "apache2"
  1101. write_config_value "WEB_RGROUPS" "www-data"
  1102. write_config_value "WEB_PORT" "8080"
  1103. write_config_value "WEB_SSL_PORT" "8443"
  1104. write_config_value "WEB_SSL" "mod_ssl"
  1105. write_config_value "PROXY_SYSTEM" "nginx"
  1106. write_config_value "PROXY_PORT" "80"
  1107. write_config_value "PROXY_SSL_PORT" "443"
  1108. write_config_value "STATS_SYSTEM" "awstats"
  1109. fi
  1110. if [ "$apache" = 'no' ]; then
  1111. write_config_value "WEB_SYSTEM" "nginx"
  1112. write_config_value "WEB_PORT" "80"
  1113. write_config_value "WEB_SSL_PORT" "443"
  1114. write_config_value "WEB_SSL" "openssl"
  1115. write_config_value "STATS_SYSTEM" "awstats"
  1116. fi
  1117. if [ "$phpfpm" = 'yes' ] || [ "$multiphp" = 'yes' ]; then
  1118. write_config_value "WEB_BACKEND" "php-fpm"
  1119. fi
  1120. # Database stack
  1121. if [ "$mysql" = 'yes' ] || [ "$mysql8" = 'yes' ]; then
  1122. installed_db_types='mysql'
  1123. fi
  1124. if [ "$postgresql" = 'yes' ]; then
  1125. installed_db_types="$installed_db_types,pgsql"
  1126. fi
  1127. if [ -n "$installed_db_types" ]; then
  1128. db=$(echo "$installed_db_types" \
  1129. | sed "s/,/\n/g" \
  1130. | sort -r -u \
  1131. | sed "/^$/d" \
  1132. | sed ':a;N;$!ba;s/\n/,/g')
  1133. write_config_value "DB_SYSTEM" "$db"
  1134. fi
  1135. # FTP stack
  1136. if [ "$vsftpd" = 'yes' ]; then
  1137. write_config_value "FTP_SYSTEM" "vsftpd"
  1138. fi
  1139. if [ "$proftpd" = 'yes' ]; then
  1140. write_config_value "FTP_SYSTEM" "proftpd"
  1141. fi
  1142. # DNS stack
  1143. if [ "$named" = 'yes' ]; then
  1144. write_config_value "DNS_SYSTEM" "bind9"
  1145. fi
  1146. # Mail stack
  1147. if [ "$exim" = 'yes' ]; then
  1148. write_config_value "MAIL_SYSTEM" "exim4"
  1149. if [ "$clamd" = 'yes' ]; then
  1150. write_config_value "ANTIVIRUS_SYSTEM" "clamav-daemon"
  1151. fi
  1152. if [ "$spamd" = 'yes' ]; then
  1153. write_config_value "ANTISPAM_SYSTEM" "spamassassin"
  1154. fi
  1155. if [ "$dovecot" = 'yes' ]; then
  1156. write_config_value "IMAP_SYSTEM" "dovecot"
  1157. fi
  1158. if [ "$sieve" = 'yes' ]; then
  1159. write_config_value "SIEVE_SYSTEM" "yes"
  1160. fi
  1161. fi
  1162. # Cron daemon
  1163. write_config_value "CRON_SYSTEM" "cron"
  1164. # Firewall stack
  1165. if [ "$iptables" = 'yes' ]; then
  1166. write_config_value "FIREWALL_SYSTEM" "iptables"
  1167. fi
  1168. if [ "$iptables" = 'yes' ] && [ "$fail2ban" = 'yes' ]; then
  1169. write_config_value "FIREWALL_EXTENSION" "fail2ban"
  1170. fi
  1171. # Disk quota
  1172. if [ "$quota" = 'yes' ]; then
  1173. write_config_value "DISK_QUOTA" "yes"
  1174. else
  1175. write_config_value "DISK_QUOTA" "no"
  1176. fi
  1177. write_config_value "WEB_TERMINAL_PORT" "8085"
  1178. # Backups
  1179. write_config_value "BACKUP_SYSTEM" "local"
  1180. write_config_value "BACKUP_GZIP" "4"
  1181. write_config_value "BACKUP_MODE" "zstd"
  1182. # Language
  1183. write_config_value "LANGUAGE" "$lang"
  1184. # Login in screen
  1185. write_config_value "LOGIN_STYLE" "default"
  1186. # Theme
  1187. write_config_value "THEME" "dark"
  1188. # Inactive session timeout
  1189. write_config_value "INACTIVE_SESSION_TIMEOUT" "60"
  1190. # Version & Release Branch
  1191. write_config_value "VERSION" "${HESTIA_INSTALL_VER}"
  1192. write_config_value "RELEASE_BRANCH" "release"
  1193. # Email notifications after upgrade
  1194. write_config_value "UPGRADE_SEND_EMAIL" "true"
  1195. write_config_value "UPGRADE_SEND_EMAIL_LOG" "false"
  1196. # Set "root" user
  1197. write_config_value "ROOT_USER" "$username"
  1198. # Installing hosting packages
  1199. cp -rf $HESTIA_COMMON_DIR/packages $HESTIA/data/
  1200. # Update nameservers in hosting package
  1201. IFS='.' read -r -a domain_elements <<< "$servername"
  1202. if [ -n "${domain_elements[-2]}" ] && [ -n "${domain_elements[-1]}" ]; then
  1203. serverdomain="${domain_elements[-2]}.${domain_elements[-1]}"
  1204. sed -i s/"domain.tld"/"$serverdomain"/g $HESTIA/data/packages/*.pkg
  1205. fi
  1206. # Installing templates
  1207. cp -rf $HESTIA_INSTALL_DIR/templates $HESTIA/data/
  1208. cp -rf $HESTIA_COMMON_DIR/templates/web/ $HESTIA/data/templates
  1209. cp -rf $HESTIA_COMMON_DIR/templates/dns/ $HESTIA/data/templates
  1210. mkdir -p /var/www/html
  1211. mkdir -p /var/www/document_errors
  1212. # Install default success page
  1213. cp -rf $HESTIA_COMMON_DIR/templates/web/unassigned/index.html /var/www/html/
  1214. cp -rf $HESTIA_COMMON_DIR/templates/web/skel/document_errors/* /var/www/document_errors/
  1215. # Installing firewall rules
  1216. cp -rf $HESTIA_COMMON_DIR/firewall $HESTIA/data/
  1217. rm -f $HESTIA/data/firewall/ipset/blacklist.sh $HESTIA/data/firewall/ipset/blacklist.ipv6.sh
  1218. # Delete rules for services that are not installed
  1219. if [ "$vsftpd" = "no" ] && [ "$proftpd" = "no" ]; then
  1220. # Remove FTP
  1221. sed -i "/COMMENT='FTP'/d" $HESTIA/data/firewall/rules.conf
  1222. fi
  1223. if [ "$exim" = "no" ]; then
  1224. # Remove SMTP
  1225. sed -i "/COMMENT='SMTP'/d" $HESTIA/data/firewall/rules.conf
  1226. fi
  1227. if [ "$dovecot" = "no" ]; then
  1228. # Remove IMAP / Dovecot
  1229. sed -i "/COMMENT='IMAP'/d" $HESTIA/data/firewall/rules.conf
  1230. sed -i "/COMMENT='POP3'/d" $HESTIA/data/firewall/rules.conf
  1231. fi
  1232. if [ "$named" = "no" ]; then
  1233. # Remove IMAP / Dovecot
  1234. sed -i "/COMMENT='DNS'/d" $HESTIA/data/firewall/rules.conf
  1235. fi
  1236. # Installing apis
  1237. cp -rf $HESTIA_COMMON_DIR/api $HESTIA/data/
  1238. # Configuring server hostname
  1239. $HESTIA/bin/v-change-sys-hostname $servername > /dev/null 2>&1
  1240. # Configuring global OpenSSL options
  1241. echo "[ * ] Configuring OpenSSL to improve TLS performance..."
  1242. tls13_ciphers="TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
  1243. if [ "$release" = "20.04" ]; then
  1244. if ! grep -qw "^openssl_conf = default_conf$" /etc/ssl/openssl.cnf 2> /dev/null; then
  1245. sed -i '/^oid_section = new_oids$/a \\n# System default\nopenssl_conf = default_conf' /etc/ssl/openssl.cnf
  1246. fi
  1247. if ! grep -qw "^[default_conf]$" /etc/ssl/openssl.cnf 2> /dev/null; then
  1248. sed -i '$a [default_conf]\nssl_conf = ssl_sect\n\n[ssl_sect]\nsystem_default = hestia_openssl_sect\n\n[hestia_openssl_sect]\nCiphersuites = '"$tls13_ciphers"'\nOptions = PrioritizeChaCha' /etc/ssl/openssl.cnf
  1249. elif grep -qw "^system_default = system_default_sect$" /etc/ssl/openssl.cnf 2> /dev/null; then
  1250. sed -i '/^system_default = system_default_sect$/a system_default = hestia_openssl_sect\n\n[hestia_openssl_sect]\nCiphersuites = '"$tls13_ciphers"'\nOptions = PrioritizeChaCha' /etc/ssl/openssl.cnf
  1251. fi
  1252. elif [ "$release" = "22.04" ]; then
  1253. sed -i '/^system_default = system_default_sect$/a system_default = hestia_openssl_sect\n\n[hestia_openssl_sect]\nCiphersuites = '"$tls13_ciphers"'\nOptions = PrioritizeChaCha' /etc/ssl/openssl.cnf
  1254. fi
  1255. # Generating SSL certificate
  1256. echo "[ * ] Generating default self-signed SSL certificate..."
  1257. $HESTIA/bin/v-generate-ssl-cert $(hostname) '' 'US' 'California' \
  1258. 'San Francisco' 'Hestia Control Panel' 'IT' > /tmp/hst.pem
  1259. # Parsing certificate file
  1260. crt_end=$(grep -n "END CERTIFICATE-" /tmp/hst.pem | cut -f 1 -d:)
  1261. if [ "$release" = "22.04" ]; then
  1262. key_start=$(grep -n "BEGIN PRIVATE KEY" /tmp/hst.pem | cut -f 1 -d:)
  1263. key_end=$(grep -n "END PRIVATE KEY" /tmp/hst.pem | cut -f 1 -d:)
  1264. else
  1265. key_start=$(grep -n "BEGIN RSA" /tmp/hst.pem | cut -f 1 -d:)
  1266. key_end=$(grep -n "END RSA" /tmp/hst.pem | cut -f 1 -d:)
  1267. fi
  1268. # Adding SSL certificate
  1269. echo "[ * ] Adding SSL certificate to Hestia Control Panel..."
  1270. cd $HESTIA/ssl
  1271. sed -n "1,${crt_end}p" /tmp/hst.pem > certificate.crt
  1272. sed -n "$key_start,${key_end}p" /tmp/hst.pem > certificate.key
  1273. chown root:mail $HESTIA/ssl/*
  1274. chmod 660 $HESTIA/ssl/*
  1275. rm /tmp/hst.pem
  1276. # Install dhparam.pem
  1277. cp -f $HESTIA_INSTALL_DIR/ssl/dhparam.pem /etc/ssl
  1278. # Enable sftp jail
  1279. echo "[ * ] Enabling SFTP jail..."
  1280. $HESTIA/bin/v-add-sys-sftp-jail > /dev/null 2>&1
  1281. check_result $? "can't enable sftp jail"
  1282. # Adding Hestia admin account
  1283. echo "[ * ] Creating default admin account..."
  1284. $HESTIA/bin/v-add-user $username $vpass $email "default" "System Administrator"
  1285. check_result $? "can't create admin user"
  1286. $HESTIA/bin/v-change-user-shell $username nologin
  1287. $HESTIA/bin/v-change-user-role $username admin
  1288. $HESTIA/bin/v-change-user-language $username $lang
  1289. $HESTIA/bin/v-change-sys-config-value 'POLICY_SYSTEM_PROTECTED_ADMIN' 'yes'
  1290. #----------------------------------------------------------#
  1291. # Configure Nginx #
  1292. #----------------------------------------------------------#
  1293. echo "[ * ] Configuring NGINX..."
  1294. rm -f /etc/nginx/conf.d/*.conf
  1295. cp -f $HESTIA_INSTALL_DIR/nginx/nginx.conf /etc/nginx/
  1296. cp -f $HESTIA_INSTALL_DIR/nginx/status.conf /etc/nginx/conf.d/
  1297. cp -f $HESTIA_INSTALL_DIR/nginx/0rtt-anti-replay.conf /etc/nginx/conf.d/
  1298. cp -f $HESTIA_INSTALL_DIR/nginx/agents.conf /etc/nginx/conf.d/
  1299. # Copy over cloudflare.inc incase in the next step there are connection issues with CF
  1300. cp -f $HESTIA_INSTALL_DIR/nginx/cloudflare.inc /etc/nginx/conf.d/
  1301. cp -f $HESTIA_INSTALL_DIR/nginx/phpmyadmin.inc /etc/nginx/conf.d/
  1302. cp -f $HESTIA_INSTALL_DIR/nginx/phppgadmin.inc /etc/nginx/conf.d/
  1303. cp -f $HESTIA_INSTALL_DIR/logrotate/nginx /etc/logrotate.d/
  1304. mkdir -p /etc/nginx/conf.d/domains
  1305. mkdir -p /etc/nginx/conf.d/main
  1306. mkdir -p /etc/nginx/modules-enabled
  1307. mkdir -p /var/log/nginx/domains
  1308. # Update dns servers in nginx.conf
  1309. for nameserver in $(grep -is '^nameserver' /etc/resolv.conf | cut -d' ' -f2 | tr '\r\n' ' ' | xargs); do
  1310. if [[ "$nameserver" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
  1311. if [ -z "$resolver" ]; then
  1312. resolver="$nameserver"
  1313. else
  1314. resolver="$resolver $nameserver"
  1315. fi
  1316. fi
  1317. done
  1318. if [ -n "$resolver" ]; then
  1319. sed -i "s/1.0.0.1 8.8.4.4 1.1.1.1 8.8.8.8/$resolver/g" /etc/nginx/nginx.conf
  1320. fi
  1321. # https://github.com/ergin/nginx-cloudflare-real-ip/
  1322. cf_ips="$(curl -fsLm5 --retry 2 https://api.cloudflare.com/client/v4/ips)"
  1323. if [ -n "$cf_ips" ] && [ "$(echo "$cf_ips" | jq -r '.success//""')" = "true" ]; then
  1324. cf_inc="/etc/nginx/conf.d/cloudflare.inc"
  1325. echo "[ * ] Updating Cloudflare IP Ranges for Nginx..."
  1326. echo "# Cloudflare IP Ranges" > $cf_inc
  1327. echo "" >> $cf_inc
  1328. echo "# IPv4" >> $cf_inc
  1329. for ipv4 in $(echo "$cf_ips" | jq -r '.result.ipv4_cidrs[]//""' | sort); do
  1330. echo "set_real_ip_from $ipv4;" >> $cf_inc
  1331. done
  1332. echo "" >> $cf_inc
  1333. echo "# IPv6" >> $cf_inc
  1334. for ipv6 in $(echo "$cf_ips" | jq -r '.result.ipv6_cidrs[]//""' | sort); do
  1335. echo "set_real_ip_from $ipv6;" >> $cf_inc
  1336. done
  1337. echo "" >> $cf_inc
  1338. echo "real_ip_header CF-Connecting-IP;" >> $cf_inc
  1339. fi
  1340. update-rc.d nginx defaults > /dev/null 2>&1
  1341. systemctl start nginx >> $LOG
  1342. check_result $? "nginx start failed"
  1343. #----------------------------------------------------------#
  1344. # Configure Apache #
  1345. #----------------------------------------------------------#
  1346. if [ "$apache" = 'yes' ]; then
  1347. echo "[ * ] Configuring Apache Web Server..."
  1348. mkdir -p /etc/apache2/conf.d
  1349. mkdir -p /etc/apache2/conf.d/domains
  1350. # Copy configuration files
  1351. cp -f $HESTIA_INSTALL_DIR/apache2/apache2.conf /etc/apache2/
  1352. cp -f $HESTIA_INSTALL_DIR/apache2/status.conf /etc/apache2/mods-available/hestia-status.conf
  1353. cp -f /etc/apache2/mods-available/status.load /etc/apache2/mods-available/hestia-status.load
  1354. cp -f $HESTIA_INSTALL_DIR/logrotate/apache2 /etc/logrotate.d/
  1355. # Enable needed modules
  1356. a2enmod rewrite > /dev/null 2>&1
  1357. a2enmod suexec > /dev/null 2>&1
  1358. a2enmod ssl > /dev/null 2>&1
  1359. a2enmod actions > /dev/null 2>&1
  1360. a2dismod --quiet status > /dev/null 2>&1
  1361. a2enmod --quiet hestia-status > /dev/null 2>&1
  1362. # Enable mod_ruid/mpm_itk or mpm_event
  1363. if [ "$phpfpm" = 'yes' ]; then
  1364. # Disable prefork and php, enable event
  1365. a2dismod php$fpm_v > /dev/null 2>&1
  1366. a2dismod mpm_prefork > /dev/null 2>&1
  1367. a2enmod mpm_event > /dev/null 2>&1
  1368. cp -f $HESTIA_INSTALL_DIR/apache2/hestia-event.conf /etc/apache2/conf.d/
  1369. else
  1370. a2enmod ruid2 > /dev/null 2>&1
  1371. fi
  1372. echo "# Powered by hestia" > /etc/apache2/sites-available/default
  1373. echo "# Powered by hestia" > /etc/apache2/sites-available/default-ssl
  1374. echo "# Powered by hestia" > /etc/apache2/ports.conf
  1375. echo -e "/home\npublic_html/cgi-bin" > /etc/apache2/suexec/www-data
  1376. touch /var/log/apache2/access.log /var/log/apache2/error.log
  1377. mkdir -p /var/log/apache2/domains
  1378. chmod a+x /var/log/apache2
  1379. chmod 640 /var/log/apache2/access.log /var/log/apache2/error.log
  1380. chmod 751 /var/log/apache2/domains
  1381. # Prevent remote access to server-status page
  1382. sed -i '/Allow from all/d' /etc/apache2/mods-available/hestia-status.conf
  1383. update-rc.d apache2 defaults > /dev/null 2>&1
  1384. systemctl start apache2 >> $LOG
  1385. check_result $? "apache2 start failed"
  1386. else
  1387. update-rc.d apache2 disable > /dev/null 2>&1
  1388. systemctl stop apache2 > /dev/null 2>&1
  1389. fi
  1390. #----------------------------------------------------------#
  1391. # Configure PHP-FPM #
  1392. #----------------------------------------------------------#
  1393. if [ "$phpfpm" = "yes" ]; then
  1394. if [ "$multiphp" = 'yes' ]; then
  1395. for v in "${multiphp_v[@]}"; do
  1396. echo "[ * ] Installing PHP $v..."
  1397. $HESTIA/bin/v-add-web-php "$v" > /dev/null 2>&1
  1398. done
  1399. else
  1400. echo "[ * ] Installing PHP $fpm_v..."
  1401. $HESTIA/bin/v-add-web-php "$fpm_v" > /dev/null 2>&1
  1402. fi
  1403. echo "[ * ] Configuring PHP-FPM $fpm_v..."
  1404. # Create www.conf for webmail and php(*)admin
  1405. cp -f $HESTIA_INSTALL_DIR/php-fpm/www.conf /etc/php/$fpm_v/fpm/pool.d/www.conf
  1406. update-rc.d php$fpm_v-fpm defaults > /dev/null 2>&1
  1407. systemctl start php$fpm_v-fpm >> $LOG
  1408. check_result $? "php-fpm start failed"
  1409. # Set default php version to $fpm_v
  1410. update-alternatives --set php /usr/bin/php$fpm_v > /dev/null 2>&1
  1411. fi
  1412. #----------------------------------------------------------#
  1413. # Configure PHP #
  1414. #----------------------------------------------------------#
  1415. echo "[ * ] Configuring PHP..."
  1416. ZONE=$(timedatectl > /dev/null 2>&1 | grep Timezone | awk '{print $2}')
  1417. if [ -z "$ZONE" ]; then
  1418. ZONE='UTC'
  1419. fi
  1420. for pconf in $(find /etc/php* -name php.ini); do
  1421. sed -i "s%;date.timezone =%date.timezone = $ZONE%g" $pconf
  1422. sed -i 's%_open_tag = Off%_open_tag = On%g' $pconf
  1423. done
  1424. # Cleanup php session files not changed in the last 7 days (60*24*7 minutes)
  1425. echo '#!/bin/sh' > /etc/cron.daily/php-session-cleanup
  1426. 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
  1427. 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
  1428. chmod 755 /etc/cron.daily/php-session-cleanup
  1429. #----------------------------------------------------------#
  1430. # Configure Vsftpd #
  1431. #----------------------------------------------------------#
  1432. if [ "$vsftpd" = 'yes' ]; then
  1433. echo "[ * ] Configuring Vsftpd server..."
  1434. cp -f $HESTIA_INSTALL_DIR/vsftpd/vsftpd.conf /etc/
  1435. touch /var/log/vsftpd.log
  1436. chown root:adm /var/log/vsftpd.log
  1437. chmod 640 /var/log/vsftpd.log
  1438. touch /var/log/xferlog
  1439. chown root:adm /var/log/xferlog
  1440. chmod 640 /var/log/xferlog
  1441. update-rc.d vsftpd defaults > /dev/null 2>&1
  1442. systemctl start vsftpd >> $LOG
  1443. check_result $? "vsftpd start failed"
  1444. fi
  1445. #----------------------------------------------------------#
  1446. # Configure ProFTPD #
  1447. #----------------------------------------------------------#
  1448. if [ "$proftpd" = 'yes' ]; then
  1449. echo "[ * ] Configuring ProFTPD server..."
  1450. echo "127.0.0.1 $servername" >> /etc/hosts
  1451. cp -f $HESTIA_INSTALL_DIR/proftpd/proftpd.conf /etc/proftpd/
  1452. cp -f $HESTIA_INSTALL_DIR/proftpd/tls.conf /etc/proftpd/
  1453. # Disable TLS 1.3 support for ProFTPD versions older than v1.3.7a
  1454. if [ "$release" = '20.04' ]; then
  1455. sed -i 's/TLSProtocol TLSv1.2 TLSv1.3/TLSProtocol TLSv1.2/' /etc/proftpd/tls.conf
  1456. fi
  1457. update-rc.d proftpd defaults > /dev/null 2>&1
  1458. systemctl start proftpd >> $LOG
  1459. check_result $? "proftpd start failed"
  1460. if [ "$release" = '22.04' ]; then
  1461. unit_files="$(systemctl list-unit-files | grep proftpd)"
  1462. if [[ "$unit_files" =~ "disabled" ]]; then
  1463. systemctl enable proftpd
  1464. fi
  1465. fi
  1466. fi
  1467. #----------------------------------------------------------#
  1468. # Configure MariaDB / MySQL #
  1469. #----------------------------------------------------------#
  1470. if [ "$mysql" = 'yes' ] || [ "$mysql8" = 'yes' ]; then
  1471. [ "$mysql" = 'yes' ] && mysql_type="MariaDB" || mysql_type="MySQL"
  1472. echo "[ * ] Configuring $mysql_type database server..."
  1473. mycnf="my-small.cnf"
  1474. if [ $memory -gt 1200000 ]; then
  1475. mycnf="my-medium.cnf"
  1476. fi
  1477. if [ $memory -gt 3900000 ]; then
  1478. mycnf="my-large.cnf"
  1479. fi
  1480. if [ "$mysql_type" = 'MariaDB' ]; then
  1481. # Run mysql_install_db
  1482. mysql_install_db >> $LOG
  1483. fi
  1484. # Remove symbolic link
  1485. rm -f /etc/mysql/my.cnf
  1486. # Configuring MariaDB
  1487. cp -f $HESTIA_INSTALL_DIR/mysql/$mycnf /etc/mysql/my.cnf
  1488. # Switch MariaDB inclusions to the MySQL
  1489. if [ "$mysql_type" = 'MySQL' ]; then
  1490. sed -i '/query_cache_size/d' /etc/mysql/my.cnf
  1491. sed -i 's|mariadb.conf.d|mysql.conf.d|g' /etc/mysql/my.cnf
  1492. fi
  1493. if [ "$mysql_type" = 'MariaDB' ]; then
  1494. update-rc.d mariadb defaults > /dev/null 2>&1
  1495. systemctl -q enable mariadb 2> /dev/null
  1496. systemctl start mariadb >> $LOG
  1497. check_result $? "${mysql_type,,} start failed"
  1498. fi
  1499. if [ "$mysql_type" = 'MySQL' ]; then
  1500. update-rc.d mysql defaults > /dev/null 2>&1
  1501. systemctl -q enable mysql 2> /dev/null
  1502. systemctl start mysql >> $LOG
  1503. check_result $? "${mysql_type,,} start failed"
  1504. fi
  1505. # Securing MariaDB/MySQL installation
  1506. mpass=$(gen_pass)
  1507. echo -e "[client]\npassword='$mpass'\n" > /root/.my.cnf
  1508. chmod 600 /root/.my.cnf
  1509. if [ -f '/usr/bin/mariadb' ]; then
  1510. mysql_server="mariadb"
  1511. else
  1512. mysql_server="mysql"
  1513. fi
  1514. # Alter root password
  1515. $mysql_server -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$mpass'; FLUSH PRIVILEGES;"
  1516. if [ "$mysql_type" = 'MariaDB' ]; then
  1517. # Allow mysql access via socket for startup
  1518. $mysql_server -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';"
  1519. # Disable anonymous users
  1520. $mysql_server -e "DELETE FROM mysql.global_priv WHERE User='';"
  1521. else
  1522. $mysql_server -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '$mpass';"
  1523. $mysql_server -e "DELETE FROM mysql.user WHERE User='';"
  1524. $mysql_server -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');"
  1525. fi
  1526. # Drop test database
  1527. $mysql_server -e "DROP DATABASE IF EXISTS test"
  1528. $mysql_server -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'"
  1529. # Flush privileges
  1530. $mysql_server -e "FLUSH PRIVILEGES;"
  1531. fi
  1532. #----------------------------------------------------------#
  1533. # Configure phpMyAdmin #
  1534. #----------------------------------------------------------#
  1535. # Source upgrade.conf with phpmyadmin versions
  1536. # shellcheck source=/usr/local/hestia/install/upgrade/upgrade.conf
  1537. source $HESTIA/install/upgrade/upgrade.conf
  1538. if [ "$mysql" = 'yes' ] || [ "$mysql8" = 'yes' ]; then
  1539. # Display upgrade information
  1540. echo "[ * ] Installing phpMyAdmin version v$pma_v..."
  1541. # Download latest phpmyadmin release
  1542. wget --quiet --retry-connrefused https://files.phpmyadmin.net/phpMyAdmin/$pma_v/phpMyAdmin-$pma_v-all-languages.tar.gz
  1543. # Unpack files
  1544. tar xzf phpMyAdmin-$pma_v-all-languages.tar.gz
  1545. # Create folders
  1546. mkdir -p /usr/share/phpmyadmin
  1547. mkdir -p /etc/phpmyadmin
  1548. mkdir -p /etc/phpmyadmin/conf.d/
  1549. mkdir /usr/share/phpmyadmin/tmp
  1550. # Configuring Apache2 for PHPMYADMIN
  1551. if [ "$apache" = 'yes' ]; then
  1552. touch /etc/apache2/conf.d/phpmyadmin.inc
  1553. fi
  1554. # Overwrite old files
  1555. cp -rf phpMyAdmin-$pma_v-all-languages/* /usr/share/phpmyadmin
  1556. # Create copy of config file
  1557. cp -f $HESTIA_INSTALL_DIR/phpmyadmin/config.inc.php /etc/phpmyadmin/
  1558. mkdir -p /var/lib/phpmyadmin/tmp
  1559. chmod 770 /var/lib/phpmyadmin/tmp
  1560. chown root:www-data /usr/share/phpmyadmin/tmp
  1561. # Set config and log directory
  1562. sed -i "s|'configFile' => ROOT_PATH . 'config.inc.php',|'configFile' => '/etc/phpmyadmin/config.inc.php',|g" /usr/share/phpmyadmin/libraries/vendor_config.php
  1563. # Create temporary folder and change permission
  1564. chmod 770 /usr/share/phpmyadmin/tmp
  1565. chown root:www-data /usr/share/phpmyadmin/tmp
  1566. # Generate blow fish
  1567. blowfish=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)
  1568. sed -i "s|%blowfish_secret%|$blowfish|" /etc/phpmyadmin/config.inc.php
  1569. # Clean Up
  1570. rm -fr phpMyAdmin-$pma_v-all-languages
  1571. rm -f phpMyAdmin-$pma_v-all-languages.tar.gz
  1572. write_config_value "DB_PMA_ALIAS" "phpmyadmin"
  1573. $HESTIA/bin/v-change-sys-db-alias 'pma' "phpmyadmin"
  1574. # Special thanks to Pavel Galkin (https://skurudo.ru)
  1575. # https://github.com/skurudo/phpmyadmin-fixer
  1576. # shellcheck source=/usr/local/hestia/install/deb/phpmyadmin/pma.sh
  1577. source $HESTIA_INSTALL_DIR/phpmyadmin/pma.sh > /dev/null 2>&1
  1578. # limit access to /etc/phpmyadmin/
  1579. chown -R root:www-data /etc/phpmyadmin/
  1580. chmod -R 640 /etc/phpmyadmin/*
  1581. chmod 750 /etc/phpmyadmin/conf.d/
  1582. fi
  1583. #----------------------------------------------------------#
  1584. # Configure PostgreSQL #
  1585. #----------------------------------------------------------#
  1586. if [ "$postgresql" = 'yes' ]; then
  1587. echo "[ * ] Configuring PostgreSQL database server..."
  1588. ppass=$(gen_pass)
  1589. cp -f $HESTIA_INSTALL_DIR/postgresql/pg_hba.conf /etc/postgresql/*/main/
  1590. systemctl restart postgresql
  1591. sudo -iu postgres psql -c "ALTER USER postgres WITH PASSWORD '$ppass'" > /dev/null 2>&1
  1592. mkdir -p /etc/phppgadmin/
  1593. mkdir -p /usr/share/phppgadmin/
  1594. wget --retry-connrefused --quiet https://github.com/hestiacp/phppgadmin/releases/download/v$pga_v/phppgadmin-v$pga_v.tar.gz
  1595. tar xzf phppgadmin-v$pga_v.tar.gz -C /usr/share/phppgadmin/
  1596. cp -f $HESTIA_INSTALL_DIR/pga/config.inc.php /etc/phppgadmin/
  1597. ln -s /etc/phppgadmin/config.inc.php /usr/share/phppgadmin/conf/
  1598. # Configuring phpPgAdmin
  1599. if [ "$apache" = 'yes' ]; then
  1600. cp -f $HESTIA_INSTALL_DIR/pga/phppgadmin.conf /etc/apache2/conf.d/phppgadmin.inc
  1601. fi
  1602. rm phppgadmin-v$pga_v.tar.gz
  1603. write_config_value "DB_PGA_ALIAS" "phppgadmin"
  1604. $HESTIA/bin/v-change-sys-db-alias 'pga' "phppgadmin"
  1605. fi
  1606. #----------------------------------------------------------#
  1607. # Configure Bind #
  1608. #----------------------------------------------------------#
  1609. if [ "$named" = 'yes' ]; then
  1610. echo "[ * ] Configuring Bind DNS server..."
  1611. cp -f $HESTIA_INSTALL_DIR/bind/named.conf /etc/bind/
  1612. cp -f $HESTIA_INSTALL_DIR/bind/named.conf.options /etc/bind/
  1613. chown root:bind /etc/bind/named.conf
  1614. chown root:bind /etc/bind/named.conf.options
  1615. chown bind:bind /var/cache/bind
  1616. chmod 640 /etc/bind/named.conf
  1617. chmod 640 /etc/bind/named.conf.options
  1618. aa-complain /usr/sbin/named > /dev/null 2>&1
  1619. echo "/home/** rwm," >> /etc/apparmor.d/local/usr.sbin.named 2> /dev/null
  1620. if ! grep --quiet lxc /proc/1/environ; then
  1621. systemctl status apparmor > /dev/null 2>&1
  1622. if [ $? -ne 0 ]; then
  1623. systemctl restart apparmor >> $LOG
  1624. fi
  1625. fi
  1626. update-rc.d bind9 defaults > /dev/null 2>&1
  1627. systemctl start bind9
  1628. check_result $? "bind9 start failed"
  1629. # Workaround for OpenVZ/Virtuozzo
  1630. if [ -e "/proc/vz/veinfo" ] && [ -e "/etc/rc.local" ]; then
  1631. sed -i "s/^exit 0/service bind9 restart\nexit 0/" /etc/rc.local
  1632. fi
  1633. fi
  1634. #----------------------------------------------------------#
  1635. # Configure Exim #
  1636. #----------------------------------------------------------#
  1637. if [ "$exim" = 'yes' ]; then
  1638. echo "[ * ] Configuring Exim mail server..."
  1639. gpasswd -a Debian-exim mail > /dev/null 2>&1
  1640. exim_version=$(exim4 --version | head -1 | awk '{print $3}' | cut -f -2 -d .)
  1641. # if Exim version > 4.9.4 or greater!
  1642. if ! version_ge "4.9.4" "$exim_version"; then
  1643. # Ubuntu 22.04 (Jammy) uses Exim 4.95 instead but config works with Exim4.94
  1644. cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.4.95.template /etc/exim4/exim4.conf.template
  1645. else
  1646. cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.template /etc/exim4/
  1647. fi
  1648. cp -f $HESTIA_INSTALL_DIR/exim/dnsbl.conf /etc/exim4/
  1649. cp -f $HESTIA_INSTALL_DIR/exim/spam-blocks.conf /etc/exim4/
  1650. cp -f $HESTIA_INSTALL_DIR/exim/limit.conf /etc/exim4/
  1651. cp -f $HESTIA_INSTALL_DIR/exim/system.filter /etc/exim4/
  1652. touch /etc/exim4/white-blocks.conf
  1653. if [ "$spamd" = 'yes' ]; then
  1654. sed -i "s/#SPAM/SPAM/g" /etc/exim4/exim4.conf.template
  1655. fi
  1656. if [ "$clamd" = 'yes' ]; then
  1657. sed -i "s/#CLAMD/CLAMD/g" /etc/exim4/exim4.conf.template
  1658. fi
  1659. # Generate SRS KEY If not support just created it will get ignored anyway
  1660. srs=$(gen_pass)
  1661. echo $srs > /etc/exim4/srs.conf
  1662. chmod 640 /etc/exim4/srs.conf
  1663. chmod 640 /etc/exim4/exim4.conf.template
  1664. chown root:Debian-exim /etc/exim4/srs.conf
  1665. rm -rf /etc/exim4/domains
  1666. mkdir -p /etc/exim4/domains
  1667. rm -f /etc/alternatives/mta
  1668. ln -s /usr/sbin/exim4 /etc/alternatives/mta
  1669. update-rc.d -f sendmail remove > /dev/null 2>&1
  1670. systemctl stop sendmail > /dev/null 2>&1
  1671. update-rc.d -f postfix remove > /dev/null 2>&1
  1672. systemctl stop postfix > /dev/null 2>&1
  1673. update-rc.d exim4 defaults
  1674. systemctl start exim4 >> $LOG
  1675. check_result $? "exim4 start failed"
  1676. fi
  1677. #----------------------------------------------------------#
  1678. # Configure Dovecot #
  1679. #----------------------------------------------------------#
  1680. if [ "$dovecot" = 'yes' ]; then
  1681. echo "[ * ] Configuring Dovecot POP/IMAP mail server..."
  1682. gpasswd -a dovecot mail > /dev/null 2>&1
  1683. cp -rf $HESTIA_COMMON_DIR/dovecot /etc/
  1684. cp -f $HESTIA_INSTALL_DIR/logrotate/dovecot /etc/logrotate.d/
  1685. rm -f /etc/dovecot/conf.d/15-mailboxes.conf
  1686. chown -R root:root /etc/dovecot*
  1687. #Alter config for 2.2
  1688. version=$(dovecot --version | cut -f -2 -d .)
  1689. if [ "$version" = "2.2" ]; then
  1690. echo "[ * ] Downgrade dovecot config to sync with 2.2 settings"
  1691. sed -i 's|#ssl_dh_parameters_length = 4096|ssl_dh_parameters_length = 4096|g' /etc/dovecot/conf.d/10-ssl.conf
  1692. sed -i 's|ssl_dh = </etc/ssl/dhparam.pem|#ssl_dh = </etc/ssl/dhparam.pem|g' /etc/dovecot/conf.d/10-ssl.conf
  1693. sed -i 's|ssl_min_protocol = TLSv1.2|ssl_protocols = !SSLv3 !TLSv1 !TLSv1.1|g' /etc/dovecot/conf.d/10-ssl.conf
  1694. fi
  1695. update-rc.d dovecot defaults
  1696. systemctl start dovecot >> $LOG
  1697. check_result $? "dovecot start failed"
  1698. fi
  1699. #----------------------------------------------------------#
  1700. # Configure ClamAV #
  1701. #----------------------------------------------------------#
  1702. if [ "$clamd" = 'yes' ]; then
  1703. gpasswd -a clamav mail > /dev/null 2>&1
  1704. gpasswd -a clamav Debian-exim > /dev/null 2>&1
  1705. cp -f $HESTIA_INSTALL_DIR/clamav/clamd.conf /etc/clamav/
  1706. update-rc.d clamav-daemon defaults
  1707. echo -ne "[ * ] Installing ClamAV anti-virus definitions... "
  1708. /usr/bin/freshclam >> $LOG > /dev/null 2>&1
  1709. BACK_PID=$!
  1710. spin_i=1
  1711. while kill -0 $BACK_PID > /dev/null 2>&1; do
  1712. printf "\b${spinner:spin_i++%${#spinner}:1}"
  1713. sleep 0.5
  1714. done
  1715. echo
  1716. systemctl start clamav-daemon >> $LOG
  1717. check_result $? "clamav-daemon start failed"
  1718. fi
  1719. #----------------------------------------------------------#
  1720. # Configure SpamAssassin #
  1721. #----------------------------------------------------------#
  1722. if [ "$spamd" = 'yes' ]; then
  1723. echo "[ * ] Configuring SpamAssassin..."
  1724. update-rc.d spamassassin defaults > /dev/null 2>&1
  1725. sed -i "s/ENABLED=0/ENABLED=1/" /etc/default/spamassassin
  1726. systemctl start spamassassin >> $LOG
  1727. check_result $? "spamassassin start failed"
  1728. unit_files="$(systemctl list-unit-files | grep spamassassin)"
  1729. if [[ "$unit_files" =~ "disabled" ]]; then
  1730. systemctl enable spamassassin > /dev/null 2>&1
  1731. fi
  1732. sed -i "s/#CRON=1/CRON=1/" /etc/default/spamassassin
  1733. fi
  1734. #----------------------------------------------------------#
  1735. # Configure Fail2Ban #
  1736. #----------------------------------------------------------#
  1737. if [ "$fail2ban" = 'yes' ]; then
  1738. echo "[ * ] Configuring fail2ban access monitor..."
  1739. cp -rf $HESTIA_INSTALL_DIR/fail2ban /etc/
  1740. if [ "$dovecot" = 'no' ]; then
  1741. fline=$(cat /etc/fail2ban/jail.local | grep -n dovecot-iptables -A 2)
  1742. fline=$(echo "$fline" | grep enabled | tail -n1 | cut -f 1 -d -)
  1743. sed -i "${fline}s/true/false/" /etc/fail2ban/jail.local
  1744. fi
  1745. if [ "$exim" = 'no' ]; then
  1746. fline=$(cat /etc/fail2ban/jail.local | grep -n exim-iptables -A 2)
  1747. fline=$(echo "$fline" | grep enabled | tail -n1 | cut -f 1 -d -)
  1748. sed -i "${fline}s/true/false/" /etc/fail2ban/jail.local
  1749. fi
  1750. if [ "$vsftpd" = 'yes' ]; then
  1751. # Create vsftpd Log File
  1752. if [ ! -f "/var/log/vsftpd.log" ]; then
  1753. touch /var/log/vsftpd.log
  1754. fi
  1755. fline=$(cat /etc/fail2ban/jail.local | grep -n vsftpd-iptables -A 2)
  1756. fline=$(echo "$fline" | grep enabled | tail -n1 | cut -f 1 -d -)
  1757. sed -i "${fline}s/false/true/" /etc/fail2ban/jail.local
  1758. fi
  1759. if [ -f /etc/fail2ban/jail.d/defaults-debian.conf ]; then
  1760. rm -f /etc/fail2ban/jail.d/defaults-debian.conf
  1761. fi
  1762. update-rc.d fail2ban defaults
  1763. # Ubuntu 22.04 doesn't start F2B by default on boot
  1764. update-rc.d fail2ban enable
  1765. systemctl start fail2ban >> $LOG
  1766. check_result $? "fail2ban start failed"
  1767. fi
  1768. # Configuring MariaDB/MySQL host
  1769. if [ "$mysql" = 'yes' ] || [ "$mysql8" = 'yes' ]; then
  1770. $HESTIA/bin/v-add-database-host mysql localhost root $mpass
  1771. fi
  1772. # Configuring PostgreSQL host
  1773. if [ "$postgresql" = 'yes' ]; then
  1774. $HESTIA/bin/v-add-database-host pgsql localhost postgres $ppass
  1775. fi
  1776. #----------------------------------------------------------#
  1777. # Install Roundcube #
  1778. #----------------------------------------------------------#
  1779. # Min requirements Dovecot + Exim + Mysql
  1780. if ([ "$mysql" == 'yes' ] || [ "$mysql8" == 'yes' ]) && [ "$dovecot" == "yes" ]; then
  1781. echo "[ * ] Installing Roundcube..."
  1782. $HESTIA/bin/v-add-sys-roundcube
  1783. write_config_value "WEBMAIL_ALIAS" "webmail"
  1784. else
  1785. write_config_value "WEBMAIL_ALIAS" ""
  1786. write_config_value "WEBMAIL_SYSTEM" ""
  1787. fi
  1788. #----------------------------------------------------------#
  1789. # Install Sieve #
  1790. #----------------------------------------------------------#
  1791. # Min requirements Dovecot + Exim + Mysql + Roundcube
  1792. if [ "$sieve" = 'yes' ]; then
  1793. # Folder paths
  1794. RC_INSTALL_DIR="/var/lib/roundcube"
  1795. RC_CONFIG_DIR="/etc/roundcube"
  1796. echo "[ * ] Installing Sieve Mail Filter..."
  1797. # dovecot.conf install
  1798. 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
  1799. # Dovecot conf files
  1800. # 10-master.conf
  1801. 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
  1802. # 15-lda.conf
  1803. sed -i "s/\#mail_plugins = \\\$mail_plugins/mail_plugins = \$mail_plugins quota sieve\n auth_socket_path = \/var\/run\/dovecot\/auth-master/g" /etc/dovecot/conf.d/15-lda.conf
  1804. # 20-imap.conf
  1805. sed -i "s/mail_plugins = quota imap_quota/mail_plugins = quota imap_quota imap_sieve/g" /etc/dovecot/conf.d/20-imap.conf
  1806. # Replace dovecot-sieve config files
  1807. cp -f $HESTIA_COMMON_DIR/dovecot/sieve/* /etc/dovecot/conf.d
  1808. # Dovecot default file install
  1809. echo -e "require [\"fileinto\"];\n# rule:[SPAM]\nif header :contains \"X-Spam-Flag\" \"YES\" {\n fileinto \"INBOX.Spam\";\n}\n" > /etc/dovecot/sieve/default
  1810. # exim4 install
  1811. sed -i "s/\stransport = local_delivery/ transport = dovecot_virtual_delivery/" /etc/exim4/exim4.conf.template
  1812. sed -i "s/address_pipe:/dovecot_virtual_delivery:\n driver = pipe\n command = \/usr\/lib\/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
  1813. # Permission changes
  1814. chown -R dovecot:mail /var/log/dovecot.log
  1815. chmod 660 /var/log/dovecot.log
  1816. if [ -d "/var/lib/roundcube" ]; then
  1817. # Modify Roundcube config
  1818. mkdir -p $RC_CONFIG_DIR/plugins/managesieve
  1819. cp -f $HESTIA_COMMON_DIR/roundcube/plugins/config_managesieve.inc.php $RC_CONFIG_DIR/plugins/managesieve/config.inc.php
  1820. ln -s $RC_CONFIG_DIR/plugins/managesieve/config.inc.php $RC_INSTALL_DIR/plugins/managesieve/config.inc.php
  1821. chown -R root:www-data $RC_CONFIG_DIR/
  1822. chmod 751 -R $RC_CONFIG_DIR
  1823. chmod 644 $RC_CONFIG_DIR/*.php
  1824. chmod 644 $RC_CONFIG_DIR/plugins/managesieve/config.inc.php
  1825. sed -i "s/\"archive\"/\"archive\", \"managesieve\"/g" $RC_CONFIG_DIR/config.inc.php
  1826. fi
  1827. # Restart Dovecot and exim4
  1828. systemctl restart dovecot > /dev/null 2>&1
  1829. systemctl restart exim4 > /dev/null 2>&1
  1830. fi
  1831. #----------------------------------------------------------#
  1832. # Configure API #
  1833. #----------------------------------------------------------#
  1834. if [ "$api" = "yes" ]; then
  1835. # Keep legacy api enabled until transition is complete
  1836. write_config_value "API" "yes"
  1837. write_config_value "API_SYSTEM" "1"
  1838. write_config_value "API_ALLOWED_IP" ""
  1839. else
  1840. write_config_value "API" "no"
  1841. write_config_value "API_SYSTEM" "0"
  1842. write_config_value "API_ALLOWED_IP" ""
  1843. $HESTIA/bin/v-change-sys-api disable
  1844. fi
  1845. #----------------------------------------------------------#
  1846. # Configure File Manager #
  1847. #----------------------------------------------------------#
  1848. echo "[ * ] Configuring File Manager..."
  1849. $HESTIA/bin/v-add-sys-filemanager quiet
  1850. #----------------------------------------------------------#
  1851. # Configure Web terminal #
  1852. #----------------------------------------------------------#
  1853. # Web terminal
  1854. if [ "$webterminal" = 'yes' ]; then
  1855. write_config_value "WEB_TERMINAL" "true"
  1856. systemctl daemon-reload > /dev/null 2>&1
  1857. systemctl enable hestia-web-terminal > /dev/null 2>&1
  1858. systemctl restart hestia-web-terminal > /dev/null 2>&1
  1859. else
  1860. write_config_value "WEB_TERMINAL" "false"
  1861. fi
  1862. #----------------------------------------------------------#
  1863. # Configure dependencies #
  1864. #----------------------------------------------------------#
  1865. echo "[ * ] Configuring PHP dependencies..."
  1866. $HESTIA/bin/v-add-sys-dependencies quiet
  1867. echo "[ * ] Installing Rclone..."
  1868. curl -s https://rclone.org/install.sh | bash > /dev/null 2>&1
  1869. #----------------------------------------------------------#
  1870. # Configure IP #
  1871. #----------------------------------------------------------#
  1872. # Configuring system IPs
  1873. echo "[ * ] Configuring System IP..."
  1874. $HESTIA/bin/v-update-sys-ip > /dev/null 2>&1
  1875. # Get primary IP
  1876. default_nic="$(ip -d -j route show | jq -r '.[] | if .dst == "default" then .dev else empty end')"
  1877. # IPv4
  1878. 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)"
  1879. # IPv6
  1880. #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)"
  1881. ip="$primary_ipv4"
  1882. local_ip="$primary_ipv4"
  1883. # Configuring firewall
  1884. if [ "$iptables" = 'yes' ]; then
  1885. $HESTIA/bin/v-update-firewall
  1886. fi
  1887. # Get public IP
  1888. pub_ipv4="$(curl -fsLm5 --retry 2 --ipv4 https://ip.hestiacp.com/)"
  1889. if [ -n "$pub_ipv4" ] && [ "$pub_ipv4" != "$ip" ]; then
  1890. if [ -e /etc/rc.local ]; then
  1891. sed -i '/exit 0/d' /etc/rc.local
  1892. else
  1893. touch /etc/rc.local
  1894. fi
  1895. check_rclocal=$(cat /etc/rc.local | grep "#!")
  1896. if [ -z "$check_rclocal" ]; then
  1897. echo "#!/bin/sh" >> /etc/rc.local
  1898. fi
  1899. # Fix for Proxmox VE containers where hostname is reset to non-FQDN format on reboot
  1900. check_pve=$(uname -r | grep pve)
  1901. if [ ! -z "$check_pve" ]; then
  1902. echo 'hostname=$(hostname --fqdn)' >> /etc/rc.local
  1903. echo ""$HESTIA/bin/v-change-sys-hostname" "'"$hostname"'"" >> /etc/rc.local
  1904. fi
  1905. echo "$HESTIA/bin/v-update-sys-ip" >> /etc/rc.local
  1906. echo "exit 0" >> /etc/rc.local
  1907. chmod +x /etc/rc.local
  1908. systemctl enable rc-local > /dev/null 2>&1
  1909. $HESTIA/bin/v-change-sys-ip-nat "$ip" "$pub_ipv4" > /dev/null 2>&1
  1910. ip="$pub_ipv4"
  1911. fi
  1912. # Configuring libapache2-mod-remoteip
  1913. if [ "$apache" = 'yes' ] && [ "$nginx" = 'yes' ]; then
  1914. cd /etc/apache2/mods-available
  1915. echo "<IfModule mod_remoteip.c>" > remoteip.conf
  1916. echo " RemoteIPHeader X-Real-IP" >> remoteip.conf
  1917. if [ "$local_ip" != "127.0.0.1" ] && [ "$pub_ipv4" != "127.0.0.1" ]; then
  1918. echo " RemoteIPInternalProxy 127.0.0.1" >> remoteip.conf
  1919. fi
  1920. if [ -n "$local_ip" ] && [ "$local_ip" != "$pub_ipv4" ]; then
  1921. echo " RemoteIPInternalProxy $local_ip" >> remoteip.conf
  1922. fi
  1923. if [ -n "$pub_ipv4" ]; then
  1924. echo " RemoteIPInternalProxy $pub_ipv4" >> remoteip.conf
  1925. fi
  1926. echo "</IfModule>" >> remoteip.conf
  1927. sed -i "s/LogFormat \"%h/LogFormat \"%a/g" /etc/apache2/apache2.conf
  1928. a2enmod remoteip >> $LOG
  1929. systemctl restart apache2
  1930. fi
  1931. # Adding default domain
  1932. $HESTIA/bin/v-add-web-domain "$username" "$servername" "$ip"
  1933. check_result $? "can't create $servername domain"
  1934. # Adding cron jobs
  1935. export SCHEDULED_RESTART="yes"
  1936. min=$(gen_pass '012345' '2')
  1937. hour=$(gen_pass '1234567' '1')
  1938. echo "MAILTO=\"\"" > /var/spool/cron/crontabs/hestiaweb
  1939. echo "CONTENT_TYPE=\"text/plain; charset=utf-8\"" >> /var/spool/cron/crontabs/hestiaweb
  1940. echo "*/2 * * * * sudo /usr/local/hestia/bin/v-update-sys-queue restart" >> /var/spool/cron/crontabs/hestiaweb
  1941. echo "10 00 * * * sudo /usr/local/hestia/bin/v-update-sys-queue daily" >> /var/spool/cron/crontabs/hestiaweb
  1942. echo "15 02 * * * sudo /usr/local/hestia/bin/v-update-sys-queue disk" >> /var/spool/cron/crontabs/hestiaweb
  1943. echo "10 00 * * * sudo /usr/local/hestia/bin/v-update-sys-queue traffic" >> /var/spool/cron/crontabs/hestiaweb
  1944. echo "30 03 * * * sudo /usr/local/hestia/bin/v-update-sys-queue webstats" >> /var/spool/cron/crontabs/hestiaweb
  1945. echo "*/5 * * * * sudo /usr/local/hestia/bin/v-update-sys-queue backup" >> /var/spool/cron/crontabs/hestiaweb
  1946. echo "10 05 * * * sudo /usr/local/hestia/bin/v-backup-users" >> /var/spool/cron/crontabs/hestiaweb
  1947. echo "20 00 * * * sudo /usr/local/hestia/bin/v-update-user-stats" >> /var/spool/cron/crontabs/hestiaweb
  1948. echo "*/5 * * * * sudo /usr/local/hestia/bin/v-update-sys-rrd" >> /var/spool/cron/crontabs/hestiaweb
  1949. echo "$min $hour * * * sudo /usr/local/hestia/bin/v-update-letsencrypt-ssl" >> /var/spool/cron/crontabs/hestiaweb
  1950. echo "41 4 * * * sudo /usr/local/hestia/bin/v-update-sys-hestia-all" >> /var/spool/cron/crontabs/hestiaweb
  1951. chmod 600 /var/spool/cron/crontabs/hestiaweb
  1952. chown hestiaweb:hestiaweb /var/spool/cron/crontabs/hestiaweb
  1953. # Enable automatic updates
  1954. $HESTIA/bin/v-add-cron-hestia-autoupdate apt
  1955. # Building initital rrd images
  1956. $HESTIA/bin/v-update-sys-rrd
  1957. # Enabling file system quota
  1958. if [ "$quota" = 'yes' ]; then
  1959. $HESTIA/bin/v-add-sys-quota
  1960. fi
  1961. # Set backend port
  1962. $HESTIA/bin/v-change-sys-port $port > /dev/null 2>&1
  1963. # Create default configuration files
  1964. $HESTIA/bin/v-update-sys-defaults
  1965. # Update remaining packages since repositories have changed
  1966. echo -ne "[ * ] Installing remaining software updates..."
  1967. apt-get -qq update
  1968. apt-get -y upgrade >> $LOG &
  1969. BACK_PID=$!
  1970. echo
  1971. # Starting Hestia service
  1972. update-rc.d hestia defaults
  1973. systemctl start hestia
  1974. check_result $? "hestia start failed"
  1975. chown hestiaweb:hestiaweb $HESTIA/data/sessions
  1976. # Create backup folder and set correct permission
  1977. mkdir -p /backup/
  1978. chmod 755 /backup/
  1979. # Create cronjob to generate ssl
  1980. 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
  1981. #----------------------------------------------------------#
  1982. # Set hestia.conf default values #
  1983. #----------------------------------------------------------#
  1984. echo "[ * ] Updating configuration files..."
  1985. BIN="$HESTIA/bin"
  1986. source $HESTIA/func/syshealth.sh
  1987. syshealth_repair_system_config
  1988. # Add /usr/local/hestia/bin/ to path variable
  1989. echo 'if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then
  1990. . /etc/profile.d/hestia.sh
  1991. fi' >> /root/.bashrc
  1992. #----------------------------------------------------------#
  1993. # Hestia Access Info #
  1994. #----------------------------------------------------------#
  1995. # Comparing hostname and IP
  1996. host_ip=$(host $servername | head -n 1 | awk '{print $NF}')
  1997. if [ "$host_ip" = "$ip" ]; then
  1998. ip="$servername"
  1999. fi
  2000. echo -e "\n"
  2001. echo "===================================================================="
  2002. echo -e "\n"
  2003. # Sending notification to admin email
  2004. echo -e "Congratulations!
  2005. You have successfully installed Hestia Control Panel on your server.
  2006. Ready to get started? Log in using the following credentials:
  2007. Admin URL: https://$servername:$port" > $tmpfile
  2008. if [ "$host_ip" != "$ip" ]; then
  2009. echo " Backup URL: https://$ip:$port" >> $tmpfile
  2010. fi
  2011. echo -e -n " Username: $username
  2012. Password: $displaypass
  2013. Thank you for choosing Hestia Control Panel to power your full stack web server,
  2014. we hope that you enjoy using it as much as we do!
  2015. Please feel free to contact us at any time if you have any questions,
  2016. or if you encounter any bugs or problems:
  2017. Documentation: https://docs.hestiacp.com/
  2018. Forum: https://forum.hestiacp.com/
  2019. GitHub: https://www.github.com/hestiacp/hestiacp
  2020. Note: Automatic updates are enabled by default. If you would like to disable them,
  2021. please log in and navigate to Server > Updates to turn them off.
  2022. Help support the Hestia Control Panel project by donating via PayPal:
  2023. https://www.hestiacp.com/donate
  2024. --
  2025. Sincerely yours,
  2026. The Hestia Control Panel development team
  2027. Made with love & pride by the open-source community around the world.
  2028. " >> $tmpfile
  2029. send_mail="$HESTIA/web/inc/mail-wrapper.php"
  2030. cat $tmpfile | $send_mail -s "Hestia Control Panel" $email
  2031. # Congrats
  2032. echo
  2033. cat $tmpfile
  2034. rm -f $tmpfile
  2035. # Add welcome message to notification panel
  2036. $HESTIA/bin/v-add-user-notification "$username" 'Welcome to Hestia Control Panel!' '<p>You are now ready to begin adding <a href="/add/user/">user accounts</a> and <a href="/add/web/">domains</a>. For help and assistance, <a href="https://hestiacp.com/docs/" target="_blank">view the documentation</a> or <a href="https://forum.hestiacp.com/" target="_blank">visit our forum</a>.</p><p>Please <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank">report any issues via GitHub</a>.</p><p class="u-text-bold">Have a wonderful day!</p><p><i class="fas fa-heart icon-red"></i> The Hestia Control Panel development team</p>'
  2037. # Clean-up
  2038. # Sort final configuration file
  2039. sort_config_file
  2040. if [ "$interactive" = 'yes' ]; then
  2041. echo "[ ! ] IMPORTANT: The system will now reboot to complete the installation process."
  2042. read -n 1 -s -r -p "Press any key to continue"
  2043. reboot
  2044. else
  2045. echo "[ ! ] IMPORTANT: You must restart the system before continuing!"
  2046. fi
  2047. # EOF