2022-09-21 07:31:28 +00:00
# syntax=docker.io/docker/dockerfile:1
2022-08-27 23:42:42 +00:00
# This Dockerfile provides two stages: stage-base and stage-final
# This is in preparation for more granular stages (eg ClamAV and Fail2Ban split into their own)
#
# Base stage provides all packages, config, and adds scripts
#
FROM docker.io/debian:11-slim AS stage-base
2019-10-23 09:22:23 +00:00
2021-01-16 09:16:05 +00:00
ARG DEBIAN_FRONTEND = noninteractive
2023-01-02 12:25:14 +00:00
ARG DOVECOT_COMMUNITY_REPO = 1
2022-09-29 21:26:45 +00:00
ARG LOG_LEVEL = trace
2019-10-23 09:22:23 +00:00
2022-09-30 22:07:06 +00:00
SHELL [ "/bin/bash" , "-e" , "-o" , "pipefail" , "-c" ]
2019-08-13 09:41:38 +00:00
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
# --- Install Basic Software --------------------
# -----------------------------------------------
2021-01-16 09:16:05 +00:00
2022-10-15 10:01:59 +00:00
COPY target/bin/sedfile /usr/local/bin/sedfile
fix: Ensure state persisted to `/var/mail-state` retains correct group (#3011)
* fix: RSPAM ENV should only add to array if ENV enabled
* fix: Correctly match ownership for Postfix content
- `/var/lib/postfix` dir and content is `postfix:postfix`, not `postfix:root`.
- `/var/spool/postfix` is `root:root` not `postfix:root` like it's content.
- Add additional comments, including ownership changes by Postfix to `/var/spool/postfix` when process starts / restarts.
* fix: Ensure correct `chown -R` user and groups applied
These were all fine except for clamav not using the correct clamav group. `fetchmail` group is `nogroup` as per the group set by the debian package.
Additionally formatted the `-eq 1 ]]` content to align on the same columns, and added additional comment about the purpose of this `chown -R` usage so that it's clear what bug / breakage it's attempting to prevent / fix.
* refactor: `misc-stack.sh` conditional handling
The last condition doesn't get triggered at all AFAIK. Nor does it make sense to make a folder path with `mkdir -p` to symlink to when the container does not have anything to copy over?
- If that was for files, the `mkdir -p` approach seems invalid?
- If it was for a directory that could come up later, it should instead be created in advance? None of the current values for `FILES` seem to hit this path.
Removing as it doesn't seem relevant to current support.
Symlinking was done for each case, I've opted to just perform that after the conditional instead.
Additional inline docs added for additional context.
* chore: Move amavis `chown -R` fix into `misc-stack.sh`
This was handled separately for some reason. It belongs with the other services handling this fix in `misc-stack.sh`.
The `-h` option isn't relevant, when paired with `-R` it has no effect.
* fix: Dockerfile should preserve `clamav` ownership with `COPY --link`
The UID and GID were copied over but would not match `clamav` user and group due to numeric ID mismatch between containers. `--chown=clamav` fixes that.
* chore: Workaround `buildx` bug with separate `chown -R`
Avoids increasing the image weight from this change by leveraging `COPY` in the final stage.
* chore: `COPY --link` from a separate stage instead of relying on scratch
The `scratch` approach wasn't great. A single layer invalidation in the previous stage would result in a new 600MB layer to store.
`make build` with this change seems to barely be affected by such if a change came before copying over the linked stage, although with `buildx` and the `docker-container` driver with `--load` it would take much longer to import and seemed to keep adding storage. Possibly because I was testing with a minimal `buildx` command, that wasn't leveraging proper cache options?
* lint: Appease the linting gods
* chore: Align `misc-stack.sh` paths for `chown -R` operations
Review feedback
Co-authored-by: Casper <casperklein@users.noreply.github.com>
* fix: Reduce one extra cache layer copy
No apparent advantage of a `COPY --link` initially in separate stage.
Just `COPY --chown` in the separate stage and `COPY --link` the stage content. 230MB less in build cache used.
* fix: Remove separate ClamAV stage by adding `clamav` user explicitly
Creating the user before the package is installed allows to ensure a fixed numeric ID that we can provide to `--chown` that is compatible with `--link`.
This keeps the build cache minimal for CI, without being anymore complex as a workaround than the separate stage was for the most part.
* chore: Add reference link regarding users to `misc-stack.sh`
2023-01-24 23:53:47 +00:00
RUN <<EOF
chmod +x /usr/local/bin/sedfile
adduser --quiet --system --group --disabled-password --home /var/lib/clamav --no-create-home --uid 200 clamav
EOF
2022-10-15 10:01:59 +00:00
2022-09-21 07:31:28 +00:00
COPY target/scripts/build/* /build/
2022-08-29 22:33:15 +00:00
COPY target/scripts/helpers/log.sh /usr/local/bin/helpers/log.sh
2021-09-05 22:07:02 +00:00
2022-10-15 10:01:59 +00:00
RUN /bin/bash /build/packages.sh
2021-09-05 22:07:02 +00:00
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
# --- ClamAV & FeshClam -------------------------
# -----------------------------------------------
2015-03-28 14:59:15 +00:00
fix: Ensure state persisted to `/var/mail-state` retains correct group (#3011)
* fix: RSPAM ENV should only add to array if ENV enabled
* fix: Correctly match ownership for Postfix content
- `/var/lib/postfix` dir and content is `postfix:postfix`, not `postfix:root`.
- `/var/spool/postfix` is `root:root` not `postfix:root` like it's content.
- Add additional comments, including ownership changes by Postfix to `/var/spool/postfix` when process starts / restarts.
* fix: Ensure correct `chown -R` user and groups applied
These were all fine except for clamav not using the correct clamav group. `fetchmail` group is `nogroup` as per the group set by the debian package.
Additionally formatted the `-eq 1 ]]` content to align on the same columns, and added additional comment about the purpose of this `chown -R` usage so that it's clear what bug / breakage it's attempting to prevent / fix.
* refactor: `misc-stack.sh` conditional handling
The last condition doesn't get triggered at all AFAIK. Nor does it make sense to make a folder path with `mkdir -p` to symlink to when the container does not have anything to copy over?
- If that was for files, the `mkdir -p` approach seems invalid?
- If it was for a directory that could come up later, it should instead be created in advance? None of the current values for `FILES` seem to hit this path.
Removing as it doesn't seem relevant to current support.
Symlinking was done for each case, I've opted to just perform that after the conditional instead.
Additional inline docs added for additional context.
* chore: Move amavis `chown -R` fix into `misc-stack.sh`
This was handled separately for some reason. It belongs with the other services handling this fix in `misc-stack.sh`.
The `-h` option isn't relevant, when paired with `-R` it has no effect.
* fix: Dockerfile should preserve `clamav` ownership with `COPY --link`
The UID and GID were copied over but would not match `clamav` user and group due to numeric ID mismatch between containers. `--chown=clamav` fixes that.
* chore: Workaround `buildx` bug with separate `chown -R`
Avoids increasing the image weight from this change by leveraging `COPY` in the final stage.
* chore: `COPY --link` from a separate stage instead of relying on scratch
The `scratch` approach wasn't great. A single layer invalidation in the previous stage would result in a new 600MB layer to store.
`make build` with this change seems to barely be affected by such if a change came before copying over the linked stage, although with `buildx` and the `docker-container` driver with `--load` it would take much longer to import and seemed to keep adding storage. Possibly because I was testing with a minimal `buildx` command, that wasn't leveraging proper cache options?
* lint: Appease the linting gods
* chore: Align `misc-stack.sh` paths for `chown -R` operations
Review feedback
Co-authored-by: Casper <casperklein@users.noreply.github.com>
* fix: Reduce one extra cache layer copy
No apparent advantage of a `COPY --link` initially in separate stage.
Just `COPY --chown` in the separate stage and `COPY --link` the stage content. 230MB less in build cache used.
* fix: Remove separate ClamAV stage by adding `clamav` user explicitly
Creating the user before the package is installed allows to ensure a fixed numeric ID that we can provide to `--chown` that is compatible with `--link`.
This keeps the build cache minimal for CI, without being anymore complex as a workaround than the separate stage was for the most part.
* chore: Add reference link regarding users to `misc-stack.sh`
2023-01-24 23:53:47 +00:00
# Copy over latest DB updates from official ClamAV image. This is better than running `freshclam`,
# which would require an extra memory of 500MB+ during an image build.
# When using `COPY --link`, the `--chown` option is only compatible with numeric ID values.
# hadolint ignore=DL3021
COPY --link --chown= 200 --from= docker.io/clamav/clamav:latest /var/lib/clamav /var/lib/clamav
2022-09-30 22:07:06 +00:00
RUN <<EOF
echo '0 */6 * * * clamav /usr/bin/freshclam --quiet' >/etc/cron.d/clamav-freshclam
chmod 644 /etc/clamav/freshclam.conf
sedfile -i 's/Foreground false/Foreground true/g' /etc/clamav/clamd.conf
mkdir /var/run/clamav
chown -R clamav:root /var/run/clamav
2020-01-15 13:29:39 +00:00
rm -rf /var/log/clamav/
2022-09-30 22:07:06 +00:00
EOF
2016-10-08 17:02:47 +00:00
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
fix: Remove `mkcert.sh` usage + `_setup_ssl` refactor. (#2196)
* chore(refactor): DRY up the `_setup_ssl` method
- `/etc/postfix/ssl` was a bit misleading in usage here. As a maintainer (of my own contribution!) I was confused why only `/etc/postfix/ssl` was referenced and not `/etc/dovecot/ssl`.
- The postfix specific path is unnecessary, dovecot was referencing it via it's config, the same can be done from postfix to a generic DMS specific config location instead.
- This location is defined and created early as `/etc/dms/tls` (with var `DMS_TLS_PATH`). All usage of `/etc/postfix/ssl` has been replaced, making it easier to grok. Several `mkdir` commands related to this have been dropped as a result.
- Likewise, a related `TMP_DMS_TLS_PATH` var provides a reference to the config volume path `/tmp/docker-mailserver` which is used for conditions on presently hard-coded paths.
- Other values that benefit from being DRY have been lifted up into vars. Definitely easier to follow now and makes some further opportunities clearer to tackle in a future refactor.
- `chmod` has been updated where appropriate. Public key/cert is acceptable to have as readable by non-root users (644). The custom type with single fullchain file was not root accessible only, but should as it contains a private key.
- That said, the security benefit can be a bit moot due to source files that were copied remain present, the user would be responsible to ensure similar permissions on their source files.
- I've not touched LetsEncrypt section as I don't have time to investigate into that yet (not familiar with that portion).
---
* chore: Remove mkcert logic and dovecot cert
- No longer serving a purpose.
- Our own TLS startup script handles a variety of cert scenarios, while the dropped code was always generating a self-signed cert and persisting an unused cert regardless with `ONE_DIR=1`.
- To avoid similar issues that DH params had with doveadm validating filepath values in the SSL config, the default dummy values match postfix pointing to "snakeoil" cert. That serves the same purpose as mkcert was covering in the image.
- Bonus, no more hassle with differing mkcert target paths for users replacing our supplied Dovecot with the latest community edition.
---
* Error handling for SSL_TYPE
- Added a panic utility to exit early when SSL_TYPE conditions are misconfigured.
- Some info text had order of key/cert occurrence swapped to be consistent with key then cert.
- Some existing comments moved and rephrased.
- Additional comments added.
- `-f` test for cert files instead of `-e` (true also for directories/devices/symlinks).
- _notify messages lifted out of conditionals so that they always output when the case is hit.
- ~~Empty SSL_TYPE collapsed into catch all panic, while it's contents is now mapped to a new 'disabled' value.~~
---
* Use sedfile + improve sed expressions + update case style
- Uses sedfile when appropriate (file change intentional, not optional match/check).
- sed expressions modified to be DRY and reduce escaping via `-r` flag (acceptable if actual text content contains no `?`,`+`,`()` or `{}` characters, [otherwise they must be escaped](https://www.gnu.org/software/sed/manual/html_node/Extended-regexps.html)).
- sed captures anything matched between the parenthesis`()` and inserts it via `\1` as part of the replacement.
- case statements adopt the `(` prefix, adopting recent shell style for consistency.
---
* Refactor SSL_TYPE=disabled
- Postfix is also disabled now.
- Included heavy inline documentation reference for maintainers.
- Dropped an obsolete postfix config option 'use_tls' on the relayhost function, it was replaced by 'security_level'.
---
* I'm a friggin' sed wizard now
- The `modern` TLS_LEVEL is the default values for the configs they modify. As such, `sedfile` outputs an "Error" which isn't an actual concern, back to regular `sed`.
- I realized that multiple edits for the same file can all be done at once via `-e` (assuming other sed options are the same for each operation), and that `g` suffix is global scope for single line match, not whole file (default as sed iterates through individual lines).
- Some postfix replacements have `smtp` and `smtpd` lines, collapsed into a single `smtpd?` instead now that I know sed better.
---
* tests(fix): Tests that require SSL/TLS to pass
- SSL_TYPE=snakeoil added as temporary workaround.
- nmap tests are being dropped. These were added about 4-5 years ago, I have since made these redundant with the `testssl.sh` tests.
- Additionally the `--link` option is deprecated and IIRC these grades were a bit misleading when I initially used nmap in my own TLS cipher suite update PRs in the past.
- The removed SSL test is already handled in mail_ssl_manual.bats
ldap test:
- Replace `--link` alias option with `--network` and alias assignment.
- Parameterized some values and added the `SSL_TYPE` to resolve the starttls test failure.
privacy test:
- Also needed `SSL_TYPE` to pass the starttls test.
`tests.bats` had another starttls test for imap:
- Workaround for now is to give the main test container `SSL_TYPE=snakeoil`.
---
* Remove the expired lets-encrypt cert
This expired in March 2021. It was originally required when first added back in 2016 as LetsEncrypt was fairly new and not as broadly accepted into OS trust stores.
No longer the case today.
---
* chore: Housekeeping
Not required for this PR branch, little bit of tidying up while working on these two test files.
- privacy test copied over content when extracted from `tests.bats` that isn't relevant.
- ldap test was not as easy to identify the source of DOVECOT_TLS. Added comment to make the prefix connection to `configomat.sh` and `.ext` files more easier to find.
- Additionally converted the two localhost FQDN to vars.
---
* Default SSL_TYPE becomes `''` (aka equivalent to desired `disabled` case)
- This is to prevent other tests from failing by hitting the panic catchall case.
- More ideal would be adjusting tests to default to `disabled`, rather than treating `disabled` as an empty / unset SSL_TYPE value.
---
* Add inline documentation for `dms_panic`
- This could later be better formatted and placed into contributor docs.
Panic with kill (shutdown) not exit (errex):
- `kill 1` from `_shutdown` will send SIGTERM signal to PID 1 (init process).
- `exit 1` within the `start-mailserver.sh` init scripts context, will just exit the initialization script leaving the container running when it shouldn't.
The two previous `_shutdown` methods can benefit from using `dms_panic` wrapper instead to standardize on panic messages.
2021-09-19 12:31:11 +00:00
# --- Dovecot -----------------------------------
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
2021-01-16 09:16:05 +00:00
2022-05-07 22:28:32 +00:00
COPY target/dovecot/auth-passwdfile.inc target/dovecot/auth-master.inc target/dovecot/??-*.conf /etc/dovecot/conf.d/
2020-05-03 22:24:10 +00:00
COPY target/dovecot/sieve/ /etc/dovecot/sieve/
2020-12-06 18:57:38 +00:00
COPY target/dovecot/dovecot-purge.cron /etc/cron.d/dovecot-purge.disabled
RUN chmod 0 /etc/cron.d/dovecot-purge.disabled
2019-08-13 09:41:38 +00:00
WORKDIR /usr/share/dovecot
2021-01-16 09:16:05 +00:00
# hadolint ignore=SC2016,SC2086,SC2069
2022-09-30 22:07:06 +00:00
RUN <<EOF
sedfile -i -e 's/include_try \/usr\/share\/dovecot\/protocols\.d/include_try \/etc\/dovecot\/protocols\.d/g' /etc/dovecot/dovecot.conf
sedfile -i -e 's/#mail_plugins = \$mail_plugins/mail_plugins = \$mail_plugins sieve/g' /etc/dovecot/conf.d/15-lda.conf
sedfile -i -e 's/^.*lda_mailbox_autocreate.*/lda_mailbox_autocreate = yes/g' /etc/dovecot/conf.d/15-lda.conf
sedfile -i -e 's/^.*lda_mailbox_autosubscribe.*/lda_mailbox_autosubscribe = yes/g' /etc/dovecot/conf.d/15-lda.conf
sedfile -i -e 's/^.*postmaster_address.*/postmaster_address = ' ${ POSTMASTER_ADDRESS : = "postmaster@domain.com" } '/g' /etc/dovecot/conf.d/15-lda.conf
mkdir -p /usr/lib/dovecot/sieve-pipe /usr/lib/dovecot/sieve-filter /usr/lib/dovecot/sieve-global
2019-08-09 20:13:50 +00:00
chmod 755 -R /usr/lib/dovecot/sieve-pipe /usr/lib/dovecot/sieve-filter /usr/lib/dovecot/sieve-global
2022-09-30 22:07:06 +00:00
EOF
2015-03-29 12:07:56 +00:00
2023-01-05 07:39:00 +00:00
# -----------------------------------------------
# --- Rspamd ------------------------------------
# -----------------------------------------------
COPY target/rspamd/local.d/ /etc/rspamd/local.d/
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
# --- LDAP & SpamAssassin's Cron ----------------
# -----------------------------------------------
2021-01-16 09:16:05 +00:00
2016-11-13 10:39:45 +00:00
COPY target/dovecot/dovecot-ldap.conf.ext /etc/dovecot
2021-01-16 09:16:05 +00:00
COPY \
target/postfix/ldap-users.cf \
target/postfix/ldap-groups.cf \
target/postfix/ldap-aliases.cf \
target/postfix/ldap-domains.cf \
2021-04-17 20:40:19 +00:00
target/postfix/ldap-senders.cf \
2021-01-16 09:16:05 +00:00
/etc/postfix/
2016-11-13 10:39:45 +00:00
2019-08-13 09:41:38 +00:00
# hadolint ignore=SC2016
2022-09-30 22:07:06 +00:00
RUN <<EOF
sedfile -i -r 's/^(CRON)=0/\1=1/g' /etc/default/spamassassin
sedfile -i -r 's/^\$INIT restart/supervisorctl restart amavis/g' /etc/spamassassin/sa-update-hooks.d/amavisd-new
mkdir -p /etc/spamassassin/kam/
curl -sSfLo /etc/spamassassin/kam/kam.sa-channels.mcgrail.com.key https://mcgrail.com/downloads/kam.sa-channels.mcgrail.com.key
EOF
2015-03-28 14:59:15 +00:00
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
# --- PostSRSD, Postgrey & Amavis ---------------
# -----------------------------------------------
2021-01-16 09:16:05 +00:00
COPY target/postsrsd/postsrsd /etc/default/postsrsd
2017-02-06 09:21:18 +00:00
COPY target/postgrey/postgrey /etc/default/postgrey
COPY target/postgrey/postgrey.init /etc/init.d/postgrey
2022-09-30 22:07:06 +00:00
RUN <<EOF
chmod 755 /etc/init.d/postgrey
mkdir /var/run/postgrey
chown postgrey:postgrey /var/run/postgrey
2021-06-17 16:16:28 +00:00
curl -Lsfo /etc/postgrey/whitelist_clients https://postgrey.schweikert.ch/pub/postgrey_whitelist_clients
2022-09-30 22:07:06 +00:00
EOF
2017-02-06 09:21:18 +00:00
2017-08-09 21:19:00 +00:00
COPY target/amavis/conf.d/* /etc/amavis/conf.d/
2023-02-03 16:32:07 +00:00
COPY target/amavis/postfix-amavis.cf /etc/dms/postfix/master.d/
2022-09-30 22:07:06 +00:00
RUN <<EOF
sedfile -i -r 's/#(@| \\%)bypass/\1bypass/g' /etc/amavis/conf.d/15-content_filter_mode
2021-09-19 12:36:26 +00:00
# add users clamav and amavis to each others group
2022-09-30 22:07:06 +00:00
adduser clamav amavis
adduser amavis clamav
2021-01-18 19:51:56 +00:00
# no syslog user in Debian compared to Ubuntu
2022-09-30 22:07:06 +00:00
adduser --system syslog
useradd -u 5000 -d /home/docker -s /bin/bash -p " $( echo docker | openssl passwd -1 -stdin) " docker
echo "0 4 * * * /usr/local/bin/virus-wiper" | crontab -
2020-10-05 15:11:15 +00:00
chmod 644 /etc/amavis/conf.d/*
2022-09-30 22:07:06 +00:00
EOF
2015-03-28 14:59:15 +00:00
2021-01-19 14:32:16 +00:00
# overcomplication necessary for CI
2022-09-30 22:07:06 +00:00
RUN <<EOF
for _ in { 1..10} ; do
su - amavis -c "razor-admin -create"
sleep 3
if su - amavis -c "razor-admin -register" ; then
EC = 0
break
else
EC = ${ ? }
fi
done
exit ${ EC }
EOF
2021-01-16 09:16:05 +00:00
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
# --- Fail2Ban, DKIM & DMARC --------------------
# -----------------------------------------------
2021-01-16 09:16:05 +00:00
2021-04-11 15:33:39 +00:00
COPY target/fail2ban/jail.local /etc/fail2ban/jail.local
2023-01-04 16:57:08 +00:00
COPY target/fail2ban/fail2ban.d/fixes.local /etc/fail2ban/fail2ban.d/fixes.local
2022-09-30 22:07:06 +00:00
RUN <<EOF
ln -s /var/log/mail/mail.log /var/log/mail.log
2021-04-11 15:33:39 +00:00
# disable sshd jail
2022-09-30 22:07:06 +00:00
rm /etc/fail2ban/jail.d/defaults-debian.conf
2021-04-11 15:33:39 +00:00
mkdir /var/run/fail2ban
2022-09-30 22:07:06 +00:00
EOF
2016-04-17 20:59:35 +00:00
2016-09-04 18:37:16 +00:00
COPY target/opendkim/opendkim.conf /etc/opendkim.conf
COPY target/opendkim/default-opendkim /etc/default/opendkim
2016-01-20 15:41:34 +00:00
2016-09-04 18:37:16 +00:00
COPY target/opendmarc/opendmarc.conf /etc/opendmarc.conf
COPY target/opendmarc/default-opendmarc /etc/default/opendmarc
2016-10-25 06:57:08 +00:00
COPY target/opendmarc/ignore.hosts /etc/opendmarc/ignore.hosts
2016-01-26 17:26:50 +00:00
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
# --- Fetchmail, Postfix & Let'sEncrypt ---------
# -----------------------------------------------
2021-01-16 09:16:05 +00:00
2022-03-22 16:53:12 +00:00
# Remove invalid URL from SPF message
# https://bugs.launchpad.net/spf-engine/+bug/1896912
RUN echo 'Reason_Message = Message {rejectdefer} due to: {spf}.' >>/etc/postfix-policyd-spf-python/policyd-spf.conf
2021-01-16 09:16:05 +00:00
COPY target/fetchmail/fetchmailrc /etc/fetchmailrc_general
2016-09-04 18:37:16 +00:00
COPY target/postfix/main.cf target/postfix/master.cf /etc/postfix/
2021-09-15 08:28:04 +00:00
# DH parameters for DHE cipher suites, ffdhe4096 is the official standard 4096-bit DH params now part of TLS 1.3
# This file is for TLS <1.3 handshakes that rely on DHE cipher suites
# Handled at build to avoid failures by doveadm validating ssl_dh filepath in 10-ssl.auth (eg generate-accounts)
COPY target/shared/ffdhe4096.pem /etc/postfix/dhparams.pem
COPY target/shared/ffdhe4096.pem /etc/dovecot/dh.pem
2021-01-16 09:16:05 +00:00
COPY \
target/postfix/header_checks.pcre \
target/postfix/sender_header_filter.pcre \
target/postfix/sender_login_maps.pcre \
/etc/postfix/maps/
2015-03-31 15:27:54 +00:00
2022-09-30 22:07:06 +00:00
RUN <<EOF
: >/etc/aliases
sedfile -i 's/START_DAEMON=no/START_DAEMON=yes/g' /etc/default/fetchmail
fix: Remove `mkcert.sh` usage + `_setup_ssl` refactor. (#2196)
* chore(refactor): DRY up the `_setup_ssl` method
- `/etc/postfix/ssl` was a bit misleading in usage here. As a maintainer (of my own contribution!) I was confused why only `/etc/postfix/ssl` was referenced and not `/etc/dovecot/ssl`.
- The postfix specific path is unnecessary, dovecot was referencing it via it's config, the same can be done from postfix to a generic DMS specific config location instead.
- This location is defined and created early as `/etc/dms/tls` (with var `DMS_TLS_PATH`). All usage of `/etc/postfix/ssl` has been replaced, making it easier to grok. Several `mkdir` commands related to this have been dropped as a result.
- Likewise, a related `TMP_DMS_TLS_PATH` var provides a reference to the config volume path `/tmp/docker-mailserver` which is used for conditions on presently hard-coded paths.
- Other values that benefit from being DRY have been lifted up into vars. Definitely easier to follow now and makes some further opportunities clearer to tackle in a future refactor.
- `chmod` has been updated where appropriate. Public key/cert is acceptable to have as readable by non-root users (644). The custom type with single fullchain file was not root accessible only, but should as it contains a private key.
- That said, the security benefit can be a bit moot due to source files that were copied remain present, the user would be responsible to ensure similar permissions on their source files.
- I've not touched LetsEncrypt section as I don't have time to investigate into that yet (not familiar with that portion).
---
* chore: Remove mkcert logic and dovecot cert
- No longer serving a purpose.
- Our own TLS startup script handles a variety of cert scenarios, while the dropped code was always generating a self-signed cert and persisting an unused cert regardless with `ONE_DIR=1`.
- To avoid similar issues that DH params had with doveadm validating filepath values in the SSL config, the default dummy values match postfix pointing to "snakeoil" cert. That serves the same purpose as mkcert was covering in the image.
- Bonus, no more hassle with differing mkcert target paths for users replacing our supplied Dovecot with the latest community edition.
---
* Error handling for SSL_TYPE
- Added a panic utility to exit early when SSL_TYPE conditions are misconfigured.
- Some info text had order of key/cert occurrence swapped to be consistent with key then cert.
- Some existing comments moved and rephrased.
- Additional comments added.
- `-f` test for cert files instead of `-e` (true also for directories/devices/symlinks).
- _notify messages lifted out of conditionals so that they always output when the case is hit.
- ~~Empty SSL_TYPE collapsed into catch all panic, while it's contents is now mapped to a new 'disabled' value.~~
---
* Use sedfile + improve sed expressions + update case style
- Uses sedfile when appropriate (file change intentional, not optional match/check).
- sed expressions modified to be DRY and reduce escaping via `-r` flag (acceptable if actual text content contains no `?`,`+`,`()` or `{}` characters, [otherwise they must be escaped](https://www.gnu.org/software/sed/manual/html_node/Extended-regexps.html)).
- sed captures anything matched between the parenthesis`()` and inserts it via `\1` as part of the replacement.
- case statements adopt the `(` prefix, adopting recent shell style for consistency.
---
* Refactor SSL_TYPE=disabled
- Postfix is also disabled now.
- Included heavy inline documentation reference for maintainers.
- Dropped an obsolete postfix config option 'use_tls' on the relayhost function, it was replaced by 'security_level'.
---
* I'm a friggin' sed wizard now
- The `modern` TLS_LEVEL is the default values for the configs they modify. As such, `sedfile` outputs an "Error" which isn't an actual concern, back to regular `sed`.
- I realized that multiple edits for the same file can all be done at once via `-e` (assuming other sed options are the same for each operation), and that `g` suffix is global scope for single line match, not whole file (default as sed iterates through individual lines).
- Some postfix replacements have `smtp` and `smtpd` lines, collapsed into a single `smtpd?` instead now that I know sed better.
---
* tests(fix): Tests that require SSL/TLS to pass
- SSL_TYPE=snakeoil added as temporary workaround.
- nmap tests are being dropped. These were added about 4-5 years ago, I have since made these redundant with the `testssl.sh` tests.
- Additionally the `--link` option is deprecated and IIRC these grades were a bit misleading when I initially used nmap in my own TLS cipher suite update PRs in the past.
- The removed SSL test is already handled in mail_ssl_manual.bats
ldap test:
- Replace `--link` alias option with `--network` and alias assignment.
- Parameterized some values and added the `SSL_TYPE` to resolve the starttls test failure.
privacy test:
- Also needed `SSL_TYPE` to pass the starttls test.
`tests.bats` had another starttls test for imap:
- Workaround for now is to give the main test container `SSL_TYPE=snakeoil`.
---
* Remove the expired lets-encrypt cert
This expired in March 2021. It was originally required when first added back in 2016 as LetsEncrypt was fairly new and not as broadly accepted into OS trust stores.
No longer the case today.
---
* chore: Housekeeping
Not required for this PR branch, little bit of tidying up while working on these two test files.
- privacy test copied over content when extracted from `tests.bats` that isn't relevant.
- ldap test was not as easy to identify the source of DOVECOT_TLS. Added comment to make the prefix connection to `configomat.sh` and `.ext` files more easier to find.
- Additionally converted the two localhost FQDN to vars.
---
* Default SSL_TYPE becomes `''` (aka equivalent to desired `disabled` case)
- This is to prevent other tests from failing by hitting the panic catchall case.
- More ideal would be adjusting tests to default to `disabled`, rather than treating `disabled` as an empty / unset SSL_TYPE value.
---
* Add inline documentation for `dms_panic`
- This could later be better formatted and placed into contributor docs.
Panic with kill (shutdown) not exit (errex):
- `kill 1` from `_shutdown` will send SIGTERM signal to PID 1 (init process).
- `exit 1` within the `start-mailserver.sh` init scripts context, will just exit the initialization script leaving the container running when it shouldn't.
The two previous `_shutdown` methods can benefit from using `dms_panic` wrapper instead to standardize on panic messages.
2021-09-19 12:31:11 +00:00
mkdir /var/run/fetchmail && chown fetchmail /var/run/fetchmail
2022-09-30 22:07:06 +00:00
EOF
2021-01-16 09:16:05 +00:00
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
# --- Logs --------------------------------------
# -----------------------------------------------
2021-01-16 09:16:05 +00:00
2022-09-30 22:07:06 +00:00
RUN <<EOF
sedfile -i -r "/^#?compress/c\compress\ncopytruncate" /etc/logrotate.conf
mkdir -p /var/log/mail
chown syslog:root /var/log/mail
touch /var/log/mail/clamav.log
chown -R clamav:root /var/log/mail/clamav.log
touch /var/log/mail/freshclam.log
chown -R clamav:root /var/log/mail/freshclam.log
sedfile -i -r 's|/var/log/mail|/var/log/mail/mail|g' /etc/rsyslog.conf
sedfile -i -r 's|;auth,authpriv.none|;mail.none;mail.error;auth,authpriv.none|g' /etc/rsyslog.conf
sedfile -i -r 's|LogFile /var/log/clamav/|LogFile /var/log/mail/|g' /etc/clamav/clamd.conf
sedfile -i -r 's|UpdateLogFile /var/log/clamav/|UpdateLogFile /var/log/mail/|g' /etc/clamav/freshclam.conf
sedfile -i -r 's|/var/log/clamav|/var/log/mail|g' /etc/logrotate.d/clamav-daemon
sedfile -i -r 's|invoke-rc.d.*|/usr/bin/supervisorctl signal hup clamav >/dev/null \|\| true|g' /etc/logrotate.d/clamav-daemon
sedfile -i -r 's|/var/log/clamav|/var/log/mail|g' /etc/logrotate.d/clamav-freshclam
sedfile -i -r '/postrotate/,/endscript/d' /etc/logrotate.d/clamav-freshclam
sedfile -i -r 's|/var/log/mail|/var/log/mail/mail|g' /etc/logrotate.d/rsyslog
sedfile -i -r '/\/var\/log\/mail\/mail.log/d' /etc/logrotate.d/rsyslog
2021-01-18 19:51:56 +00:00
# prevent syslog logrotate warnings
2022-09-30 22:07:06 +00:00
sedfile -i -e 's/\(printerror "could not determine current runlevel"\)/#\1/' /usr/sbin/invoke-rc.d
sedfile -i -e 's/^\(POLICYHELPER=\).*/\1/' /usr/sbin/invoke-rc.d
2021-01-16 09:16:05 +00:00
# prevent syslog warning about imklog permissions
2022-09-30 22:07:06 +00:00
sedfile -i -e 's/^module(load=\"imklog\")/#module(load=\"imklog\")/' /etc/rsyslog.conf
2021-01-18 19:51:56 +00:00
# prevent email when /sbin/init or init system is not existing
2021-09-05 22:07:02 +00:00
sedfile -i -e 's|invoke-rc.d rsyslog rotate > /dev/null|/usr/bin/supervisorctl signal hup rsyslog >/dev/null|g' /usr/lib/rsyslog/rsyslog-rotate
2022-09-30 22:07:06 +00:00
EOF
2016-04-18 21:38:52 +00:00
2021-08-11 09:31:00 +00:00
# -----------------------------------------------
# --- Logwatch ----------------------------------
# -----------------------------------------------
COPY target/logwatch/maillog.conf /etc/logwatch/conf/logfiles/maillog.conf
2021-06-08 01:20:20 +00:00
# -----------------------------------------------
# --- Supervisord & Start -----------------------
# -----------------------------------------------
2016-02-08 22:47:42 +00:00
2017-09-10 13:26:21 +00:00
COPY target/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
COPY target/supervisor/conf.d/* /etc/supervisor/conf.d/
2016-01-23 22:51:09 +00:00
2021-09-19 12:36:26 +00:00
# -----------------------------------------------
# --- Scripts & Miscellaneous--------------------
# -----------------------------------------------
2022-09-30 22:07:06 +00:00
RUN <<EOF
rm -rf /usr/share/locale/*
rm -rf /usr/share/man/*
rm -rf /usr/share/doc/*
update-locale
rm /etc/postsrsd.secret
2021-09-19 12:36:26 +00:00
rm /etc/cron.daily/00logwatch
2022-09-30 22:07:06 +00:00
EOF
2021-09-19 12:36:26 +00:00
2022-08-29 22:33:15 +00:00
COPY VERSION /
2021-09-19 12:36:26 +00:00
COPY \
2022-08-29 22:33:15 +00:00
target/bin/* \
target/scripts/*.sh \
target/scripts/startup/*.sh \
target/scripts/wrapper/*.sh \
target/docker-configomat/configomat.sh \
2021-09-19 12:36:26 +00:00
/usr/local/bin/
RUN chmod +x /usr/local/bin/*
2022-08-29 22:33:15 +00:00
COPY target/scripts/helpers /usr/local/bin/helpers
2021-11-20 20:33:49 +00:00
2022-08-27 23:42:42 +00:00
#
# Final stage focuses only on image config
#
2019-08-13 09:41:38 +00:00
2022-08-27 23:42:42 +00:00
FROM stage-base AS stage-final
2022-09-16 17:23:33 +00:00
ARG VCS_REVISION = unknown
ARG VCS_VERSION = edge
2016-09-29 20:52:05 +00:00
2022-08-27 23:42:42 +00:00
WORKDIR /
EXPOSE 25 587 143 465 993 110 995 4190
2021-01-16 18:35:42 +00:00
ENTRYPOINT [ "/usr/bin/dumb-init" , "--" ]
2018-11-04 19:23:50 +00:00
CMD [ "supervisord" , "-c" , "/etc/supervisor/supervisord.conf" ]
2022-08-27 23:42:42 +00:00
# These ENVs are referenced in target/supervisor/conf.d/saslauth.conf
# and must be present when supervisord starts. Introduced by PR:
# https://github.com/docker-mailserver/docker-mailserver/pull/676
# These ENV are also configured with the same defaults at:
# https://github.com/docker-mailserver/docker-mailserver/blob/672e9cf19a3bb1da309e8cea6ee728e58f905366/target/scripts/helpers/variables.sh
ENV FETCHMAIL_POLL = 300
ENV POSTGREY_AUTO_WHITELIST_CLIENTS = 5
ENV POSTGREY_DELAY = 300
ENV POSTGREY_MAX_AGE = 35
ENV POSTGREY_TEXT = "Delayed by Postgrey"
ENV SASLAUTHD_MECH_OPTIONS = ""
# Add metadata to image:
LABEL org.opencontainers.image.title= "docker-mailserver"
LABEL org.opencontainers.image.vendor= "The Docker Mailserver Organization"
LABEL org.opencontainers.image.authors= "The Docker Mailserver Organization on GitHub"
LABEL org.opencontainers.image.licenses= "MIT"
LABEL org.opencontainers.image.description= "A fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.). Only configuration files, no SQL database."
LABEL org.opencontainers.image.url= "https://github.com/docker-mailserver"
LABEL org.opencontainers.image.documentation= "https://github.com/docker-mailserver/docker-mailserver/blob/master/README.md"
LABEL org.opencontainers.image.source= "https://github.com/docker-mailserver/docker-mailserver"
# ARG invalidates cache when it is used by a layer (implicitly affects RUN)
# Thus to maximize cache, keep these lines last:
2022-09-16 17:23:33 +00:00
LABEL org.opencontainers.image.revision= ${ VCS_REVISION }
LABEL org.opencontainers.image.version= ${ VCS_VERSION }