Loading...
05-05-2025

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.

  • Docker
  • Dovecot
  • Imap
  • Linux