Usability
I'm not sure, but as far as I understand the concept of Docker, the actual container is a disposable object, so everything that should be persistent should be integrated via volumes.
In the case of dovecot, that would be the conf, certs and the actual storage of the mails.
If you start the current image, it starts with the fact that the required user dovenull does not exist. So the image does not work at first. (Even if you wanted to deviate from the actual docker philosophy here and simply create it, you would fail because the corresponding commands are not available).
In the next step, you can then try to store the MailDir directories in a mounted directory. This fails due to missing permissions, because the rights for the user cannot be set on a new mounted directory. And since the whole thing no longer runs as root, access is consequently denied here. (Workaround chmod also fails due to missing tool).
To summarize: Running as "not-root" and minimal Linux as a basis to minimize the attack surface are great ideas. But unfortunately the image is not usable in its current state.
For me, it works like this:
read_only: true
cap_drop:
- ALL
cap_add:
- SYS_CHROOT
volumes:
- ./dovecot.conf:/etc/dovecot/dovecot.conf:ro
- ./dovecot-users:/etc/dovecot/users:ro
- type: tmpfs
target: /tmp
- type: tmpfs
target: /run
- /mnt/volumes/volume-mail:/srv/mail
The only simplifications I'd like to see is that the image would not require the SYS_CHROOT permission (Docker already provides filesystem isolation similar to a chroot) and that it would only need one temp directory not two.
Hi schildbach
how did you overcome the issue of missing "dovenull", even after setting:
default_login_user = vmail default_internal_user = vmail default_internal_group = vmail
inside the config, the system tries to find it:
Error in configuration file /etc/dovecot/dovecot.conf: default_login_user doesn't exist: dovenull
I am fine with the idea of using vmail and dovenull in the 2.4-versions of the image, but in order to make it usable dovenull should be included in the images.
I vaguely remember I had this problem with the initial 2.4.0 image, but the above lines fixed it – but I may be wrong. I just tried to reproduce the problem using the default config with the current version 2.4.1:
$ docker run dovecot/dovecot:2.4.1
Unable to find image 'dovecot/dovecot:2.4.1' locally
2.4.1: Pulling from dovecot/dovecot
254e724d7786: Already exists
8654bc72299c: Pull complete
36333adc5577: Pull complete
73976c918382: Pull complete
8c0a0e575ff0: Pull complete
dafff7eba9a8: Pull complete
4d4a02913fad: Pull complete
Digest: sha256:93ba09db50f407468fa4067eb2cc9c717835aa1e68acebe5ad25f154c05dfb60
Status: Downloaded newer image for dovecot/dovecot:2.4.1
Jul 16 13:28:38 master: Info: Dovecot v2.4.1 (7d8c0e5759) starting up for imap, submission, lmtp, sieve
As you can see, the default config seems to spin up fine. Again I might be overseeing something.
I can post you my entire config, if you think this could help.
Hmmm, after some experimentation I found out that the default volume for /srv/mail is owned by uid=0 gid=0:
$ sudo ls -la /var/lib/docker/volumes/deeeada2ceea70dce0fb27cb6a5a1de1cf57646ce43d0e04c758c0a163a5cc83/
total 0
drwx-----x 1 root root 10 Jul 16 15:46 .
drwx-----x 1 root root 184 Jul 16 15:46 ..
drwxr-xr-x 1 root root 0 Jul 16 15:46 _data
Is that a manifestation of the issue?
It doesn't affect me because I bind-mount that volume, and thus it is my own duty to chown correctly.
Perhaps can you say what image are you using? If you look at the Dockerfile there is a production image (which I'm using) and there is a production-root image (which seems to resemble a bit how previous docker images worked – not sure?).
The production image indeed does not create users dovecot and dovenull. Perhaps consider using the production-root image in your case, which creates the users?
I am using docker compose
services:
dovecot:
image: dovecot/dovecot:2.4.1
cap_drop:
- ALL
cap_add:
- CAP_SYS_CHROOT
ports:
- "143:143"
- "993:993"
volumes:
- ./maildata:/srv/vmail
- ./dovecot-config:/etc/dovecot
- ./certs:/etc/ssl/private
- ./dovecot_passwd:/etc/dovecot/passwd
restart: unless-stopped
roundcube:
image: roundcube/roundcubemail:1.6.7-apache
ports:
- "8080:80"
volumes:
- ./roundcube-config.inc.php:/var/www/html/config/config.inc.php
environment:
- ROUNDCUBEMAIL_DEFAULT_HOST=tls://dovecot
- ROUNDCUBEMAIL_DEFAULT_PORT=31143
# Dummy-SMTP (funktioniert nicht, aber Roundcube startet)
- ROUNDCUBEMAIL_SMTP_SERVER=smtp-dumm
- ROUNDCUBEMAIL_SMTP_PORT=1025
- ROUNDCUBEMAIL_DB_TYPE=sqlite
smtp-dummy:
image: mailhog/mailhog:v1.0.1
ports:
- "1025:1025" # SMTP
- "8025:8025" # Web UI1
As far as I understand the docs the dovenull is a fallback.
The error message implies that it does not exist.
volumes:
- ./maildata:/srv/vmail
- ./dovecot-config:/etc/dovecot
- ./certs:/etc/ssl/private
- ./dovecot_passwd:/etc/dovecot/passwd
I see these issues. The first one might be related to your problem.
- the mail volume that is declared by the docker image is at
/srv/mail, not/srv/vmail - you should declare all configuration as read-only, otherwise a successful attacker can change your host's config and persist backdoors etc.
- I would mount each config file individually, and not entire directories like in your case
/dovecot-config
Perhaps can you also post your dovecot config?