diff --git a/core/admin/mailu/sso/forms.py b/core/admin/mailu/sso/forms.py index c190b8bc..5cf38dbe 100644 --- a/core/admin/mailu/sso/forms.py +++ b/core/admin/mailu/sso/forms.py @@ -7,5 +7,5 @@ class LoginForm(flask_wtf.FlaskForm): csrf = False email = fields.StringField(_('E-mail'), [validators.Email(), validators.DataRequired()]) pw = fields.PasswordField(_('Password'), [validators.DataRequired()]) - submitAdmin = fields.SubmitField(_('Sign in')) submitWebmail = fields.SubmitField(_('Sign in')) + submitAdmin = fields.SubmitField(_('Sign in')) diff --git a/core/admin/mailu/sso/views/base.py b/core/admin/mailu/sso/views/base.py index 390d5bbf..cf2e166c 100644 --- a/core/admin/mailu/sso/views/base.py +++ b/core/admin/mailu/sso/views/base.py @@ -15,10 +15,10 @@ def login(): form.submitWebmail.label.text = form.submitWebmail.label.text + ' Webmail' fields = [] - if str(app.config["ADMIN"]).upper() != "FALSE": - fields.append(form.submitAdmin) if str(app.config["WEBMAIL"]).upper() != "NONE": fields.append(form.submitWebmail) + if str(app.config["ADMIN"]).upper() != "FALSE": + fields.append(form.submitAdmin) fields = [fields] if form.validate_on_submit(): diff --git a/core/dovecot/Dockerfile b/core/dovecot/Dockerfile index 16f35490..f09866b9 100644 --- a/core/dovecot/Dockerfile +++ b/core/dovecot/Dockerfile @@ -1,14 +1,4 @@ ARG DISTRO=alpine:3.14.2 -FROM $DISTRO as builder -WORKDIR /tmp -RUN apk add git build-base automake autoconf libtool dovecot-dev xapian-core-dev icu-dev -RUN git clone https://github.com/grosjo/fts-xapian.git \ - && cd fts-xapian \ - && git checkout 1.2.7 \ - && autoreconf -vi \ - && PANDOC=false ./configure --with-dovecot=/usr/lib/dovecot \ - && make \ - && make install FROM $DISTRO ARG VERSION @@ -29,11 +19,9 @@ RUN pip3 install "podop>0.2.5" # Image specific layers under this line RUN apk add --no-cache \ - dovecot dovecot-lmtpd dovecot-pop3d dovecot-submissiond dovecot-pigeonhole-plugin rspamd-client xapian-core \ + dovecot dovecot-lmtpd dovecot-pop3d dovecot-submissiond dovecot-pigeonhole-plugin rspamd-client xapian-core dovecot-fts-xapian \ && mkdir /var/lib/dovecot -COPY --from=builder /usr/lib/dovecot/lib21_fts_xapian_plugin.* /usr/lib/dovecot/ - COPY conf /conf COPY start.py /start.py diff --git a/core/dovecot/conf/ham.script b/core/dovecot/conf/ham.script index 910df8e4..57112747 100755 --- a/core/dovecot/conf/ham.script +++ b/core/dovecot/conf/ham.script @@ -1,6 +1,6 @@ #!/bin/bash - -RSPAMD_HOST="$(getent hosts {{ ANTISPAM_WEBUI_ADDRESS }}|cut -d\ -f1)" +{% set hostname,port = ANTISPAM_WEBUI_ADDRESS.split(':') %} +RSPAMD_HOST="$(getent hosts {{ hostname }}|cut -d\ -f1):{{ port }}" if [[ $? -ne 0 ]] then echo "Failed to lookup {{ ANTISPAM_WEBUI_ADDRESS }}" >&2 diff --git a/core/dovecot/conf/spam.script b/core/dovecot/conf/spam.script index e7d20427..2e3872b0 100755 --- a/core/dovecot/conf/spam.script +++ b/core/dovecot/conf/spam.script @@ -1,6 +1,6 @@ #!/bin/bash - -RSPAMD_HOST="$(getent hosts {{ ANTISPAM_WEBUI_ADDRESS }}|cut -d\ -f1)" +{% set hostname,port = ANTISPAM_WEBUI_ADDRESS.split(':') %} +RSPAMD_HOST="$(getent hosts {{ hostname }}|cut -d\ -f1):{{ port }}" if [[ $? -ne 0 ]] then echo "Failed to lookup {{ ANTISPAM_WEBUI_ADDRESS }}" >&2 diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index deedd9b8..39ea6eee 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -23,7 +23,7 @@ RUN apk add --no-cache --virtual .build-deps gcc musl-dev python3-dev RUN pip3 install --no-binary :all: postfix-mta-sts-resolver==1.0.1 RUN apk del .build-deps gcc musl-dev python3-dev -RUN apk add --no-cache postfix postfix-pcre cyrus-sasl-login +RUN apk add --no-cache postfix postfix-pcre cyrus-sasl-login rsyslog logrotate COPY conf /conf COPY start.py /start.py diff --git a/core/postfix/conf/logrotate.conf b/core/postfix/conf/logrotate.conf new file mode 100644 index 00000000..5882607c --- /dev/null +++ b/core/postfix/conf/logrotate.conf @@ -0,0 +1,11 @@ +{{POSTFIX_LOG_FILE}} { +weekly +rotate 52 +nocompress +extension log +create 0644 root root + postrotate + /bin/kill -HUP $(cat /run/rsyslogd.pid) + postfix reload + endscript +} diff --git a/core/postfix/conf/main.cf b/core/postfix/conf/main.cf index 8ac646da..444dacad 100644 --- a/core/postfix/conf/main.cf +++ b/core/postfix/conf/main.cf @@ -2,9 +2,6 @@ # General ############### -# Logging configuration -maillog_file = /dev/stdout - # Main domain and hostname mydomain = {{ DOMAIN }} myhostname = {{ HOSTNAMES.split(",")[0] }} diff --git a/core/postfix/conf/rsyslog.conf b/core/postfix/conf/rsyslog.conf new file mode 100644 index 00000000..7d55b7ba --- /dev/null +++ b/core/postfix/conf/rsyslog.conf @@ -0,0 +1,40 @@ +# rsyslog configuration file +# +# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html +# or latest version online at http://www.rsyslog.com/doc/rsyslog_conf.html +# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html + + +#### Global directives #### + +# Sets the directory that rsyslog uses for work files. +$WorkDirectory /var/lib/rsyslog + +# Sets default permissions for all log files. +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + +# Reduce repeating messages (default off). +$RepeatedMsgReduction on + + +#### Modules #### + +# Provides support for local system logging (e.g. via logger command). +module(load="imuxsock") + +#### Rules #### + +# Discard messages from local test requests +:msg, contains, "connect from localhost[127.0.0.1]" ~ + +{% if POSTFIX_LOG_FILE %} +# Log mail logs to file +mail.* -{{POSTFIX_LOG_FILE}} +{% endif %} + +# Log mail logs to stdout +mail.* -/dev/stdout diff --git a/core/postfix/start.py b/core/postfix/start.py index ac675cf1..74b5bc19 100755 --- a/core/postfix/start.py +++ b/core/postfix/start.py @@ -47,6 +47,8 @@ os.environ["FRONT_ADDRESS"] = system.get_host_address_from_environment("FRONT", os.environ["ADMIN_ADDRESS"] = system.get_host_address_from_environment("ADMIN", "admin") os.environ["ANTISPAM_MILTER_ADDRESS"] = system.get_host_address_from_environment("ANTISPAM_MILTER", "antispam:11332") os.environ["LMTP_ADDRESS"] = system.get_host_address_from_environment("LMTP", "imap:2525") +os.environ["POSTFIX_LOG_SYSLOG"] = os.environ.get("POSTFIX_LOG_SYSLOG","local") +os.environ["POSTFIX_LOG_FILE"] = os.environ.get("POSTFIX_LOG_FILE", "") for postfix_file in glob.glob("/conf/*.cf"): conf.jinja(postfix_file, os.environ, os.path.join("/etc/postfix", os.path.basename(postfix_file))) @@ -81,6 +83,16 @@ if "RELAYUSER" in os.environ: conf.jinja("/conf/sasl_passwd", os.environ, path) os.system("postmap {}".format(path)) +# Configure and start local rsyslog server +conf.jinja("/conf/rsyslog.conf", os.environ, "/etc/rsyslog.conf") +os.system("/usr/sbin/rsyslogd -n &") +# Configure logrotate and start crond +if os.environ["POSTFIX_LOG_FILE"] != "": + conf.jinja("/conf/logrotate.conf", os.environ, "/etc/logrotate.d/postfix.conf") + os.system("/usr/sbin/crond") + if os.path.exists("/overrides/logrotate.conf"): + shutil.copyfile("/overrides/logrotate.conf", "/etc/logrotate.d/postfix.conf") + # Run Podop and Postfix multiprocessing.Process(target=start_podop).start() multiprocessing.Process(target=start_mta_sts_daemon).start() diff --git a/docs/configuration.rst b/docs/configuration.rst index 0ca6cf8f..e83b3968 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -263,12 +263,9 @@ The roundcube service stores configurations in a database. - ``ROUNDCUBE_DB_USER``: the database user for roundcube service. (when not ``sqlite``) - ``ROUNDCUBE_DB_NAME``: the database name for roundcube service. (when not ``sqlite``) -.. _webmail_settings - Webmail settings ---------------- - When using roundcube it is possible to select the plugins to be enabled by setting ``ROUNDCUBE_PLUGINS`` to a comma separated list of plugin-names. Included plugins are: @@ -311,3 +308,15 @@ To disable all plugins just set ``ROUNDCUBE_PLUGINS`` to ``mailu``. To configure a plugin add php files named ``*.inc`` to roundcube's :ref:`override section `. +Mail log settings +----------------- + +By default, all services log directly to stdout/stderr. Logs can be collected by any docker log processing solution. + +Postfix writes the logs to a syslog server which logs to stdout. This is used to filter out messages from the healthcheck. +In some situations, a separate mail log is required (e.g. for legal reasons). The syslog server can be configured to write log files to a volume. It can be configured with the following option: + +- ``POSTFIX_LOG_FILE``: The file to log the mail log to. When enabled, the syslog server will also log to stdout. + +When ``POSTFIX_LOG_FILE`` is enabled, the logrotate program will automatically rotate the logs every week and keep 52 logs. +To override the logrotate configuration, create the file logrotate.conf with the desired configuration in the :ref:`Postfix overrides folder`. diff --git a/docs/faq.rst b/docs/faq.rst index 177e65d7..ced46237 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -263,6 +263,7 @@ correct syntax. The following file names will be taken as override configuration - All ``$ROOT/overrides/postfix/*.map`` files - For both ``postfix.cf`` and ``postfix.master``, you need to put one configuration per line, as they are fed line-by-line to postfix. + - ``logrotate.conf`` as ``$ROOT/overrides/postfix/logrotate.conf`` - Replaces the logrotate.conf file used for rotating ``POSTFIX_LOG_FILE``. - `Dovecot`_ - ``dovecot.conf`` in dovecot sub-directory; - `Nginx`_ - All ``*.conf`` files in the ``nginx`` sub-directory; - `Rspamd`_ - All files in the ``rspamd`` sub-directory. diff --git a/towncrier/newsfragments/1441.feature b/towncrier/newsfragments/1441.feature new file mode 100644 index 00000000..7704b2cb --- /dev/null +++ b/towncrier/newsfragments/1441.feature @@ -0,0 +1,6 @@ +Introduces postfix logging via syslog with these features: +- stdout logging still enabled +- internal test request log messages (healthcheck) are filtered out by rsyslog +- optional logging to file via POSTFIX_LOG_FILE env variable +To use logging to file configure in mailu.env +- ``POSTFIX_LOG_FILE``: The file to log the mail log to diff --git a/towncrier/newsfragments/2072.enhancement b/towncrier/newsfragments/2072.enhancement new file mode 100644 index 00000000..48275dff --- /dev/null +++ b/towncrier/newsfragments/2072.enhancement @@ -0,0 +1 @@ +use dovecot-fts-xapian from alpine package