hst-install-ubuntu.sh 78 KB

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