hst-install-ubuntu.sh 87 KB

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