Преглед на файлове

Feature Deb12 Support (#3661)

- Fix spamassassin being renamed to ClamD
- Fix bug in v-update-sys-ip on Proxmox
- Remove check for gpg.hestiacp.com
- Fix interface detection proxmox
- Fix changes ssl generation
- Fix issue with hestia service and clamav
- Enable en_US.UTF-8
- Rename spamassassin to spamd on Deb 12
- Check Exim version instead release from DEB
- Fix: Sieve and untaining exim config
@henri-hulski
- Update repos
- Feature:  add srs to exim config (#3197)
@henri-hulski


Co-authored-by: Henri Hulski <7619824+henri-hulski@users.noreply.github.com>
Jaap Marcus преди 2 години
родител
ревизия
87a0a3eaa2

+ 3 - 0
.prettierignore

@@ -23,6 +23,9 @@
 # Web templates (for now)
 web/templates/
 
+# Patch files
+/install/upgrade/patch/*
+
 # Hestia Nginx.conf
 /src/deb/nginx/nginx.conf
 /src/rpm/nginx/nginx.conf

+ 88 - 86
bin/v-list-sys-config

@@ -26,92 +26,94 @@ source_conf "$HESTIA/conf/hestia.conf"
 # JSON list function
 json_list() {
 	echo '{
-    "config": {
-        "WEB_SYSTEM": "'$WEB_SYSTEM'",
-        "WEB_RGROUPS": "'$WEB_RGROUPS'",
-        "WEB_PORT": "'$WEB_PORT'",
-        "WEB_SSL": "'$WEB_SSL'",
-        "WEB_SSL_PORT": "'$WEB_SSL_PORT'",
-        "WEB_BACKEND": "'$WEB_BACKEND'",
-        "PROXY_SYSTEM": "'$PROXY_SYSTEM'",
-        "PROXY_PORT": "'$PROXY_PORT'",
-        "PROXY_SSL_PORT": "'$PROXY_SSL_PORT'",
-        "FTP_SYSTEM": "'$FTP_SYSTEM'",
-        "MAIL_SYSTEM": "'$MAIL_SYSTEM'",
-        "IMAP_SYSTEM": "'$IMAP_SYSTEM'",
-        "ANTIVIRUS_SYSTEM": "'$ANTIVIRUS_SYSTEM'",
-        "ANTISPAM_SYSTEM": "'$ANTISPAM_SYSTEM'",
-        "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'",
-        "DISK_QUOTA": "'$DISK_QUOTA'",
-        "FIREWALL_SYSTEM": "'$FIREWALL_SYSTEM'",
-        "FIREWALL_EXTENSION": "'$FIREWALL_EXTENSION'",
-        "FILE_MANAGER": "'$FILE_MANAGER'",
-        "REPOSITORY": "'$REPOSITORY'",
-        "VERSION": "'$VERSION'",
-        "RELEASE_BRANCH": "'$RELEASE_BRANCH'",
-        "UPGRADE_SEND_EMAIL": "'$UPGRADE_SEND_EMAIL'",
-        "UPGRADE_SEND_EMAIL_LOG": "'$UPGRADE_SEND_EMAIL_LOG'",
-        "SMTP_RELAY": "'$SMTP_RELAY'",
-        "SMTP_RELAY_HOST": "'$SMTP_RELAY_HOST'",
-        "SMTP_RELAY_PORT": "'$SMTP_RELAY_PORT'",
-        "SMTP_RELAY_USER": "'$SMTP_RELAY_USER'",
-        "DEMO_MODE": "'$DEMO_MODE'",
-        "THEME": "'$THEME'",
-        "LANGUAGE": "'$LANGUAGE'",
-        "BACKUP_GZIP": "'$BACKUP_GZIP'",
-        "BACKUP": "'$BACKUP'",
-        "BACKUP_MODE": "'$BACKUP_MODE'",
-        "WEBMAIL_ALIAS": "'$WEBMAIL_ALIAS'",
-        "WEBMAIL_SYSTEM": "'$WEBMAIL_SYSTEM'",
-        "DB_PMA_ALIAS": "'$DB_PMA_ALIAS'",
-        "DB_PGA_ALIAS": "'$DB_PGA_ALIAS'",
-        "LOGIN_STYLE": "'$LOGIN_STYLE'",
-        "INACTIVE_SESSION_TIMEOUT": "'$INACTIVE_SESSION_TIMEOUT'",
-        "PHPMYADMIN_KEY": "'$PHPMYADMIN_KEY'",
-        "ENFORCE_SUBDOMAIN_OWNERSHIP": "'$ENFORCE_SUBDOMAIN_OWNERSHIP'",
-        "DEBUG_MODE": "'$DEBUG_MODE'",
-        "API": "'$API'",
-        "API_SYSTEM": "'$API_SYSTEM'",
-        "API_ALLOWED_IP": "'$API_ALLOWED_IP'",
-        "UPDATE_AVAILABLE": "'$UPDATE_AVAILABLE'",
-        "PLUGIN_APP_INSTALLER": "'$PLUGIN_APP_INSTALLER'",
-        "PLUGIN_FILE_MANAGER": "'$PLUGIN_FILE_MANAGER'",
-        "POLICY_SYSTEM_ENABLE_BACON": "'$POLICY_SYSTEM_ENABLE_BACON'",
-        "POLICY_SYSTEM_PROTECTED_ADMIN": "'$POLICY_SYSTEM_PROTECTED_ADMIN'",
-        "POLICY_SYSTEM_HIDE_ADMIN": "'$POLICY_SYSTEM_HIDE_ADMIN'",
-        "POLICY_SYSTEM_HIDE_SERVICES": "'$POLICY_SYSTEM_HIDE_SERVICES'",
-        "POLICY_SYSTEM_PASSWORD_RESET": "'$POLICY_SYSTEM_PASSWORD_RESET'",
-        "POLICY_USER_VIEW_SUSPENDED": "'$POLICY_USER_VIEW_SUSPENDED'",
-        "POLICY_USER_EDIT_DETAILS": "'$POLICY_USER_EDIT_DETAILS'",
-        "POLICY_USER_EDIT_WEB_TEMPLATES": "'$POLICY_USER_EDIT_WEB_TEMPLATES'",
-        "POLICY_USER_EDIT_DNS_TEMPLATES": "'$POLICY_USER_EDIT_DNS_TEMPLATES'",
-        "POLICY_USER_DELETE_LOGS": "'$POLICY_USER_DELETE_LOGS'",
-        "POLICY_USER_VIEW_LOGS": "'$POLICY_USER_VIEW_LOGS'",
-        "POLICY_USER_CHANGE_THEME": "'$POLICY_USER_CHANGE_THEME'",
-        "POLICY_CSRF_STRICTNESS": "'$POLICY_CSRF_STRICTNESS'",
-        "USE_SERVER_SMTP": "'$USE_SERVER_SMTP'",
-        "SERVER_SMTP_HOST": "'$SERVER_SMTP_HOST'",
-        "SERVER_SMTP_PORT": "'$SERVER_SMTP_PORT'",
-        "SERVER_SMTP_SECURITY": "'$SERVER_SMTP_SECURITY'",
-        "SERVER_SMTP_USER": "'$SERVER_SMTP_USER'",
-        "SERVER_SMTP_PASSWD": "'$SERVER_SMTP_PASSWD'",
-        "SERVER_SMTP_ADDR": "'$SERVER_SMTP_ADDR'",
-		"DISABLE_IP_CHECK": "'$DISABLE_IP_CHECK'",
-		"FROM_NAME": "'$FROM_NAME'",
-		"FROM_EMAIL": "'$FROM_EMAIL'",
-		"APP_NAME": "'$APP_NAME'",
-		"TITLE": "'$TITLE'",
-		"SUBJECT_EMAIL": "'$SUBJECT_EMAIL'",
-		"HIDE_DOCS": "'$HIDE_DOCS'"
-    }
-    }'
+		"config": {
+			"WEB_SYSTEM": "'$WEB_SYSTEM'",
+    		"WEB_RGROUPS": "'$WEB_RGROUPS'",
+    		"WEB_PORT": "'$WEB_PORT'",
+    		"WEB_SSL": "'$WEB_SSL'",
+    		"WEB_SSL_PORT": "'$WEB_SSL_PORT'",
+    		"WEB_BACKEND": "'$WEB_BACKEND'",
+    		"PROXY_SYSTEM": "'$PROXY_SYSTEM'",
+    		"PROXY_PORT": "'$PROXY_PORT'",
+    		"PROXY_SSL_PORT": "'$PROXY_SSL_PORT'",
+    		"FTP_SYSTEM": "'$FTP_SYSTEM'",
+    		"MAIL_SYSTEM": "'$MAIL_SYSTEM'",
+    		"IMAP_SYSTEM": "'$IMAP_SYSTEM'",
+    		"ANTIVIRUS_SYSTEM": "'$ANTIVIRUS_SYSTEM'",
+    		"ANTISPAM_SYSTEM": "'$ANTISPAM_SYSTEM'",
+    		"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'",
+    		"DISK_QUOTA": "'$DISK_QUOTA'",
+    		"FIREWALL_SYSTEM": "'$FIREWALL_SYSTEM'",
+    		"FIREWALL_EXTENSION": "'$FIREWALL_EXTENSION'",
+    		"FILE_MANAGER": "'$FILE_MANAGER'",
+    		"REPOSITORY": "'$REPOSITORY'",
+    		"VERSION": "'$VERSION'",
+    		"RELEASE_BRANCH": "'$RELEASE_BRANCH'",
+    		"UPGRADE_SEND_EMAIL": "'$UPGRADE_SEND_EMAIL'",
+    		"UPGRADE_SEND_EMAIL_LOG": "'$UPGRADE_SEND_EMAIL_LOG'",
+    		"SMTP_RELAY": "'$SMTP_RELAY'",
+    		"SMTP_RELAY_HOST": "'$SMTP_RELAY_HOST'",
+    		"SMTP_RELAY_PORT": "'$SMTP_RELAY_PORT'",
+    		"SMTP_RELAY_USER": "'$SMTP_RELAY_USER'",
+    		"DEMO_MODE": "'$DEMO_MODE'",
+    		"THEME": "'$THEME'",
+    		"LANGUAGE": "'$LANGUAGE'",
+    		"BACKUP_GZIP": "'$BACKUP_GZIP'",
+    		"BACKUP": "'$BACKUP'",
+    		"BACKUP_MODE": "'$BACKUP_MODE'",
+    		"WEBMAIL_ALIAS": "'$WEBMAIL_ALIAS'",
+    		"WEBMAIL_SYSTEM": "'$WEBMAIL_SYSTEM'",
+    		"DB_PMA_ALIAS": "'$DB_PMA_ALIAS'",
+    		"DB_PGA_ALIAS": "'$DB_PGA_ALIAS'",
+    		"LOGIN_STYLE": "'$LOGIN_STYLE'",
+    		"INACTIVE_SESSION_TIMEOUT": "'$INACTIVE_SESSION_TIMEOUT'",
+    		"PHPMYADMIN_KEY": "'$PHPMYADMIN_KEY'",
+    		"ENFORCE_SUBDOMAIN_OWNERSHIP": "'$ENFORCE_SUBDOMAIN_OWNERSHIP'",
+    		"DEBUG_MODE": "'$DEBUG_MODE'",
+    		"API": "'$API'",
+    		"API_SYSTEM": "'$API_SYSTEM'",
+    		"API_ALLOWED_IP": "'$API_ALLOWED_IP'",
+    		"UPDATE_AVAILABLE": "'$UPDATE_AVAILABLE'",
+    		"PLUGIN_APP_INSTALLER": "'$PLUGIN_APP_INSTALLER'",
+    		"PLUGIN_FILE_MANAGER": "'$PLUGIN_FILE_MANAGER'",
+    		"POLICY_SYSTEM_ENABLE_BACON": "'$POLICY_SYSTEM_ENABLE_BACON'",
+    		"POLICY_SYSTEM_PROTECTED_ADMIN": "'$POLICY_SYSTEM_PROTECTED_ADMIN'",
+    		"POLICY_SYSTEM_HIDE_ADMIN": "'$POLICY_SYSTEM_HIDE_ADMIN'",
+    		"POLICY_SYSTEM_HIDE_SERVICES": "'$POLICY_SYSTEM_HIDE_SERVICES'",
+    		"POLICY_SYSTEM_PASSWORD_RESET": "'$POLICY_SYSTEM_PASSWORD_RESET'",
+    		"POLICY_USER_VIEW_SUSPENDED": "'$POLICY_USER_VIEW_SUSPENDED'",
+    		"POLICY_USER_EDIT_DETAILS": "'$POLICY_USER_EDIT_DETAILS'",
+    		"POLICY_USER_EDIT_WEB_TEMPLATES": "'$POLICY_USER_EDIT_WEB_TEMPLATES'",
+    		"POLICY_USER_EDIT_DNS_TEMPLATES": "'$POLICY_USER_EDIT_DNS_TEMPLATES'",
+    		"POLICY_USER_DELETE_LOGS": "'$POLICY_USER_DELETE_LOGS'",
+    		"POLICY_USER_VIEW_LOGS": "'$POLICY_USER_VIEW_LOGS'",
+    		"POLICY_USER_CHANGE_THEME": "'$POLICY_USER_CHANGE_THEME'",
+    		"POLICY_CSRF_STRICTNESS": "'$POLICY_CSRF_STRICTNESS'",
+			"POLICY_SYNC_SKELETON": "'$POLICY_SYNC_SKELETON'",
+			"POLICY_SYNC_ERROR_DOCUMENTS": "'$POLICY_SYNC_ERROR_DOCUMENTS'",
+    		"USE_SERVER_SMTP": "'$USE_SERVER_SMTP'",
+    		"SERVER_SMTP_HOST": "'$SERVER_SMTP_HOST'",
+    		"SERVER_SMTP_PORT": "'$SERVER_SMTP_PORT'",
+    		"SERVER_SMTP_SECURITY": "'$SERVER_SMTP_SECURITY'",
+    		"SERVER_SMTP_USER": "'$SERVER_SMTP_USER'",
+    		"SERVER_SMTP_PASSWD": "'$SERVER_SMTP_PASSWD'",
+    		"SERVER_SMTP_ADDR": "'$SERVER_SMTP_ADDR'",
+			"DISABLE_IP_CHECK": "'$DISABLE_IP_CHECK'",
+			"FROM_NAME": "'$FROM_NAME'",
+			"FROM_EMAIL": "'$FROM_EMAIL'",
+			"APP_NAME": "'$APP_NAME'",
+			"TITLE": "'$TITLE'",
+			"SUBJECT_EMAIL": "'$SUBJECT_EMAIL'",
+			"HIDE_DOCS": "'$HIDE_DOCS'"
+		}
+	}'
 }
 
 # Shell list

+ 3 - 0
bin/v-list-sys-interfaces

@@ -69,6 +69,9 @@ csv_list() {
 # Defining interface list
 # Detect "physical" NICs only (virtual NICs created by Docker, WireGuard etc. are excluded)
 physical_nics="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" // .linkinfo.info_kind then empty else .ifname end')"
+if [ -z "$physical_nics" ]; then
+	physical_nics="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" then empty else .ifname end')"
+fi
 
 # Listing data
 case $format in

+ 5 - 0
bin/v-update-sys-ip

@@ -38,6 +38,11 @@ check_hestia_demo_mode
 # Detect "physical" NICs only (virtual NICs created by Docker, WireGuard etc. are excluded)
 physical_nics="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" // .linkinfo.info_kind then empty else .ifname end')"
 
+# Proxmox return empty value for $physical_nics.
+if [ -z "$physical_nics" ]; then
+	physical_nics="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" then empty else .ifname end')"
+fi
+
 for nic in $physical_nics; do
 	nic_ipv4s="$(ip -4 -d -j addr show "$nic" | jq -r '.[].addr_info[] | if .scope == "global" then .local else empty end')"
 	if [ -z "$ips" ]; then

+ 1 - 1
docs/docs/contributing/building.md

@@ -41,7 +41,7 @@ Any option can be appended to the installer command. [See the complete list](../
 
 ```bash
 # Only Hestia
-./scr/hst_autocompile.sh --hestia --noinstall --keepbuild '~localsrc'
+./hst_autocompile.sh --hestia --noinstall --keepbuild '~localsrc'
 ```
 
 ```bash

+ 4 - 0
func/main.sh

@@ -1027,6 +1027,10 @@ is_int_format_valid() {
 is_interface_format_valid() {
 	# Detect "physical" NICs only (virtual NICs created by Docker, WireGuard etc. are excluded)
 	nic_names="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" // .linkinfo.info_kind then empty else .ifname, if .altnames then .altnames[] else empty end end')"
+	# Proxmox return empty value for $physical_nics
+	if [ -z "$nic_names" ]; then
+		nic_names="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" then empty else .ifname, if .altnames then .altnames[] else empty end end')"
+	fi
 	if [ -z "$(echo "$nic_names" | grep -x "$1")" ]; then
 		check_result "$E_INVALID" "invalid interface format :: $1"
 	fi

+ 2 - 2
func/syshealth.sh

@@ -339,8 +339,8 @@ function syshealth_repair_system_config() {
 
 	# Enforce subdomain ownership
 	if [[ -z $(check_key_exists 'ENFORCE_SUBDOMAIN_OWNERSHIP') ]]; then
-		echo "[ ! ] Adding missing variable to hestia.conf: ENFORCE_SUBDOMAIN_OWNERSHIP ('no')"
-		$BIN/v-change-sys-config-value "ENFORCE_SUBDOMAIN_OWNERSHIP" "no"
+		echo "[ ! ] Adding missing variable to hestia.conf: ENFORCE_SUBDOMAIN_OWNERSHIP ('yes')"
+		$BIN/v-change-sys-config-value "ENFORCE_SUBDOMAIN_OWNERSHIP" "yes"
 	fi
 
 	if [[ -z $(check_key_exists 'API') ]]; then

+ 513 - 0
install/deb/exim/exim4.conf.4.95.template

@@ -0,0 +1,513 @@
+######################################################################
+#                                                                    #
+#          Exim configuration file for Hestia Control Panel          #
+#                                                                    #
+######################################################################
+
+#SPAMASSASSIN = yes
+#SPAM_SCORE = 50
+#SPAM_REJECT_SCORE = 100
+#CLAMD = yes
+
+smtp_banner = $smtp_active_hostname
+smtp_active_hostname = ${lookup dnsdb{>: defer_never,ptr=$interface_address}{${listextract{1}{$value}}}{$primary_hostname}}
+add_environment = <; PATH=/bin:/usr/bin
+keep_environment =
+disable_ipv6 = true
+
+SRS_SECRET = readfile{/etc/exim4/srs.conf}
+
+smtputf8_advertise_hosts =
+domainlist local_domains = dsearch;/etc/exim4/domains/
+domainlist relay_to_domains = dsearch;/etc/exim4/domains/
+hostlist relay_from_hosts = 127.0.0.1
+hostlist whitelist = net-iplsearch;/etc/exim4/white-blocks.conf
+hostlist spammers = net-iplsearch;/etc/exim4/spam-blocks.conf
+no_local_from_check
+untrusted_set_sender = *
+acl_smtp_connect = acl_check_spammers
+acl_smtp_mail = acl_check_mail
+acl_smtp_rcpt = acl_check_rcpt
+acl_smtp_data = acl_check_data
+acl_smtp_mime = acl_check_mime
+
+.ifdef SPAMASSASSIN
+spamd_address = 127.0.0.1 783
+.endif
+
+.ifdef CLAMD
+av_scanner = clamd: /run/clamav/clamd.ctl
+.endif
+
+log_selector = +tls_sni
+
+tls_advertise_hosts = *
+
+# We test that $tls_in_sni is a valid domain, by an arbitrary email address foo@domain.tld .
+# Then, we extract the domain with a function that would fail if the email address is invalid.
+# If the certificate exists, we will use it, otherwise the default certificate in /etc/ssl will be used.
+tls_certificate = \
+        ${if and {\
+                     { eq {${domain:foo@$tls_in_sni}} {$tls_in_sni}}\
+                     { exists{/usr/local/hestia/ssl/mail/$tls_in_sni.crt} }\
+                 }\
+                 {/usr/local/hestia/ssl/mail/$tls_in_sni.crt}\
+                 {/usr/local/hestia/ssl/certificate.crt}\
+         }
+
+tls_privatekey = \
+        ${if and {\
+                     { eq {${domain:foo@$tls_in_sni}} {$tls_in_sni}}\
+                     { exists{/usr/local/hestia/ssl/mail/$tls_in_sni.key} }\
+                 }\
+                 {/usr/local/hestia/ssl/mail/$tls_in_sni.key}\
+                 {/usr/local/hestia/ssl/certificate.key}\
+         }
+
+daemon_smtp_ports = 25 : 465 : 587
+tls_on_connect_ports = 465
+tls_require_ciphers = PERFORMANCE:-RSA:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3:%SERVER_PRECEDENCE
+never_users = root
+host_lookup = *
+rfc1413_hosts = *
+rfc1413_query_timeout = 0s
+ignore_bounce_errors_after = 2d
+timeout_frozen_after = 7d
+
+DKIM_DOMAIN = ${lc:${domain:$h_from:}}
+DKIM_FILE = /etc/exim4/domains/${lookup{${lc:${domain:$h_from:}}}dsearch{/etc/exim4/domains/}}/dkim.pem
+DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
+
+OUTGOING_IP = /etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/ip
+
+SMTP_RELAY_FILE = ${if exists{/etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/smtp_relay.conf}{/etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/smtp_relay.conf}{/etc/exim4/smtp_relay.conf}}
+SMTP_RELAY_HOST = ${lookup{host}lsearch{SMTP_RELAY_FILE}}
+SMTP_RELAY_PORT = ${lookup{port}lsearch{SMTP_RELAY_FILE}}
+SMTP_RELAY_USER = ${lookup{user}lsearch{SMTP_RELAY_FILE}}
+SMTP_RELAY_PASS = ${lookup{pass}lsearch{SMTP_RELAY_FILE}}
+
+# Custom Filter
+system_filter = /etc/exim4/system.filter
+system_filter_user = Debian-exim
+
+######################################################################
+#                       ACL CONFIGURATION                            #
+#         Specifies access control lists for incoming SMTP mail      #
+######################################################################
+
+acl_not_smtp = acl_not_smtp
+
+begin acl
+
+# Limit per user for PHP scripts
+acl_not_smtp:
+  deny    message       = Website of user $authenticated_id is sending too many emails - rate overlimit = $sender_rate / $sender_rate_period
+  ratelimit             = 200 / 1h / $authenticated_id
+
+  warn    ratelimit     = 100 / 1h / strict / $authenticated_id
+  log_message           = Sender rate [limitlog]: log / account / $authenticated_id / $sender_rate / $sender_rate_period
+
+  accept
+
+acl_check_spammers:
+  accept  hosts         = +whitelist
+
+  drop    message       = Your host in blacklist on this server.
+          log_message   = Host in blacklist
+          hosts         = +spammers
+
+  accept
+
+
+acl_check_mail:
+	deny    condition     = ${if eq{$sender_helo_name}{}}
+			message       = HELO required before MAIL
+
+	drop    !authenticated = *
+			message       =  Helo name contains an IP address (HELO was $sender_helo_name) and not is valid
+			condition     = ${if match{$sender_helo_name}{\N((\d{1,3}[.-]\d{1,3}[.-]\d{1,3}[.-]\d{1,3})|([0-9a-f]{8})|([0-9A-F]{8}))\N}{yes}{no}}
+			condition     = ${if match {${lookup dnsdb{>: defer_never,ptr=$sender_host_address}}\}{$sender_helo_name}{no}{yes}}
+			delay         = 45s
+
+	drop    !authenticated = *
+			condition     = ${if isip{$sender_helo_name}}
+			message       = Access denied - Invalid HELO name (See RFC2821 4.1.3)
+
+	drop    !authenticated = *
+			condition    = ${if eq{[$interface_address]}{$sender_helo_name}}
+			message       = $interface_address is _my_ address
+
+	accept
+
+
+acl_check_rcpt:
+  accept  hosts         = :
+
+# Limit per email account for SMTP auhenticated users
+  deny    message       = Email account $authenticated_id is sending too many emails - rate overlimit = $sender_rate / $sender_rate_period
+          set acl_c_msg_limit  = ${if exists{/etc/exim4/domains/${lookup{${domain:$authenticated_id}}dsearch{/etc/exim4/domains/}}/limits}{${lookup {$authenticated_id} lsearch{/etc/exim4/domains/${lookup{${domain:$authenticated_id}}dsearch{/etc/exim4/domains/}}/limits}{$value}{${readfile{/etc/exim4/limit.conf}}}}}{${readfile{/etc/exim4/limit.conf}}} }
+          ratelimit     = $acl_c_msg_limit / 1h / strict/ $authenticated_id
+
+  warn    ratelimit     = ${eval:$acl_c_msg_limit / 2} / 1h / strict / $authenticated_id
+  log_message           = Sender rate [limitlog]: log / email / $authenticated_id / $sender_rate / $sender_rate_period
+
+  deny    message       = Restricted characters in address
+          domains       = +local_domains
+          local_parts   = ^[.] : ^.*[@%!/|]
+
+  deny    message       = Restricted characters in address
+          domains       = !+local_domains
+          local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
+
+  require verify        = sender
+
+  accept  hosts         = +relay_from_hosts
+          control       = submission
+
+  accept  authenticated = *
+          control       = submission/domain=
+
+  deny    message       = Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
+          hosts         = !+whitelist
+          dnslists      = ${readfile {/etc/exim4/dnsbl.conf}{:}}
+
+  require message       = relay not permitted
+          domains       = +local_domains : +relay_to_domains
+
+  deny    message       = smtp auth required
+         sender_domains = +local_domains
+         !authenticated = *
+
+  require verify        = recipient
+
+.ifdef CLAMD
+  warn    set acl_m0    = no
+
+  warn    condition     = ${if exists {/etc/exim4/domains/$domain/antivirus}{yes}{no}}
+          set acl_m0    = yes
+.endif
+
+.ifdef SPAMASSASSIN
+ warn    set acl_m1    = no
+         set acl_m3    = no
+ warn    condition     = ${if exists {/etc/exim4/domains/$domain/antispam}{yes}{no}}
+         set acl_m1    = yes
+ warn    condition     = ${if exists {/etc/exim4/domains/$domain/reject_spam}{yes}{no}}
+         set acl_m3    = yes
+.endif
+
+  accept
+
+
+acl_check_data:
+.ifdef CLAMD
+  deny   message        = Message contains a virus ($malware_name) and has been rejected
+         malware        = */defer_ok
+         condition      = ${if eq{$acl_m0}{yes}{yes}{no}}
+.endif
+
+.ifdef SPAMASSASSIN
+ warn   !authenticated = *
+        hosts          = !+relay_from_hosts
+        condition      = ${if < {$message_size}{1024K}}
+        condition      = ${if eq{$acl_m1}{yes}{yes}{no}}
+        spam           = debian-spamd:true/defer_ok
+        add_header     = X-Spam-Score: $spam_score_int
+        add_header     = X-Spam-Bar: $spam_bar
+        add_header     = X-Spam-Report: $spam_report
+        set acl_m2     = $spam_score_int
+
+ warn   condition      = ${if !eq{$acl_m2}{} {yes}{no}}
+        condition      = ${if >{$acl_m2}{SPAM_SCORE} {yes}{no}}
+        add_header     = X-Spam-Status: Yes
+        message        = SpamAssassin detected spam (from $sender_address to $recipients).
+
+  # Deny spam at high score if spam score > SPAM_REJECT_SCORE and delete_spam is enabled
+  deny   message        = This message scored $spam_score spam points
+         spam           = debian-spamd:true
+         condition      = ${if eq{$acl_m3}{yes}{yes}{no}}
+         condition      = ${if >{$spam_score_int}{SPAM_REJECT_SCORE}{1}{0}}
+.endif
+
+  accept
+
+
+acl_check_mime:
+  deny   message        = Blacklisted file extension detected
+         condition      = ${if match {${lc:$mime_filename}}{\N(\.ace|\.ade|\.adp|\.app|\.arj|\.asp|\.aspx|\.asx|\.bas|\.bat|\.cab|\.cer|\.chm|\.cmd|\.cnt|\.com|\.cpl|\.crt|\.csh|\.der|\.diagcab|\.dll|\.efi|\.exe|\.fla|\.fon|\.fxp|\.gadget|\.grp|\.hlp|\.hpj|\.hta|\.htc|\.img|\.inf|\.ins|\.iso|\.isp|\.its|\.jar|\.jnlp|\.js|\.jse|\.ksh|\.lib|\.lnk|\.mad|\.maf|\.mag|\.mam|\.maq|\.mar|\.mas|\.mat|\.mau|\.mav|\.maw|\.mcf|\.mda|\.mdb|\.mde|\.mdt|\.mdw|\.mdz|\.msc|\.msh|\.msh1|\.msh1xml|\.msh2|\.msh2xml|\.mshxml|\.msi|\.msp|\.mst|\.msu|\.ops|\.osd|\.pcd|\.pif|\.pl|\.plg|\.prf|\.prg|\.printerexport|\.ps1|\.ps1xml|\.ps2|\.ps2xml|\.psc1|\.psc2|\.psd1|\.psdm1|\.pst|\.py|\.pyc|\.pyo|\.pyw|\.pyz|\.pyzw|\.reg|\.scf|\.scr|\.sct|\.sfx|\.shb|\.shs|\.swf|\.sys|\.theme|\.tmp|\.ttf|\.url|\.vb|\.vba|\.vbe|\.vbp|\.vbs|\.vhd|\.vhdx|\.vsmacros|\.vsw|\.vxd|\.webpnp|\.website|\.wim|\.ws|\.wsc|\.wsf|\.wsh|\.xbap|\.xll|\.xnk)$\N}{1}{0}}
+
+  accept
+
+
+
+######################################################################
+#                   AUTHENTICATION CONFIGURATION                     #
+######################################################################
+begin authenticators
+
+smtp_relay_login:
+  driver = plaintext
+  public_name = LOGIN
+  hide client_send = : SMTP_RELAY_USER : SMTP_RELAY_PASS
+
+dovecot_plain:
+  driver = dovecot
+  public_name = PLAIN
+  server_socket = /run/dovecot/auth-client
+  server_set_id = $auth1
+
+dovecot_login:
+  driver = dovecot
+  public_name = LOGIN
+  server_socket = /run/dovecot/auth-client
+  server_set_id = $auth1
+
+
+
+######################################################################
+#                      ROUTERS CONFIGURATION                         #
+#               Specifies how addresses are handled                  #
+######################################################################
+begin routers
+
+send_via_unauthenticated_smtp_relay:
+  driver = manualroute
+  address_data = SMTP_RELAY_HOST:SMTP_RELAY_PORT
+  domains = !+local_domains
+  require_files = SMTP_RELAY_FILE
+  condition = ${if eq{SMTP_RELAY_USER}{}}
+  transport = remote_smtp
+  route_list = * ${extract{1}{:}{$address_data}}::${extract{2}{:}{$address_data}}
+  no_more
+  no_verify
+
+send_via_smtp_relay:
+  driver = manualroute
+  address_data = SMTP_RELAY_HOST:SMTP_RELAY_PORT
+  domains = !+local_domains
+  require_files = SMTP_RELAY_FILE
+  transport = smtp_relay_smtp
+  route_list = * ${extract{1}{:}{$address_data}}::${extract{2}{:}{$address_data}}
+  no_more
+  no_verify
+
+dnslookup:
+  driver = dnslookup
+  # if outbound, and forwarding has been done, use an alternate transport
+  domains = ! +local_domains
+  transport = ${if eq {$local_part@$domain} \
+                      {$original_local_part@$original_domain} \
+                      {remote_smtp} {remote_forwarded_smtp}}
+  no_more
+
+userforward:
+  driver = redirect
+  check_local_user
+  file = $home/.forward
+  require_files = ${local_part}:+${home}/.forward
+  domains = +local_domains
+  allow_filter
+  no_verify
+  no_expn
+  check_ancestor
+  file_transport = address_file
+  pipe_transport = address_pipe
+  reply_transport = address_reply
+
+procmail:
+  driver = accept
+  check_local_user
+  require_files = ${local_part}:+${home}/.procmailrc:/usr/bin/procmail
+  transport = procmail
+  no_verify
+
+autoreplay:
+  driver = accept
+  require_files = /etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${local_part}.msg
+  condition = ${if exists{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${local_part}.msg}{yes}{no}}
+  retry_use_local_part
+  transport = userautoreply
+  unseen
+
+inbound_srs:
+    driver = redirect
+    senders = :
+    domains = +local_domains
+    # detect inbound bounces which are SRS'd, and decode them
+    condition = ${if inbound_srs {$local_part} {SRS_SECRET}}
+    data = $srs_recipient
+
+inbound_srs_failure:
+    driver = redirect
+    senders = :
+    domains = +local_domains
+    # detect inbound bounces which look SRS'd but are invalid
+    condition = ${if inbound_srs {$local_part} {}}
+    allow_fail
+    data = :fail: Invalid SRS recipient address
+
+aliases:
+  driver = redirect
+  headers_add = X-redirected: yes
+  data = ${extract{1}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}}}}
+  require_files = /etc/exim4/domains/$domain/aliases
+  redirect_router = dnslookup
+  pipe_transport = address_pipe
+  unseen
+
+localuser_fwd_only:
+  driver = accept
+  transport = devnull
+  condition = ${if exists{/etc/exim4/domains/$domain/fwd_only}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/fwd_only}{true}{false}}}}
+
+localuser_spam:
+  driver = accept
+  transport = local_spam_delivery
+  condition = ${if eq {${if match{$h_X-Spam-Status:}{\N^Yes\N}{yes}{no}}} {${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}{yes}{no_such_user}}}}
+
+localuser:
+  driver = accept
+  transport = local_delivery
+  condition = ${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}{true}{false}}
+
+catchall:
+  driver = redirect
+  headers_add = X-redirected: yes
+  require_files = /etc/exim4/domains/$domain/aliases
+  data = ${extract{1}{:}{${lookup{*@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}}}}
+  file_transport = local_delivery
+  redirect_router = dnslookup
+
+terminate_alias:
+  driver = accept
+  transport = devnull
+  condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{true}{false}}
+
+
+
+######################################################################
+#                      TRANSPORTS CONFIGURATION                      #
+######################################################################
+begin transports
+
+smtp_relay_smtp:
+  driver = smtp
+  hosts_require_auth = $host_address
+  hosts_require_tls = $host_address
+
+remote_smtp:
+  driver = smtp
+  helo_data = ${lookup dnsdb{>: defer_never,ptr=$sending_ip_address}{${listextract{1}{$value}}}{$primary_hostname}}
+  dkim_domain = DKIM_DOMAIN
+  dkim_selector = mail
+  dkim_private_key = DKIM_PRIVATE_KEY
+  dkim_canon = relaxed
+  dkim_strict = 0
+  hosts_try_fastopen = !*.l.google.com
+  interface = ${if exists{OUTGOING_IP}{${readfile{OUTGOING_IP}}}}
+
+remote_forwarded_smtp:
+  driver = smtp
+  helo_data = ${lookup dnsdb{>: defer_never,ptr=$sending_ip_address}{${listextract{1}{$value}}}{$primary_hostname}}
+  dkim_domain = DKIM_DOMAIN
+  dkim_selector = mail
+  dkim_private_key = DKIM_PRIVATE_KEY
+  dkim_canon = relaxed
+  dkim_strict = 0
+  hosts_try_fastopen = !*.l.google.com
+  interface = ${if exists{OUTGOING_IP}{${readfile{OUTGOING_IP}}}}
+  # modify the envelope from, for mails that we forward
+  max_rcpt = 1
+  return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
+
+procmail:
+  driver = pipe
+  command = "/usr/bin/procmail -d $local_part"
+  return_path_add
+  delivery_date_add
+  envelope_to_add
+  user = $local_part
+  initgroups
+  return_output
+
+local_delivery:
+  driver = appendfile
+  maildir_format
+  maildir_use_size_file
+  user = ${extract{2}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}
+  group = mail
+  create_directory
+  directory_mode = 770
+  mode = 660
+  use_lockfile = no
+  delivery_date_add
+  envelope_to_add
+  return_path_add
+  directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}"
+  quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}M
+  quota_warn_threshold = 75%
+
+local_spam_delivery:
+  driver = appendfile
+  maildir_format
+  maildir_use_size_file
+  user = ${extract{2}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}
+  group = mail
+  create_directory
+  directory_mode = 770
+  mode = 660
+  use_lockfile = no
+  delivery_date_add
+  envelope_to_add
+  return_path_add
+  directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}/.Spam"
+  quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}M
+  quota_directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}"
+  quota_warn_threshold = 75%
+
+address_pipe:
+  driver = pipe
+  return_output
+
+address_file:
+  driver = appendfile
+  delivery_date_add
+  envelope_to_add
+  return_path_add
+
+address_reply:
+  driver = autoreply
+
+userautoreply:
+  driver = autoreply
+  file = /etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${extract{1}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/accounts}}}}.msg
+  from = "${extract{1}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/accounts}}}}@${lookup{$domain}dsearch{/etc/exim4/domains/}}"
+  headers = Content-Type: text/plain; charset=utf-8;\nContent-Transfer-Encoding: 8bit
+  subject = "${if def:h_Subject: {Autoreply: \"${rfc2047:$h_Subject:}\"} {Autoreply Message}}"
+  to = "${sender_address}"
+
+devnull:
+  driver = appendfile
+  file = /dev/null
+
+
+
+######################################################################
+#                      RETRY CONFIGURATION                           #
+######################################################################
+begin retry
+
+# Address or Domain    Error       Retries
+# -----------------    -----       -------
+*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h
+
+
+
+######################################################################
+#                      REWRITE CONFIGURATION                         #
+######################################################################
+begin rewrite
+
+
+
+######################################################################

+ 1 - 0
install/deb/exim/srs.conf

@@ -0,0 +1 @@
+TOBEREPLACED

+ 38 - 0
install/deb/exim/text.patch

@@ -0,0 +1,38 @@
+17a18,19
+> SRS_SECRET = readfile{/etc/exim4/srs.conf}
+>
+326a332,348
+> inbound_srs:
+>     driver = redirect
+>     senders = :
+>     domains = +local_domains
+>     # detect inbound bounces which are SRS'd, and decode them
+>     condition = ${if inbound_srs {$local_part} {SRS_SECRET}}
+>     data = $srs_recipient
+>
+> inbound_srs_failure:
+>     driver = redirect
+>     senders = :
+>     domains = +local_domains
+>     # detect inbound bounces which look SRS'd but are invalid
+>     condition = ${if inbound_srs {$local_part} {}}
+>     allow_fail
+>     data = :fail: Invalid SRS recipient address
+>
+358d379
+<   condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{false}{true}}
+387a409,422
+> remote_forwarded_smtp:
+>   driver = smtp
+>   helo_data = ${lookup dnsdb{>: defer_never,ptr=$sending_ip_address}{${listextract{1}{$value}}}{$primary_hostname}}
+>   dkim_domain = DKIM_DOMAIN
+>   dkim_selector = mail
+>   dkim_private_key = DKIM_PRIVATE_KEY
+>   dkim_canon = relaxed
+>   dkim_strict = 0
+>   hosts_try_fastopen = !*.l.google.com
+>   interface = ${if exists{OUTGOING_IP}{${readfile{OUTGOING_IP}}}}
+>   # modify the envelope from, for mails that we forward
+>   max_rcpt = 1
+>   return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
+>

+ 84 - 34
install/hst-install-debian.sh

@@ -15,8 +15,8 @@
 #----------------------------------------------------------#
 export PATH=$PATH:/sbin
 export DEBIAN_FRONTEND=noninteractive
-RHOST='apt.hestiacp.com'
-GPG='gpg.hestiacp.com'
+# For testing
+RHOST='-apt.hestiacp.com'
 VERSION='debian'
 HESTIA='/usr/local/hestia'
 LOG="/root/hst_install_backups/hst_install-$(date +%d%m%Y%H%M).log"
@@ -35,7 +35,8 @@ VERBOSE='no'
 HESTIA_INSTALL_VER='1.8.0~alpha'
 # Dependencies
 multiphp_v=("5.6" "7.0" "7.1" "7.2" "7.3" "7.4" "8.0" "8.1" "8.2")
-fpm_v="8.1"
+#deb.sury not yet ready
+fpm_v="8.2"
 mariadb_v="10.11"
 
 # Defining software pack for all distros
@@ -47,7 +48,7 @@ software="acl apache2 apache2-suexec-custom apache2-suexec-pristine apache2-util
   php$fpm_v php$fpm_v-apcu php$fpm_v-bz2 php$fpm_v-cgi php$fpm_v-cli php$fpm_v-common php$fpm_v-curl php$fpm_v-gd
   php$fpm_v-imagick php$fpm_v-imap php$fpm_v-intl php$fpm_v-ldap php$fpm_v-mbstring php$fpm_v-mysql php$fpm_v-opcache
   php$fpm_v-pgsql php$fpm_v-pspell php$fpm_v-readline php$fpm_v-xml php$fpm_v-zip postgresql postgresql-contrib
-  proftpd-basic quota rrdtool rsyslog spamassassin sudo sysstat unrar-free unzip util-linux vim-common vsftpd whois zip zstd"
+  proftpd-basic quota rrdtool rsyslog spamassassin sudo sysstat unrar-free unzip util-linux vim-common vsftpd xxd whois zip zstd"
 
 installer_dependencies="apt-transport-https ca-certificates curl dirmngr gnupg openssl wget"
 
@@ -186,6 +187,8 @@ validate_email() {
 	fi
 }
 
+version_ge() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1" -o -n "$1" -a "$1" = "$2"; }
+
 #----------------------------------------------------------#
 #                    Verifications                         #
 #----------------------------------------------------------#
@@ -376,7 +379,7 @@ else
 fi
 
 # Check repository availability
-wget --quiet "https://$GPG/deb_signing.key" -O /dev/null
+wget --quiet "https://$RHOST" -O /dev/null
 check_result $? "Unable to connect to the Hestia APT repository"
 
 # Check installed packages
@@ -715,16 +718,28 @@ curl -s https://packages.sury.org/php/apt.gpg | gpg --dearmor | tee /usr/share/k
 
 # Installing sury Apache2 repo
 if [ "$apache" = 'yes' ]; then
-	echo "[ * ] Apache2"
-	echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/apache2-keyring.gpg] https://packages.sury.org/apache2/ $codename main" > $apt/apache2.list
-	curl -s https://packages.sury.org/apache2/apt.gpg | gpg --dearmor | tee /usr/share/keyrings/apache2-keyring.gpg > /dev/null 2>&1
+	if [ "$release" != '12' ]; then
+		echo "[ * ] Apache2"
+		echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/apache2-keyring.gpg] https://packages.sury.org/apache2/ $codename main" > $apt/apache2.list
+		curl -s https://packages.sury.org/apache2/apt.gpg | gpg --dearmor | tee /usr/share/keyrings/apache2-keyring.gpg > /dev/null 2>&1
+	else
+		echo "[ * ] Apache2"
+		echo "#deb [arch=$ARCH signed-by=/usr/share/keyrings/apache2-keyring.gpg] https://packages.sury.org/apache2/ $codename main" > $apt/apache2.list
+		curl -s https://packages.sury.org/apache2/apt.gpg | gpg --dearmor | tee /usr/share/keyrings/apache2-keyring.gpg > /dev/null 2>&1
+	fi
 fi
 
 # Installing MariaDB repo
 if [ "$mysql" = 'yes' ]; then
-	echo "[ * ] MariaDB"
-	echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/mariadb-keyring.gpg] https://dlm.mariadb.com/repo/mariadb-server/$mariadb_v/repo/$VERSION $codename main" > $apt/mariadb.list
-	curl -s https://mariadb.org/mariadb_release_signing_key.asc | gpg --dearmor | tee /usr/share/keyrings/mariadb-keyring.gpg > /dev/null 2>&1
+	if [ "$release" != '12' ]; then
+		echo "[ * ] MariaDB"
+		echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/mariadb-keyring.gpg] https://dlm.mariadb.com/repo/mariadb-server/$mariadb_v/repo/$VERSION $codename main" > $apt/mariadb.list
+		curl -s https://mariadb.org/mariadb_release_signing_key.asc | gpg --dearmor | tee /usr/share/keyrings/mariadb-keyring.gpg > /dev/null 2>&1
+	else
+		echo "[ * ] MariaDB"
+		echo "#deb [arch=$ARCH signed-by=/usr/share/keyrings/mariadb-keyring.gpg] https://dlm.mariadb.com/repo/mariadb-server/$mariadb_v/repo/$VERSION $codename main" > $apt/mariadb.list
+		curl -s https://mariadb.org/mariadb_release_signing_key.asc | gpg --dearmor | tee /usr/share/keyrings/mariadb-keyring.gpg > /dev/null 2>&1
+	fi
 fi
 
 # Installing Mysql8 repo
@@ -951,6 +966,10 @@ fi
 #                     Install packages                     #
 #----------------------------------------------------------#
 
+# Enable en_US.UTF-8
+sed -i "s/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g" /etc/locale.gen
+locale-gen > /dev/null 2>&1
+
 # Disabling daemon autostart on apt-get install
 echo -e '#!/bin/sh\nexit 101' > /usr/sbin/policy-rc.d
 chmod a+x /usr/sbin/policy-rc.d
@@ -1054,10 +1073,11 @@ if [ -z "$(grep ^/usr/sbin/nologin /etc/shells)" ]; then
 fi
 
 # Configuring NTP
-sed -i 's/#NTP=/NTP=pool.ntp.org/' /etc/systemd/timesyncd.conf
-systemctl enable systemd-timesyncd
-systemctl start systemd-timesyncd
-
+if [ ! -f "/etc/default/ntpsec-ntpdate " ]; then
+	sed -i 's/#NTP=/NTP=pool.ntp.org/' /etc/systemd/timesyncd.conf
+	systemctl enable systemd-timesyncd
+	systemctl start systemd-timesyncd
+fi
 # Restrict access to /proc fs
 # - Prevent unpriv users from seeing each other running processes
 mount -o remount,defaults,hidepid=2 /proc > /dev/null 2>&1
@@ -1179,7 +1199,11 @@ if [ "$exim" = 'yes' ]; then
 		write_config_value "ANTIVIRUS_SYSTEM" "clamav-daemon"
 	fi
 	if [ "$spamd" = 'yes' ]; then
-		write_config_value "ANTISPAM_SYSTEM" "spamassassin"
+		if [ "$release" = '10' ] || [ "$release" = '11' ]; then
+			write_config_value "ANTISPAM_SYSTEM" "spamassassin"
+		else
+			write_config_value "ANTISPAM_SYSTEM" "spamd"
+		fi
 	fi
 	if [ "$dovecot" = 'yes' ]; then
 		write_config_value "IMAP_SYSTEM" "dovecot"
@@ -1285,10 +1309,14 @@ echo "[ * ] Generating default self-signed SSL certificate..."
 $HESTIA/bin/v-generate-ssl-cert $(hostname) '' 'US' 'California' \
 	'San Francisco' 'Hestia Control Panel' 'IT' > /tmp/hst.pem
 
-# Parsing certificate file
 crt_end=$(grep -n "END CERTIFICATE-" /tmp/hst.pem | cut -f 1 -d:)
-key_start=$(grep -n "BEGIN RSA" /tmp/hst.pem | cut -f 1 -d:)
-key_end=$(grep -n "END RSA" /tmp/hst.pem | cut -f 1 -d:)
+if [ "$release" = "12" ]; then
+	key_start=$(grep -n "BEGIN PRIVATE KEY" /tmp/hst.pem | cut -f 1 -d:)
+	key_end=$(grep -n "END PRIVATE KEY" /tmp/hst.pem | cut -f 1 -d:)
+else
+	key_start=$(grep -n "BEGIN RSA" /tmp/hst.pem | cut -f 1 -d:)
+	key_end=$(grep -n "END RSA" /tmp/hst.pem | cut -f 1 -d:)
+fi
 
 # Adding SSL certificate
 echo "[ * ] Adding SSL certificate to Hestia Control Panel..."
@@ -1328,8 +1356,6 @@ $HESTIA/bin/v-change-user-role admin admin
 $HESTIA/bin/v-change-user-language admin $lang
 $HESTIA/bin/v-change-sys-config-value 'POLICY_SYSTEM_PROTECTED_ADMIN' 'yes'
 
-locale-gen "en_US.utf8" > /dev/null 2>&1
-
 #----------------------------------------------------------#
 #                     Configure Nginx                      #
 #----------------------------------------------------------#
@@ -1740,10 +1766,15 @@ if [ "$exim" = 'yes' ]; then
 	echo "[ * ] Configuring Exim mail server..."
 	gpasswd -a Debian-exim mail > /dev/null 2>&1
 	exim_version=$(exim4 --version | head -1 | awk '{print $3}' | cut -f -2 -d .)
-	if [ "$exim_version" = "4.94" ]; then
-		cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.4.94.template /etc/exim4/exim4.conf.template
+	# if Exim version > 4.9.4 or greater!
+	if ! version_ge "4.9.5" "$exim_version"; then
+		cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.4.95.template /etc/exim4/exim4.conf.template
 	else
-		cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.template /etc/exim4/
+		if ! version_ge "4.9.3" "$exim_version"; then
+			cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.4.94.template /etc/exim4/exim4.conf.template
+		else
+			cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.template /etc/exim4/
+		fi
 	fi
 	cp -f $HESTIA_INSTALL_DIR/exim/dnsbl.conf /etc/exim4/
 	cp -f $HESTIA_INSTALL_DIR/exim/spam-blocks.conf /etc/exim4/
@@ -1762,7 +1793,12 @@ if [ "$exim" = 'yes' ]; then
 		sed -i "/^smtputf8_advertise_hosts =/d" /etc/exim4/exim4.conf.template
 	fi
 
+	# Generate SRS KEY If not support just created it will get ignored anyway
+	srs=$(gen_pass)
+	echo $srs > /etc/exim4/srs.conf
+	chmod 640 /etc/exim4/srs.conf
 	chmod 640 /etc/exim4/exim4.conf.template
+
 	rm -rf /etc/exim4/domains
 	mkdir -p /etc/exim4/domains
 
@@ -1819,12 +1855,15 @@ if [ "$clamd" = 'yes' ]; then
 	if [ -e "/lib/systemd/system/clamav-daemon.service" ]; then
 		exec_pre1='ExecStartPre=-/bin/mkdir -p /run/clamav'
 		exec_pre2='ExecStartPre=-/bin/chown -R clamav:clamav /run/clamav'
-		sed -i "s|\[Service\]/|[Service]\n$exec_pre1\n$exec_pre2|g" \
+		sed -i "s|\[Service\]|[Service]\n$exec_pre1\n$exec_pre2|g" \
 			/lib/systemd/system/clamav-daemon.service
 		systemctl daemon-reload
 	fi
+	systemctl start clamav-daemon > /dev/null 2>&1
+	sleep 1
+	systemctl status clamav-daemon > /dev/null 2>&1
 	echo -ne "[ * ] Installing ClamAV anti-virus definitions... "
-	/usr/bin/freshclam >> $LOG &
+	/usr/bin/freshclam >> $LOG > /dev/null 2>&1
 	BACK_PID=$!
 	spin_i=1
 	while kill -0 $BACK_PID > /dev/null 2>&1; do
@@ -1843,14 +1882,25 @@ fi
 if [ "$spamd" = 'yes' ]; then
 	echo "[ * ] Configuring SpamAssassin..."
 	update-rc.d spamassassin defaults > /dev/null 2>&1
-	sed -i "s/ENABLED=0/ENABLED=1/" /etc/default/spamassassin
-	systemctl start spamassassin >> $LOG
-	check_result $? "spamassassin start failed"
-	unit_files="$(systemctl list-unit-files | grep spamassassin)"
-	if [[ "$unit_files" =~ "disabled" ]]; then
-		systemctl enable spamassassin > /dev/null 2>&1
+	if [ "$release" = "10" ] || [ "$release" = "11" ]; then
+		update-rc.d spamassassin enable > /dev/null 2>&1
+		systemctl start spamassassin >> $LOG
+		check_result $? "spamassassin start failed"
+		unit_files="$(systemctl list-unit-files | grep spamassassin)"
+		if [[ "$unit_files" =~ "disabled" ]]; then
+			systemctl enable spamassassin > /dev/null 2>&1
+		fi
+		sed -i "s/#CRON=1/CRON=1/" /etc/default/spamassassin
+	else
+		# Deb 12+ renamed to spamd
+		update-rc.d spamd enable > /dev/null 2>&1
+		systemctl start spamd >> $LOG
+		unit_files="$(systemctl list-unit-files | grep spamassassin)"
+		if [[ "$unit_files" =~ "disabled" ]]; then
+			systemctl enable spamassassin > /dev/null 2>&1
+		fi
+
 	fi
-	sed -i "s/#CRON=1/CRON=1/" /etc/default/spamassassin
 fi
 
 #----------------------------------------------------------#
@@ -1949,7 +1999,7 @@ if [ "$sieve" = 'yes' ]; then
 
 	# exim4 install
 	sed -i "s/\stransport = local_delivery/ transport = dovecot_virtual_delivery/" /etc/exim4/exim4.conf.template
-	sed -i "s/address_pipe:/dovecot_virtual_delivery:\n  driver = pipe\n  command = \/usr\/lib\/dovecot\/dovecot-lda -e -d \$local_part@\$domain -f \$sender_address -a \$original_local_part@\$original_domain\n  delivery_date_add\n  envelope_to_add\n  return_path_add\n  log_output = true\n  log_defer_output = true\n  user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n  group = mail\n  return_output\n\naddress_pipe:/g" /etc/exim4/exim4.conf.template
+	sed -i "s/address_pipe:/dovecot_virtual_delivery:\n  driver = pipe\n  command = \/usr\/lib\/dovecot\/dovecot-lda -e -d \${extract{1}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/accounts}}}}@\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\n  delivery_date_add\n  envelope_to_add\n  return_path_add\n  log_output = true\n  log_defer_output = true\n  user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n  group = mail\n  return_output\n\naddress_pipe:/g" /etc/exim4/exim4.conf.template
 
 	# Permission changes
 	chown -R dovecot:mail /var/log/dovecot.log

+ 17 - 7
install/hst-install-ubuntu.sh

@@ -16,7 +16,6 @@
 export PATH=$PATH:/sbin
 export DEBIAN_FRONTEND=noninteractive
 RHOST='apt.hestiacp.com'
-GPG='gpg.hestiacp.com'
 VERSION='ubuntu'
 HESTIA='/usr/local/hestia'
 LOG="/root/hst_install_backups/hst_install-$(date +%d%m%Y%H%M).log"
@@ -186,6 +185,8 @@ validate_email() {
 	fi
 }
 
+version_ge() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1" -o -n "$1" -a "$1" = "$2"; }
+
 #----------------------------------------------------------#
 #                    Verifications                         #
 #----------------------------------------------------------#
@@ -365,7 +366,7 @@ apt-get -y install $installer_dependencies >> $LOG
 check_result $? "Package installation failed, check log file for more details."
 
 # Check repository availability
-wget --quiet "https://$GPG/deb_signing.key" -O /dev/null
+wget --quiet "https://$RHOST" -O /dev/null
 check_result $? "Unable to connect to the Hestia APT repository"
 
 # Check installed packages
@@ -946,6 +947,10 @@ fi
 #                     Install packages                     #
 #----------------------------------------------------------#
 
+# Enable en_US.UTF-8
+sed -i "s/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g" /etc/locale.gen
+locale-gen > /dev/null 2>&1
+
 # Disabling daemon autostart on apt-get install
 echo -e '#!/bin/sh\nexit 101' > /usr/sbin/policy-rc.d
 chmod a+x /usr/sbin/policy-rc.d
@@ -1367,8 +1372,6 @@ $HESTIA/bin/v-change-user-role admin admin
 $HESTIA/bin/v-change-user-language admin $lang
 $HESTIA/bin/v-change-sys-config-value 'POLICY_SYSTEM_PROTECTED_ADMIN' 'yes'
 
-locale-gen "en_US.utf8" > /dev/null 2>&1
-
 #----------------------------------------------------------#
 #                     Configure Nginx                      #
 #----------------------------------------------------------#
@@ -1778,9 +1781,11 @@ fi
 if [ "$exim" = 'yes' ]; then
 	echo "[ * ] Configuring Exim mail server..."
 	gpasswd -a Debian-exim mail > /dev/null 2>&1
-	if [ "$release" = "22.04" ]; then
+	exim_version=$(exim4 --version | head -1 | awk '{print $3}' | cut -f -2 -d .)
+	# if Exim version > 4.9.4 or greater!
+	if ! version_ge "4.9.4" "$exim_version"; then
 		# Jammyy uses Exim 4.95 instead but config works with Exim4.94
-		cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.4.94.template /etc/exim4/exim4.conf.template
+		cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.4.95.template /etc/exim4/exim4.conf.template
 	else
 		cp -f $HESTIA_INSTALL_DIR/exim/exim4.conf.template /etc/exim4/
 	fi
@@ -1797,6 +1802,11 @@ if [ "$exim" = 'yes' ]; then
 		sed -i "s/#CLAMD/CLAMD/g" /etc/exim4/exim4.conf.template
 	fi
 
+	# Generate SRS KEY If not support just created it will get ignored anyway
+	srs=$(gen_pass)
+	echo $srs > /etc/exim4/srs.conf
+	chmod 640 /etc/exim4/srs.conf
+
 	chmod 640 /etc/exim4/exim4.conf.template
 	rm -rf /etc/exim4/domains
 	mkdir -p /etc/exim4/domains
@@ -1969,7 +1979,7 @@ if [ "$sieve" = 'yes' ]; then
 
 	# exim4 install
 	sed -i "s/\stransport = local_delivery/ transport = dovecot_virtual_delivery/" /etc/exim4/exim4.conf.template
-	sed -i "s/address_pipe:/dovecot_virtual_delivery:\n  driver = pipe\n  command = \/usr\/lib\/dovecot\/dovecot-lda -e -d \$local_part@\$domain -f \$sender_address -a \$original_local_part@\$original_domain\n  delivery_date_add\n  envelope_to_add\n  return_path_add\n  log_output = true\n  log_defer_output = true\n  user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n  group = mail\n  return_output\n\naddress_pipe:/g" /etc/exim4/exim4.conf.template
+	sed -i "s/address_pipe:/dovecot_virtual_delivery:\n  driver = pipe\n  command = \/usr\/lib\/dovecot\/dovecot-lda -e -d \${extract{1}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/accounts}}}}@\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\n  delivery_date_add\n  envelope_to_add\n  return_path_add\n  log_output = true\n  log_defer_output = true\n  user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n  group = mail\n  return_output\n\naddress_pipe:/g" /etc/exim4/exim4.conf.template
 
 	# Permission changes
 	chown -R dovecot:mail /var/log/dovecot.log

+ 2 - 2
install/upgrade/manual/install_sieve.sh

@@ -63,7 +63,7 @@ if [ "$HAS_DOVECOT_SIEVE_INSTALLED" = "0" ]; then
 	# exim4 install
 	sed -i "s/\stransport = local_delivery/ transport = dovecot_virtual_delivery/" /etc/exim4/exim4.conf.template
 
-	sed -i "s/address_pipe:/dovecot_virtual_delivery:\n  driver = pipe\n  command = \/usr\/lib\/dovecot\/dovecot-lda -e -d \$local_part@\$domain -f \$sender_address -a \$original_local_part@\$original_domain\n  delivery_date_add\n  envelope_to_add\n  return_path_add\n  log_output = true\n  log_defer_output = true\n  user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n  group = mail\n  return_output\n\naddress_pipe:/g" /etc/exim4/exim4.conf.template
+	sed -i "s/address_pipe:/dovecot_virtual_delivery:\n  driver = pipe\n  command = \/usr\/lib\/dovecot\/dovecot-lda -e -d \${extract{1}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/accounts}}}}@\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\n  delivery_date_add\n  envelope_to_add\n  return_path_add\n  log_output = true\n  log_defer_output = true\n  user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n  group = mail\n  return_output\n\naddress_pipe:/g" /etc/exim4/exim4.conf.template
 
 	# roundcube install
 	mkdir -p $RC_CONFIG_DIR/plugins/managesieve
@@ -113,7 +113,7 @@ else
 
 		# Exim4
 		sed -i "s/\stransport = dovecot_virtual_delivery/ transport = local_delivery/" /etc/exim4/exim4.conf.template
-		sed -i "s/dovecot_virtual_delivery:\n  driver = pipe\n  command = \/usr\/lib\/dovecot\/dovecot-lda -e -d \$local_part@\$domain -f \$sender_address -a \$original_local_part@\$original_domain\n  delivery_date_add\n  envelope_to_add\n  return_path_add\n  log_output = true\n  log_defer_output = true\n  user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n  group = mail\n  return_output\n//g" /etc/exim4/exim4.conf.template
+		sed -i "s/dovecot_virtual_delivery:\n  driver = pipe\n  command = \/usr\/lib\/dovecot\/dovecot-lda -e -d \${extract{1}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains/}}\/accounts}}}}@\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\n  delivery_date_add\n  envelope_to_add\n  return_path_add\n  log_output = true\n  log_defer_output = true\n  user = \${extract{2}{:}{\${lookup{\$local_part}lsearch{\/etc\/exim4\/domains\/\${lookup{\$domain}dsearch{\/etc\/exim4\/domains\/}}\/passwd}}}}\n  group = mail\n  return_output\n//g" /etc/exim4/exim4.conf.template
 
 		# Roundcube
 		rm -f -r $RC_CONFIG_DIR/plugins/managesieve

+ 38 - 0
install/upgrade/patch/3661-exim-srs-support.patch

@@ -0,0 +1,38 @@
+17a18,19
+> SRS_SECRET = readfile{/etc/exim4/srs.conf}
+>   
+326a332,348
+> inbound_srs:
+>     driver = redirect
+>     senders = :
+>     domains = +local_domains
+>     # detect inbound bounces which are SRS'd, and decode them
+>     condition = ${if inbound_srs {$local_part} {SRS_SECRET}}
+>     data = $srs_recipient
+>   
+> inbound_srs_failure:
+>     driver = redirect
+>     senders = :
+>     domains = +local_domains
+>     # detect inbound bounces which look SRS'd but are invalid
+>     condition = ${if inbound_srs {$local_part} {}}
+>     allow_fail
+>     data = :fail: Invalid SRS recipient address
+>   
+358d379
+<   condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{false}{true}}
+387a409,422
+> remote_forwarded_smtp:
+>   driver = smtp
+>   helo_data = ${lookup dnsdb{>: defer_never,ptr=$sending_ip_address}{${listextract{1}{$value}}}{$primary_hostname}}
+>   dkim_domain = DKIM_DOMAIN
+>   dkim_selector = mail
+>   dkim_private_key = DKIM_PRIVATE_KEY
+>   dkim_canon = relaxed
+>   dkim_strict = 0
+>   hosts_try_fastopen = !*.l.google.com
+>   interface = ${if exists{OUTGOING_IP}{${readfile{OUTGOING_IP}}}}
+>   # modify the envelope from, for mails that we forward
+>   max_rcpt = 1
+>   return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
+>   

+ 15 - 1
install/upgrade/versions/1.8.0.sh

@@ -39,7 +39,7 @@ fi
 
 if [ -f /etc/fail2ban/jail.local ]; then
 	# Add phpmyadmin rule
-	if ! grep -qw "^phpmyadmin-auth$" /etc/fail2ban/jail.local 2> /dev/null; then
+	if ! grep -qw "phpmyadmin-auth" /etc/fail2ban/jail.local 2> /dev/null; then
 		sed -i '/\[recidive\]/i [phpmyadmin-auth]\nenabled  = true\nfilter   = phpmyadmin-syslog\naction   = hestia[name=WEB]\nlogpath  = /var/log/auth.log\nmaxretry = 5\n' /etc/fail2ban/jail.local
 	fi
 fi
@@ -196,3 +196,17 @@ fi
 
 unset commit nameserver nginx_conf_commit nginx_conf_compare nginx_conf_local os_release tls12_ciphers tls13_ciphers resolver
 # Finish configuring the "Enhanced and Optimized TLS" feature
+
+exim_version=$(exim4 --version | head -1 | awk '{print $3}' | cut -f -2 -d .)
+# if Exim version > 4.9.4 or greater!
+if ! version_ge "4.9.4" "$exim_version"; then
+	if ! grep -q 'SRS_SECRET' /etc/exim4/exim4.conf.template; then
+		srs=$(gen_pass)
+		echo $srs > /etc/exim4/srs.conf
+		chmod 640 /etc/exim4/srs.conf
+		echo "[ * ] Update exim4.conf.template ..."
+		patch /etc/exim4/exim4.conf.template $HESTIA/install/upgrade/patch/3661-exim-srs-support.patch
+	fi
+else
+	echo $exim_version
+fi

+ 3 - 1
src/deb/nginx/hestia

@@ -34,7 +34,9 @@ set -e
 adapt_nginx_config() {
 	# Detect "physical" NICs only (virtual NICs created by Docker, WireGuard etc. are excluded)
 	physical_nics="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" // .linkinfo.info_kind then empty else .ifname end')"
-
+	if [ -z "$physical_nics" ]; then
+		physical_nics="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" then empty else .ifname end')"
+	fi
 	for nic in $physical_nics; do
 		if [ -z "$ipv4_scope_global" ]; then
 			ipv4_scope_global="$(ip -4 -d -j addr show "$nic" | jq -r '.[].addr_info[] | if .scope == "global" then .local else empty end')"

+ 5 - 2
web/edit/server/index.php

@@ -666,6 +666,9 @@ if (!empty($_POST["save"])) {
 
 	// Update phpPgAdmin url
 	if (empty($_SESSION["error_msg"])) {
+		if (empty($_POST["v_pgsql_url"])) {
+			$_POST["v_pgsql_url"] = "";
+		}
 		if ($_POST["v_pgsql_url"] != $_SESSION["DB_PGA_ALIAS"]) {
 			exec(
 				HESTIA_CMD . "v-change-sys-db-alias pga " . quoteshellarg($_POST["v_pgsql_url"]),
@@ -1577,7 +1580,7 @@ if (!empty($_POST["save"])) {
 			check_return_code($return_var, $output);
 			unset($output);
 			if (empty($_SESSION["error_msg"])) {
-				$v_policy_system_hide_services = $_POST["v_policy_sync_error_documents"];
+				$v_policy_sync_error_documents = $_POST["v_policy_sync_error_documents"];
 			}
 			$v_security_adv = "yes";
 		}
@@ -1594,7 +1597,7 @@ if (!empty($_POST["save"])) {
 			check_return_code($return_var, $output);
 			unset($output);
 			if (empty($_SESSION["error_msg"])) {
-				$v_policy_system_hide_services = $_POST["v_policy_sync_skeleton"];
+				$v_policy_sync_skeleton = $_POST["v_policy_sync_skeleton"];
 			}
 			$v_security_adv = "yes";
 		}