From 008cc7da0e550f1fec15d5891507976a9fe0208d Mon Sep 17 00:00:00 2001 From: usmannasir Date: Fri, 6 Mar 2026 03:32:04 +0500 Subject: [PATCH] Enable Sieve email filtering in install and upgrade for all OS - Add sieve to dovecot protocols in both dovecot.conf templates - Add sieve plugin to LDA mail_plugins in dovecot.conf templates - Write ManageSieve config (20-managesieve.conf) during installSieve() - Add setupSieve() upgrade function: patches dovecot.conf, installs packages (dovecot-sieve/managesieved on Ubuntu, pigeonhole on CentOS), writes ManageSieve config, opens firewall port 4190, restarts dovecot - Call setupSieve() in main upgrade flow --- install/email-configs-one/dovecot.conf | 4 +- install/email-configs/dovecot.conf | 4 +- install/installCyberPanel.py | 29 ++++++++-- plogical/upgrade.py | 80 ++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/install/email-configs-one/dovecot.conf b/install/email-configs-one/dovecot.conf index 682e5764d..bc162626c 100644 --- a/install/email-configs-one/dovecot.conf +++ b/install/email-configs-one/dovecot.conf @@ -1,4 +1,4 @@ -protocols = imap pop3 +protocols = imap pop3 sieve log_timestamp = "%Y-%m-%d %H:%M:%S " #mail_location = maildir:/home/vmail/%d/%n/Maildir #mail_location = mdbox:/home/vmail/%d/%n/Mdbox @@ -41,7 +41,7 @@ protocol lda { auth_socket_path = /var/run/dovecot/auth-master postmaster_address = postmaster@example.com - mail_plugins = zlib + mail_plugins = zlib sieve } protocol pop3 { diff --git a/install/email-configs/dovecot.conf b/install/email-configs/dovecot.conf index 5f7188139..843c43f64 100644 --- a/install/email-configs/dovecot.conf +++ b/install/email-configs/dovecot.conf @@ -1,4 +1,4 @@ -protocols = imap pop3 +protocols = imap pop3 sieve log_timestamp = "%Y-%m-%d %H:%M:%S " #mail_location = maildir:/home/vmail/%d/%n/Maildir #mail_location = mdbox:/home/vmail/%d/%n/Mdbox @@ -41,7 +41,7 @@ protocol lda { auth_socket_path = /var/run/dovecot/auth-master postmaster_address = postmaster@example.com - mail_plugins = zlib + mail_plugins = zlib sieve } protocol pop3 { diff --git a/install/installCyberPanel.py b/install/installCyberPanel.py index bca540d2e..9b6469bc9 100644 --- a/install/installCyberPanel.py +++ b/install/installCyberPanel.py @@ -686,21 +686,42 @@ module cyberpanel_ols { """Install Sieve (Dovecot Sieve) for email filtering on all OS variants""" try: InstallCyberPanel.stdOut("Installing Sieve (Dovecot Sieve) for email filtering...", 1) - + if self.distro == ubuntu: # Install dovecot-sieve and dovecot-managesieved self.install_package('dovecot-sieve dovecot-managesieved') else: # For CentOS/AlmaLinux/OpenEuler self.install_package('dovecot-pigeonhole') - + + # Write ManageSieve config + managesieve_conf = '/etc/dovecot/conf.d/20-managesieve.conf' + with open(managesieve_conf, 'w') as f: + f.write("""protocols = $protocols sieve + +service managesieve-login { + inet_listener sieve { + port = 4190 + } +} + +service managesieve { + process_limit = 256 +} + +protocol sieve { + managesieve_notify_capability = mailto + managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext +} +""") + # Add Sieve port 4190 to firewall from plogical.firewallUtilities import FirewallUtilities FirewallUtilities.addSieveFirewallRule() - + InstallCyberPanel.stdOut("Sieve successfully installed and configured!", 1) return 1 - + except BaseException as msg: logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [installSieve]") return 0 diff --git a/plogical/upgrade.py b/plogical/upgrade.py index 1fa3ba792..6228a2484 100644 --- a/plogical/upgrade.py +++ b/plogical/upgrade.py @@ -2849,6 +2849,85 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL except: pass + @staticmethod + def setupSieve(): + """Enable Sieve plugin and ManageSieve for email filtering (idempotent)""" + try: + if not os.path.exists('/etc/dovecot/dovecot.conf'): + Upgrade.stdOut("Dovecot not installed, skipping Sieve setup.", 0) + return + + dovecot_conf = '/etc/dovecot/dovecot.conf' + with open(dovecot_conf, 'r') as f: + content = f.read() + + changed = False + + # Add sieve to protocols if missing + if 'sieve' not in content.split('\n')[0]: + content = content.replace('protocols = imap pop3', 'protocols = imap pop3 sieve', 1) + changed = True + + # Add sieve plugin to protocol lda if missing + import re + lda_match = re.search(r'(protocol lda\s*\{[^}]*mail_plugins\s*=\s*)(zlib)(\s*\n)', content) + if lda_match and 'sieve' not in lda_match.group(0): + content = content.replace(lda_match.group(0), + lda_match.group(1) + 'zlib sieve' + lda_match.group(3)) + changed = True + + if changed: + with open(dovecot_conf, 'w') as f: + f.write(content) + + # Write ManageSieve config if not properly configured + managesieve_conf = '/etc/dovecot/conf.d/20-managesieve.conf' + write_managesieve = True + if os.path.exists(managesieve_conf): + with open(managesieve_conf, 'r') as f: + existing = f.read() + if 'inet_listener sieve' in existing and not existing.strip().startswith('#'): + write_managesieve = False + + if write_managesieve: + with open(managesieve_conf, 'w') as f: + f.write("""protocols = $protocols sieve + +service managesieve-login { + inet_listener sieve { + port = 4190 + } +} + +service managesieve { + process_limit = 256 +} + +protocol sieve { + managesieve_notify_capability = mailto + managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext +} +""") + + # Install sieve packages if missing + if os.path.exists('/etc/lsb-release') or os.path.exists('/etc/debian_version'): + Upgrade.executioner('apt-get install -y dovecot-sieve dovecot-managesieved', 'Install Sieve packages', 0) + else: + Upgrade.executioner('yum install -y dovecot-pigeonhole', 'Install Sieve packages', 0) + + # Open firewall port + try: + from plogical.firewallUtilities import FirewallUtilities + FirewallUtilities.addSieveFirewallRule() + except: + pass + + subprocess.call(['systemctl', 'restart', 'dovecot']) + Upgrade.stdOut("Sieve setup complete!", 0) + + except BaseException as msg: + Upgrade.stdOut("setupSieve error: " + str(msg), 0) + @staticmethod def setupWebmail(): """Set up Dovecot master user and webmail config for SSO (idempotent)""" @@ -4917,6 +4996,7 @@ pm.max_spare_servers = 3 Upgrade.manageServiceMigrations() Upgrade.fixMailTLS() Upgrade.setupWebmail() + Upgrade.setupSieve() Upgrade.enableServices() Upgrade.installPHP73()