hst-install-ubuntu.sh 81 KB

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