In mijn zoektocht voor een alleen-archief-imap omgeving, was mijn eerste plan om een Debian of Ubuntu omgeving te gebruiken. Ik kwam er al snel achter dat er niet heel veel documentatie over de opzet te vinden was. Toen liep ik tegen een officiele docker implementatie.
De opzet van de container is echter wel wat simpeler dan de Debian of Ubuntu versie. Maar het lijkt er wel op dat alles erin zit wat nodig is. Inmiddels is versie 2.4.1 van de container te verkrijgen. Maar ja, hoe nu verder?
De basis setup van de container verwacht een wachtwoord via environment variabelen voor een gebruiker en de dovecot admin:
USER_PASSWORD=
DOVEADM_PASSWORD=
"Een wachtwoord voor één gebruiker?". Het blijkt dat de initiële setup zo gemaakt is dat hij elke gebruikersnaam accepteert en daarvoor een mailbox maakt, als dit wachtwoord wordt gebruikt. Op zich handig voor test omgevingen of zo, maar niet wat ik momenteel zoek. Ik wil voorlopig een basis opzet hebben, waarbij eventueel meerdere gebruikers aangemaakt kunnen worden. met een eigen wachtwoord. Dit wachtwoord en de opgeslagen mail moeten geëncrypt zijn. Hierbij ga ik alleen IMAP met SSL gebruiken. Voor het SSL certificaat wil ik letsencrypt gebruiken.
Ik heb via Dehydrated en Nginx een certificaat voor mijn domeinnaam aangemaakt. De container verwacht dat de certificaten als /etc/dovecot/ssl/tls.crt
en /etc/dovecot/ssl/tls.key
beschikbaar zijn. Voor de .crt
gebruik ik fullchain.pem
en voor de .key
het privkey.pem
certificaat. Deze worden via een volume mapping toegewezen.
De opgeslagen mail wil ik ook buiten de container opslaan. Standaard worden de mailboxen onder /srv/vmail
aangemaakt.
services:
dovecot:
image: dovecot/dovecot:latest
restart: always
ports:
- 0.0.0.0:993:31993
volumes:
- "${DOCKER_DATAPATH}/certs/fullchain.pem:/etc/dovecot/ssl/tls.crt:ro"
- "${DOCKER_DATAPATH}/certs/privkey.pem:/etc/dovecot/ssl/tls.key:ro"
- "${DOCKER_DATAPATH}/vmail:/srv/vmail"
Voor het totale plaatje zijn er nog 3 mappings nodig. Ik pas de basis configuratie niet aan van de container, maar voeg alleen toe. Voor de gebruikers wordt en een users
bestand (passwd-file) gebruikt, dat een zowel de gebruiker als het wachtwoord bevat, maar ook een paar extra lege velden.
Voor de aanvullende configuratie wordt een 10-auth.conf
bestand aangemaakt in de conf.d
map. Bij het opstarten wordt elke .conf
bestand in deze map meegenomen.
Aanvullend kan ik alvast verklappen dat certificaten voor het encrypten van de bestanden in de map /etc/dovecot/mail-crypt
terecht gaan komen"
- "${DOCKER_DATAPATH}/users:/etc/dovecot/users:ro"
- "${DOCKER_DATAPATH}/10-auth.conf:/etc/dovecot/conf.d/10-auth.conf:ro"
- "${DOCKER_DATAPATH}/dovecot-mail-crypt:/etc/dovecot/mail-crypt:ro"
Tijdens het testen heb ik Thunderbird gebruikt. Hierdoor liep ik al snel tegen een paar problemen aan. Het eerste probleem was, wanneer ik een mailtje in de mailbox sleepte, werd de verbinding verbroken met de melding dat er teveel ongeldige commando's verstuurd werden:
dovecot-1 | May 05 07:55:06 imap(myarchive)<21><t9Qz0F40vPW8Wgp1>: Info: Disconnected: Too many invalid IMAP commands. in=1677 out=2637 deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0
Na een behoorlijke wat zoektijd, kwam ik in een github ticket tegen, dat een experimentele extentie het probleem zou kunnen zijn. Via mail_utf8_extensions=no
kan deze worden uitgeschakeld en werkt Thunderbird in eens wel zoals verwacht.
Het tweede probleem had iets met de standaard mappen te maken. Na deze uit de Ubuntu configuratie over genomen te hebben (zie namespace inbox {...
) werkte de mailbox in eens zoals verwacht.
Zo ben ik tot de volgende opzet van 10-auth.conf
gekomen:
# Use for debugging
# mail_debug=yes
# auth_verbose=yes
# auth_debug=yes
# auth_debug_passwords=yes
# mail_debug=yes
# Fix for Thunderbird
mail_utf8_extensions=no
# Authorization
auth_verbose_passwords=plain
auth_mechanisms = plain login
# removed: digest-md5 cram-md5
# Passdb configuration
passdb passwd-file {
driver = passwd-file
passwd_file_path = /etc/dovecot/users
}
# Userdb configuration
userdb passwd-file {
driver = passwd-file
passwd_file_path = /etc/dovecot/users
}
# Default folders
namespace inbox {
inbox = yes
mailbox Trash {
special_use = \Trash
auto = subscribe
}
# These mailboxes are widely used and could perhaps be created automatically:
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
}
# For \Sent mailboxes there are two widely used names. We'll mark both of
# them as \Sent. User typically deletes one of them if duplicates are created.
mailbox Sent {
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
}
# Encryption of mails
mail_plugins {
mail_crypt = yes
}
crypt_global_public_key_file = /etc/dovecot/mail-crypt/ecpubkey.pem
crypt_global_private_key main {
crypt_private_key_file = /etc/dovecot/mail-crypt/ecprivkey.pem
}
De certificaten voor het encrypten van de data moeten ook nog aangemaakt worden. Zorg ook dat de certificaten de juiste owner en rechten hebben binnen de container. De vmail
gebruiker en groep hebben beide nummer 1000.
mkdir -p data/dovecot-mail-crypt
openssl ecparam -name prime256v1 -genkey | openssl pkey -out data/dovecot-mail-crypt/ecprivkey.pem
openssl pkey -in data/dovecot-mail-crypt/ecprivkey.pem -pubout -out data/dovecot-mail-crypt/ecpubkey.pem
chmod -Rf 600 data/dovecot-mail-crypt/*
chown -Rf 1000.1000 data/dovecot-mail-crypt
Om dit allemaal nou ook nog werkend te krijgen, moet er in ieder geval 1 gebruiker toegevoegd worden. Hiervoor kan de tool doveadm
gebruikt worden. Misschien is het ook mogelijk om hiermee een gebruiker volledig toe te voegen aan het users
bestand, maar zover heb ik niet gekeken. doveadm
is in de container beschikbaar. Ik gebruik hier de encryptie SHA512-CRYPT
om te zorgen dat het wachtwoord niet leesbaar is in de configuratie. Hier een voorbeeld:
docker compose exec dovecot doveadm pw -s SHA512-CRYPT
Enter new password:
Retype new password:
{SHA512-CRYPT}$6$RVEYzANS6v0a.kAB$.0lLSo2DaXwpi8E.iAClBoQu3GK36oWPCRp503ZlhDok3ixomdcMbiwURNScpxVlYHGD7UItfrlQz4tEMgaZ.
Deze laatste regel is het geëncrypte wachtwoord. Deze gaan we toevoegen aan het users
bestand. Allereerst komt de gebruikersnaam in het bestand te staan. Hou er rekening mee dat deze in ieder geval geen :
mag bevatten, omdat dit het scheidingsteken is tussen de velden. Deze wordt gevolgd door het wachtwoord. Het users
bestandsformaat verwacht dan nog een aantal velden die we leeg gaan laten. Hierom voegen we ::::::
toe aan de regel. Een voorbeeld is dan als volgt:
my-mail-user:{SHA512-CRYPT}$6$RVEYzANS6v0a.kAB$.0lLSo2DaXwpi8E.iAClBoQu3GK36oWPCRp503ZlhDok3ixomdcMbiwURNScpxVlYHGD7UItfrlQz4tEMgaZ.::::::
Belangrijk punt is dat dovecot herstart moet worden als dit bestand veranderd. Dit is een goed argument om een SQL server te gaan gebruiken hiervoor. Sqlite zou een prima oplossing kunnen zijn, maar dat is voor een andere keer. De container is zodanig kaal, dat ps
of killall
niet beschikbaar zijn. Een alternatief is dan ook om de container te herstarten. Maar dovecot
heeft ook een herstart optie ingebouwd, wat het proces wat vloeiender maakt:
docker compose exec dovecot doveadm reload
Hierna zou je met elke IMAP applicatie moeten kunnen verbinden en mail naar deze mailbox moeten kunnen verplaatsen. Zorg wel voor een goede backup van de certificaten, anders zijn de e-mails niet meer te redden na een crash.