hst-install-debian.sh 80 KB

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