Browse Source

Merge remote-tracking branch 'upstream/main' into ipv6

asmcc 2 years ago
parent
commit
845c20a185
100 changed files with 1073 additions and 175 deletions
  1. 1 3
      .eslintrc.cjs
  2. 1 1
      .github/ISSUE_TEMPLATE/BUG-REPORT.yml
  3. 1 0
      .prettierignore
  4. 44 1
      CHANGELOG.md
  5. 1 1
      README.md
  6. 1 1
      SECURITY.md
  7. 1 1
      bin/v-add-backup-host
  8. 2 0
      bin/v-add-dns-record
  9. 26 6
      bin/v-add-letsencrypt-domain
  10. 1 1
      bin/v-add-letsencrypt-user
  11. 3 3
      bin/v-add-mail-domain-webmail
  12. 7 2
      bin/v-add-remote-dns-domain
  13. 2 2
      bin/v-add-sys-dependencies
  14. 2 2
      bin/v-add-sys-filemanager
  15. 2 1
      bin/v-add-sys-firewall
  16. 33 2
      bin/v-add-web-domain-redirect
  17. 1 1
      bin/v-backup-user
  18. 11 1
      bin/v-change-dns-domain-dnssec
  19. 2 0
      bin/v-change-dns-domain-ip
  20. 2 0
      bin/v-change-dns-domain-soa
  21. 2 0
      bin/v-change-dns-domain-tpl
  22. 2 0
      bin/v-change-dns-domain-ttl
  23. 2 0
      bin/v-change-dns-record
  24. 2 0
      bin/v-change-dns-record-id
  25. 2 1
      bin/v-change-sys-php
  26. 4 0
      bin/v-change-sys-webmail
  27. 2 0
      bin/v-delete-dns-record
  28. 7 7
      bin/v-export-rrd
  29. 7 0
      bin/v-import-cpanel
  30. 11 0
      bin/v-list-sys-config
  31. 7 2
      bin/v-sync-dns-cluster
  32. 6 5
      docs/.vitepress/config.ts
  33. 324 0
      docs/.vitepress/theme/components/InstallOptions.vue
  34. 31 0
      docs/.vitepress/theme/components/InstallOptionsSection.vue
  35. 28 0
      docs/.vitepress/theme/components/InstallPage.vue
  36. 42 0
      docs/.vitepress/theme/components/InstallPageTitle.vue
  37. 2 0
      docs/.vitepress/theme/index.ts
  38. 42 0
      docs/_data/languages.ts
  39. 154 0
      docs/_data/options.ts
  40. 6 9
      docs/_data/team.ts
  41. 29 3
      docs/docs/introduction/getting-started.md
  42. 45 2
      docs/docs/server-administration/backup-restore.md
  43. 2 8
      docs/docs/server-administration/customisation.md
  44. 4 4
      docs/docs/server-administration/dns.md
  45. 6 0
      docs/docs/server-administration/email.md
  46. 27 0
      docs/docs/server-administration/troubleshooting.md
  47. 23 0
      docs/install.md
  48. BIN
      docs/public/webfonts/fa-brands-400.ttf
  49. BIN
      docs/public/webfonts/fa-brands-400.woff2
  50. BIN
      docs/public/webfonts/fa-solid-900.ttf
  51. BIN
      docs/public/webfonts/fa-solid-900.woff2
  52. 1 10
      docs/team.md
  53. 12 10
      func/backup.sh
  54. 4 1
      func/domain.sh
  55. 5 0
      func/main.sh
  56. 1 1
      func/rebuild.sh
  57. 1 1
      func/syshealth.sh
  58. 25 24
      func/upgrade.sh
  59. 1 0
      install/deb/apache2/apache2.conf
  60. 2 2
      install/deb/filemanager/install-fm.sh
  61. 1 2
      install/deb/templates/web/apache2/default.stpl
  62. 1 2
      install/deb/templates/web/apache2/default.tpl
  63. 1 2
      install/deb/templates/web/apache2/hosting.stpl
  64. 1 2
      install/deb/templates/web/apache2/hosting.tpl
  65. 1 2
      install/deb/templates/web/apache2/php-fpm/default.stpl
  66. 1 2
      install/deb/templates/web/apache2/php-fpm/default.tpl
  67. 1 2
      install/deb/templates/web/apache2/phpcgi.stpl
  68. 1 2
      install/deb/templates/web/apache2/phpcgi.tpl
  69. 1 2
      install/deb/templates/web/apache2/phpfcgid.stpl
  70. 1 2
      install/deb/templates/web/apache2/phpfcgid.tpl
  71. 1 2
      install/deb/templates/web/apache2/www-data.stpl
  72. 1 2
      install/deb/templates/web/apache2/www-data.tpl
  73. 1 1
      install/deb/templates/web/nginx/caching.stpl
  74. 1 1
      install/deb/templates/web/nginx/caching.tpl
  75. 1 2
      install/deb/templates/web/nginx/default.stpl
  76. 1 2
      install/deb/templates/web/nginx/default.tpl
  77. 1 2
      install/deb/templates/web/nginx/hosting.stpl
  78. 1 2
      install/deb/templates/web/nginx/hosting.tpl
  79. 1 1
      install/deb/templates/web/nginx/php-fpm/chevereto.stpl
  80. 1 1
      install/deb/templates/web/nginx/php-fpm/chevereto.tpl
  81. 1 1
      install/deb/templates/web/nginx/php-fpm/cms_made_simple.stpl
  82. 1 1
      install/deb/templates/web/nginx/php-fpm/cms_made_simple.tpl
  83. 1 1
      install/deb/templates/web/nginx/php-fpm/codeigniter.stpl
  84. 1 1
      install/deb/templates/web/nginx/php-fpm/codeigniter.tpl
  85. 10 1
      install/deb/templates/web/nginx/php-fpm/craftcms.stpl
  86. 10 1
      install/deb/templates/web/nginx/php-fpm/craftcms.tpl
  87. 1 1
      install/deb/templates/web/nginx/php-fpm/datalife_engine.stpl
  88. 1 1
      install/deb/templates/web/nginx/php-fpm/datalife_engine.tpl
  89. 1 1
      install/deb/templates/web/nginx/php-fpm/default.stpl
  90. 1 1
      install/deb/templates/web/nginx/php-fpm/default.tpl
  91. 1 1
      install/deb/templates/web/nginx/php-fpm/dokuwiki.stpl
  92. 1 1
      install/deb/templates/web/nginx/php-fpm/dokuwiki.tpl
  93. 1 1
      install/deb/templates/web/nginx/php-fpm/drupal-composer.stpl
  94. 1 1
      install/deb/templates/web/nginx/php-fpm/drupal-composer.tpl
  95. 1 1
      install/deb/templates/web/nginx/php-fpm/drupal-social.stpl
  96. 1 1
      install/deb/templates/web/nginx/php-fpm/drupal-social.tpl
  97. 1 1
      install/deb/templates/web/nginx/php-fpm/drupal.stpl
  98. 1 1
      install/deb/templates/web/nginx/php-fpm/drupal.tpl
  99. 1 1
      install/deb/templates/web/nginx/php-fpm/flarum.stpl
  100. 1 1
      install/deb/templates/web/nginx/php-fpm/flarum.tpl

+ 1 - 3
.eslintrc.cjs

@@ -25,15 +25,13 @@ module.exports = {
 	rules: {
 		// Set those as warnings instead. They should be fixed at some point
 		'@typescript-eslint/no-unused-vars': [
-			'warn',
+			'error',
 			{
 				argsIgnorePattern: '^_',
 				varsIgnorePattern: '^_',
 				caughtErrorsIgnorePattern: '^_',
 			},
 		],
-		'@typescript-eslint/no-empty-function': 'warn',
-		'@typescript-eslint/no-this-alias': 'warn',
 		'@typescript-eslint/no-var-requires': 'off',
 		'no-redeclare': 'off',
 		'no-undef': 'off',

+ 1 - 1
.github/ISSUE_TEMPLATE/BUG-REPORT.yml

@@ -22,7 +22,7 @@ body:
     attributes:
       label: Tell us how to replicate the bug
       description: |
-        What steps did you take when the bug occured or things did not work as you expected?
+        What steps did you take when the bug occurred or things did not work as you expected?
       placeholder: |
         1. Click on the Web tab.
         2. Click on Add Web Domain.

+ 1 - 0
.prettierignore

@@ -34,6 +34,7 @@ web/templates/
 
 # vitepress build output
 **/.vitepress/dist/
+**/.vitepress/cache/
 
 # Logs
 logs

+ 44 - 1
CHANGELOG.md

@@ -2,6 +2,49 @@
 
 All notable changes to this project will be documented in this file.
 
+## [1.7.2] - Service release
+
+### Note
+
+- HestiaCP 1.7.2 fixes an issue with downloading certificates from Let's Encrypt due to the implementation of asynchronous requests which will go live on 10th April 2023. Please update your server before this date to ensure compatibility with Let's Encrypt.
+
+### Bugfixes
+
+- Fixed an issue php after default php version change (#3145 #3414)
+- Fixed importing Add Domains v-import-cpanel (#3242 @adion-gorani)
+- Fixed and issue with DNSSSEC check if DNSEC is available (#3430)
+- Fixed an issue with v-add-web-domain-redirection (#3438 #3440)
+- Remove leading and trailing spaces on a domain (#3439 #3440)
+- Fixed an issue with domain.com:/public_html in v-backup-users (#3434)
+- Fix and issue with custom webmail clients (#3419 #3420)
+- Refine :focus styles (#3432)
+- Replace jQuery UI tabs with vanilla JS (#3413)
+- Reduce amount of animation styles (#3418)
+- Minor UI updates (#3425)
+- Fixed an issue with v-suspend-dns-record still loading after being disabled (#3441 @setiseta)
+- Replace jQuery UI dialogs with <dialog> (#3401)
+- Fixed an issue SSL not found + php error on login page. (#3404)
+
+## [1.7.1] - Service release
+
+### Bugfixes
+
+- Fixed an issue with wildcard overruling webmail.domain.com config in Apache2 (#3400 #1631)
+- Removed delete button edit user page (#3997)
+- Fixed an issue with serial not increasing (#3396)
+- Fixed an issue with new hestia-zone sync and servers behind NAT or with multiple IPs (#3388 #3396)
+- Remove option to enable DNSSEC when DNSSEC is not supported (#3372 #3396)
+- Fix toolbar items on locales with long words (#3380 #3395)
+- Only count \*.tar files in rotate routine (#3393 #3385)
+- Fixed broken upgrade_mariadb.sh (#3391 @myrevery)
+- Improve add_firewall_ipset.php (#3390 @myrevery)
+- Update Path change of IPset blacklist.sh (#3389 @myrevery)
+- Improve upgrade script Cloudflare ips (#3388 @myrevery)
+- Update supported message hst-install.sh (#3377 @shizualand)
+- Fixed an issue with adding own ssl certificated to website config (#3374 #3371)
+- Fixed javascript logic edit mail domains (#3373)
+- Add required attribute to login forms (#3376)
+
 ## [1.7.0] - Feature / Major release
 
 ### Note
@@ -707,7 +750,7 @@ After that run apt update && apt upgrade
 
 ### Features
 
-- Add support for Dovecote Sieve #2163 (@gejobj) => [How to enable Managesieve](https://docs.hestiacp.com/admin_docs/mail.html#how-can-i-enable-managesieve)
+- Add support for Dovecote Sieve #2163 (@gejobj) => [How to enable Managesieve](https://hestiacp.com/docs/server-administration/email.html#how-can-i-enable-managesieve)
 - Improve HELO based system and use RDNS lookup instead our old system
 - Add support for PHP 8.1 #2233
 - Set default php version for new installs to PHP 8.0

+ 1 - 1
README.md

@@ -8,7 +8,7 @@
 
 <p align="center">
 	<a href="https://www.hestiacp.com/">HestiaCP.com</a> |
-	<a href="https://docs.hestiacp.com/">Documentation</a> |
+	<a href="https://hestiacp.com/docs/">Documentation</a> |
 	<a href="https://forum.hestiacp.com/">Forum</a> |
 	<a href="https://discord.gg/nXRUZch">Discord</a>
 	<br/><br/>

+ 1 - 1
SECURITY.md

@@ -7,7 +7,7 @@ We are mostly interested in reports by actual Hestia CP users but all high quali
 If you believe that you have have discovered a vulnerability in Hestia Control Panel,
 please let our development team know by submitting a report [Huntr.dev](https://huntr.dev/bounties/disclose/?target=https://github.com/hestiacp/hestiacp) Bounties and CVEs are automatically managed and allocated via the platform.
 
-If you are unable to use [Huntr.dev](https://huntr.dev/bounties/disclose/?target=https://github.com/hestiacp/hestiacp) please send an email to support@hestiacp.com
+If you are unable to use [Huntr.dev](https://huntr.dev/bounties/disclose/?target=https://github.com/hestiacp/hestiacp) please send an email to info@hestiacp.com
 
 We ask you to include a detailed description of the vulnerability, a list of services involved (e.g. exim, dovecot) and the versions which you've tested, full steps to reproduce the vulnerability, and include your findings and expected results.
 

+ 1 - 1
bin/v-add-backup-host

@@ -298,7 +298,7 @@ if [ "$type" = 'rclone' ]; then
 			rclone delete $host:$path/hestia-backup.txt
 		fi
 	else
-		check_result "$E_CONNECT" "Rclone config does not exits"
+		check_result "$E_CONNECT" "Rclone config does not exist"
 	fi
 fi
 

+ 2 - 0
bin/v-add-dns-record

@@ -132,6 +132,8 @@ chmod 660 $zone
 # Sorting records
 sort_dns_records
 
+# Update serial
+update_domain_serial
 # Updating zone
 if [[ "$DNS_SYSTEM" =~ named|bind ]]; then
 	# Do full rebuild due DNS SEC

+ 26 - 6
bin/v-add-letsencrypt-domain

@@ -59,7 +59,7 @@ query_le_v2() {
 	# Save http response to file passed as "$4" arg or print to stdout if not provided
 	# http response headers are always sent to stdout
 	local save_to_file=${4:-"/dev/stdout"}
-	curl --location --insecure --retry 5 --retry-connrefused --silent --dump-header /dev/stdout --data "$post_data" "$1" --header "$content" --output "$save_to_file"
+	curl --location --user-agent "HestiaCP" --insecure --retry 5 --retry-connrefused --silent --dump-header /dev/stdout --data "$post_data" "$1" --header "$content" --output "$save_to_file"
 	debug_log "API call" "exit status: $?"
 }
 
@@ -208,7 +208,7 @@ if [ -n "$DNS_SYSTEM" ]; then
 fi
 
 # Requesting nonce / STEP 1
-answer=$(curl -s -I "$LE_API/directory")
+answer=$(curl --user-agent "HestiaCP" -s -I "$LE_API/directory")
 nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
 status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')
 
@@ -242,8 +242,9 @@ nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
 authz=$(echo "$answer" | grep "acme/authz" | cut -f2 -d '"')
 finalize=$(echo "$answer" | grep 'finalize":' | cut -f4 -d '"')
 status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f2 -d ' ')
+order=$(echo -e "$answer" | grep -i location | cut -f2 -d \  | tr -d '\r\n')
 
-debug_log "Step 2" "- status: ${status}\n- nonce: ${nonce}\n- authz: ${authz}\n- finalize: ${finalize}\n- payload: ${payload}\n- answer: ${answer}"
+debug_log "Step 2" "- status: ${status}\n- nonce: ${nonce}\n- authz: ${authz}\n- finalize: ${finalize}\n- payload: ${payload}\n- answer: ${answer}\n order: ${order}"
 
 if [[ "$status" -ne 201 ]]; then
 	# Delete DNS CAA record
@@ -461,6 +462,25 @@ if [[ "$status" -ne 200 ]]; then
 	check_result "$E_CONNECT" "Let's Encrypt finalize bad status $status ($domain)"
 fi
 
+if [ -z "$certificate" ]; then
+	validation="processing"
+	i=1
+	while [ "$validation" = "processing" ]; do
+		answer=$(query_le_v2 "$order" "" "$nonce")
+		i=$((i + 1))
+
+		nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
+		status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')
+		validation=$(echo "$answer" | grep 'status":' | cut -f4 -d '"')
+		certificate=$(echo "$answer" | grep 'certificate":' | cut -f4 -d '"')
+		sleep $((i * 2)) # Sleep for 2s, 4s, 6s, 8s
+		if [ $i -gt 10 ]; then
+			check_result "$E_CONNECT" "Certificate processing timeout ($domain)"
+		fi
+		debug_log "Step 7" "- status: ${status}\n- nonce: ${nonce}\n- payload: ${payload}\n- certificate: ${certificate}\n- answer: ${answer}"
+	done
+fi
+
 # Downloading signed certificate / STEP 7
 status=0
 retry=0
@@ -470,7 +490,7 @@ while [[ $status != 200 && $retry -lt 3 ]]; do
 	answer=$(query_le_v2 "$certificate" "" "$nonce" "$ssl_dir/$domain.pem")
 	status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')
 
-	debug_log "Step 7" "- status: ${status}\n- retry: ${retry}\n- answer: ${answer}"
+	debug_log "Step 8" "- status: ${status}\n- retry: ${retry}\n- answer: ${answer}"
 
 	if [[ $status != 200 ]]; then
 		retry=$((retry + 1))
@@ -481,10 +501,10 @@ done
 
 # Fallback on depreciated download method for certs (unauthenticated GET)
 if [[ $status != 200 ]]; then
-	answer=$(curl --insecure --retry 5 --retry-connrefused --silent --dump-header /dev/stdout "$certificate" --output "$ssl_dir/$domain.pem")
+	answer=$(curl --insecure --user-agent "HestiaCP" --retry 5 --retry-connrefused --silent --dump-header /dev/stdout "$certificate" --output "$ssl_dir/$domain.pem")
 	status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')
 
-	debug_log "Step 7 - Fallback" "- status: ${status}\n- answer: ${answer}"
+	debug_log "Step 8 - Fallback" "- status: ${status}\n- answer: ${answer}"
 fi
 
 debug_log "CERT DIR" "$(ls -las "$ssl_dir/")"

+ 1 - 1
bin/v-add-letsencrypt-user

@@ -50,7 +50,7 @@ query_le_v2() {
 	post_data=$post_data'"payload":"'"$payload_"'",'
 	post_data=$post_data'"signature":"'"$signature_"'"}'
 
-	curl -s -i -d "$post_data" "$1" -H "$content"
+	curl --user-agent "HestiaCP" -s -i -d "$post_data" "$1" -H "$content"
 }
 
 #----------------------------------------------------------#

+ 3 - 3
bin/v-add-mail-domain-webmail

@@ -142,10 +142,10 @@ else
 		if [ "$WEB_SYSTEM" = "nginx" ]; then
 			WEBMAIL_TEMPLATE="web_system"
 		fi
-	elif [ "$webmail" == "rainloop" ]; then
-		WEBMAIL_TEMPLATE="rainloop"
+	elif [ -f "$HESTIA/data/templates/mail/$WEB_SYSTEM/$webmail.tpl" ]; then
+		WEBMAIL_TEMPLATE="$webmail"
 		if [ -n "$PROXY_SYSTEM" ]; then
-			PROXY_TEMPLATE="default_rainloop"
+			PROXY_TEMPLATE="default_$webmail"
 		fi
 	else
 		WEBMAIL_TEMPLATE="disabled"

+ 7 - 2
bin/v-add-remote-dns-domain

@@ -58,8 +58,13 @@ fi
 if [ "$DNS_CLUSTER_SYSTEM" = "hestia-zone" ]; then
 	str=$(echo "$str" | sed "s/SLAVE='no'/SLAVE='yes'/g")
 	str=$(echo "$str" | sed "s/SLAVE=''/SLAVE='yes'/g")
-	ip=$($BIN/v-list-sys-ips plain | cut -f1 | head -n1)
-	str=$(echo "$str" | sed "s/MASTER=''/MASTER='$ip'/g")
+	ip=$(ip addr | grep 'inet ' | grep global | head -n1 | awk '{print $2}' | cut -f1 -d/)
+	source_conf $HESTIA/data/ips/$ip
+	if [ -z $NAT ]; then
+		str=$(echo "$str" | sed "s/MASTER=''/MASTER='$ip'/g")
+	else
+		str=$(echo "$str" | sed "s/MASTER=''/MASTER='$NAT'/g")
+	fi
 fi
 
 IFS=$'\n'

+ 2 - 2
bin/v-add-sys-dependencies

@@ -49,7 +49,7 @@ fi
 if [ ! -f "$COMPOSER_BIN" ]; then
 	$BIN/v-add-user-composer "$user"
 	if [ $? -ne 0 ]; then
-		$BIN/v-add-user-notification admin 'Composer installation failed!' '<b>Hestia will not work without Composer.</b><br><br>Please try running the installer manually from a shell session:<br>v-add-sys-dependencies<br><br>If this continues, open an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> GitHub</a>.'
+		$BIN/v-add-user-notification admin 'Composer installation failed!' '<b>Hestia will not work without Composer.</b><br><br>Please try running the installer manually from a shell session:<br>v-add-sys-dependencies<br><br>If this continues, open an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> GitHub</a>.'
 		exit 1
 	fi
 fi
@@ -78,7 +78,7 @@ if [ $? -ne 0 ]; then
 	echo "ERROR: PHPMailer installation failed!"
 	echo "Please report this to our development team:"
 	echo "https://github.com/hestiacp/hestiacp/issues"
-	$BIN/v-add-user-notification admin 'Hestia PHP dependencies installation failed!' 'Please report this to our development team on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> GitHub</a>.'
+	$BIN/v-add-user-notification admin 'Hestia PHP dependencies installation failed!' 'Please report this to our development team on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> GitHub</a>.'
 	# Installation failed, clean up files
 	rm --recursive --force ${PM_INSTALL_DIR}/vendor
 	$BIN/v-change-sys-config-value 'USE_SERVER_SMTP' 'n'

+ 2 - 2
bin/v-add-sys-filemanager

@@ -51,7 +51,7 @@ fi
 if [ ! -f "$COMPOSER_BIN" ]; then
 	$BIN/v-add-user-composer "$user"
 	if [ $? -ne 0 ]; then
-		$BIN/v-add-user-notification admin 'Composer installation failed!' '<b>The File Manager will not work without Composer.</b><br><br>Please try running the installer manually from a shell session:<br>v-add-sys-filemanager<br><br>If this continues, open an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> GitHub</a>.'
+		$BIN/v-add-user-notification admin 'Composer installation failed!' '<b>The File Manager will not work without Composer.</b><br><br>Please try running the installer manually from a shell session:<br>v-add-sys-filemanager<br><br>If this continues, open an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> GitHub</a>.'
 		exit 1
 	fi
 fi
@@ -91,7 +91,7 @@ if [ $? -ne 0 ]; then
 	echo "ERROR: File Manager installation failed!"
 	echo "Please report this to our development team:"
 	echo "https://github.com/hestiacp/hestiacp/issues"
-	$BIN/v-add-user-notification admin 'File Manager installation failed!' 'Please report this to our development team on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> GitHub</a>.'
+	$BIN/v-add-user-notification admin 'File Manager installation failed!' 'Please report this to our development team on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> GitHub</a>.'
 	# Installation failed, clean up files
 	rm --recursive --force ${FM_INSTALL_DIR}
 	$BIN/v-change-sys-config-value 'FILE_MANAGER' 'false'

+ 2 - 1
bin/v-add-sys-firewall

@@ -35,7 +35,8 @@ check_hestia_demo_mode
 
 # Adding default ruleset
 if [ -z "$(ls -A $HESTIA/data/firewall 2> /dev/null)" ]; then
-	cp -rf $HESTIA_INSTALL_DIR/firewall $HESTIA/data/
+	cp -rf $HESTIA_COMMON_DIR/firewall $HESTIA/data/
+	rm -f $HESTIA/data/firewall/ipset/blacklist.sh $HESTIA/data/firewall/ipset/blacklist.ipv6.sh
 fi
 
 # Updating FIREWAL_SYSTEM value

+ 33 - 2
bin/v-add-web-domain-redirect

@@ -42,13 +42,20 @@ is_object_unsuspended 'user' 'USER' "$user"
 is_object_valid 'web' 'DOMAIN' "$domain"
 is_object_unsuspended 'web' 'DOMAIN' "$domain"
 
+requesturi=0
 if [[ "$3" =~ http://|https:// ]]; then
 	scheme_check=1
 	scheme=$($HESTIA_PHP -r '$url=parse_url($argv[1]); echo $url["scheme"];' "$redirect")
 	host=$($HESTIA_PHP -r '$url=parse_url($argv[1]); echo $url["host"];' "$redirect")
 	path=$($HESTIA_PHP -r '$url=parse_url($argv[1]); if(!empty($url["path"])){echo $url["path"];}' "$redirect")
+	port=$($HESTIA_PHP -r '$url=parse_url($argv[1]); if(!empty($url["port"])){echo $url["port"];}' "$redirect")
+
 	host=$(idn2 --quiet "$host")
 	redirect="$scheme://$host$path"
+	if [ -n "$port" ]; then
+		redirect="$scheme://$host:$port$path"
+	fi
+
 	isValidUrl=$(php -r '$url=$argv[1]; $url=filter_var($url,FILTER_VALIDATE_URL); echo $url;' "$redirect")
 	if [ -z "$isValidUrl" ]; then
 		check_result $E_INVALID "Invalid redirect"
@@ -56,8 +63,15 @@ if [[ "$3" =~ http://|https:// ]]; then
 else
 	host=$($HESTIA_PHP -r '$url=parse_url($argv[1]); echo $url["host"];' "http://$redirect")
 	path=$($HESTIA_PHP -r '$url=parse_url($argv[1]); if(!empty($url["path"])){echo $url["path"];}' "http://$redirect")
+	port=$($HESTIA_PHP -r '$url=parse_url($argv[1]); if(!empty($url["port"])){echo $url["port"];}' "$redirect")
+
 	host=$(idn2 --quiet "$host")
+
 	redirect="$host$path"
+	if [ -n "$port" ]; then
+		redirect="$host:$port$path"
+	fi
+
 	isValidUrl=$(php -r '$url=$argv[1]; $url=filter_var($url,FILTER_VALIDATE_URL); echo $url;' "http://$redirect")
 	if [ -z "$isValidUrl" ]; then
 		check_result $E_INVALID "Invalid redirect"
@@ -77,16 +91,33 @@ if [ "$WEB_SYSTEM" = 'nginx' ] || [ "$PROXY_SYSTEM" = 'nginx' ]; then
 	sconf="$HOMEDIR/$user/conf/web/$domain/nginx.ssl.conf_redirect"
 fi
 
+# Prevent $request_uri being added if ends in .html
+requesturi=0
+if [ -n "$path" ]; then
+	lastchr=${path#${path%?}}
+	if [ "$lastchr" = "/" ]; then
+		requesturi=1
+	fi
+fi
+
 # Insert redirect commands
 if [ -n "$PROXY_SYSTEM" ] || [ "$WEB_SYSTEM" = 'nginx' ]; then
 	if [ "$scheme_check" = 1 ]; then
-		echo "   return $code $redirect\$request_uri;" > $conf
+		if [ "$requesturi" = 1 ]; then
+			echo "   return $code $redirect\$request_uri;" > $conf
+		else
+			echo "   return $code $redirect;" > $conf
+		fi
 		if [ ! -e "$sconf" ]; then
 			ln -s "$conf" "$sconf"
 		fi
 	else
 		echo "if (\$host != \"$redirect\") {" > $conf
-		echo "   return $code \$scheme://$redirect\$request_uri;" >> $conf
+		if [ "$requesturi" = 1 ]; then
+			echo "   return $code \$scheme://$redirect\$request_uri;" >> $conf
+		else
+			echo "   return $code \$scheme://$redirect;" >> $conf
+		fi
 		echo "}" >> $conf
 
 		if [ ! -e "$sconf" ]; then

+ 1 - 1
bin/v-backup-user

@@ -245,7 +245,7 @@ if [ -n "$WEB_SYSTEM" ] && [ "$WEB" != '*' ]; then
 	# Parsing domain exclusions
 	conf="$USER_DATA/web.conf"
 	for domain in $(search_objects 'web' 'SUSPENDED' "*" 'DOMAIN'); do
-		exclusion=$(echo -e "$WEB" | tr ',' '\n' | grep "^$domain\|\*$")
+		exclusion=$(echo -e "$WEB" | tr ',' '\n' | grep "^$domain$\|^\*$")
 		if [ -z "$exclusion" ]; then
 			web_list="$web_list $domain"
 		else

+ 11 - 1
bin/v-change-dns-domain-dnssec

@@ -51,6 +51,15 @@ fi
 # Perform verification if read-only mode is enabled
 check_hestia_demo_mode
 
+if [ "$DNS_CLUSTER_SYSTEM" != 'hestia-zone' ]; then
+	check_result "$E_DISABLED" "DNSSEC is not supported when DNS_CLUSTER_SYSTEM is not set to hestia-zone"
+fi
+
+version=$(named -v | awk 'NR==1{print $2}')
+if version_ge '9.16.18' $version; then
+	check_result "$E_DISABLED" "DNSSEC is not supported when bind / named version <= 9.16.18"
+fi
+
 #----------------------------------------------------------#
 #                       Action                             #
 #----------------------------------------------------------#
@@ -64,8 +73,9 @@ syshealth_repair_dns_config
 # Changing exp
 update_object_value 'dns' 'DOMAIN' "$domain" '$DNSSEC' "$status"
 
+# Update serial
+update_domain_serial
 # Rebuild DNS config
-
 rebuild_dns_domain_conf
 
 if [ $status = "no" ]; then

+ 2 - 0
bin/v-change-dns-domain-ip

@@ -65,6 +65,8 @@ update_object_value 'dns' 'DOMAIN' "$domain" '$IP' "$ip"
 # Changing records
 sed -i "s/$old/$ip/g" $USER_DATA/dns/$domain.conf
 
+# Update serial
+update_domain_serial
 # Updating zone
 if [[ "$DNS_SYSTEM" =~ named|bind ]]; then
 	rebuild_dns_domain_conf

+ 2 - 0
bin/v-change-dns-domain-soa

@@ -57,6 +57,8 @@ check_hestia_demo_mode
 # Changing soa
 update_object_value 'dns' 'DOMAIN' "$domain" '$SOA' "$soa"
 
+# Update serial
+update_domain_serial
 # Updating zone
 if [[ "$DNS_SYSTEM" =~ named|bind ]]; then
 	rebuild_dns_domain_conf

+ 2 - 0
bin/v-change-dns-domain-tpl

@@ -131,6 +131,8 @@ if [ "$template" = "office365" ]; then
 	fi
 fi
 
+# Update serial
+update_domain_serial
 # Updating zone
 if [[ "$DNS_SYSTEM" =~ named|bind ]]; then
 	rebuild_dns_domain_conf

+ 2 - 0
bin/v-change-dns-domain-ttl

@@ -56,6 +56,8 @@ check_hestia_demo_mode
 # Changing ttl
 update_object_value 'dns' 'DOMAIN' "$domain" '$TTL' "$ttl"
 
+# Update serial
+update_domain_serial
 # Updating zone
 if [[ "$DNS_SYSTEM" =~ named|bind ]]; then
 	rebuild_dns_domain_conf

+ 2 - 0
bin/v-change-dns-record

@@ -136,6 +136,8 @@ echo "$dns_rec" >> $USER_DATA/dns/$domain.conf
 # Sorting records
 sort_dns_records
 
+# Update serial
+update_domain_serial
 # Updating zone
 if [[ "$DNS_SYSTEM" =~ named|bind ]]; then
 	rebuild_dns_domain_conf

+ 2 - 0
bin/v-change-dns-record-id

@@ -62,6 +62,8 @@ sed -i "s/^ID='$id'/ID='$newid'/" $USER_DATA/dns/$domain.conf
 # Sorting records
 sort_dns_records
 
+# Update serial
+update_domain_serial
 # Updating zone
 if [[ "$DNS_SYSTEM" =~ named|bind ]]; then
 	rebuild_dns_domain_conf

+ 2 - 1
bin/v-change-sys-php

@@ -52,7 +52,8 @@ for user in $($BIN/v-list-sys-users plain); do
 	$BIN/v-rebuild-mail-domains "$user" 'no' > /dev/null 2>&1
 done
 
-# restart
+# Reload "current" php version before reload everthing
+$BIN/v-restart-web-backend '' $(multiphp_default_version)
 $BIN/v-restart-web-backend
 $BIN/v-restart-web
 $BIN/v-restart-proxy

+ 4 - 0
bin/v-change-sys-webmail

@@ -51,6 +51,10 @@ for user in $($BIN/v-list-sys-users plain); do
 	done
 done
 
+if [ -d /etc/apache2/ ]; then
+	sed -i "s/IncludeOptional conf.d\/domains\/$WEBMAIL_ALIAS.*.conf/IncludeOptional conf.d\/domains\/$NEW_ALIAS.*.conf/g" /etc/apache2/apache2.conf
+fi
+
 #----------------------------------------------------------#
 #                       Hestia                             #
 #----------------------------------------------------------#

+ 2 - 0
bin/v-delete-dns-record

@@ -56,6 +56,8 @@ check_hestia_demo_mode
 # Deleting record
 sed -i "/^ID='$id'/d" $USER_DATA/dns/$domain.conf
 
+# Update serial
+update_domain_serial
 # Updating zone
 if [[ "$DNS_SYSTEM" =~ named|bind ]]; then
 	rebuild_dns_domain_conf

+ 7 - 7
bin/v-export-rrd

@@ -9,7 +9,7 @@
 #----------------------------------------------------------#
 
 chart=$1
-timespan=${2-hour}
+timespan=${2-daily}
 
 # Includes
 # shellcheck source=/etc/hestiacp/hestia.conf
@@ -33,8 +33,8 @@ function generate_load_table() {
 	rrdtool xport --json -s $start -e $end --step $step \
 		DEF:la=$RRD/la/la.rrd:LA:AVERAGE \
 		DEF:pr=$RRD/la/la.rrd:PR:AVERAGE \
-		XPORT:la:load \
-		XPORT:pr:Proccess
+		XPORT:la:Load \
+		XPORT:pr:Processes
 }
 
 function generate_mem_table() {
@@ -115,21 +115,21 @@ function generate_net_table() {
 			DEF:inoctets=$RRD/net/$host.rrd:RX:AVERAGE \
 			DEF:outoctets=$RRD/net/$host.rrd:TX:AVERAGE \
 			XPORT:inoctets:"Input (rx)" \
-			XPORT:outoctets:"Output (rx)"
+			XPORT:outoctets:"Output (tx)"
 	else
 		echo "Does not exists"
 		exit 1
 	fi
 }
 
-if [ "$timespan" = "week" ]; then
+if [ "$timespan" = "weekly" ]; then
 	start=$(date -d "7 days ago" +%s)
 	# every 30 min
 	step=3600
-elif [ "$timespan" = "month" ]; then
+elif [ "$timespan" = "monthly" ]; then
 	start=$(date -d "1 month ago" +%s)
 	step=21600
-elif [ "$timespan" = "year" ]; then
+elif [ "$timespan" = "yearly" ]; then
 	start=$(date -d "1 year ago" +%s)
 	step=172800
 else

+ 7 - 0
bin/v-import-cpanel

@@ -174,6 +174,13 @@ echo "Converting addons domains, subdomains and some other fun"
 cp sds hst_sds
 cp sds2 hst_sds2
 sed -i 's/_/./g' hst_sds
+cat addons | while read ddon_domain addon_sub
+do
+        echo "Converting default subdomain: $addon_sub in domain: $addon_domain"
+        sed -i -e "s/$addon_sub/$addon_domain/g" hst_sds
+        sed -i -e "s/$addon_sub/$addon_domain/g" hst_sds2
+        mv userdata/$addon_sub userdata/${addon_domain}
+done
 sed -i 's/public_html/public@html/g; s/_/./g; s/public@html/public_html/g; s/=/ /g' hst_sds2
 
 tput setaf 2

+ 11 - 0
bin/v-list-sys-config

@@ -44,6 +44,8 @@ json_list() {
         "DB_SYSTEM": "'$DB_SYSTEM'",
         "DNS_SYSTEM": "'$DNS_SYSTEM'",
         "DNS_CLUSTER": "'$DNS_CLUSTER'",
+		"DNS_CLUSTER_SYSTEM": "'$DNS_CLUSTER_SYSTEM'",
+		"SUPPORT_DNSSEC": "'$SUPPORT_DNSSEC'",
         "STATS_SYSTEM": "'$STATS_SYSTEM'",
         "BACKUP_SYSTEM": "'$BACKUP_SYSTEM'",
         "CRON_SYSTEM": "'$CRON_SYSTEM'",
@@ -266,6 +268,15 @@ csv_list() {
 #                       Action                             #
 #----------------------------------------------------------#
 
+if [ -n "$DNS_SYSTEM" ]; then
+	version=$(named -v | awk 'NR==1{print $2}')
+	if version_ge '9.16.18' $version; then
+		SUPPORT_DNSSEC="no"
+	else
+		SUPPORT_DNSSEC="yes"
+	fi
+fi
+
 # Listing data
 case $format in
 	json) json_list ;;

+ 7 - 2
bin/v-sync-dns-cluster

@@ -86,8 +86,13 @@ for cluster in $hosts; do
 						str=$(echo "$str" | sed "s/SLAVE='no'/SLAVE='yes'/g")
 						str=$(echo "$str" | sed "s/SLAVE=''/SLAVE='yes'/g")
 
-						ip=$($BIN/v-list-sys-ips plain | cut -f1 | head -n1)
-						str=$(echo "$str" | sed "s/MASTER=''/MASTER='$ip'/g")
+						ip=$(ip addr | grep 'inet ' | grep global | head -n1 | awk '{print $2}' | cut -f1 -d/)
+						source_conf $HESTIA/data/ips/$ip
+						if [ -z $NAT ]; then
+							str=$(echo "$str" | sed "s/MASTER=''/MASTER='$ip'/g")
+						else
+							str=$(echo "$str" | sed "s/MASTER=''/MASTER='$NAT'/g")
+						fi
 
 						# Syncing domain data
 						cluster_cmd v-insert-dns-domain $DNS_USER "$str" $HOSTNAME $flush 'no'

+ 6 - 5
docs/.vitepress/config.ts

@@ -43,17 +43,18 @@ export default defineConfig({
 			copyright: "Copyright © 2019-present Hestia Control Panel",
 		},
 
-		// algolia: {
-		//   appId: "REPLACE_ME",
-		//   apiKey: "REPLACE_ME",
-		//   indexName: "REPLACE_ME",
-		// },
+		algolia: {
+			appId: "V04P0P5D2R",
+			apiKey: "7a90a3ac7f9313f174c50b0f301f7ec6",
+			indexName: "hestia_cp",
+		},
 	},
 });
 
 function nav(): DefaultTheme.NavItem[] {
 	return [
 		{ text: "Features", link: "/features.md" },
+		{ text: "Install", link: "/install.md" },
 		{ text: "Documentation", link: "/docs/introduction/getting-started.md", activeMatch: "/docs/" },
 		{ text: "Team", link: "/team.md" },
 		{ text: "Demo", link: "https://demo.hestiacp.com:8083/" },

+ 324 - 0
docs/.vitepress/theme/components/InstallOptions.vue

@@ -0,0 +1,324 @@
+<script lang="ts">
+import { InstallOptions } from "../../../_data/options";
+import { LanguagesOptions } from "../../../_data/languages";
+import { ref } from "vue";
+const slot = ref(null);
+
+export default {
+	props: {
+		languages: {
+			type: Array<LanguagesOptions>,
+			required: true,
+			selected: "en",
+		},
+		items: {
+			type: Array<InstallOptions>,
+			required: true,
+		},
+	},
+	data() {
+		return {
+			pageloader: false,
+			hestia_wget:
+				"wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh",
+			hestia_install: "sudo bash hst-install.sh",
+			installStr: "",
+		};
+	},
+	methods: {
+		getOptionString(item: InstallOptions): string {
+			if (item.textField && item.selected) {
+				return item.text.length >= 2 ? `${item.param} '${item.text}'` : "";
+			}
+
+			if (item.selectField) {
+				return `${item.param} '${item.text}'`;
+			}
+
+			return item.param.includes("force") && item.selected
+				? item.param
+				: `${item.param}${item.selected ? " yes" : " no"}`;
+		},
+		generateString() {
+			const installStr = this.items.map(this.getOptionString).filter(Boolean);
+
+			this.installStr = `${this.hestia_install} ${installStr.join(" ")}`;
+			(this.$refs.dialog as HTMLDialogElement).showModal();
+		},
+		closeDialog(e) {
+			if (e.target === this.$refs.dialogClose || e.target === this.$refs.dialog) {
+				(this.$refs.dialog as HTMLDialogElement).close();
+			}
+		},
+		toggleOption(e) {
+			if (e.target.checked) {
+				let conflicts = e.target.getAttribute("conflicts");
+				if (conflicts) {
+					document.getElementById(conflicts).checked = false;
+				}
+				let depends = e.target.getAttribute("depends");
+				if (depends) {
+					document.getElementById(depends).checked = true;
+				}
+			}
+		},
+		copyToClipboard(text: string, button: HTMLButtonElement) {
+			navigator.clipboard.writeText(text).then(
+				() => {
+					button.textContent = "Copied!";
+					setTimeout(() => {
+						button.textContent = "Copy";
+					}, 1000);
+				},
+				(err) => {
+					console.error("Could not copy to clipboard:", err);
+				}
+			);
+		},
+	},
+};
+</script>
+
+<template>
+	<div class="container">
+		<div class="grid">
+			<div class="form-group" v-for="item in items">
+				<div class="form-check u-mb10">
+					<input
+						@change="toggleOption"
+						type="checkbox"
+						class="form-check-input"
+						v-model="item.selected"
+						:value="item.value"
+						:id="item.id"
+						:conflicts="item.conflicts"
+						:depends="item.depends"
+					/>
+					<label :for="item.id">{{ item.id }}</label>
+				</div>
+				<template v-if="item.textField || item.selectField">
+					<label class="form-label" :for="'input-' + item.id">{{ item.desc }}</label>
+				</template>
+				<template v-else>
+					<p>{{ item.desc }}</p>
+				</template>
+				<div v-if="item.textField">
+					<input type="text" class="form-control" v-model="item.text" :id="'input-' + item.id" />
+				</div>
+				<div v-if="item.selectField">
+					<select class="form-select" v-model="item.text" :id="'input-' + item.id">
+						<option v-for="language in languages" :value="language.value" :key="language.value">
+							{{ language.text }}
+						</option>
+					</select>
+				</div>
+			</div>
+		</div>
+		<div class="u-text-center u-mb10">
+			<button @click="generateString" class="form-submit" type="button">Submit</button>
+		</div>
+		<dialog ref="dialog" class="modal" @click="closeDialog">
+			<button class="modal-close" @click="closeDialog" type="button" ref="dialogClose">
+				Close
+			</button>
+			<div ref="dialogContent" class="modal-content">
+				<h1 class="modal-heading">Installation instructions</h1>
+				<p class="u-mb10">
+					Log in to your server as root, either directly or via SSH:
+					<code>ssh root@your.server</code> and download the installation script:
+				</p>
+				<div class="u-pos-relative">
+					<input
+						type="text"
+						class="form-control u-monospace u-mb10"
+						v-model="hestia_wget"
+						readonly
+					/>
+					<button
+						class="button-positioned"
+						@click="copyToClipboard(hestia_wget, $event.target)"
+						type="button"
+						title="Copy to Clipboard"
+					>
+						Copy
+					</button>
+				</div>
+				<p class="u-mb10">Then run the following command:</p>
+				<div class="u-pos-relative">
+					<textarea class="form-control u-min-height100" v-model="installStr" readonly />
+					<button
+						class="button-positioned"
+						@click="copyToClipboard(installStr, $event.target)"
+						type="button"
+						title="Copy to Clipboard"
+					>
+						Copy
+					</button>
+				</div>
+			</div>
+		</dialog>
+	</div>
+</template>
+
+<style scoped>
+.container {
+	margin: 0px auto;
+	max-width: 1152px;
+}
+.grid {
+	display: grid;
+	grid-gap: 20px;
+	margin-top: 30px;
+	margin-bottom: 30px;
+
+	@media (min-width: 640px) {
+		grid-template-columns: 1fr 1fr;
+	}
+
+	@media (min-width: 960px) {
+		grid-template-columns: 1fr 1fr 1fr;
+	}
+}
+.form-group {
+	font-size: 0.9em;
+	border-radius: 10px;
+	padding: 15px 20px;
+	background-color: var(--vp-c-bg-alt);
+}
+.form-label {
+	display: inline-block;
+	margin-left: 2px;
+	padding-bottom: 5px;
+	text-transform: capitalize;
+}
+.form-control {
+	font-size: 0.9em;
+	border: 1px solid var(--vp-c-border);
+	border-radius: 4px;
+	background-color: var(--vp-c-bg);
+	width: 100%;
+	padding: 5px 10px;
+
+	&:hover {
+		border-color: var(--vp-c-border-hover);
+	}
+
+	&:focus {
+		border-color: var(--vp-c-brand);
+	}
+}
+.form-select {
+	appearance: auto;
+	font-size: 0.9em;
+	border: 1px solid var(--vp-c-border);
+	border-radius: 4px;
+	background-color: var(--vp-c-bg);
+	padding: 5px 10px;
+	width: 100%;
+
+	&:hover {
+		border-color: var(--vp-c-border-hover);
+	}
+
+	&:focus {
+		border-color: var(--vp-c-brand);
+	}
+}
+.form-check {
+	position: relative;
+	padding-left: 20px;
+	margin-left: 3px;
+	min-height: 24px;
+
+	& label {
+		font-weight: 600;
+	}
+}
+.form-check-input {
+	position: absolute;
+	margin-top: 5px;
+	margin-left: -20px;
+}
+.form-submit {
+	border: 1px solid transparent;
+	display: inline-block;
+	font-weight: 600;
+	transition: color 0.25s, border-color 0.25s, background-color 0.25s;
+	border-radius: 20px;
+	font-size: 16px;
+	padding: 10px 20px;
+	background-color: var(--vp-button-brand-bg);
+	border-color: var(--vp-button-brand-border);
+	color: var(--vp-button-brand-text);
+
+	&:hover {
+		background-color: var(--vp-button-brand-hover-bg);
+		border-color: var(--vp-button-brand-hover-border);
+		color: var(--vp-button-brand-hover-text);
+	}
+
+	&:active {
+		background-color: var(--vp-button-brand-active-bg);
+		border-color: var(--vp-button-brand-active-border);
+		color: var(--vp-button-brand-active-text);
+	}
+}
+.button-positioned {
+	position: absolute;
+	right: 1px;
+	top: 1px;
+	border-top-right-radius: 3px;
+	border-bottom-right-radius: 3px;
+	color: var(--vp-c-brand);
+	font-weight: 600;
+	padding: 6px 10px;
+	background-color: var(--vp-c-bg);
+}
+.modal {
+	position: fixed;
+	border-radius: 10px;
+	border: 1px solid var(--vp-c-border);
+	box-shadow: 0 8px 40px 0 rgb(0 0 0 / 35%);
+	padding: 0;
+
+	&::backdrop {
+		background-color: rgb(0 0 0 / 60%);
+	}
+}
+.modal-close {
+	position: absolute;
+	top: 10px;
+	right: 15px;
+	font-weight: 600;
+	color: var(--vp-c-brand);
+}
+.modal-content {
+	padding: 30px;
+}
+.modal-heading {
+	font-weight: 600;
+	font-size: 1.3em;
+	text-align: center;
+	margin-bottom: 15px;
+}
+code {
+	background-color: var(--vp-c-bg-alt);
+	border-radius: 3px;
+	padding: 2px 5px;
+}
+.u-mb10 {
+	margin-bottom: 10px !important;
+}
+.u-min-height100 {
+	min-height: 100px;
+}
+.u-text-center {
+	text-align: center !important;
+}
+.u-monospace {
+	font-family: monospace !important;
+}
+.u-pos-relative {
+	position: relative !important;
+}
+</style>

+ 31 - 0
docs/.vitepress/theme/components/InstallOptionsSection.vue

@@ -0,0 +1,31 @@
+<script lang="ts"></script>
+
+<template>
+	<form class="InstallForm" id="form">
+		<div class="InstallOptionsSection">
+			<slot name="list" />
+		</div>
+		<cite
+			>Based on: <a href="https://github.com/gabizz/hestiacp-scriptline-generator">@gabizz</a> and
+			<a href="https://github.com/turbopixel/HestiaCP-Command-Creator">@turbopixel</a></cite
+		>
+	</form>
+</template>
+
+<style scoped>
+.InstallForm {
+	margin: 0.55em 0;
+	padding: 0 1em;
+	line-height: 1.5;
+}
+cite {
+	font-size: small;
+	margin: 0.55em 0;
+	display: block;
+	text-align: center;
+
+	& a {
+		color: var(--vp-c-txt-1) !important;
+	}
+}
+</style>

+ 28 - 0
docs/.vitepress/theme/components/InstallPage.vue

@@ -0,0 +1,28 @@
+<template>
+	<div class="InstallPage">
+		<slot></slot>
+	</div>
+</template>
+
+<style scoped>
+.InstallPage {
+	line-height: 1.5;
+}
+.InstallPage :deep(.container) {
+	display: flex;
+	flex-direction: column;
+	margin: 0 auto;
+	max-width: 1152px;
+}
+
+.InstallPage :deep(a) {
+	font-weight: 500;
+	color: var(--vp-c-brand);
+	text-decoration-style: dotted;
+	transition: color 0.25s;
+}
+
+.InstallPage :deep(a:hover) {
+	color: var(--vp-c-brand-dark);
+}
+</style>

+ 42 - 0
docs/.vitepress/theme/components/InstallPageTitle.vue

@@ -0,0 +1,42 @@
+<template>
+	<header class="InstallPageTitle">
+		<div class="container">
+			<h1>
+				<slot name="title"></slot>
+			</h1>
+			<p v-if="$slots.lead" class="lead">
+				<slot name="lead" />
+			</p>
+		</div>
+	</header>
+</template>
+
+<style scoped>
+.InstallPageTitle {
+	padding: 0 24px;
+	background-color: var(--vp-c-bg-alt);
+}
+
+.InstallPageTitle h1 {
+	margin: 0.75em 0;
+	font-size: 2rem;
+	font-weight: 700;
+	line-height: inherit;
+}
+
+@media (min-width: 640px) {
+	.InstallPageTitle {
+		padding: 0 48px;
+	}
+
+	.InstallPageTitle h1 {
+		font-size: 2.5rem;
+	}
+}
+
+@media (min-width: 960px) {
+	.InstallPageTitle {
+		padding: 0 64px;
+	}
+}
+</style>

+ 2 - 0
docs/.vitepress/theme/index.ts

@@ -5,10 +5,12 @@ import "@fortawesome/fontawesome-free/css/solid.css";
 import "./styles/base.css";
 import "./styles/vars.css";
 import FeaturePage from "./components/FeaturePage.vue";
+import InstallPage from "./components/InstallPage.vue";
 
 export default {
 	...Theme,
 	enhanceApp({ app }) {
 		app.component("FeaturePage", FeaturePage);
+		app.component("InstallPage", InstallPage);
 	},
 };

+ 42 - 0
docs/_data/languages.ts

@@ -0,0 +1,42 @@
+export const languages: LanguagesListItem[] = [
+	{ text: "Arabic", value: "ar" },
+	{ text: "Armenian", value: "hy" },
+	{ text: "Azerbaijani", value: "az" },
+	{ text: "Bengali", value: "bn" },
+	{ text: "Bosnian", value: "bs" },
+	{ text: "Bulgarian", value: "bg" },
+	{ text: "Croatian", value: "hr" },
+	{ text: "Czech", value: "cs" },
+	{ text: "Danish", value: "da" },
+	{ text: "Dutch", value: "nl" },
+	{ text: "English", value: "en" },
+	{ text: "Finnish", value: "fi" },
+	{ text: "French", value: "fr" },
+	{ text: "Georgian", value: "ka" },
+	{ text: "German", value: "de" },
+	{ text: "Greek", value: "el" },
+	{ text: "Hungarian", value: "hu" },
+	{ text: "Indonesian", value: "id" },
+	{ text: "Italian", value: "it" },
+	{ text: "Japanese", value: "ja" },
+	{ text: "Korean", value: "ko" },
+	{ text: "Kurdish Sorani" },
+	{ text: "Norwegain", value: "no" },
+	{ text: "Persian", value: "fa" },
+	{ text: "Polish", value: "pl" },
+	{ text: "Portuguese", value: "pt" },
+	{ text: "Portuguese (Brasil)", value: "pt-br" },
+	{ text: "Romanian", value: "ro" },
+	{ text: "Russian", value: "ru" },
+	{ text: "Serbian", value: "sr" },
+	{ text: "Simplified Chinese (China)", value: "zh-cn" },
+	{ text: "Slovak", value: "sk" },
+	{ text: "Spanish", value: "es" },
+	{ text: "Swedish", value: "sv" },
+	{ text: "Thai", value: "th" },
+	{ text: "Traditional Chinese (Taiwan)", value: "zh-tw" },
+	{ text: "Turkish", value: "tr" },
+	{ text: "Ukrainian", value: "uk" },
+	{ text: "Urdu", value: "ur" },
+	{ text: "Vietnamese", value: "vi" },
+];

+ 154 - 0
docs/_data/options.ts

@@ -0,0 +1,154 @@
+export const options: OptionsListItem[] = [
+	{
+		name: " --port",
+		id: "port",
+		param: "--port",
+		desc: "Change Backend Port",
+		selected: true,
+		text: "8083",
+		textField: true,
+	},
+	{
+		name: " --lang",
+		id: "language",
+		param: "--lang",
+		desc: "ISO 639-1 codes",
+		selected: true,
+		default: "en",
+		selectField: true,
+		text: "en",
+	},
+	{
+		name: " --hostname",
+		id: "hostname",
+		param: "--hostname",
+		desc: "Set hostname",
+		selected: false,
+		text: "",
+		textField: true,
+	},
+	{
+		name: " --email",
+		id: "email",
+		param: "--email",
+		desc: "Set admin email",
+		selected: false,
+		text: "",
+		textField: true,
+	},
+	{
+		name: " --password",
+		id: "password",
+		param: "--password",
+		desc: "Set admin password",
+		selected: false,
+		text: "",
+		textField: true,
+	},
+	{ name: " --apache", id: "apache", param: "--apache", desc: " Install Apache.", selected: true },
+	{ name: " --phpfpm", id: "phpfpm", param: "--phpfpm", desc: "Install PHP-FPM.", selected: true },
+	{
+		name: " --multiphp",
+		id: "multiphp",
+		param: "--multiphp",
+		desc: " Install Multi-PHP.",
+		selected: true,
+	},
+	{
+		name: " --vsftpd",
+		id: "vsftpd",
+		param: "--vsftpd",
+		desc: "Install Vsftpd.",
+		selected: true,
+		conflicts: "proftpd",
+	},
+	{
+		name: " --proftpd",
+		id: "proftpd",
+		param: "--proftpd",
+		desc: "Install ProFTPD.",
+		selected: false,
+		conflicts: "vsftpd",
+	},
+	{ name: " --named", id: "named", param: "--named", desc: "Install Bind.", selected: true },
+	{
+		name: " --mysql",
+		id: "mysql",
+		param: "--mysql",
+		desc: "Install MariaDB.",
+		selected: true,
+		conflicts: "mysql8",
+	},
+	{
+		name: " --mysql-classic",
+		id: "mysql8",
+		param: "--mysql-classic",
+		desc: "Install Mysql8.",
+		selected: false,
+		conflicts: "mysql",
+	},
+	{
+		name: " --postgresql",
+		id: "postgresql",
+		param: "--postgresql",
+		desc: "Install PostgreSQL.",
+		selected: false,
+	},
+	{ name: " --exim", id: "exim", param: "--exim", desc: "Install Exim.", selected: true },
+	{
+		name: " --dovecot",
+		id: "dovecot",
+		param: "--dovecot",
+		desc: "Install Dovecot.",
+		selected: true,
+		depends: "exim",
+	},
+	{
+		name: " --sieve",
+		id: "sieve",
+		param: "--sieve",
+		desc: "Enable Dovecot sieve.",
+		selected: false,
+		depends: "dovecot",
+	},
+	{
+		name: " --clamav",
+		id: "clamav",
+		param: "--clamav",
+		desc: "Install ClamAV.",
+		selected: true,
+		depends: "exim",
+	},
+	{
+		name: " --spamassassin",
+		id: "spamassassin",
+		param: "--spamassassin",
+		desc: "Install SpamAssassin.",
+		selected: true,
+		depends: "exim",
+	},
+	{
+		name: " --iptables",
+		id: "iptables",
+		param: "--iptables",
+		desc: "Install Iptables.",
+		selected: true,
+	},
+	{
+		name: " --fail2ban",
+		id: "fail2ban",
+		param: "--fail2ban",
+		desc: "Install Fail2ban.",
+		selected: true,
+	},
+	{ name: " --quota", id: "quota", param: "--quota", desc: "Filesystem Quota.", selected: false },
+	{ name: " --api", id: "api", param: "--api", desc: "Activate API.", selected: true },
+	{
+		name: " --interactive",
+		id: "interactive",
+		param: "--interactive",
+		desc: "Interactive install.",
+		selected: true,
+	},
+	{ name: " --force", id: "force", param: "--force", desc: "Force installation.", selected: false },
+];

+ 6 - 9
docs/_data/team.ts

@@ -20,6 +20,11 @@ export const projectManagers: DefaultTheme.TeamMember[] = [
 		name: "Robert Zollner 🇷🇴",
 		links: [{ icon: "github", link: "https://github.com/Lupul" }],
 	},
+	{
+		avatar:
+			"https://cdn.discordapp.com/avatars/737720562482151485/bac8f56f0a909032efaf60c1aa4047e5.webp",
+		name: "Kristan Kenney 🇨🇦",
+	},
 ];
 
 export const teamMembers: DefaultTheme.TeamMember[] = [
@@ -31,7 +36,7 @@ export const teamMembers: DefaultTheme.TeamMember[] = [
 		orgLink: "https://prosomo.com",
 		links: [
 			{ icon: "github", link: "https://github.com/jakobbouchard" },
-			{ icon: "linkedin", link: "https://linkedin.com/in/bouchardjakob" },
+			{ icon: "linkedin", link: "https://linkedin.com/in/jakobbouchard" },
 			{
 				icon: {
 					svg: '<svg role="img" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><title>Website</title><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" /></svg>',
@@ -67,11 +72,3 @@ export const teamMembers: DefaultTheme.TeamMember[] = [
 		links: [{ icon: "github", link: "https://github.com/AlecRust" }],
 	},
 ];
-
-export const emeriti: DefaultTheme.TeamMember[] = [
-	{
-		avatar:
-			"https://cdn.discordapp.com/avatars/737720562482151485/bac8f56f0a909032efaf60c1aa4047e5.webp",
-		name: "Kristan Kenney 🇨🇦",
-	},
-];

+ 29 - 3
docs/docs/introduction/getting-started.md

@@ -37,18 +37,44 @@ Hestia does not support non-LTS Operating systems. If you install it on, for exa
 
 Interactive installer that will install the default Hestia software configuration.
 
+### Step 1: Download
+
+Download the installation script for the latest release:
+
+```bash
+wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
+```
+
+If the download fails due to an SSL validation error, please be sure you've installed the ca-certificate package on your system - you can do this with the following command:
+
+```bash
+apt-get update && apt-get install ca-certificates
+```
+
+### Step 2: Run
+
+To begin the installation process, simply run the script and follow the on-screen prompts:
+
 ```bash
-wget -qO - https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh | bash
+bash hst-install.sh
 ```
 
+You will receive a welcome email at the address specified during installation (if applicable) and on-screen instructions after the installation is completed to log in and access your server.
+
 ## Custom installation
 
 If you want to customise which software gets installed, or want to run an unattended installation, you will need to run a custom installation.
 
+To view a list of available options, run
+
+```bash
+bash hst-install.sh -h
+```
+
 ### List of installation options
 
 ::: tip
-An easier way to choose your installation options is by using the [Install string generator](https://gabizz.github.io/hestiacp-scriptline-generator/) by [Gabriel Claudiu Maftei](https://github.com/gabizz/).
+An easier way to choose your installation options is by using the [Install string generator](/install.md).
 :::
 
 To choose what software gets installed, you can provide flags to the installation script. You can view the full list of options below.
@@ -86,7 +112,7 @@ To choose what software gets installed, you can provide flags to the installatio
 #### Example
 
 ```bash
-wget -qO - https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh | bash -s -- \
+bash hst-install.sh \
 	--interactive no \
 	--hostname host.domain.tld \
 	--email email@domain.tld \

+ 45 - 2
docs/docs/server-administration/backup-restore.md

@@ -105,16 +105,59 @@ curl https://rclone.org/install.sh | sudo bash
 
 Once the download and installation is complete, run `rclone config` and then `n`. Follow the instruction on the screen, then save when completed.
 
+To verify if it is working run as intended:
+
+```bash
+echo "test" > /tmp/backuptest.txt
+rclone cp /tmp/backuptest.txt $HOST:$FOLDER/backuptest.txt
+rclone lsf $HOST:$FOLDER
+```
+
+And see the file has been uploaded
+
+```bash
+rclone delete $HOST:$FOLDER/backuptest.txt
+```
+
 Once the config has been saved you can setup Hestia with the following command:
 
 ```bash
-v-add-backup-host 'rclone' 'config_name' '' '' 'Bucket or Folder name' ''
+v-add-backup-host 'rclone' 'remote-name' '' '' 'Bucket or Folder name' ''
 ```
 
 ::: tip
-B2 requires you to setup a bucket during the `v-add-backup-host` stage. S3 or R2 storage will work fine during the setup stage.
+Configuration per endpoint might be different! Make sure to test it is working before relying on it. To verify it works run
+
+```bash
+v-backup-user admin
+```
+
 :::
 
+For example:
+
+```bash
+rclone config
+
+Current remotes:
+
+Name Type
+==== ====
+r2 s3
+```
+
+To use the "R2" endpoint use
+
+```bash
+v-add-backup-host 'rclone' 'r2' '' '' 'folder'
+```
+
+For Blackblaze use
+
+```bash
+v-add-backup-host 'rclone' 'b2' '' '' 'hestiacp'
+```
+
 ## How to change default backup folder
 
 For security reasons, symlinks are not allowed. To change the default backup folder, you can do the following:

+ 2 - 8
docs/docs/server-administration/customisation.md

@@ -20,15 +20,9 @@ Create a new theme in `/usr/local/hestia/web/css/theme/custom/my_theme.css`
 
 ## Customising a default theme
 
-Changes to default themes are always overwritten during updates. However, via the `v-add-sys-theme` command, you can create a new theme.
+Changes to default themes are always overwritten during updates. Custom CSS files can be uploaded to `/usr/local/hestia/web/css/custom` in `.css` or `.min.css` format.
 
-If you want to edit the dark theme,
-
-```bash
-cp $HESTIA/install/deb/themes/dark.css /root/my_dark.css
-```
-
-Apply your changes and follow the instructions above.
+Please note that `default.css` base theme is always loaded. Other default and custom themes override the rules in this file.
 
 ## Customising the _Domain not found_ page
 

+ 4 - 4
docs/docs/server-administration/dns.md

@@ -22,13 +22,13 @@ With the release of 1.6.0, we have implemented a new API authentication system.
 If you still want to use the legacy API to authenticate with **admin** username and the password make sure **Enable legacy API** access is set to **yes**.
 :::
 
-### DNS Cluster with the Hestia API (Master <-> Master)
+### DNS Cluster with the Hestia API (Master <-> Master) "Default setup!"
 
 ::: warning
 This method does not support DNSSEC!
 :::
 
-1. Create a new user on the Hestia server that will act as a “Slave”.
+1. Create a new user on the Hestia server that will act as a “Slave”. Make sure it uses the username of "dns-user" or has the role `dns-cluster`
 2. Run the following command to enable the DNS server.
 
 ```bash
@@ -47,7 +47,7 @@ There is no limitation on how to chain DNS servers.
 
 ### DNS Cluster with the Hestia API (Master -> Slave)
 
-1. Create a new user on the Hestia server that will act as a “Slave”.
+1. Create a new user on the Hestia server that will act as a “Slave”. Make sure it uses the username of "dns-user" or has the role `dns-cluster`
 2. In `/usr/local/hestia/conf/hestia.conf`, change `DNS_CLUSTER_SYSTEM='hestia'` to `DNS_CLUSTER_SYSTEM='hestia-zone'`.
 3. On the master server, open `/etc/bind/named.options`, do the following changes, then restart bind9 with `systemctl restart bind9`.
 
@@ -147,7 +147,7 @@ v-add-remote-dns-host slave.yourhost.com 8083 api_key '' '' useraccount
 With the new API system, you can also replace `api_key` with `access_key:secret_key`
 
 ::: info
-Please note that currently, only the user `dns-user` is exempted from syncing to other servers. If you have a DNS cluster with multiple master slaves you might run in issues.
+By default the user `dns-user` or user with the role `dns-cluster` are exempted from syncing to other DNS servers!
 :::
 
 ## I am not able to add a server as DNS host

+ 6 - 0
docs/docs/server-administration/email.md

@@ -37,6 +37,12 @@ If not, you have 2 options:
    - [SMTP2GO](https://www.smtp2go.com)
    - [Sendinblue](https://www.sendinblue.com)
 
+## What is an SMTP relay service and how to set it up
+
+SMTP mail relay is the process of transferring an email from one server to another for delivery. Often email from a server is blocked by de service provider due to fear of spam. Or the IP reputation is so low that all email go straight into the spam box. To prevent such issues a lot of companies offer a SMTP relay that takes care of the delivery part. As they send a lot email via the same ip addresses they have a better reputation.
+
+To setup create a account by the provider you want or use and follow their instruction to update your DNS. When completed you can enter the SMTP user account they provider in the settings under "Global SMTP" or under the "Edit mail domain" -> "SMTP relay"
+
 ## I am unable to receive email
 
 If you are unable to receive emails, make sure you have setup your DNS properly. If you are using Cloudflare, disable the use of the proxy for `mail.domain.tld`.

+ 27 - 0
docs/docs/server-administration/troubleshooting.md

@@ -28,3 +28,30 @@ v-change-user-config-value admin LOGIN_ALLOW_IPS ''
 ## Can I update my cronjobs via `crontab -e`?
 
 No, you cannot. When you update HestiaCP, the crontab will simply get overwritten. The changes will not get saved in backups either.
+
+## After update Apache2 I am not able to restart Apache2 or Nginx
+
+The error message states (98) Address already in use: AG0072: make_sock: could not bind to address 0.0.0.0:80
+
+When a package update sometimes comes with a new config and probally it has been overwritten...
+
+```batch
+Configuration file '/etc/apache2/apache2.conf'
+ ==> Modified (by you or by a script) since installation.
+ ==> Package distributor has shipped an updated version.
+   What would you like to do about it ?  Your options are:
+	Y or I  : install the package maintainer's version
+	N or O  : keep your currently-installed version
+	  D     : show the differences between the versions
+	  Z     : start a shell to examine the situation
+ The default action is to keep your current version.
+*** apache2.conf (Y/I/N/O/D/Z) [default=N] ?
+```
+
+If you see this message **ALWAYS** press "N" or **ENTER** to select the default value!
+
+How ever if you entered Y or I. Then replace the config that can be found in /root/hst_backups/xxxxx/conf/apache2/ folder and copy over apache2.conf and ports.conf to /etc/apache2/ folder
+
+xxxxxx is the date/time the backup is made during the last update of HestiaCP
+
+If you don't have have a backup made you can also copy the config in /usr/local/hestia/install/deb/apache2/apache2.conf to /etc/apache2.conf and also empty /etc/apache2/ports.conf

+ 23 - 0
docs/install.md

@@ -0,0 +1,23 @@
+---
+layout: page
+title: Install
+---
+
+<script setup lang="ts">
+  import InstallPageTitle from "./.vitepress/theme/components/InstallPageTitle.vue";
+  import InstallOptions from "./.vitepress/theme/components/InstallOptions.vue";
+  import InstallOptionsSection from "./.vitepress/theme/components/InstallOptionsSection.vue";
+  import { options } from "./_data/options";
+  import { languages } from "./_data/languages";
+</script>
+
+<InstallPage>
+  <InstallPageTitle>
+	<template #title>Install</template>
+  </InstallPageTitle>
+  <InstallOptionsSection>
+  	<template #list>
+	  <InstallOptions :items="options" :languages="languages"></InstallOptions>
+	</template>
+  </InstallOptionsSection>
+</InstallPage>

BIN
docs/public/webfonts/fa-brands-400.ttf


BIN
docs/public/webfonts/fa-brands-400.woff2


BIN
docs/public/webfonts/fa-solid-900.ttf


BIN
docs/public/webfonts/fa-solid-900.woff2


+ 1 - 10
docs/team.md

@@ -6,7 +6,7 @@ title: The Team
 
 <script setup lang="ts">
   import { VPTeamPage, VPTeamPageTitle, VPTeamPageSection, VPTeamMembers } from "vitepress/theme";
-  import { projectManagers, teamMembers, emeriti } from "./_data/team";
+  import { projectManagers, teamMembers } from "./_data/team";
 </script>
 
 <VPTeamPage>
@@ -28,15 +28,6 @@ title: The Team
       <VPTeamMembers :members="teamMembers" />
     </template>
   </VPTeamPageSection>
-  <VPTeamPageSection>
-    <template #title>Team Emeriti</template>
-    <template #lead>
-      Here we honor some no-longer-active team members who have made valuable contributions in the past.
-    </template>
-    <template #members>
-      <VPTeamMembers :members="emeriti" />
-    </template>
-  </VPTeamPageSection>
   <!-- <VPTeamPageSection>
     <template #title>Contributors ❤️</template>
     <template #members>

+ 12 - 10
func/backup.sh

@@ -124,11 +124,11 @@ ftp_backup() {
 		return "$E_FTP"
 	fi
 
-	# Checking retention
+	# Checking retention (Only include .tar files)
 	if [ -z $BPATH ]; then
-		backup_list=$(ftpc "ls" | awk '{print $9}' | grep "^$user\.")
+		backup_list=$(ftpc "ls" | awk '{print $9}' | grep "^$user\." | grep ".tar")
 	else
-		backup_list=$(ftpc "cd $BPATH" "ls" | awk '{print $9}' | grep "^$user\.")
+		backup_list=$(ftpc "cd $BPATH" "ls" | awk '{print $9}' | grep "^$user\." | grep ".tar")
 	fi
 	backups_count=$(echo "$backup_list" | wc -l)
 	if [ "$backups_count" -ge "$BACKUPS" ]; then
@@ -399,11 +399,11 @@ sftp_backup() {
 		return "$rc"
 	fi
 
-	# Checking retention
+	# Checking retention (Only include .tar files)
 	if [ -z $BPATH ]; then
-		backup_list=$(sftpc "ls -l" | awk '{print $9}' | grep "^$user\.")
+		backup_list=$(sftpc "ls -l" | awk '{print $9}' | grep "^$user\." | grep ".tar")
 	else
-		backup_list=$(sftpc "cd $BPATH" "ls -l" | awk '{print $9}' | grep "^$user\.")
+		backup_list=$(sftpc "cd $BPATH" "ls -l" | awk '{print $9}' | grep "^$user\." | grep ".tar")
 	fi
 	backups_count=$(echo "$backup_list" | wc -l)
 	if [ "$backups_count" -ge "$BACKUPS" ]; then
@@ -510,7 +510,7 @@ b2_delete() {
 rclone_backup() {
 	# Define rclone config
 	source_conf "$HESTIA/conf/rclone.backup.conf"
-	echo -e "$(date "+%F %T") Upload With Rclone: $user.$backup_new_date.tar"
+	echo -e "$(date "+%F %T") Upload With Rclone to $HOST: $user.$backup_new_date.tar"
 	if [ "$localbackup" != 'yes' ]; then
 		cd $tmpdir
 		tar -cf $BACKUP/$user.$backup_new_date.tar .
@@ -518,12 +518,13 @@ rclone_backup() {
 	cd $BACKUP/
 
 	if [ -z "$BPATH" ]; then
-		rclone copy -v $user.$backup_new_date.tar $HOST
+		rclone copy -v $user.$backup_new_date.tar $HOST:$backup
 		if [ "$?" -ne 0 ]; then
 			check_result "$E_CONNECT" "Unable to upload backup"
 		fi
 
-		backup_list=$(rclone lsf $HOST | cut -d' ' -f1 | grep "^$user\.")
+		# Only include *.tar files
+		backup_list=$(rclone lsf $HOST: | cut -d' ' -f1 | grep "^$user\." | grep ".tar")
 		backups_count=$(echo "$backup_list" | wc -l)
 		backups_rm_number=$((backups_count - BACKUPS))
 		if [ "$backups_count" -ge "$BACKUPS" ]; then
@@ -538,7 +539,8 @@ rclone_backup() {
 			check_result "$E_CONNECT" "Unable to upload backup"
 		fi
 
-		backup_list=$(rclone lsf $HOST:$BPATH | cut -d' ' -f1 | grep "^$user\.")
+		# Only include *.tar files
+		backup_list=$(rclone lsf $HOST:$BPATH | cut -d' ' -f1 | grep "^$user\." | grep ".tar")
 		backups_count=$(echo "$backup_list" | wc -l)
 		backups_rm_number=$(($backups_count - $BACKUPS))
 		if [ "$backups_count" -ge "$BACKUPS" ]; then

+ 4 - 1
func/domain.sh

@@ -582,7 +582,10 @@ update_domain_zone() {
 				fi
 			fi
 		fi
-		eval echo -e "\"$fields\"" | sed "s/%quote%/'/g" >> $zn_conf
+
+		if [ "$SUSPENDED" != 'yes' ]; then
+			eval echo -e "\"$fields\"" | sed "s/%quote%/'/g" >> $zn_conf
+		fi
 	done < $USER_DATA/dns/$domain.conf
 }
 

+ 5 - 0
func/main.sh

@@ -169,6 +169,9 @@ check_args() {
 	fi
 }
 
+# Define version check function
+version_ge() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1" -o -n "$1" -a "$1" = "$2"; }
+
 # Subsystem checker
 is_system_enabled() {
 	if [ -z "$1" ] || [ "$1" = no ]; then
@@ -1475,6 +1478,8 @@ format_domain() {
 	if [[ "$domain" =~ ^\. ]]; then
 		domain=$(echo "$domain" | sed -e "s/^[.]*//")
 	fi
+	# Remove white spaces
+	domain=$(echo $domain | sed 's/^[ \t]*//;s/[ \t]*$//')
 }
 
 format_domain_idn() {

+ 1 - 1
func/rebuild.sh

@@ -170,7 +170,7 @@ rebuild_user_conf() {
 		else
 			dns_group='bind'
 		fi
-		chown root:$dns_group $HOMEDIR/$user/conf/dns
+		chown $dns_group:$dns_group $HOMEDIR/$user/conf/dns
 		if [ "$create_user" = "yes" ]; then
 			$BIN/v-rebuild-dns-domains $user $restart
 		fi

+ 1 - 1
func/syshealth.sh

@@ -52,7 +52,7 @@ function syshealth_update_web_config_format() {
 	# WEB DOMAINS
 	# Create array of known keys in configuration file
 	system="web"
-	known_keys="DOMAIN IP IP6 CUSTOM_DOCROOT CUSTOM_PHPROOT FASTCGI_CACHE FASTCGI_DURATION ALIAS TPL SSL SSL_FORCE SSL_HOME LETSENCRYPT FTP_USER FTP_MD5 FTP_PATH BACKEND PROXY PROXY_EXT STATS STATS_USER STATS_CRYPT REDIRECT REDIRECT_CODE AUTH_USER AUTH_HASH SUSPENDED TIME DATE"
+	known_keys="DOMAIN IP IP6 CUSTOM_DOCROOT CUSTOM_PHPROOT FASTCGI_CACHE FASTCGI_DURATION ALIAS TPL SSL SSL_FORCE SSL_HSTS SSL_HOME LETSENCRYPT FTP_USER FTP_MD5 FTP_PATH BACKEND PROXY PROXY_EXT STATS STATS_USER STATS_CRYPT REDIRECT REDIRECT_CODE AUTH_USER AUTH_HASH SUSPENDED TIME DATE"
 	write_kv_config_file
 	unset system
 	unset known_keys

+ 25 - 24
func/upgrade.sh

@@ -14,9 +14,6 @@ source $HESTIA/func/syshealth.sh
 #######                Functions & Initialization             #######
 #####################################################################
 
-# Define version check function
-function version_ge() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1" -o -n "$1" -a "$1" = "$2"; }
-
 add_upgrade_message() {
 	if [ -f "$HESTIA_BACKUP/message.log" ]; then
 		echo -e $1 >> $HESTIA_BACKUP/message.log
@@ -186,13 +183,13 @@ upgrade_send_notification_to_panel() {
 	# Add notification to panel if variable is set to true or is not set
 	if [[ "$new_version" =~ "alpha" ]]; then
 		# Send notifications for development releases
-		$BIN/v-add-user-notification admin 'Development snapshot installed' '<b>Version:</b> '$new_version'<br><b>Code Branch:</b> '$RELEASE_BRANCH'<br><br>Please tell us about any bugs or issues by opening an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> GitHub</a> and feel free to share your feedback on our <a href="https://forum.hestiacp.com" target="_new">discussion forum</a>.<br><br><i class="fas fa-heart icon-red"></i> The Hestia Control Panel development team'
+		$BIN/v-add-user-notification admin 'Development snapshot installed' '<b>Version:</b> '$new_version'<br><b>Code Branch:</b> '$RELEASE_BRANCH'<br><br>Please tell us about any bugs or issues by opening an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> GitHub</a> and feel free to share your feedback on our <a href="https://forum.hestiacp.com" target="_blank">discussion forum</a>.<br><br><i class="fas fa-heart icon-red"></i> The Hestia Control Panel development team'
 	elif [[ "$new_version" =~ "beta" ]]; then
 		# Send feedback notification for beta releases
-		$BIN/v-add-user-notification admin 'Thank you for testing Hestia Control Panel '$new_version'.' '<b>Please share your feedback with our development team through our <a href="https://forum.hestiacp.com" target="_new">discussion forum</a>.<br><br>Found a bug? Report it on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> GitHub</a>!</b><br><br><i class="fas fa-heart icon-red"></i> The Hestia Control Panel development team'
+		$BIN/v-add-user-notification admin 'Thank you for testing Hestia Control Panel '$new_version'.' '<b>Please share your feedback with our development team through our <a href="https://forum.hestiacp.com" target="_blank">discussion forum</a>.<br><br>Found a bug? Report it on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> GitHub</a>!</b><br><br><i class="fas fa-heart icon-red"></i> The Hestia Control Panel development team'
 	else
 		# Send normal upgrade complete notification for stable releases
-		$BIN/v-add-user-notification admin 'Upgrade complete' 'Hestia Control Panel has been updated to <b>v'$new_version'</b>.<br><a href="https://github.com/hestiacp/hestiacp/blob/release/CHANGELOG.md" target="_new">View release notes</a><br><br>Please tell us about any bugs or issues by opening a new issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> 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'
+		$BIN/v-add-user-notification admin 'Upgrade complete' 'Hestia Control Panel has been updated to <b>v'$new_version'</b>.<br><a href="https://github.com/hestiacp/hestiacp/blob/release/CHANGELOG.md" target="_blank">View release notes</a><br><br>Please tell us about any bugs or issues by opening a new issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> 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'
 	fi
 }
 
@@ -551,24 +548,28 @@ upgrade_b2_tool() {
 }
 
 upgrade_cloudflare_ip() {
-	echo "[ * ] Update Cloudflare IP..."
-	# https://github.com/ergin/nginx-cloudflare-real-ip/
-	CLOUDFLARE_FILE_PATH='/etc/nginx/conf.d/cloudflare.inc'
-	echo "#Cloudflare" > $CLOUDFLARE_FILE_PATH
-	echo "" >> $CLOUDFLARE_FILE_PATH
-
-	echo "# - IPv4" >> $CLOUDFLARE_FILE_PATH
-	for i in $(curl -s -L https://www.cloudflare.com/ips-v4); do
-		echo "set_real_ip_from $i;" >> $CLOUDFLARE_FILE_PATH
-	done
-	echo "" >> $CLOUDFLARE_FILE_PATH
-	echo "# - IPv6" >> $CLOUDFLARE_FILE_PATH
-	for i in $(curl -s -L https://www.cloudflare.com/ips-v6); do
-		echo "set_real_ip_from $i;" >> $CLOUDFLARE_FILE_PATH
-	done
-
-	echo "" >> $CLOUDFLARE_FILE_PATH
-	echo "real_ip_header CF-Connecting-IP;" >> $CLOUDFLARE_FILE_PATH
+	if [ "$WEB_SYSTEM" = "nginx" ] || [ "$PROXY_SYSTEM" = "nginx" ]; then
+		cf_ips="$(curl -fsLm2 --retry 1 https://api.cloudflare.com/client/v4/ips)"
+
+		if [ -n "$cf_ips" ] && [ "$(echo "$cf_ips" | jq -r '.success//""')" = "true" ]; then
+			cf_inc="/etc/nginx/conf.d/cloudflare.inc"
+
+			echo "[ * ] Updating Cloudflare IP Ranges for Nginx..."
+			echo "# Cloudflare IP Ranges" > $cf_inc
+			echo "" >> $cf_inc
+			echo "# IPv4" >> $cf_inc
+			for ipv4 in $(echo "$cf_ips" | jq -r '.result.ipv4_cidrs[]//""' | sort); do
+				echo "set_real_ip_from $ipv4;" >> $cf_inc
+			done
+			echo "" >> $cf_inc
+			echo "# IPv6" >> $cf_inc
+			for ipv6 in $(echo "$cf_ips" | jq -r '.result.ipv6_cidrs[]//""' | sort); do
+				echo "set_real_ip_from $ipv6;" >> $cf_inc
+			done
+			echo "" >> $cf_inc
+			echo "real_ip_header CF-Connecting-IP;" >> $cf_inc
+		fi
+	fi
 }
 
 upgrade_phppgadmin() {

+ 1 - 0
install/deb/apache2/apache2.conf

@@ -81,6 +81,7 @@ LogFormat "%{User-agent}i" agent
 LogFormat "%b" bytes
 
 IncludeOptional conf.d/*.conf
+IncludeOptional conf.d/domains/webmail.*.conf
 IncludeOptional conf.d/domains/*.conf
 
 # Include the virtual host configurations:

+ 2 - 2
install/deb/filemanager/install-fm.sh

@@ -29,7 +29,7 @@ COMPOSER_BIN="$HOMEDIR/$user/.composer/composer"
 if [ ! -f "$COMPOSER_BIN" ]; then
 	$BIN/v-add-user-composer "$user"
 	if [ $? -ne 0 ]; then
-		$BIN/v-add-user-notification admin 'Composer installation failed!' '<b>The File Manager will not work without Composer.</b><br><br>Please try running the installer from a shell session:<br>bash $HESTIA/install/deb/filemanager/install-fm.sh<br><br>If this issue continues, please open an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> GitHub</a>.'
+		$BIN/v-add-user-notification admin 'Composer installation failed!' '<b>The File Manager will not work without Composer.</b><br><br>Please try running the installer from a shell session:<br>bash $HESTIA/install/deb/filemanager/install-fm.sh<br><br>If this issue continues, please open an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> GitHub</a>.'
 		fm_error='yes'
 	fi
 fi
@@ -54,7 +54,7 @@ if [ "$fm_error" != "yes" ]; then
 	if [ -f "/usr/bin/php7.3" ]; then
 		COMPOSER_HOME="$HOMEDIR/$user/.config/composer" user_exec /usr/bin/php7.3 $COMPOSER_BIN --quiet --no-dev install
 		if [ $? -ne 0 ]; then
-			$BIN/v-add-user-notification admin 'File Manager installation failed!' 'Please try running the installer from a shell session:<br>bash $HESTIA/install/deb/filemanager/install-fm.sh<br><br>If this issue continues, please open an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_new"><i class="fab fa-github"></i> GitHub</a>.'
+			$BIN/v-add-user-notification admin 'File Manager installation failed!' 'Please try running the installer from a shell session:<br>bash $HESTIA/install/deb/filemanager/install-fm.sh<br><br>If this issue continues, please open an issue report on <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank"><i class="fab fa-github"></i> GitHub</a>.'
 			fm_error="yes"
 		fi
 	else

+ 1 - 2
install/deb/templates/web/apache2/default.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost%<i4 %web_ipv4%:%web_ssl_port%i4>%%<i6 %web_ipv6%:%web_ssl_port%i6>%>
@@ -47,4 +47,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.ssl.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/default.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost%<i4 %web_ipv4%:%web_port%i4>%%<i6 %web_ipv6%:%web_port%i6>%>
@@ -44,4 +44,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/hosting.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost %ip%:%web_ssl_port%>
@@ -53,4 +53,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.ssl.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc*
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/hosting.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost %ip%:%web_port%>
@@ -50,4 +50,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/php-fpm/default.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost%<i4 %web_ipv4%:%web_ssl_port%i4>%%<i6 %web_ipv6%:%web_ssl_port%i6>%>
@@ -39,4 +39,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.ssl.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/php-fpm/default.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost%<i4 %web_ipv4%:%web_port%i4>%%<i6 %web_ipv6%:%web_port%i6>%>
@@ -36,4 +36,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/phpcgi.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost %ip%:%web_ssl_port%>
@@ -42,4 +42,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.ssl.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/phpcgi.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost %ip%:%web_port%>
@@ -38,4 +38,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/phpfcgid.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost %ip%:%web_ssl_port%>
@@ -43,4 +43,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.ssl.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/phpfcgid.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 <VirtualHost %ip%:%web_port%>
@@ -38,4 +38,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/www-data.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 # PHPMyAdmin and phppgadmin require access as www-data instead of user for security reasons
@@ -39,4 +39,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.ssl.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 2
install/deb/templates/web/apache2/www-data.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 # phpMyAdmin and phpPgAdmin require access as www-data instead of user for security reasons
@@ -36,4 +36,3 @@
     IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.conf_*
     IncludeOptional /etc/apache2/conf.d/*.inc
 </VirtualHost>
-

+ 1 - 1
install/deb/templates/web/nginx/caching.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/caching.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 2
install/deb/templates/web/nginx/default.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {
@@ -44,4 +44,3 @@ server {
 
     include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
 }
-

+ 1 - 2
install/deb/templates/web/nginx/default.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {
@@ -37,4 +37,3 @@ server {
 
     include %home%/%user%/conf/web/%domain%/nginx.conf_*;
 }
-

+ 1 - 2
install/deb/templates/web/nginx/hosting.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {
@@ -45,4 +45,3 @@ server {
 
     include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
 }
-

+ 1 - 2
install/deb/templates/web/nginx/hosting.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {
@@ -38,4 +38,3 @@ server {
 
     include %home%/%user%/conf/web/%domain%/nginx.conf_*;
 }
-

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/chevereto.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/chevereto.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/cms_made_simple.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/cms_made_simple.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/codeigniter.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/codeigniter.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 10 - 1
install/deb/templates/web/nginx/php-fpm/craftcms.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {
@@ -43,6 +43,15 @@ server {
             fastcgi_hide_header "Set-Cookie";
         }
 
+		# Craft-specific location handlers to ensure AdminCP requests route through index.php
+		# If you change your `cpTrigger`, change it here as well
+		location ^~ /admin {
+			try_files $uri $uri/ /index.php?$query_string;
+		}
+		location ^~ /cpresources {
+			try_files $uri $uri/ /index.php?$query_string;
+		}
+
         location ~ [^/]\.php(/|$) {
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             try_files $uri =404;

+ 10 - 1
install/deb/templates/web/nginx/php-fpm/craftcms.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {
@@ -38,6 +38,15 @@ server {
             fastcgi_hide_header "Set-Cookie";
         }
 
+		# Craft-specific location handlers to ensure AdminCP requests route through index.php
+		# If you change your `cpTrigger`, change it here as well
+		location ^~ /admin {
+			try_files $uri $uri/ /index.php?$query_string;
+		}
+		location ^~ /cpresources {
+			try_files $uri $uri/ /index.php?$query_string;
+		}
+
         location ~ [^/]\.php(/|$) {
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             try_files $uri =404;

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/datalife_engine.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/datalife_engine.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/default.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/default.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/dokuwiki.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/dokuwiki.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/drupal-composer.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/drupal-composer.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/drupal-social.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/drupal-social.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/drupal.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/drupal.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/flarum.stpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/flarum.tpl

@@ -1,7 +1,7 @@
 #=========================================================================#
 # Default Web Domain Template                                             #
 # DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
-# https://docs.hestiacp.com/admin_docs/web.html#how-do-web-templates-work #
+# https://hestiacp.com/docs/server-administration/web-templates.html      #
 #=========================================================================#
 
 server {

Some files were not shown because too many files changed in this diff