diff --git a/docs/content/config/environment.md b/docs/content/config/environment.md index 062a20f8..535dec5b 100644 --- a/docs/content/config/environment.md +++ b/docs/content/config/environment.md @@ -75,8 +75,8 @@ Note: Emails will be rejected, if they don't pass the block list checks! ##### ENABLE_CLAMAV -- **0** => Clamav is disabled -- 1 => Clamav is enabled +- **0** => ClamAV is disabled +- 1 => ClamAV is enabled ##### ENABLE_POP3 @@ -192,6 +192,13 @@ Set the message size limit for all users. If set to zero, the size will be unlim - **empty** => 10240000 (~10 MB) +##### CLAMAV_MESSAGE_SIZE_LIMIT + +Mails larger than this limit won't be scanned. +ClamAV must be enabled (ENABLE_CLAMAV=1) for this. + +- **empty** => 25M (25 MB) + ##### ENABLE_MANAGESIEVE - **empty** => Managesieve service disabled @@ -319,9 +326,9 @@ Changes the interval in which a report is being sent. !!! note `LOGROTATE_INTERVAL` only manages `logrotate` within the container for services we manage internally. - + The entire log output for the container is still available via `docker logs mailserver` (or your respective container name). If you want to configure external log rotation for that container output as well, : [Docker Logging Drivers](https://docs.docker.com/config/containers/logging/configure/). - + By default, the logs are lost when the container is destroyed (eg: re-creating via `docker-compose down && docker-compose up -d`). To keep the logs, mount a volume (to `/var/log/mail/`). !!! note diff --git a/docs/content/faq.md b/docs/content/faq.md index 8c9b07bb..058865de 100644 --- a/docs/content/faq.md +++ b/docs/content/faq.md @@ -4,8 +4,8 @@ title: 'FAQ' ### What kind of database are you using? -None! No database is required. Filesystem is the database. -This image is based on config files that can be persisted using Docker volumes, and as such versioned, backed up and so forth. +None! No database is required. Filesystem is the database. +This image is based on config files that can be persisted using Docker volumes, and as such versioned, backed up and so forth. ### Where are emails stored? @@ -30,7 +30,7 @@ See [supervisorctl's documentation](http://supervisord.org/running.html#running- ### How can I sync container with host date/time? Timezone? -Share the host's [`/etc/localtime`](https://www.freedesktop.org/software/systemd/man/localtime.html) with the `docker-mailserver` container, using a Docker volume: +Share the host's [`/etc/localtime`](https://www.freedesktop.org/software/systemd/man/localtime.html) with the `docker-mailserver` container, using a Docker volume: ```yaml volumes: @@ -322,13 +322,13 @@ If we're blind, we won't be able to do anything. ### What system requirements are required to run `docker-mailserver` effectively? -1 core and 1GB of RAM + swap partition is recommended to run `docker-mailserver` with clamav. +1 core and 1GB of RAM + swap partition is recommended to run `docker-mailserver` with ClamAV. Otherwise, it could work with 512M of RAM. !!! warning - Clamav can consume a lot of memory, as it reads the entire signature database into RAM. + ClamAV can consume a lot of memory, as it reads the entire signature database into RAM. - Current figure is about 850M and growing. If you get errors about clamav or amavis failing to allocate memory you need more RAM or more swap and of course docker must be allowed to use swap (not always the case). If you can't use swap at all you may need 3G RAM. + Current figure is about 850M and growing. If you get errors about ClamAV or amavis failing to allocate memory you need more RAM or more swap and of course docker must be allowed to use swap (not always the case). If you can't use swap at all you may need 3G RAM. ### Can `docker-mailserver` run in a Rancher Environment? diff --git a/mailserver.env b/mailserver.env index 8ffdd88e..6d3d7bca 100644 --- a/mailserver.env +++ b/mailserver.env @@ -178,6 +178,12 @@ ENABLE_QUOTAS=1 # empty => 10240000 (~10 MB) POSTFIX_MESSAGE_SIZE_LIMIT= +# Mails larger than this limit won't be scanned. +# ClamAV must be enabled (ENABLE_CLAMAV=1) for this. +# +# empty => 25M (25 MB) +CLAMAV_MESSAGE_SIZE_LIMIT= + # Enables regular pflogsumm mail reports. # This is a new option. The old REPORT options are still supported for backwards compatibility. If this is not set and reports are enabled with the old options, logrotate will be used. # diff --git a/target/scripts/start-mailserver.sh b/target/scripts/start-mailserver.sh index f234d14c..b4da3e31 100755 --- a/target/scripts/start-mailserver.sh +++ b/target/scripts/start-mailserver.sh @@ -21,6 +21,7 @@ VARS[REPORT_RECIPIENT]="${REPORT_RECIPIENT:=${POSTMASTER_ADDRESS}}" VARS[REPORT_SENDER]="${REPORT_SENDER:=mailserver-report@${DOMAINNAME}}" VARS[AMAVIS_LOGLEVEL]="${AMAVIS_LOGLEVEL:=0}" +VARS[CLAMAV_MESSAGE_SIZE_LIMIT]="${CLAMAV_MESSAGE_SIZE_LIMIT:=25M}" # 25 MB VARS[DEFAULT_RELAY_HOST]="${DEFAULT_RELAY_HOST:=}" VARS[DMS_DEBUG]="${DMS_DEBUG:=0}" VARS[DOVECOT_INET_PROTOCOLS]="${DOVECOT_INET_PROTOCOLS:=all}" @@ -53,13 +54,13 @@ VARS[MOVE_SPAM_TO_JUNK]="${MOVE_SPAM_TO_JUNK:=1}" VARS[NETWORK_INTERFACE]="${NETWORK_INTERFACE:=eth0}" VARS[ONE_DIR]="${ONE_DIR:=1}" VARS[OVERRIDE_HOSTNAME]="${OVERRIDE_HOSTNAME:-}" +VARS[PERMIT_DOCKER]="${PERMIT_DOCKER:=none}" VARS[PFLOGSUMM_RECIPIENT]="${PFLOGSUMM_RECIPIENT:=${REPORT_RECIPIENT}}" VARS[PFLOGSUMM_SENDER]="${PFLOGSUMM_SENDER:=${REPORT_SENDER}}" VARS[PFLOGSUMM_TRIGGER]="${PFLOGSUMM_TRIGGER:=none}" -VARS[PERMIT_DOCKER]="${PERMIT_DOCKER:=none}" VARS[POSTFIX_INET_PROTOCOLS]="${POSTFIX_INET_PROTOCOLS:=all}" VARS[POSTFIX_MAILBOX_SIZE_LIMIT]="${POSTFIX_MAILBOX_SIZE_LIMIT:=0}" -VARS[POSTFIX_MESSAGE_SIZE_LIMIT]="${POSTFIX_MESSAGE_SIZE_LIMIT:=10240000}" # ~10MB +VARS[POSTFIX_MESSAGE_SIZE_LIMIT]="${POSTFIX_MESSAGE_SIZE_LIMIT:=10240000}" # ~10 MB VARS[POSTGREY_AUTO_WHITELIST_CLIENTS]="${POSTGREY_AUTO_WHITELIST_CLIENTS:=5}" VARS[POSTGREY_DELAY]="${POSTGREY_DELAY:=300}" VARS[POSTGREY_MAX_AGE]="${POSTGREY_MAX_AGE:=35}" @@ -116,6 +117,7 @@ function register_functions [[ ${DOVECOT_INET_PROTOCOLS} != 'all' ]] && _register_setup_function '_setup_dovecot_inet_protocols' [[ ${ENABLE_FAIL2BAN} -eq 1 ]] && _register_setup_function '_setup_fail2ban' [[ ${ENABLE_DNSBL} -eq 0 ]] && _register_setup_function '_setup_dnsbl_disable' + [[ ${CLAMAV_MESSAGE_SIZE_LIMIT} != '25M' ]] && _register_setup_function '_setup_clamav_sizelimit' _register_setup_function '_setup_dkim' _register_setup_function '_setup_ssl' diff --git a/target/scripts/startup/daemons-stack.sh b/target/scripts/startup/daemons-stack.sh index 43ed4d6e..b45d1e97 100644 --- a/target/scripts/startup/daemons-stack.sh +++ b/target/scripts/startup/daemons-stack.sh @@ -130,7 +130,7 @@ EOF function _start_daemons_clamav { - _notify 'task' 'Starting clamav' + _notify 'task' 'Starting ClamAV' supervisorctl start clamav || dms_panic__fail_init 'ClamAV' } diff --git a/target/scripts/startup/setup-stack.sh b/target/scripts/startup/setup-stack.sh index f7cda1bf..74f53aca 100644 --- a/target/scripts/startup/setup-stack.sh +++ b/target/scripts/startup/setup-stack.sh @@ -443,16 +443,22 @@ function _setup_postfix_postscreen function _setup_postfix_sizelimits { - _notify 'inf' "Configuring postfix message size limit" + _notify 'inf' "Configuring postfix message size limit to ${POSTFIX_MESSAGE_SIZE_LIMIT}" postconf -e "message_size_limit = ${POSTFIX_MESSAGE_SIZE_LIMIT}" - _notify 'inf' "Configuring postfix mailbox size limit" + _notify 'inf' "Configuring postfix mailbox size limit to ${POSTFIX_MAILBOX_SIZE_LIMIT}" postconf -e "mailbox_size_limit = ${POSTFIX_MAILBOX_SIZE_LIMIT}" - _notify 'inf' "Configuring postfix virtual mailbox size limit" + _notify 'inf' "Configuring postfix virtual mailbox size limit to ${POSTFIX_MAILBOX_SIZE_LIMIT}" postconf -e "virtual_mailbox_limit = ${POSTFIX_MAILBOX_SIZE_LIMIT}" } +function _setup_clamav_sizelimit +{ + _notify 'inf' "Configuring ClamAV message scan size limit to ${CLAMAV_MESSAGE_SIZE_LIMIT}" + sedfile -i "s/^MaxFileSize.*/MaxFileSize ${CLAMAV_MESSAGE_SIZE_LIMIT}/" /etc/clamav/clamd.conf +} + function _setup_postfix_smtputf8 { _notify 'inf' "Configuring postfix smtputf8 support (disable)" @@ -948,14 +954,14 @@ EOM fi fi - # Clamav + # ClamAV if [[ ${ENABLE_CLAMAV} -eq 0 ]] then - _notify 'warn' "Clamav is disabled. You can enable it with 'ENABLE_CLAMAV=1'" + _notify 'warn' "ClamAV is disabled. You can enable it with 'ENABLE_CLAMAV=1'" echo '@bypass_virus_checks_maps = (1);' >>"${DMS_AMAVIS_FILE}" elif [[ ${ENABLE_CLAMAV} -eq 1 ]] then - _notify 'inf' 'Enabling clamav' + _notify 'inf' 'Enabling ClamAV' fi echo '1; # ensure a defined return' >>"${DMS_AMAVIS_FILE}" diff --git a/test/mail_disabled_clamav_spamassassin.bats b/test/mail_disabled_clamav_spamassassin.bats index 4928bf96..fa2d988b 100644 --- a/test/mail_disabled_clamav_spamassassin.bats +++ b/test/mail_disabled_clamav_spamassassin.bats @@ -12,7 +12,7 @@ setup_file() { -e AMAVIS_LOGLEVEL=2 \ -h mail.my-domain.com -t "${NAME}" # TODO: find a better way to know when we have waited long enough - # for clamav to should have come up, if it were enabled + # for ClamAV to should have come up, if it were enabled wait_for_smtp_port_in_container mail_disabled_clamav_spamassassin docker exec mail_disabled_clamav_spamassassin /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt" } @@ -21,7 +21,7 @@ teardown_file() { docker rm -f mail_disabled_clamav_spamassassin } -@test "checking process: clamav (clamav disabled by ENABLED_CLAMAV=0)" { +@test "checking process: ClamAV (ClamAV disabled by ENABLED_CLAMAV=0)" { run docker exec mail_disabled_clamav_spamassassin /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/sbin/clamd'" assert_failure } @@ -31,17 +31,17 @@ teardown_file() { assert_success } -@test "checking clamav: should not be listed in amavis when disabled" { +@test "checking ClamAV: should not be listed in amavis when disabled" { run docker exec mail_disabled_clamav_spamassassin grep -i 'Found secondary av scanner ClamAV-clamscan' /var/log/mail/mail.log assert_failure } -@test "checking clamav: should not be called when disabled" { +@test "checking ClamAV: should not be called when disabled" { run docker exec mail_disabled_clamav_spamassassin grep -i 'connect to /var/run/clamav/clamd.ctl failed' /var/log/mail/mail.log assert_failure } -@test "checking restart of process: clamav (clamav disabled by ENABLED_CLAMAV=0)" { +@test "checking restart of process: ClamAV (ClamAV disabled by ENABLED_CLAMAV=0)" { run docker exec mail_disabled_clamav_spamassassin /bin/bash -c "pkill -f clamd && sleep 10 && ps aux --forest | grep -v grep | grep '/usr/sbin/clamd'" assert_failure } diff --git a/test/test_helper.bats b/test/test_helper.bats index 63610e35..86317652 100644 --- a/test/test_helper.bats +++ b/test/test_helper.bats @@ -204,7 +204,7 @@ load 'test_helper/common' local PRIVATE_CONFIG PRIVATE_CONFIG="$(duplicate_config_for_container .)" # variable not local to make visible to teardown - # enable clamav to make message delivery slower, so we can detect it + # enable ClamAV to make message delivery slower, so we can detect it CONTAINER_NAME="$(docker run -d --rm \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ @@ -235,7 +235,7 @@ load 'test_helper/common' local PRIVATE_CONFIG PRIVATE_CONFIG="$(duplicate_config_for_container .)" # variable not local to make visible to teardown - # enable clamav to make message delivery slower, so we can detect it + # enable ClamAV to make message delivery slower, so we can detect it CONTAINER_NAME="$(docker run -d --rm \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ diff --git a/test/tests.bats b/test/tests.bats index afd01051..29053792 100644 --- a/test/tests.bats +++ b/test/tests.bats @@ -14,16 +14,17 @@ setup_file() { -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/onedir":/var/mail-state \ -e AMAVIS_LOGLEVEL=2 \ + -e CLAMAV_MESSAGE_SIZE_LIMIT=30M \ -e DMS_DEBUG=0 \ -e ENABLE_CLAMAV=1 \ -e ENABLE_MANAGESIEVE=1 \ -e ENABLE_QUOTAS=1 \ -e ENABLE_SPAMASSASSIN=1 \ -e ENABLE_SRS=1 \ - -e PFLOGSUMM_TRIGGER=logrotate \ -e ENABLE_UPDATE_CHECK=0 \ -e PERMIT_DOCKER=container \ -e PERMIT_DOCKER=host \ + -e PFLOGSUMM_TRIGGER=logrotate \ -e REPORT_RECIPIENT=user1@localhost.localdomain \ -e REPORT_SENDER=report1@mail.my-domain.com \ -e SA_KILL=3.0 \ @@ -54,7 +55,7 @@ setup_file() { wait_for_smtp_port_in_container mail - # wait for clamav to be fully setup or we will get errors on the log + # wait for ClamAV to be fully setup or we will get errors on the log repeat_in_container_until_success_or_timeout 60 mail test -e /var/run/clamav/clamd.ctl # sending test mails @@ -421,14 +422,19 @@ EOF # -# clamav +# ClamAV # -@test "checking clamav: should be listed in amavis when enabled" { +@test "checking ClamAV: should be listed in amavis when enabled" { run docker exec mail grep -i 'Found secondary av scanner ClamAV-clamscan' /var/log/mail/mail.log assert_success } +@test "checking ClamAV: CLAMAV_MESSAGE_SIZE_LIMIT" { + run docker exec mail grep -q '^MaxFileSize 30M$' /etc/clamav/clamd.conf + assert_success +} + # # postsrsd #