added plugin selection, derive key, clean env

master
Alexander Graf 3 years ago
parent 7c2c2dc65a
commit 547ad253e1
No known key found for this signature in database
GPG Key ID: B8A9DC143E075629

@ -38,7 +38,6 @@ RUN set -eu \
&& rm -rf /var/lib/apt/lists && rm -rf /var/lib/apt/lists
ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.5.1/roundcubemail-1.5.1-complete.tar.gz ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.5.1/roundcubemail-1.5.1-complete.tar.gz
ENV CARDDAV_URL https://github.com/mstilkerich/rcmcarddav/releases/download/v4.3.0/carddav-v4.3.0.tar.gz ENV CARDDAV_URL https://github.com/mstilkerich/rcmcarddav/releases/download/v4.3.0/carddav-v4.3.0.tar.gz
RUN set -eu \ RUN set -eu \
@ -58,10 +57,10 @@ RUN set -eu \
&& a2enmod rewrite deflate expires headers \ && a2enmod rewrite deflate expires headers \
&& echo date.timezone=${TZ} > /usr/local/etc/php/conf.d/timezone.ini && echo date.timezone=${TZ} > /usr/local/etc/php/conf.d/timezone.ini
COPY php.ini /php.ini
COPY config.inc.php /var/www/html/config/
COPY mailu.php /var/www/html/plugins/mailu/mailu.php COPY mailu.php /var/www/html/plugins/mailu/mailu.php
COPY start.py /start.py COPY php.ini /
COPY config.inc.php /
COPY start.py /
EXPOSE 80/tcp EXPOSE 80/tcp
VOLUME ["/data"] VOLUME ["/data"]

@ -3,46 +3,29 @@
$config = array(); $config = array();
// Generals // Generals
$config['db_dsnw'] = getenv('DB_DSNW');; $config['db_dsnw'] = '{{ DB_DSNW }}';
$config['temp_dir'] = '/tmp/'; $config['temp_dir'] = '/tmp/';
$config['des_key'] = getenv('SECRET_KEY') ? getenv('SECRET_KEY') : trim(file_get_contents(getenv('SECRET_KEY_FILE'))); $config['des_key'] = '{{ SECRET_KEY }}';
$config['cipher_method'] = 'AES-256-CBC'; $config['cipher_method'] = 'AES-256-CBC';
$config['identities_level'] = 0; $config['identities_level'] = 0;
$config['reply_all_mode'] = 1; $config['reply_all_mode'] = 1;
$config['log_driver'] = 'stdout';
// List of active plugins (in plugins/ directory) $config['zipdownload_selection'] = true;
$config['plugins'] = array( $config['enable_spellcheck'] = true;
'archive', $config['spellcheck_engine'] = 'pspell';
'zipdownload',
'markasjunk',
'managesieve',
'enigma',
'carddav'
);
$front = getenv('FRONT_ADDRESS') ? getenv('FRONT_ADDRESS') : 'front';
$imap = getenv('IMAP_ADDRESS') ? getenv('IMAP_ADDRESS') : 'imap';
// Mail servers // Mail servers
$config['default_host'] = $front; $config['default_host'] = '{{ FRONT_ADDRESS or "front" }}';
$config['default_port'] = 10143; $config['default_port'] = 10143;
$config['smtp_server'] = $front; $config['smtp_server'] = '{{ FRONT_ADDRESS or "front" }}';
$config['smtp_port'] = 10025; $config['smtp_port'] = 10025;
$config['smtp_user'] = '%u'; $config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p'; $config['smtp_pass'] = '%p';
// Sieve script management // Sieve script management
$config['managesieve_host'] = $imap; $config['managesieve_host'] = '{{ IMAP_ADDRESS or "imap" }}';
$config['managesieve_usetls'] = false; $config['managesieve_usetls'] = false;
// Customization settings
if (filter_var(getenv('ADMIN'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) {
$config['support_url'] = getenv('WEB_ADMIN') ? '../..' . getenv('WEB_ADMIN') : '';
}
$config['product_name'] = 'Mailu Webmail';
array_push($config['plugins'], 'mailu');
$config['sso_logout_url'] = '/sso/logout';
// We access the IMAP and SMTP servers locally with internal names, SSL // We access the IMAP and SMTP servers locally with internal names, SSL
// will obviously fail but this sounds better than allowing insecure login // will obviously fail but this sounds better than allowing insecure login
// from the outter world // from the outter world
@ -56,11 +39,22 @@ $config['imap_conn_options'] = $ssl_no_check;
$config['smtp_conn_options'] = $ssl_no_check; $config['smtp_conn_options'] = $ssl_no_check;
$config['managesieve_conn_options'] = $ssl_no_check; $config['managesieve_conn_options'] = $ssl_no_check;
// roundcube customization
$config['product_name'] = 'Mailu Webmail';
{%- if ADMIN and WEB_ADMIN %}
$config['support_url'] = '../..{{ WEB_ADMIN }}';
{%- endif %}
$config['plugins'] = array({{ PLUGINS }});
// skin name: folder from skins/ // skin name: folder from skins/
$config['skin'] = 'elastic'; $config['skin'] = 'elastic';
// Enigma gpg plugin // configure mailu sso plugin
$config['sso_logout_url'] = '/sso/logout';
// configure enigma gpg plugin
$config['enigma_pgp_homedir'] = '/data/gpg'; $config['enigma_pgp_homedir'] = '/data/gpg';
// Set From header for DKIM signed message delivery reports // Set From header for DKIM signed message delivery reports
$config['mdn_use_from'] = true; $config['mdn_use_from'] = true;

@ -0,0 +1,2 @@
#!/bin/sh
SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000 2>/dev/null | grep -qFx pong

@ -1,67 +1,102 @@
#!/usr/bin/python3 #!/usr/bin/python3
import os import os
import logging as log import logging
import sys import sys
from socrate import conf from socrate import conf
import subprocess import subprocess
import hmac
log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING")) env = os.environ
os.environ["MAX_FILESIZE"] = str(int(int(os.environ.get("MESSAGE_SIZE_LIMIT")) * 0.66 / 1048576)) logging.basicConfig(stream=sys.stderr, level=env.get("LOG_LEVEL", "WARNING"))
db_flavor = os.environ.get("ROUNDCUBE_DB_FLAVOR", "sqlite") # jinja context
context = {}
context.update(env)
context["MAX_FILESIZE"] = str(int(int(env.get("MESSAGE_SIZE_LIMIT", "50000000")) * 0.66 / 1048576))
db_flavor = env.get("ROUNDCUBE_DB_FLAVOR", "sqlite")
if db_flavor == "sqlite": if db_flavor == "sqlite":
os.environ["DB_DSNW"] = "sqlite:////data/roundcube.db" context["DB_DSNW"] = "sqlite:////data/roundcube.db"
elif db_flavor == "mysql": elif db_flavor == "mysql":
os.environ["DB_DSNW"] = "mysql://%s:%s@%s/%s" % ( context["DB_DSNW"] = "mysql://%s:%s@%s/%s" % (
os.environ.get("ROUNDCUBE_DB_USER", "roundcube"), env.get("ROUNDCUBE_DB_USER", "roundcube"),
os.environ.get("ROUNDCUBE_DB_PW"), env.get("ROUNDCUBE_DB_PW"),
os.environ.get("ROUNDCUBE_DB_HOST", "database"), env.get("ROUNDCUBE_DB_HOST", "database"),
os.environ.get("ROUNDCUBE_DB_NAME", "roundcube") env.get("ROUNDCUBE_DB_NAME", "roundcube")
) )
elif db_flavor == "postgresql": elif db_flavor == "postgresql":
os.environ["DB_DSNW"] = "pgsql://%s:%s@%s/%s" % ( context["DB_DSNW"] = "pgsql://%s:%s@%s/%s" % (
os.environ.get("ROUNDCUBE_DB_USER", "roundcube"), env.get("ROUNDCUBE_DB_USER", "roundcube"),
os.environ.get("ROUNDCUBE_DB_PW"), env.get("ROUNDCUBE_DB_PW"),
os.environ.get("ROUNDCUBE_DB_HOST", "database"), env.get("ROUNDCUBE_DB_HOST", "database"),
os.environ.get("ROUNDCUBE_DB_NAME", "roundcube") env.get("ROUNDCUBE_DB_NAME", "roundcube")
) )
else: else:
print("Unknown ROUNDCUBE_DB_FLAVOR: %s", db_flavor) print(f"Unknown ROUNDCUBE_DB_FLAVOR: {db_flavor}", file=sys.stderr)
exit(1) exit(1)
conf.jinja("/php.ini", os.environ, "/usr/local/etc/php/conf.d/roundcube.ini") # derive roundcube secret key
secret_key = env.get("SECRET_KEY")
if not secret_key:
try:
secret_key = open(env.get("SECRET_KEY_FILE"), "r").read().strip()
except Exception as exc:
print(f"Can't read SECRET_KEY from file: {exc}", file=sys.stderr)
exit(2)
# Create dirs, setup permissions context['SECRET_KEY'] = hmac.new(bytearray(secret_key, 'utf-8'), bytearray('ROUNDCUBE_KEY', 'utf-8'), 'sha256').hexdigest()
# roundcube plugins
# (using "dict" because it is ordered and "set" is not)
plugins = dict((p, None) for p in env.get("ROUNCUBE_PLUGINS", "").replace(" ", "").split(",") if p and os.path.isdir(os.path.join("/var/www/plugins", p)))
if plugins:
plugins["mailu"] = None
else:
plugins = dict((k, None) for k in ["archive", "zipdownload", "markasjunk", "managesieve", "enigma", "carddav", "mailu"])
context["PLUGINS"] = ",".join(f"'{p}'" for p in plugins)
# create config files
conf.jinja("/php.ini", context, "/usr/local/etc/php/conf.d/roundcube.ini")
conf.jinja("/config.inc.php", context, "/var/www/html/config/config.inc.php")
# create dirs
os.system("mkdir -p /data/gpg") os.system("mkdir -p /data/gpg")
try:
print("Initializing database") print("Initializing database")
try:
result = subprocess.check_output(["/var/www/html/bin/initdb.sh", "--dir", "/var/www/html/SQL"], result = subprocess.check_output(["/var/www/html/bin/initdb.sh", "--dir", "/var/www/html/SQL"],
stderr=subprocess.STDOUT) stderr=subprocess.STDOUT)
print(result.decode()) print(result.decode())
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as exc:
if "already exists" in e.stdout.decode(): err = exc.stdout.decode()
if "already exists" in err:
print("Already initialzed") print("Already initialzed")
else: else:
print(e.stdout.decode()) print(err)
quit(1) exit(3)
try:
print("Upgrading database") print("Upgrading database")
subprocess.check_call(["/var/www/html/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
quit(1)
else:
try: try:
subprocess.check_call(["/var/www/html/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
exit(4)
else:
print("Cleaning database") print("Cleaning database")
try:
subprocess.check_call(["/var/www/html/bin/cleandb.sh"], stderr=subprocess.STDOUT) subprocess.check_call(["/var/www/html/bin/cleandb.sh"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as exc:
quit(1) exit(5)
# Setup database permissions # setup permissions
os.system("chown -R www-data:www-data /data") os.system("chown -R www-data:www-data /data")
# Run apache # clean env
os.execv("/usr/local/bin/apache2-foreground", ["apache2-foreground"]) [env.pop(key, None) for key in env.keys() if key == "SECRET_KEY" or key.startswith("ROUNDCUBE_")]
# run apache
os.execve("/usr/local/bin/apache2-foreground", ["apache2-foreground"], env)

Loading…
Cancel
Save