1
1
Fork 0
mirror of https://github.com/docker-mailserver/docker-mailserver synced 2024-04-28 08:45:06 +02:00
docker-mailserver/docs/content/faq.md
wernerfred 463bc967d2 docs(fix): Update wiki references to the new docs url
Additionally replaces old references to `tvial` images with the new `mailserver` docker image name.
2021-03-25 11:49:24 +13:00

16 KiB

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.

Where are emails stored?

Mails are stored in /var/mail/${domain}/${username}.

You should use a data volume container for /var/mail to persist data.

Otherwise, your data may be lost.

How to alter the running mailserver instance without relaunching the container?

docker-mailserver aggregates multiple "sub-services", such as Postfix, Dovecot, Fail2ban, SpamAssasin, etc. In many cases, one may edit a sub-service's config and reload that very sub-service, without stopping and relaunching the whole mail server.

In order to do so, you'll probably want to push your config updates to your server through a Docker volume, then restart the sub-service to apply your changes, using supervisorctl. For instance, after editing fail2ban's config: supervisorctl restart fail2ban.

See supervisorctl's documentation.

!!! tip To add, update or delete an email account; there is no need to restart postfix / dovecot service inside the container after using setup.sh script.

For more information, see [#1639][github-issue-1639].

How can I sync container with host date/time? Timezone?

Share the host's /etc/localtime with the docker-mailserver container, using a Docker volume:

volumes:
  - /etc/localtime:/etc/localtime:ro

!!! help "Optional" Add one line to .env or env-mailserver to set timetzone for container, for example:

```env
TZ=Europe/Berlin
```

Check here for the [`tz name list`](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)

What is the file format?

All files are using the Unix format with LF line endings.

Please do not use CRLF.

What about backups?

Assuming that you use docker-compose and a data volumes, you can backup your user mails like this:

docker run --rm -ti \
  -v maildata:/var/mail \
  -v mailstate:/var/mail-state \
  -v /backup/mail:/backup \
  alpine:3.2 \
  tar czf "/backup/mail-$(date +%y%m%d-%H%M%S).tgz" /var/mail /var/mail-state

find /backup/mail -type f -mtime +30 -exec rm -f {} \;

What about mail-state folder?

This folder consolidates all data generated by the server itself to persist when you upgrade. Example of data folder persisted: lib-amavis, lib-clamav, lib-fail2ban, lib-postfix, lib-postgrey, lib-spamassasin, lib-spamassassin, spool-postfix, ...

How can I configure my email client?

Login are full email address (user@domain.com).

# imap
username:           <user1@domain.tld>
password:           <mypassword>
server:             <mail.domain.tld>
imap port:          143 or 993 with ssl (recommended)
imap path prefix:   INBOX

# smtp
smtp port:          25 or 587 with ssl (recommended)
username:           <user1@domain.tld>
password:           <mypassword>

Please use STARTTLS.

How can I manage my custom Spamassassin rules?

Antispam rules are managed in config/spamassassin-rules.cf.

What are acceptable SA_SPAM_SUBJECT values?

For no subject set SA_SPAM_SUBJECT=undef.

For a trailing white-space subject one can define the whole variable with quotes in docker-compose.yml:

environment:
  - "SA_SPAM_SUBJECT=[SPAM] "

Can I use naked/bare domains (no host name)?

Yes, but not without some configuration changes. Normally it is assumed that docker-mailserver runs on a host with a name, so the fully qualified host name might be mail.example.com with the domain example.com. The MX records point to mail.example.com.

To use a bare domain where the host name is example.com and the domain is also example.com, change mydestination:

  • From: mydestination = $myhostname, localhost.$mydomain, localhost
  • To: mydestination = localhost.$mydomain, localhost

Add the latter line to config/postfix-main.cf. That should work. Without that change there will be warnings in the logs like:

warning: do not list domain example.com in BOTH mydestination and virtual_mailbox_domains

Plus of course mail delivery fails.

Why are Spamassassin x-headers not inserted into my sample.domain.com subdomain emails?

In the default setup, amavis only applies Spamassassin x-headers into domains matching the template listed in the config file (05-domain_id in the amavis defaults).

The default setup @local_domains_acl = ( ".$mydomain" ); does not match subdomains. To match subdomains, you can override the @local_domains_acl directive in the amavis user config file 50-user with @local_domains_maps = ("."); to match any sort of domain template.

How can I make SpamAssassin better recognize spam?

Put received spams in .Junk/ imap folder using SPAMASSASSIN_SPAM_TO_INBOX=1 and MOVE_SPAM_TO_JUNK=1 and add a user cron like the following:

# This assumes you're having `environment: ONE_DIR=1` in the `mailserver.env`,
# with a consolidated config in `/var/mail-state`
#
# m h dom mon dow command
# Everyday 2:00AM, learn spam from a specific user
0 2 * * * docker exec mail sa-learn --spam /var/mail/domain.com/username/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin

If you run the server with docker-compose, you can leverage on docker configs and the mailserver's own cron. This is less problematic than the simple solution shown above, because it decouples the learning from the host on which the mailserver is running and avoids errors if the server is not running.

The following configuration works nicely:

Create a system cron file:

# in the docker-compose.yml root directory
mkdir cron
touch cron/sa-learn
chown root:root cron/sa-learn
chmod 0644 cron/sa-learn

Edit the system cron file nano cron/sa-learn, and set an appropriate configuration:

# This assumes you're having `environment: ONE_DIR=1` in the env-mailserver,
# with a consolidated config in `/var/mail-state`
#
# m h dom mon dow user command
#
# Everyday 2:00AM, learn spam from a specific user
# spam: junk directory
0  2 * * * root  sa-learn --spam /var/mail/domain.com/username/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin
# ham: archive directories
15 2 * * * root  sa-learn --ham /var/mail/domain.com/username/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin
# ham: inbox subdirectories
30 2 * * * root  sa-learn --ham /var/mail/domain.com/username/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin
#
# Everyday 3:00AM, learn spam from all users of a domain
# spam: junk directory
0  3 * * * root  sa-learn --spam /var/mail/otherdomain.com/*/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin
# ham: archive directories
15 3 * * * root  sa-learn --ham /var/mail/otherdomain.com/*/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin
# ham: inbox subdirectories
30 3 * * * root  sa-learn --ham /var/mail/otherdomain.com/*/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin

Then with plain docker-compose:

services:
  mail:
    image: mailserver/docker-mailserver:latest
    volumes:
      - ./cron/sa-learn:/etc/cron.d/sa-learn

Or with docker swarm:

version: "3.3"

services:
  mail:
    image: mailserver/docker-mailserver:latest
    # ...
    configs:
      - source: my_sa_crontab
        target: /etc/cron.d/sa-learn

configs:
  my_sa_crontab:
    file: ./cron/sa-learn

With the default settings, Spamassassin will require 200 mails trained for spam (for example with the method explained above) and 200 mails trained for ham (using the same command as above but using --ham and providing it with some ham mails). Until you provided these 200+200 mails, Spamassasin will not take the learned mails into account. For further reference, see the Spamassassin Wiki.

How can I configure a catch-all?

Considering you want to redirect all incoming e-mails for the domain domain.tld to user1@domain.tld, add the following line to config/postfix-virtual.cf:

@domain.tld user1@domain.tld

How can I delete all the emails for a specific user?

First of all, create a special alias named devnull by editing config/postfix-aliases.cf:

devnull: /dev/null

Considering you want to delete all the e-mails received for baduser@domain.tld, add the following line to config/postfix-virtual.cf:

baduser@domain.tld devnull

How do I have more control about what SPAMASSASIN is filtering?

By default, SPAM and INFECTED emails are put to a quarantine which is not very straight forward to access. Several config settings are affecting this behavior:

First, make sure you have the proper thresholds set:

SA_TAG=-100000.0
SA_TAG2=3.75
SA_KILL=100000.0
  • The very negative vaue in SA_TAG makes sure, that all emails have the Spamassasin headers included.
  • SA_TAG2 is the actual threshold to set the YES/NO flag for spam detection.
  • SA_KILL needs to be very high, to make sure nothing is bounced at all (SA_KILL superseeds SPAMASSASSIN_SPAM_TO_INBOX)

Make sure everything (including SPAM) is delivered to the inbox and not quarantined:

SPAMASSASSIN_SPAM_TO_INBOX=1

Use MOVE_SPAM_TO_JUNK=1 or create a sieve script which puts spam to the Junk folder:

require ["comparator-i;ascii-numeric","relational","fileinto"];

if header :contains "X-Spam-Flag" "YES" {
  fileinto "Junk";
} elsif allof (
   not header :matches "x-spam-score" "-*",
   header :value "ge" :comparator "i;ascii-numeric" "x-spam-score" "3.75" ) {
  fileinto "Junk";
}

Create a dedicated mailbox for emails which are infected/bad header and everything amavis is blocking by default and put its address into config/amavis.cf

$clean_quarantine_to      = "amavis\@domain.com";
$virus_quarantine_to      = "amavis\@domain.com";
$banned_quarantine_to     = "amavis\@domain.com";
$bad_header_quarantine_to = "amavis\@domain.com";
$spam_quarantine_to       = "amavis\@domain.com";

What kind of SSL certificates can I use?

You can use the same certificates you use with another mail server.

The only thing is that we provide a self-signed certificate tool and a letsencrypt certificate loader.

I just moved from my old mail server, but "it doesn't work"?

If this migration implies a DNS modification, be sure to wait for DNS propagation before opening an issue. Few examples of symptoms can be found here or here.

This could be related to a modification of your MX record, or the IP mapped to mail.my-domain.tld. Additionally, validate your DNS configuration.

If everything is OK regarding DNS, please provide formatted logs and config files. This will allow us to help you.

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. Otherwise, it could work with 512M of RAM.

!!! note 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.

Can docker-mailserver run in a Rancher Environment?

Yes, by adding the environment variable PERMIT_DOCKER: network.

!!! warning Adding the docker network's gateway to the list of trusted hosts, e.g. using the network or connected-networks option, can create an open relay, for instance if IPv6 is enabled on the host machine but not in Docker.

How can I Authenticate Users with SMTP_ONLY?

See #1247 for an example.

!!! todo Write a How-to / Use-Case / Tutorial about authentication with SMTP_ONLY.

Common Errors

warning: connect to Milter service inet:localhost:8893: Connection refused
# DMARC not running
# => /etc/init.d/opendmarc restart

warning: connect to Milter service inet:localhost:8891: Connection refused
# DKIM not running
# => /etc/init.d/opendkim restart

mail amavis[1459]: (01459-01) (!)connect to /var/run/clamav/clamd.ctl failed, attempt #1: Can't connect to a UNIX socket /var/run/clamav/clamd.ctl: No such file or directory
mail amavis[1459]: (01459-01) (!)ClamAV-clamd: All attempts (1) failed connecting to /var/run/clamav/clamd.ctl, retrying (2)
mail amavis[1459]: (01459-01) (!)ClamAV-clamscan av-scanner FAILED: /usr/bin/clamscan KILLED, signal 9 (0009) at (eval 100) line 905.
mail amavis[1459]: (01459-01) (!!)AV: ALL VIRUS SCANNERS FAILED
# Clamav is not running (not started or because you don't have enough memory)
# => check requirements and/or start Clamav

How to use when behind a Proxy

Add to /etc/postfix/main.cf :

proxy_interfaces = X.X.X.X (your public IP)

What About Updates

You can of course use a own script or every now and then pull && stop && rm && start the images but there are tools available for this. There is a section in the Update and Cleanup documentation page that explains how to use it the docker way.

How to adjust settings with the user-patches.sh script

Suppose you want to change a number of settings that are not listed as variables or add things to the server that are not included?

This docker-container has a built-in way to do post-install processes. If you place a script called user-patches.sh in the config directory it will be run after all configuration files are set up, but before the postfix, amavis and other daemons are started.

The config file I am talking about is this volume in the yml file: ./config/:/tmp/docker-mailserver/

To place such a script you can just make it in the config dir, for instance like this:

cd ./config
touch user-patches.sh
chmod +x user-patches.sh

Then fill user-patches.sh with suitable code.

If you want to test it you can move into the running container, run it and see if it does what you want. For instance:

# start shell in container
./setup.sh debug login

# check the file
cat /tmp/docker-mailserver/user-patches.sh

# run the script
/tmp/docker-mailserver/user-patches.sh

# exit the container shell back to the host shell
exit

You can do a lot of things with such a script. You can find an example user-patches.sh script here: example user-patches.sh script

Special use-case - Patching the supervisord config

It seems worth noting, that the user-patches.sh gets executed trough supervisord. If you need to patch some supervisord config (e.g. /etc/supervisor/conf.d/saslauth.conf), the patching happens too late.

An easy workaround is to make the user-patches.sh reload the supervisord config after patching it:

#!/bin/bash
sed -i 's/rimap -r/rimap/' /etc/supervisor/conf.d/saslauth.conf
supervisorctl update