hst-install-debian.sh 81 KB

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