|
|
@ -1,6 +1,8 @@ |
|
|
|
import os |
|
|
|
import sys |
|
|
|
import random |
|
|
|
import string |
|
|
|
import shutil |
|
|
|
from ee.core.variables import EEVariables |
|
|
|
from ee.core.aptget import EEAptGet |
|
|
|
from ee.cli.plugins.eestack import EEStack |
|
|
@ -12,7 +14,9 @@ from ee.core.services import EEService |
|
|
|
from ee.cli.plugins.mysqlstack import EEMysqlStack |
|
|
|
from ee.cli.plugins.nginxstack import EENginxStack |
|
|
|
from ee.cli.plugins.phpstack import EEPhpStack |
|
|
|
from ee.core.logging import Log |
|
|
|
from ee.core.download import EEDownload |
|
|
|
from ee.core.extract import EEExtract |
|
|
|
from ee.core.mysql import EEMysql |
|
|
|
from ee.cli.main import app |
|
|
|
|
|
|
|
|
|
|
@ -24,19 +28,45 @@ class EEMailStack(EEStack): |
|
|
|
app = app |
|
|
|
log = app.log |
|
|
|
|
|
|
|
def __init__(self, packages_name=None): |
|
|
|
def __init__(self, package_dict=None, apt_packages=None): |
|
|
|
""" |
|
|
|
Initialize packages list in stack |
|
|
|
pkgs_name : list of packages to be intialized for operations |
|
|
|
in stack |
|
|
|
package_url : list of urls from where packages to be fetched |
|
|
|
""" |
|
|
|
|
|
|
|
self.packages_name = self._get_stack() |
|
|
|
super(EEMailStack, self).__init__(self.packages_name) |
|
|
|
self.apt_packages = apt_packages |
|
|
|
self.manual_packages = package_dict |
|
|
|
self.packages_name = self._get_stack() |
|
|
|
super(EEMailStack, self).__init__(self.apt_packages) |
|
|
|
|
|
|
|
def _get_stack(self): |
|
|
|
""" |
|
|
|
""" |
|
|
|
if self.apt_packages or self.manual_packages: |
|
|
|
if not self.apt_packages: |
|
|
|
return (self.manual_packages) |
|
|
|
elif not self.manual_packages: |
|
|
|
return (self.apt_packages) |
|
|
|
else: |
|
|
|
return (self.apt_packages, self.manual_packages) |
|
|
|
|
|
|
|
return EEMailStack.packages_name |
|
|
|
|
|
|
|
def _set_stack(self): |
|
|
|
""" |
|
|
|
""" |
|
|
|
|
|
|
|
if type(self.packages_name) is tuple: |
|
|
|
for packages in self.packages_name: |
|
|
|
if type(packages) is list: |
|
|
|
self.apt_packages = packages |
|
|
|
if type(packages) is dict: |
|
|
|
self.manual_packages = packages |
|
|
|
elif type(self.packages_name) is dict: |
|
|
|
self.manual_packages = self.packages_name |
|
|
|
|
|
|
|
|
|
|
|
def _requirement_check(self): |
|
|
|
""" |
|
|
|
Check if requirements for this EEWebmailAdmin stack are fullfilled. |
|
|
@ -65,275 +95,13 @@ class EEMailStack(EEStack): |
|
|
|
# update repository information |
|
|
|
EEAptGet.update(self) |
|
|
|
|
|
|
|
def _pre_install_stack(self): |
|
|
|
""" |
|
|
|
Defines pre-install activities done before installing mail stack |
|
|
|
""" |
|
|
|
# Add mail repository |
|
|
|
|
|
|
|
self._requirement_check() |
|
|
|
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() |
|
|
|
EEWebmailAdmin(self).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() |
|
|
|
EEWebmailAdmin(self).purge_stack() |
|
|
|
|
|
|
|
|
|
|
|
import string |
|
|
|
import shutil |
|
|
|
from ee.core.download import EEDownload |
|
|
|
from ee.core.extract import EEExtract |
|
|
|
from ee.core.mysql import EEMysql |
|
|
|
|
|
|
|
class EEWebmailAdmin (EEStack): |
|
|
|
""" |
|
|
|
EasyEngine Web Mail stack |
|
|
|
VimbAdmin + Roundcube |
|
|
|
""" |
|
|
|
packages_name = { |
|
|
|
'Vimbadmin': "https://github.com/opensolutions/ViMbAdmin/archive/{0}.tar.gz".format(EEVariables.ee_vimbadmin), |
|
|
|
'Roundcube': "https://github.com/roundcube/roundcubemail/releases/download/{0}/roundcubemail-{0}.tar.gz".format(EEVariables.ee_roundcube) |
|
|
|
} |
|
|
|
app = app |
|
|
|
log = app.log |
|
|
|
|
|
|
|
def __init__(self, package_name=None, package_url=None): |
|
|
|
""" |
|
|
|
Initialize packages list in stack |
|
|
|
pkgs_name : list of packages to be intialized for operations |
|
|
|
in stack |
|
|
|
package_url : list of urls from where packages to be fetched |
|
|
|
""" |
|
|
|
|
|
|
|
self.packages_name = self._get_stack() |
|
|
|
|
|
|
|
super(EEWebmailAdmin, self).__init__(self.packages_name) |
|
|
|
|
|
|
|
def _get_stack(self): |
|
|
|
return EEWebmailAdmin.packages_name |
|
|
|
|
|
|
|
def _get_package_url(self, package_name): |
|
|
|
return self.packages_name[package_name] |
|
|
|
|
|
|
|
def _get_package_path(self, package): |
|
|
|
return "/tmp/{0}.tar.gz".format(package) |
|
|
|
|
|
|
|
def _pre_install(self): |
|
|
|
""" |
|
|
|
""" |
|
|
|
for pkg in self.packages_name: |
|
|
|
print([self._get_package_url(pkg), '/tmp/{0}.tar.gz'.format(pkg), pkg]) |
|
|
|
print() |
|
|
|
EEDownload.download(self, [[self._get_package_url(pkg), '/tmp/{0}.tar.gz'.format(pkg), pkg]]) |
|
|
|
|
|
|
|
def _post_install(self): |
|
|
|
""" |
|
|
|
""" |
|
|
|
pass |
|
|
|
|
|
|
|
def _install_vimbadmin(self): |
|
|
|
def _install_vimbadmin(self, file_path): |
|
|
|
""" |
|
|
|
|
|
|
|
""" |
|
|
|
self.log.debug(self, "Extracting ViMbAdmin.tar.gz to " |
|
|
|
"location /tmp/") |
|
|
|
EEExtract.extract(self, self._get_package_path('Vimbadmin'), '/tmp/') |
|
|
|
"location {0}".format(EEVariables.ee_downloads)) |
|
|
|
EEExtract.extract(self, file_path, EEVariables.ee_downloads) |
|
|
|
if not os.path.exists('{0}22222/htdocs/' |
|
|
|
.format(EEVariables.ee_webroot)): |
|
|
|
self.log.debug(self, "Creating directory " |
|
|
@ -341,8 +109,8 @@ class EEWebmailAdmin (EEStack): |
|
|
|
.format(EEVariables.ee_webroot)) |
|
|
|
os.makedirs('{0}22222/htdocs/' |
|
|
|
.format(EEVariables.ee_webroot)) |
|
|
|
shutil.move('/tmp/ViMbAdmin-{0}/' |
|
|
|
.format(EEVariables.ee_vimbadmin), |
|
|
|
shutil.move('{0}ViMbAdmin-{1}/' |
|
|
|
.format(EEVariables.ee_downloads, EEVariables.ee_vimbadmin), |
|
|
|
'{0}22222/htdocs/vimbadmin/' |
|
|
|
.format(EEVariables.ee_webroot)) |
|
|
|
|
|
|
@ -471,14 +239,14 @@ class EEWebmailAdmin (EEStack): |
|
|
|
|
|
|
|
print("Vimbadmin Security Salt : "+ vm_salt) |
|
|
|
|
|
|
|
def _install_roundcube(self): |
|
|
|
def _install_roundcube(self, file_path): |
|
|
|
""" |
|
|
|
Install and configure roundcube for mailstack |
|
|
|
""" |
|
|
|
# Extract RoundCubemail |
|
|
|
self.log.debug(self, "Extracting file /tmp/roundcube.tar.gz " |
|
|
|
"to location /tmp/ ") |
|
|
|
EEExtract.extract(self, self._get_package_path('Roundcube'), '/tmp/') |
|
|
|
self.log.debug(self, "Extracting file {0}roundcube.tar.gz " |
|
|
|
"to location {0} ".format(EEVariables.ee_downloads)) |
|
|
|
EEExtract.extract(self, file_path, EEVariables.ee_downloads) |
|
|
|
if not os.path.exists('{0}roundcubemail' |
|
|
|
.format(EEVariables.ee_webroot)): |
|
|
|
self.log.debug(self, "Creating new directory " |
|
|
@ -486,8 +254,8 @@ class EEWebmailAdmin (EEStack): |
|
|
|
.format(EEVariables.ee_webroot)) |
|
|
|
os.makedirs('{0}roundcubemail/' |
|
|
|
.format(EEVariables.ee_webroot)) |
|
|
|
shutil.move('/tmp/roundcubemail-{0}/' |
|
|
|
.format(EEVariables.ee_roundcube), |
|
|
|
shutil.move('{0}roundcubemail-{1}/' |
|
|
|
.format(EEVariables.ee_downloads, EEVariables.ee_roundcube), |
|
|
|
'{0}roundcubemail/htdocs' |
|
|
|
.format(EEVariables.ee_webroot)) |
|
|
|
|
|
|
@ -563,23 +331,262 @@ class EEWebmailAdmin (EEStack): |
|
|
|
ee_rc.close() |
|
|
|
|
|
|
|
|
|
|
|
def install_stack(self): |
|
|
|
def _remove_vimbadmin(self): |
|
|
|
""" |
|
|
|
Remove Vimbadmin Stack |
|
|
|
""" |
|
|
|
self._pre_install() |
|
|
|
self._install_vimbadmin() |
|
|
|
self._install_roundcube() |
|
|
|
self.log.info("Removing Vimbadmin, please wait...") |
|
|
|
# Remove Vimbadmin database |
|
|
|
if EEShellExec.cmd_exec(self, "mysqladmin ping"): |
|
|
|
EEMysql.execute(self, "drop database IF EXISTS vimbadmin") |
|
|
|
|
|
|
|
def purge_stack(self): |
|
|
|
# Remove Vimbadmin |
|
|
|
if EEFileUtils.isexist(self, "{0}22222/htdocs/vimbadmin" |
|
|
|
.format(EEVariables.ee_webroot)): |
|
|
|
EEFileUtils.remove(self, ["{0}22222/htdocs/vimbadmin".format(EEVariables.ee_webroot)]) |
|
|
|
|
|
|
|
def _remove_roundcube(self): |
|
|
|
""" |
|
|
|
Remove Roundcube Stack |
|
|
|
""" |
|
|
|
print("Inside webmailstack purge .....") |
|
|
|
|
|
|
|
self.log.info("Removing Roundcube, please wait...") |
|
|
|
# Remove Roundcube database |
|
|
|
if EEShellExec.cmd_exec(self, "mysqladmin ping"): |
|
|
|
EEMysql.execute(self, "drop database IF EXISTS vimbadmin") |
|
|
|
EEMysql.execute(self, "drop database IF EXISTS roundcubemail") |
|
|
|
if EEFileUtils.isexist(self, "{0}22222/htdocs/vimbadmin".format(EEVariables.ee_webroot)): |
|
|
|
print("Removing : {0}22222/htdocs/vimbadmin".format(EEVariables.ee_webroot)) |
|
|
|
EEFileUtils.remove(self, "{0}22222/htdocs/vimbadmin".format(EEVariables.ee_webroot)) |
|
|
|
|
|
|
|
# Remove Roundcube files |
|
|
|
if EEFileUtils.isexist(self, "{0}roundcubemail".format(EEVariables.ee_webroot)): |
|
|
|
print("Removing: {0}roundcubemail".format(EEVariables.ee_webroot)) |
|
|
|
EEFileUtils.remove(self, "{0}roundcubemail".format(EEVariables.ee_webroot)) |
|
|
|
EEFileUtils.remove(self, ["{0}roundcubemail".format(EEVariables.ee_webroot)]) |
|
|
|
|
|
|
|
|
|
|
|
def _pre_install_stack(self): |
|
|
|
""" |
|
|
|
Defines pre-install activities done before installing mail stack |
|
|
|
""" |
|
|
|
# Add mail repository |
|
|
|
|
|
|
|
self._requirement_check() |
|
|
|
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._set_stack() |
|
|
|
self._pre_install_stack() |
|
|
|
|
|
|
|
if self.apt_packages: |
|
|
|
super(EEMailStack, self).install_stack() |
|
|
|
self._post_install_stack() |
|
|
|
|
|
|
|
if self.manual_packages: |
|
|
|
for key in self.manual_packages.keys(): |
|
|
|
path = EEDownload(('%s' %key), self.manual_packages[key]).download() |
|
|
|
print("Evaluating function %s..." %key) |
|
|
|
print("self._install_{0}(self, '{1}')".format(key, path)) |
|
|
|
eval("self._install_{0}('{1}')".format(key, path)) |
|
|
|
|
|
|
|
def remove_stack(self): |
|
|
|
""" |
|
|
|
Remove MAIL stack |
|
|
|
""" |
|
|
|
self.log.info("Removing MAIL stack, please wait...") |
|
|
|
self._set_stack() |
|
|
|
if self.apt_packages: |
|
|
|
super(EEMailStack, self).remove_stack() |
|
|
|
if self.manual_packages: |
|
|
|
for key in self.manual_packages.keys(): |
|
|
|
print("Evaluating function %s..." %key) |
|
|
|
print("self._remove_{0}(self)".format(key)) |
|
|
|
eval("self._remove_{0}()".format(key)) |
|
|
|
|
|
|
|
def purge_stack(self): |
|
|
|
self.log.info("Purging MAIL stack, please wait...") |
|
|
|
self._set_stack() |
|
|
|
if self.apt_packages: |
|
|
|
super(EEMailStack, self).purge_stack() |
|
|
|
if self.manual_packages: |
|
|
|
for key in self.manual_packages.keys(): |
|
|
|
print("Evaluating function %s..." %key) |
|
|
|
print("self._remove_{0}(self)".format(key)) |
|
|
|
eval("self._remove_{0}()".format(key)) |
|
|
|