2 changed files with 410 additions and 0 deletions
@ -0,0 +1,162 @@ |
|||
import os |
|||
import sys |
|||
import random |
|||
from ee.core.variables import EEVariables |
|||
from ee.core.aptget import EEAptGet |
|||
from ee.cli.plugins.eestack import EEStack |
|||
from ee.core.shellexec import EEShellExec |
|||
from ee.core.shellexec import CommandExecutionError |
|||
from ee.core.fileutils import EEFileUtils |
|||
from ee.core.git import EEGit |
|||
from ee.core.services import EEService |
|||
from ee.core.logging import Log |
|||
from ee.cli.main import app |
|||
|
|||
|
|||
class EEMailScannerStack(EEStack): |
|||
""" |
|||
EasyEngine MAILScanner stack |
|||
""" |
|||
packages_name = EEVariables.ee_mailscanner |
|||
app = app |
|||
log = app.log |
|||
|
|||
def __init__(self, packages_name=None): |
|||
""" |
|||
Initialize packages list in stack |
|||
pkgs_name : list of packages to be intialized for operations |
|||
in stack |
|||
""" |
|||
|
|||
self.packages_name = self._get_stack() |
|||
super(EEMailScannerStack, self).__init__(self.packages_name) |
|||
|
|||
def _get_stack(self): |
|||
return EEMailScannerStack.packages_name |
|||
|
|||
def _add_repo(self): |
|||
""" |
|||
Add repository for packages to be downloaded from |
|||
""" |
|||
self.log.info("Adding MAILScanner repository, please wait...") |
|||
|
|||
EEAptGet.update(self) |
|||
|
|||
def _pre_install_stack(self): |
|||
""" |
|||
Defines pre-install activities done before installing mail stack |
|||
""" |
|||
# Add mail repository |
|||
self._add_repo() |
|||
|
|||
|
|||
def _post_install_stack(self): |
|||
""" |
|||
Defines activities done after installing mail stack |
|||
""" |
|||
# Set up Custom amavis configuration |
|||
data = dict() |
|||
self.log.debug(self, "Configuring file /etc/amavis/conf.d" |
|||
"/15-content_filter_mode") |
|||
ee_amavis = open('/etc/amavis/conf.d/15-content_filter_mode', |
|||
encoding='utf-8', mode='w') |
|||
self.app.render((data), '15-content_filter_mode.mustache', |
|||
out=ee_amavis) |
|||
ee_amavis.close() |
|||
|
|||
# Amavis ViMbadmin configuration |
|||
if os.path.isfile("/etc/postfix/mysql/virtual_alias_maps.cf"): |
|||
vm_host = os.popen("grep hosts /etc/postfix/mysql/virtual_" |
|||
"alias_maps.cf | awk \'{ print $3 }\' |" |
|||
" tr -d '\\n'").read() |
|||
vm_pass = os.popen("grep password /etc/postfix/mysql/" |
|||
"virtual_alias_maps.cf | awk \'{ print " |
|||
"$3 }\' | tr -d '\\n'").read() |
|||
|
|||
data = dict(host=vm_host, password=vm_pass) |
|||
vm_config = open('/etc/amavis/conf.d/50-user', |
|||
encoding='utf-8', mode='w') |
|||
self.app.render((data), '50-user.mustache', out=vm_config) |
|||
vm_config.close() |
|||
|
|||
# Amavis postfix configuration |
|||
try: |
|||
EEShellExec.cmd_exec(self, "postconf -e \"content_filter =" |
|||
" smtp-amavis:[127.0.0.1]:10024\"") |
|||
EEShellExec.cmd_exec(self, "sed -i \"s/1 pickup/1 " |
|||
" pickup" |
|||
"\\n -o content_filter=\\n " |
|||
" -o receive_override_options=" |
|||
"no_header_body" |
|||
"_checks/\" /etc/postfix/master.cf") |
|||
except CommandExecutionError as e: |
|||
raise SiteError("Failed to update Amavis-Postfix config") |
|||
|
|||
amavis_master = ("""smtp-amavis unix - - n - 2 smtp |
|||
-o smtp_data_done_timeout=1200 |
|||
-o smtp_send_xforward_command=yes |
|||
-o disable_dns_lookups=yes |
|||
-o max_use=20 |
|||
127.0.0.1:10025 inet n - n - - smtpd |
|||
-o content_filter= |
|||
-o smtpd_delay_reject=no |
|||
-o smtpd_client_restrictions=permit_mynetworks,reject |
|||
-o smtpd_helo_restrictions= |
|||
-o smtpd_sender_restrictions= |
|||
-o smtpd_recipient_restrictions=permit_mynetworks,reject |
|||
-o smtpd_data_restrictions=reject_unauth_pipelining |
|||
-o smtpd_end_of_data_restrictions= |
|||
-o smtpd_restriction_classes= |
|||
-o mynetworks=127.0.0.0/8 |
|||
-o smtpd_error_sleep_time=0 |
|||
-o smtpd_soft_error_limit=1001 |
|||
-o smtpd_hard_error_limit=1000 |
|||
-o smtpd_client_connection_count_limit=0 |
|||
-o smtpd_client_connection_rate_limit=0 |
|||
-o local_header_rewrite_clients=""") |
|||
|
|||
with open("/etc/postfix/master.cf", |
|||
encoding='utf-8', mode='a') as am_config: |
|||
am_config.write(amavis_master) |
|||
|
|||
try: |
|||
# Amavis ClamAV configuration |
|||
self.log.debug(self, "Adding new user clamav amavis") |
|||
EEShellExec.cmd_exec(self, "adduser clamav amavis") |
|||
self.log.debug(self, "Adding new user amavis clamav") |
|||
EEShellExec.cmd_exec(self, "adduser amavis clamav") |
|||
self.log.debug(self, "Setting Privileges to /var/lib/amavis" |
|||
"/tmp") |
|||
EEFileUtils.chmod(self, "/var/lib/amavis/tmp", 0o755) |
|||
|
|||
# Update ClamAV database |
|||
self.log.debug(self, "Updating database") |
|||
EEShellExec.cmd_exec(self, "freshclam") |
|||
except CommandExecutionError as e: |
|||
raise SiteError(" Unable to update ClamAV-Amavis config") |
|||
|
|||
EEGit.add(self, ["/etc/amavis"], msg="Adding Amavis into Git") |
|||
EEService.restart_service(self, 'dovecot') |
|||
EEService.reload_service(self, 'postfix') |
|||
EEService.restart_service(self, 'amavis') |
|||
|
|||
|
|||
def install_stack(self): |
|||
""" |
|||
Install MAILScanner stack |
|||
""" |
|||
self.log.info("Installing MAILScanner stack, please wait...") |
|||
self._pre_install_stack() |
|||
super(EEMailScannerStack, self).install_stack() |
|||
self._post_install_stack() |
|||
|
|||
def remove_stack(self): |
|||
""" |
|||
Remove MAILScanner stack |
|||
""" |
|||
self.log.info("Removing MAILScanner stack, please wait...") |
|||
super(EEMailScannerStack, self).remove_stack() |
|||
|
|||
def purge_stack(self): |
|||
self.log.info("Purging MAILScanner stack, please wait...") |
|||
super(EEMailScannerStack, self).purge_stack() |
@ -0,0 +1,248 @@ |
|||
import os |
|||
import sys |
|||
import random |
|||
from ee.core.variables import EEVariables |
|||
from ee.core.aptget import EEAptGet |
|||
from ee.cli.plugins.eestack import EEStack |
|||
from ee.core.shellexec import EEShellExec |
|||
from ee.core.shellexec import CommandExecutionError |
|||
from ee.core.fileutils import EEFileUtils |
|||
from ee.core.git import EEGit |
|||
from ee.core.services import EEService |
|||
from ee.core.logging import Log |
|||
from ee.cli.main import app |
|||
|
|||
|
|||
class EEMailStack(EEStack): |
|||
""" |
|||
EasyEngine MAIL stack |
|||
""" |
|||
packages_name = EEVariables.ee_mail |
|||
app = app |
|||
log = app.log |
|||
|
|||
def __init__(self, packages_name=None): |
|||
""" |
|||
Initialize packages list in stack |
|||
pkgs_name : list of packages to be intialized for operations |
|||
in stack |
|||
""" |
|||
|
|||
self.packages_name = self._get_stack() |
|||
super(EEMailStack, self).__init__(self.packages_name) |
|||
|
|||
def _get_stack(self): |
|||
return EEMailStack.packages_name |
|||
|
|||
def _add_repo(self): |
|||
""" |
|||
Add repository for packages to be downloaded from |
|||
""" |
|||
self.log.info("Adding MAIL repository, please wait...") |
|||
|
|||
EEAptGet.update(self) |
|||
|
|||
def _pre_install_stack(self): |
|||
""" |
|||
Defines pre-install activities done before installing mail stack |
|||
""" |
|||
# Add mail repository |
|||
self._add_repo() |
|||
|
|||
self.log.debug(self, 'Executing the command debconf-set-selections.') |
|||
try: |
|||
EEShellExec.cmd_exec(self, "echo \"dovecot-core dovecot-core/" |
|||
"create-ssl-cert boolean yes\" " |
|||
"| debconf-set-selections") |
|||
EEShellExec.cmd_exec(self, "echo \"dovecot-core dovecot-core" |
|||
"/ssl-cert-name string $(hostname -f)\"" |
|||
" | debconf-set-selections") |
|||
except CommandExecutionError as e: |
|||
self.log.error("Failed to initialize dovecot packages") |
|||
|
|||
def _post_install_stack(self): |
|||
""" |
|||
Defines activities done after installing mail stack |
|||
""" |
|||
self.log.debug(self, "Adding user") |
|||
try: |
|||
EEShellExec.cmd_exec(self, "adduser --uid 5000 --home /var" |
|||
"/vmail --disabled-password --gecos " |
|||
"'' vmail") |
|||
except CommandExecutionError as e: |
|||
self.log.error(self, "Unable to add vmail user for mail server") |
|||
try: |
|||
EEShellExec.cmd_exec(self, "openssl req -new -x509 -days" |
|||
" 3650 " |
|||
"-nodes -subj /commonName={hostname}" |
|||
"/emailAddress={email} -out /etc/ssl" |
|||
"/certs/dovecot." |
|||
"pem -keyout " |
|||
"/etc/ssl/private/dovecot.pem" |
|||
.format(hostname=EEVariables.ee_fqdn, |
|||
email=EEVariables.ee_email)) |
|||
except CommandExecutionError as e: |
|||
self.log.error(self, "Unable to generate PEM key for dovecot") |
|||
self.log.debug(self, "Setting Privileges to " |
|||
"/etc/ssl/private/dovecot.pem file ") |
|||
EEFileUtils.chmod(self, "/etc/ssl/private/dovecot.pem", 0o600) |
|||
|
|||
# Custom Dovecot configuration by EasyEngine |
|||
data = dict() |
|||
self.log.debug(self, "Writting configuration into file" |
|||
"/etc/dovecot/conf.d/auth-sql.conf.ext ") |
|||
ee_dovecot = open('/etc/dovecot/conf.d/auth-sql.conf.ext', |
|||
encoding='utf-8', mode='w') |
|||
app.render((data), 'auth-sql-conf.mustache', |
|||
out=ee_dovecot) |
|||
ee_dovecot.close() |
|||
|
|||
data = dict(email=EEVariables.ee_email) |
|||
self.log.debug(self, "Writting configuration into file" |
|||
"/etc/dovecot/conf.d/99-ee.conf ") |
|||
ee_dovecot = open('/etc/dovecot/conf.d/99-ee.conf', |
|||
encoding='utf-8', mode='w') |
|||
app.render((data), 'dovecot.mustache', out=ee_dovecot) |
|||
ee_dovecot.close() |
|||
try: |
|||
EEShellExec.cmd_exec(self, "sed -i \"s/\\!include " |
|||
"auth-system.conf.ext/#\\!include " |
|||
"auth-system.conf.ext/\" " |
|||
"/etc/dovecot/conf.d/10-auth.conf") |
|||
|
|||
EEShellExec.cmd_exec(self, "sed -i \"s\'/etc/dovecot/" |
|||
"dovecot.pem\'/etc/ssl/certs/" |
|||
"dovecot.pem" |
|||
"\'\" /etc/dovecot/conf.d/" |
|||
"10-ssl.conf") |
|||
EEShellExec.cmd_exec(self, "sed -i \"s\'/etc/dovecot/" |
|||
"private/dovecot.pem\'/etc/ssl/" |
|||
"private" |
|||
"/dovecot.pem\'\" /etc/dovecot/" |
|||
"conf.d/" |
|||
"10-ssl.conf") |
|||
|
|||
# Custom Postfix configuration needed with Dovecot |
|||
# Changes in master.cf |
|||
# TODO: Find alternative for sed in Python |
|||
EEShellExec.cmd_exec(self, "sed -i \'s/#submission/" |
|||
"submission/\'" |
|||
" /etc/postfix/master.cf") |
|||
EEShellExec.cmd_exec(self, "sed -i \'s/#smtps/smtps/\'" |
|||
" /etc/postfix/master.cf") |
|||
|
|||
EEShellExec.cmd_exec(self, "postconf -e \"smtpd_sasl_type " |
|||
"= dovecot\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"smtpd_sasl_path " |
|||
"= private/auth\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"" |
|||
"smtpd_sasl_auth_enable = " |
|||
"yes\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"" |
|||
" smtpd_relay_restrictions =" |
|||
" permit_sasl_authenticated, " |
|||
" permit_mynetworks, " |
|||
" reject_unauth_destination\"") |
|||
|
|||
EEShellExec.cmd_exec(self, "postconf -e \"" |
|||
"smtpd_tls_mandatory_" |
|||
"protocols = !SSLv2,!SSLv3\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"smtp_tls_" |
|||
"mandatory_protocols = !SSLv2," |
|||
"!SSLv3\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls" |
|||
"_protocols = !SSLv2,!SSLv3\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"smtp_tls" |
|||
"_protocols = !SSLv2,!SSLv3\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"mydestination " |
|||
"= localhost\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"virtual" |
|||
"_transport " |
|||
"= lmtp:unix:private/dovecot-lmtp\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"virtual_uid_" |
|||
"maps = static:5000\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"virtual_gid_" |
|||
"maps = static:5000\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"" |
|||
" virtual_mailbox_domains = " |
|||
"mysql:/etc/postfix/mysql/virtual_" |
|||
"domains_maps.cf\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"virtual_mailbox" |
|||
"_maps" |
|||
" = mysql:/etc/postfix/mysql/virtual_" |
|||
"mailbox_maps.cf\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"virtual_alias" |
|||
"_maps " |
|||
"= mysql:/etc/postfix/mysql/virtual_" |
|||
"alias_maps.cf\"") |
|||
EEShellExec.cmd_exec(self, "openssl req -new -x509 -days " |
|||
" 3650 -nodes -subj /commonName=" |
|||
"{hostname}/emailAddress={email}" |
|||
" -out /etc/ssl/certs/postfix.pem" |
|||
" -keyout /etc/ssl/private/" |
|||
"postfix.pem" |
|||
.format(hostname=EEVariables.ee_fqdn, |
|||
email=EEVariables.ee_email)) |
|||
EEShellExec.cmd_exec(self, "chmod 0600 /etc/ssl/private" |
|||
"/postfix.pem") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls_cert_" |
|||
"file = /etc/ssl/certs/postfix.pem\"") |
|||
EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls_key_" |
|||
"file = /etc/ssl/private/" |
|||
"postfix.pem\"") |
|||
|
|||
except CommandExecutionError as e: |
|||
self.log.error(self, "Failed to update Dovecot configuration") |
|||
|
|||
# Sieve configuration |
|||
if not os.path.exists('/var/lib/dovecot/sieve/'): |
|||
self.log.debug(self, 'Creating directory ' |
|||
'/var/lib/dovecot/sieve/ ') |
|||
os.makedirs('/var/lib/dovecot/sieve/') |
|||
|
|||
# Custom sieve configuration by EasyEngine |
|||
data = dict() |
|||
self.log.debug(self, "Writting configuration of EasyEngine into " |
|||
"file /var/lib/dovecot/sieve/default.sieve") |
|||
ee_sieve = open('/var/lib/dovecot/sieve/default.sieve', |
|||
encoding='utf-8', mode='w') |
|||
app.render((data), 'default-sieve.mustache', |
|||
out=ee_sieve) |
|||
ee_sieve.close() |
|||
|
|||
# Compile sieve rules |
|||
self.log.debug(self, "Setting Privileges to dovecot ") |
|||
# EEShellExec.cmd_exec(self, "chown -R vmail:vmail /var/lib" |
|||
# "/dovecot") |
|||
EEFileUtils.chown(self, "/var/lib/dovecot", 'vmail', 'vmail', |
|||
recursive=True) |
|||
try: |
|||
EEShellExec.cmd_exec(self, "sievec /var/lib/dovecot/" |
|||
"/sieve/default.sieve") |
|||
except CommandExecutionError as e: |
|||
raise SiteError("Failed to compile default.sieve") |
|||
|
|||
EEGit.add(self, ["/etc/postfix", "/etc/dovecot"], |
|||
msg="Installed mail server") |
|||
EEService.restart_service(self, 'dovecot') |
|||
EEService.reload_service(self, 'postfix') |
|||
|
|||
def install_stack(self): |
|||
""" |
|||
Install MAIL stack |
|||
""" |
|||
self.log.info("Installing MAIL stack, please wait...") |
|||
self._pre_install_stack() |
|||
super(EEMailStack, self).install_stack() |
|||
self._post_install_stack() |
|||
|
|||
def remove_stack(self): |
|||
""" |
|||
Remove MAIL stack |
|||
""" |
|||
self.log.info("Removing MAIL stack, please wait...") |
|||
super(EEMailStack, self).remove_stack() |
|||
|
|||
def purge_stack(self): |
|||
self.log.info("Purging MAIL stack, please wait...") |
|||
super(EEMailStack, self).purge_stack() |
Loading…
Reference in new issue