Mise en place d'un serveur mail - Postfix, Dspam et Dovecot

Update 14/01/14 : ajout de la liste complète des paquets nécessaires et correction de quelques typos. Thx @Puckel_ !

Cette documentation décrit la mise en place de postfix, dspam et dovecot pour un usage simple, géré avec des utilisateurs et domaines virtuels. Le stockage se fait en fichiers, que ce soit pour les règles antispam ou les mails (pas besoin de databases).

Le tout en mode sécurisé, avec de l’imap et du smtp via starttls. Il est aussi possible de signaler un spam simplement en le déplaçant dans le dossier “SPAM” afin que dspam l’apprenne.

Les doc existantes ne me convenaient pas, soit obsolètes, soit demandant de desactiver le chroot de postfix, soit trop de hacks dans le master.cf, ou bien incomplètes…

On prendra en domaine de test domain.org et comme nom de serveur server.domain.org

Le fonctionnement est le suivant :

Postfix -> dspam -> dovecot

Postfix transmet le mail à dspam (via socket), qui analyse le mail, puis le retourne (toujours via socket) à dovecot qui le stocke.

Dovecot centralise l’authentification via sasl, que ce soit pour imap ou pour smtp.

On utilise les version suivante (debian wheezy):

postfix 2.9 : smtp
dspam 3.10  : antispam 
dovecot 2.1 : imap

On a aussi besoin des paquets suivants :

postfix
dspam
libdspam7-drv-hash
dovecot-antispam
dovecot-managesieved
dovecot-sieve
dovecot-imapd
dovecot-lmtp

Tout d’abord, on créé un user vmail, qui s’occupera du stockage des mails (ici /home/mail)

addgroup --gid 5000 vmail
adduser --home /home/mail/ --uid 5000 --gid 5000 --shell /bin/false vmail

On configure Postfix, les commentaires sont integrés :

smtpd_tls_cert_file=/etc/ssl/domain.chain.crt
smtpd_tls_key_file=/etc/ssl/domain.key
smtpd_use_tls=yes

myhostname = server.domain.org
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = server.domain.org, localhost.localdomain, localhost

virtual_mailbox_domains = domain.org # completer avec d'autres domaines, séparé par des virgules
virtual_mailbox_base = /home/mail/vhosts # ou sont physiquement stockés les mails
virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox_recipients # le mapping entre l'adresse et le stockage physique 
virtual_uid_maps = static:5000 # tout est géré via l'utilisateur vmail, qui a l'id 5000
virtual_gid_maps = static:5000
virtual_alias_maps = hash:/etc/postfix/virtual_alias_recipients # en cas d'alias (par exemple root@ -> posmaster@)
smtpd_sasl_auth_enable = yes # activer l'auth sasl pour l'envoi de mail
smtpd_sasl_local_domain =
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot # On passe par dovecot pour l'auth sasl
smtpd_sasl_path = private/auth # la socket d'authentifiction
broken_sasl_auth_clients = yes # pour allow de vieux clients mails
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_unverified_recipient
smtpd_tls_auth_only = yes
virtual_transport  = lmtp:unix:dspam/dspam.sock # et on transmet le mail à dspam

Les fichiers virtual_mailbox_recipients et virtual_alias_recipients sont de la forme suivante :

$ cat virtual_mailbox_recipients 
myuser@domain.org    domain.org/myuser

domain.org/myuser correspond au stockage physique, ce qui va se transformer en /home/mail/vhosts/domain.org/myuser

$ cat virtual_alias_recipients
aliasuser@domain.org myuser@domain.org

Il faut ensuite générer les fichiers .db pour que postfix puisse les utiliser, à faire à chaque modification

$ postmap virtual_mailbox_recipients
$ postmap virtual_alias_recipients

Reste à modifier le master.cf de postfix afin d’activer le port submission (port 587) pour l’envoi de mails. Décommenter les lignes suivantes :

submission inet n       -       -       -       -       smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING

On est bon coté postfix.

Attaquons dspam. On a vu que postfix passe le mail à dspam via dspam/dspam.sock, qui se situe dans le chroot de postfix, par défaut dans /var/spool/postfix/ . On créé donc un dossier /var/spool/postfix/dspam :

mkdir /var/spool/postfix/dspam
chown dspam: /var/spool/postfix/dspam

Editer le /etc/default/dspam

START=yes

Editer le /etc/dspam/dspam.conf

DeliveryHost            /var/run/dovecot/lmtp # On delivera le mail à dovecot après le parsing antispam
DeliveryIdent           dspam.domain
DeliveryProto           LMTP

Trust vmail # C'est l'utilisateur vmail qui déplace dans le dossier SPAM via les règles sieve

Preference "tagSpam=on" # On veut que les spams soient taggués  

ServerMode auto
ServerParameters        "--deliver=innocent,spam" # On veut que dspam délivre aussi les mails taggués en spam (que l'ont mettra dans le dossier SPAM via sieve)
ServerDomainSocketPath  "/var/spool/postfix/dspam/dspam.sock" # Le path dans le chroot de postfix

Ensuite dans /etc/dspam/default.prefs

spamAction=deliver # On veut delivrer dans la mailbox, pas en quarantaine

On passe à dovecot. Debian split la configuration dans de multiples fichier sous /etc/dovecot/conf.d/, ici une version simplifiée, à adapter à la configuration existante (il vous faudra modifier 10-auth.conf 10-mail.conf 10-ssl.conf 15-lda.conf 20-imap.conf 10-director.conf 10-master.conf 20-lmtp.conf 20-managesieve.conf 90-plugin.conf 90-sieve.conf auth-passwdfile.conf.ext):

disable_plaintext_auth = yes
auth_mechanisms = plain login
!include auth-passwdfile.conf.ext # On y revient plus tard

mail_location = maildir:/home/mail/vhosts/%d/%n # %d = domaine %n = user
namespace inbox {
separator = /
inbox = yes
}
mail_uid = 5000 # Utilisateur vmail
mail_gid = 5000

service lmtp {
unix_listener lmtp {
user = vmail # On tourne avec le user vmail
}
}

service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
}

ssl = required
ssl_cert = </etc/ssl/domain.chain.crt
ssl_key = </etc/ssl/domain.key

postmaster_address = root@domain.org

protocol lda {
auth_socket_path = /var/spool/postfix/private/auth
}

protocol imap {
mail_plugins = $mail_plugins antispam # On load le plugin antispam
}

protocol lmtp {
# Space separated list of plugins to load (default is global mail_plugins).
mail_plugins = $mail_plugins sieve # On load le pluin sieve pour trier les mails
}

# On active managesieve, afin de pouvoir gérer les règles sieve
service managesieve-login {
inet_listener sieve {
port = 4190
}

service managesieve {
}

protocol sieve {
}

# On passe à la configuration antispam, afin de faire apprendre à dspam lorsque vous placez manuellement dans le repertoire SPAM

plugin {
antispam_backend = dspam
antispam_dspam_binary = /usr/bin/dspam
antispam_dspam_args = --deliver;--user;%u
antispam_spam = SPAM; Spam
antispam_trash = Trash
antispam_unsure = Trash
antispam_signature = X-DSPAM-Signature
}


plugin {
# The path to the user's main active script. If ManageSieve is used, this the
# location of the symbolic link controlled by ManageSieve.
sieve = ~/.dovecot.sieve
sieve_dir = ~/sieve
sieve_before = /home/mail/sieve/before/ # Cette règle sera appliquée à TOUS les mails
}

Dans le fichier auth-passwdfile.conf.ext:

passdb {
	driver = passwd-file
	args = scheme=CRYPT username_format=%u /etc/dovecot/users
}
userdb {
	args = uid=vmail gid=vmail home=/home/mail/vhosts/%d/%n allow_all_users=yes
	driver = static
}

C’en est fini pour Dovecot.

On utilise le driver static, car dans ce setup tout est géré via l’utilisateur vmail.

Pour créer un user, il faut remplir le fichier /etc/dovecot/users. Comme postfix utilise dovecot pour l’authentification, tout se passe ici, que ce soit imap ou smtp.

L’ajout d’un utilisateur se fait de la façon suivante :

echo "myuser@domain.org:$(doveadm pw -s CRYPT -p mypassword)" >> /etc/dovecot/users
echo myuser@domain.org domain.org/myuser >> /etc/postfix/virtual_mailbox_recipients
postmap /etc/postfix/virtual_mailbox_recipients

Il est ensuite simple de faire un script shell pour créer les users en une commande.

On voit qu’une règle sieve par défaut est appliquée à tous les mails. Je m’en sers pour mettre les mails taggués en SPAM dans le dossier spam automatiquement.

$ vim /home/mail/sieve/before/spam.sieve
require ["fileinto"];
# rule:[SPAM]
if anyof (header :contains "X-DSPAM-Result" "Spam")
{
    fileinto "SPAM";
    stop;
}

# Puis on compile la règle
sievec /home/mail/sieve/before/spam.sieve

J’utilise Roundcube en tant que webmail, la seul configuration à ajouter est de charger le plugin “managesieve”, afin que chaque utilisateur puisse éditer ses règles de filtrage via roundcube.

$ vim roundcube/config/main.inc.php
$rcmail_config['plugins'] = array('managesieve');

Avec un client mail, il suffit de se connecter en imap sur le port 143 (avec starttls) et le port 587 pour l’envoi (toujours en starttls).

En bonus, pour implementer DKIM, c’est par ici : http://blog.alteroot.org/articles/2014-01-30/mise-en-place-dkim-postfix.html

Sources: