Publié le 03/09/2013, dernière modification le 30/11/2022.
Si les emails sont quelque chose de courant sur internet, la mise en place d'un serveur d'emails n'est pas quelque chose de trivial. On trouve donc de nombreux tutoriaux sur le net, plus ou moins fiable, plus ou moins complets et plus ou moins obsolètes. Chacun ayant une manière de faire et ses logiciels préférés, voici la mienne.
Ce guide suppose que vous :
Afin d'avoir un serveur email accessible, il est important d'ajouter un champ MX à notre nom de domaine. On va le faire pointer sur un sous domaine qui, lui, disposera des entrées A et AAAA.
example.org. IN MX 10 mx1.example.org.
mx1.example.org. IN A 203.0.113.42
mx1.example.org. IN AAAA 2001:db8::42
Avant d'aller plus loin, vous devez vérifier si votre nom de domaine dispose d'un FCrDNS valide. Pour faire court, il faut que les requêtes de recherche inverse du DNS retournent le nom de domaine associé.
$ dig +short -x "203.0.113.42"
mx1.example.org.
$ dig +short -x "2001:db8::42"
mx1.example.org.
Si ce n'est pas le cas, corriger votre configuration DNS.
Afin de luter contre l'usurpation d'identité il existe plusieurs système. Deux d'entre eux sont SPF et DMARC. Pour ceci, il suffit d'ajouter des entrées TXT
dont le contenu définit la politique de protection des emails dont la provenance est votre domaine. Exemple:
example.org. IN TXT "v=spf1 a mx ip6:2001:db8::/32 -all"
_dmarc.example.org. IN TXT "v=DMARC1;adkim=s;aspf=s;p=reject;sp=reject;ruf=mailto:postmaster@example.org;fo=1"
Le MTA (Mail Transfer Agent) est le logiciel qui va vous permettre d'envoyer et recevoir des emails. Il en existe beaucoup (qmail, exim, postfix, sendmail, …), ici nous nous focaliserons sur un MTA qui a l'avantage d'être fiable, complet et surtout extrêmement simple à configurer : OpenSMTPD. Attention toutefois, ce guide nécessite au moins la version 6.4 d'OpenSMTPD.
Une fois installé, la configuration s'effectue dans /etc/smtpd/smtpd.conf
. Un simple man 5 smtpd.conf
est là pour nous aider. Pour avoir un serveur email capable de recevoir des emails pour le domaine example.org
, nous n'avons besoin que de ceci :
table aliases "file:/etc/smtpd/aliases"
listen on 127.0.0.1
listen on ::1
listen on 203.0.113.42
listen on 2001:db8::42
action local_deliver maildir alias <aliases>
match from local for local action local_deliver
match from any for domain "example.org" action local_deliver
Nous allons maintenant la rendre un peu plus robuste et fonctionnelle en utilisant TLS, et en autorisant l'envoie d'emails pour les utilisateurs.
pki example.org cert "/etc/acmed/certs/example.org_ecdsa-p384.crt.pem"
pki example.org key "/etc/acmed/certs/example.org_ecdsa-p384.pk.pem"
smtp ciphers "HIGH:!eNULL:!LOW:!MEDIUM:!EXP:!RC4:!3DES:!MD5:!SHA1:!PSK:!kRSA:!SRP:-DH:+ECDH"
table aliases "file:/etc/smtpd/aliases"
# SMTP port 25 from localhost
listen on 127.0.0.1 tls pki example.org hostname mx1.example.org
listen on ::1 tls pki example.org hostname mx1.example.org
# SMTP port 25 from external sources
listen on 203.0.113.42 tls pki example.org hostname mx1.example.org
listen on 2001:db8::42 tls pki example.org hostname mx1.example.org
# SMTPS port 465 from authenticated users
listen on 203.0.113.42 smtps pki example.org auth hostname mx1.example.org mask-src
listen on 2001:db8::42 smtps pki example.org auth hostname mx1.example.org mask-src
action local_deliver maildir alias <aliases>
action relay_out relay helo example.org
match from local for local action local_deliver
match from any for domain "example.org" action local_deliver
match from any auth for any action relay_out
La clé privée ne doit pas être accessible (lecture, écriture, exécution), sauf pour le propriétaire. Le mieux est de lui mettre un chmod 600
ou chmod 400
.
Pensez à accepter les nouvelles connexions TCP entrantes sur les ports 25 (SMTP) et 465 (SMTPS).
Pour l'instant, notre MTA fait usage des utilisateurs du système. Si dans certaines situations c'est une bonne chose, dans d'autres ça ne l'est pas forcément. À titre personnel, je préfère utiliser un utilisateur virtuel afin d'avoir des mots de passe différents entre mon compte email et mon compte sur mon serveur dédié.
Créons donc le fichier /etc/smtpd/vusers
qui contiendra, sur chaque ligne, nos utilisateurs au format <nom d'utilisateur>:<mot de passe haché>
:
marie:$y$jCT$JnBTCfMf6qDY0YAyr.Wyz1$gFFF/qWkcclRfahZOcPa7Q2vTwYmX1omW34AL/kR9U1
ernest:$y$jCT$2JqWUNiukyr5XRvieZQS4.$RF7fRV9fCEqRw7k65A0iWFz1vp/MCpORif3p.aqvQj6
celestine:$y$jCT$bRvBpoQV2LtjoNC.ooKbe1$aIy2AMzL0Ip1ejE1AjV/A1kG.uyx51innV9ok/R5mO0
Les mots de passes sont hachés à l'aide de la fonction crypt(3) qui peut, par exemple, être appelée à l'aide de la commande smtpctl encrypt
. Après chaque modification de ce fichier, on doit exécuter la commande smtpctl update table vusers
.
Pour utiliser cette nouvelle base d'utilisateurs dans OpenSMTPD, il nous suffit d'ajouter la nouvelle table vusers
et de l'ajouter après auth
dans les listen
:
table vusers "file:/etc/smtpd/vusers"
# SMTPS port 465 from authenticated users
listen on 203.0.113.42 smtps pki example.org auth <vusers> hostname mx1.example.org mask-src
listen on 2001:db8::42 smtps pki example.org auth <vusers> hostname mx1.example.org mask-src
Pour définir des alias, éditons le fichier /etc/smtpd/aliases
:
#
# Please run `smtpctl update table <table_name>` after any change to this file.
#
# Person who should get root's mail. Don't receive mail as root!
root: marie
# Basic system aliases
MAILER-DAEMON: postmaster
postmaster: root
# General redirections for pseudo accounts
bin: root
daemon: root
nobody: root
decode: root
# Well-known aliases
manager: root
dumper: root
operator: root
abuse: root
admin: root
webmaster: root
hostmaster: root
spam: root
# Personal aliases
marie.lambda: marie
lambda.marie: marie
ernest.tartempion: ernest
Tout comme pour le fichier des utilisateurs virtuels, après chaque modification de ce fichier il faut exécuter la commande smtpctl update table aliases
.
Afin de récupérer les emails depuis notre MUA (Mail User Agent, par exemple ThunderBird ou mutt) il nous faut mettre en place un serveur POP ou IMAP. Nous utiliseront ici Dovecot.
Le fichier /etc/dovecot/dovecot.conf
contient la configuration générale de Dovecot. Nous allons y modifier les deux paramètres suivants :
protocols = imap sieve lmtp
afin d'avoir un serveur IMAP, mais aussi utiliser Sieve et permettre la réception de courriers depuis OpenSMTPD à l'aide de LMTP ;listen = 203.0.113.42 2001:db8::42
afin que notre serveur IMAP écoute sur les IP publiques.Afin de stocker le courrier de nos utilisateurs virtuels, nous créons un nouvel utilisateur système vmail
qui regroupera les dossiers de chaque utilisateur virtuel dans /var/vmail
:
useradd --system --user-group --shell /usr/bin/nologin --home-dir /var/vmail --create-home vmail
Il nous faut maintenant indiquer à Dovecot comment utiliser notre base d'utilisateurs virtuels. Pour ceci, éditons le fichier /etc/dovecot/conf.d/10-auth.conf
. Par défaut, ce fichier inclue un autre fichier décrivant la méthode à utiliser pour authentifier les utilisateurs. Nous commentons donc la méthode par défaut et ajoutons à la fin notre propre méthode :
#!include auth-system.conf.ext
!include auth-passwdfile-static.conf.ext
Et créons le fichier /etc/dovecot/conf.d/auth-passwdfile-static.conf.ext
:
passdb {
driver = passwd-file
args = scheme=CRYPT username_format=%n /etc/smtpd/vusers
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/vmail/%n
}
Assurons nous que, dans le fichier /etc/dovecot/conf.d/10-mail.conf
, le chemin vers le dossier email des utilisateurs soit bien indiqué :
mail_location = maildir:~/Maildir
Comme mentionné plus haut, LMTP sera utilisé pour que Dovecot puisse distribuer aux utilisateurs les emails reçus par OpenSMTPD. Sa configuration se fait dans le fichier /etc/dovecot/conf.d/20-lmtp.conf
. Assurons nous d'avoir activé le plugin Sieve.
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
Sieve étant activé, nous pouvons le configurer dans le fichier /etc/dovecot/conf.d/20-managesieve.conf
:
plugin {
sieve = ~/.dovecot.sieve
sieve_dir = ~/sieve
sieve_extensions = +notify +imap4flags +imapflags +editheader
}
Afin d'utiliser TLS pour protéger les échanges entre le client et le serveur, nous éditons le fichier /etc/dovecot/conf.d/10-ssl.conf
:
ssl = required
ssl_cert = </etc/acmed/certs/example.org_ecdsa-p384.crt.pem
ssl_key = </etc/acmed/certs/example.org_ecdsa-p384.pk.pem
ssl_min_protocol = TLSv1.2
ssl_cipher_list = HIGH:!aNULL:!eNULL:!LOW:!MEDIUM:!EXP:!RC4:!3DES:!MD5:!SHA1:!PSK:!kRSA:!SRP:-AES128:-DH:+ECDH
ssl_prefer_server_ciphers = yes
Sauf configuration particulière, toutes les autres lignes doivent être vides ou commentées.
Attention au certificat, pensez à utiliser quelque chose de mieux que ceux qui sont auto-générés. Remarquez que nous n'accepterons qu'au minimum TLSv1.2, les versions antérieures n'étant pas recommandées. TLS 1.2 n'est lui-même plus trop recommandé, dans l'idéal, utilisez uniquement TLS 1.3. Malheureusement, Dovecot ne permet pas actuellement de spécifier TLS 1.3 comme version minimale.
Notez également que le paramétrage TLS interdit les échange de clés Diffie-Hellman traditionnels mais autorise cependant la variante basée sur les courbes elliptiques. Il n'y a donc pas besoin de s'inquiéter des paramètres par défaut qui sont en général très faibles.
Pensez à accepter les nouvelles connexions TCP entrantes sur le port 993 (IMAPS).
Si un MTA est capable d'envoyer et de recevoir des emails, le MDA (Mail Delivery Agent) est le logiciel qui distribue les emails reçus à son destinataire. La plupart des serveurs SMTP font à la fois MTA et MDA, ce qui est le cas d'OpenSMTPD. Nous lui avons d'ailleurs indiqué de délivrer les emails à leur destinataire dans son répertoire au format maildir.
Utiliser le MDA intégré à notre serveur SMTPD fonctionne, mais ne nous donne malheureusement pas trop de possibilités de configuration. À la place, nous allons donc utiliser celui fourni par dovecot grâce à LMTP. Ce MDA a l'avantage de gérer sieve.
Du côté d'OpenSMTPD, il suffit d'éditer notre action local_deliver
afin de lui donner l'adresse du socket utilisé par LMTP :
action local_deliver lmtp "/run/dovecot/lmtp" alias <aliases>
L'adresse du socket peut varier suivant les systèmes.
Nous pouvons maintenant utiliser sieve pour filtrer nos emails. La configuration se fait dans le fichier ~/.dovecot.sieve
de chaque utilisateur (exemple: /var/vmail/marie/.dovecot.sieve
). Un exemple de configuration :
require ["fileinto", "imapflags"];
if header :contains "X-Spam" "yes" {
setflag "\\Seen";
fileinto "Junk";
}
elsif address :is ["From", "To", "Cc", "Reply-to"] "nantes@lists.afpy.org" {
fileinto "INBOX.Python.Nantes";
}
elsif address :is ["From", "To", "Cc", "Reply-to"] "python@example.org" {
fileinto "INBOX.Python";
}
Cet exemple permet de marquer le spam comme lu et de le placer dans le dossier qui leur est dédié. Il y a ensuite des filtres pour placer automatiquement des emails dans certains dossiers.
DomainKeys Identified Mail (DKIM) est une autre technique pour luter contre l'usurpation d'identité. Le principe est de signer (au niveau du serveur) les emails envoyés et de mettre la clé publique associée dans une entrée DNS. Par exemple, à la réception d'un email provenant de whatever@example.org
, une requête DNS sur un sous domaine de example.org
permet de récupérer la clé publique permettant de vérifier la signature de l'email. Si tout concorde, l'email à bien été envoyé par un serveur possédant la clé privée associée.
OpenDKIM est certainement l'implémentation la plus connue et utilisée de DKIM. Malheureusement, elle s'interface avec les MTAs en utilisant un milter, ce qui n'est pas supporté par OpenSMTPD. Nous utiliserons donc une autre solution, moins connue : dkimproxy
Comme son nom l'indique, dkimproxy agit comme un proxy SMTP. On lui envoie un email en SMTP par un port et il le retourne, signé, sur un autre port. Pour sa configuration, nous supposerons que la configuration de dkimproxy se trouve dans le répertoire /etc/dkimproxy
au lieux de celui par défaut.
mkdir -p "/etc/dkimproxy/private"
chown dkimproxy:root "/etc/dkimproxy/private"
chmod 700 "/etc/dkimproxy/private"
cd "/etc/dkimproxy/private"
openssl genrsa -out "private.key" 2048
openssl rsa -in "private.key" -pubout -out "public.key"
chown dkimproxy:root "private.key" "public.key"
chmod 600 "private.key"
Et dans notre /etc/dkimproxy/dkimproxy_out.conf
:
# specify what address/port DKIMproxy should listen on
listen 127.0.0.1:10027
# specify what address/port DKIMproxy forwards mail to
relay 127.0.0.1:10028
# specify what domains DKIMproxy can sign for (comma-separated, no spaces)
domain example.org
# specify what signatures to add
signature dkim(c=relaxed)
signature domainkeys(c=nofws)
# specify location of the private key
keyfile /etc/dkimproxy/private/private.key
# specify the selector (i.e. the name of the key record put in DNS)
selector pubkey
Ajoutez ensuite une entrée TXT pour pubkey._domainkey.example.org
dont la valeur est v=DKIM1; k=rsa; t=s; p=contenu_de_la_clef_publique
(la liste des options est définie dans la RFC 6376.
Attention, pour les clés RSA de 2048 bits ou plus la clé publique dépassera la longueur maximale d'une une chaîne de caractères (255 bytes) dans les entrées TXT et SPF. Comme indiqué dans la RFC 7208, il faut alors utiliser plusieurs chaînes de caractères qui seront concaténées.
pubkey._domainkey.example.org. IN TXT "v=DKIM1; k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEjPmxQHTJeBoHSJPuPMl0ry0q31TqoC2OuqUiVHSk3hM6x6oDat4pIischVYi/3ODsjBC6wg1BPgtfdVfzboAF/bQK+Kh0rBaQlv2vloP96mu6dmUGMJSo5BrtoAMdx6DbMe7s7TP58uAUknQNEL6s9w7iNF9gD/+yBiEB+yDYwIDAQAB"
Enfin, configurons OpenSMTPD pour lui faire utiliser dkimproxy.
listen on lo port 10028 tag DkimOut
action to_dkimproxy relay host smtp://127.0.0.1:10027
action relay_out relay helo example.org
match from any tagged DkimOut for any action relay_out
match for any action to_dkimproxy
match from any auth for any action to_dkimproxy
Comme anti-spam, le plus simple est d'utiliser rspamd, ce dernier s'intégrant parfaitement grâce à filter-rspamd. Une fois le filtre déclaré à l'aide de filter
, il suffit de l'ajouter à la fin des listen
d'où proviennent les emails de sources non-sûres.
filter "rspamd" proc-exec "/usr/lib/smtpd/opensmtpd/filter-rspamd"
listen on 203.0.113.42 tls pki example.org hostname mx1.example.org filter "rspamd"
listen on 2001:db8::42 tls pki example.org hostname mx1.example.org filter "rspamd"
Notez que le chemin vers l'exécutable filter-rspamd
peut varier suivant votre distribution.
La configuration de votre client de messagerie s'effectue comme tel :
~/Maildir
de Marie (non illustré : il utilise sieve) ;#
# Encryption
#
pki example.org cert "/etc/acmed/certs/example.org_ecdsa-p384.crt.pem"
pki example.org key "/etc/acmed/certs/example.org_ecdsa-p384.pk.pem"
smtp ciphers "HIGH:!eNULL:!LOW:!MEDIUM:!EXP:!RC4:!3DES:!MD5:!SHA1:!PSK:!kRSA:!SRP:-DH:+ECDH"
#
# Tables
# If you edit a file, you have to run "smtpctl update table <table_name>"
#
table vusers "file:/etc/smtpd/vusers"
table aliases "file:/etc/smtpd/aliases"
#
# Filters
#
filter "rspamd" proc-exec "/usr/lib/smtpd/opensmtpd/filter-rspamd"
#
# Listening
#
# SMTP port 25 from localhost
listen on 127.0.0.1 tls pki example.org hostname mx1.example.org
listen on ::1 tls pki example.org hostname mx1.example.org
# SMTP port 25 from external sources
listen on 203.0.113.42 tls pki example.org hostname mx1.example.org filter "rspamd"
listen on 2001:db8::42 tls pki example.org hostname mx1.example.org filter "rspamd"
# SMTPS port 465 from authenticated users
listen on 203.0.113.42 smtps pki example.org auth <vusers> hostname mx1.example.org mask-src
listen on 2001:db8::42 smtps pki example.org auth <vusers> hostname mx1.example.org mask-src
# signed by dkimproxy
listen on lo port 10028 tag DkimOut
#
# Actions
#
action local_deliver lmtp "/run/dovecot/lmtp" alias <aliases>
action to_dkimproxy relay host smtp://127.0.0.1:10027
action relay_out relay helo example.org
#
# Matches
#
# Deliver emails
match from local for local action local_deliver
match from any for domain "example.org" action local_deliver
# Relay outgoing emails when signed
match from any tag DkimOut for any action relay_out
# Send outgoing unsigned emails to dkimproxy
match for any action to_dkimproxy
match from any auth for any action to_dkimproxy
Certains outils sont là pour vérifier certaines parties de votre configuration :
Pour vérifier que les emails que vous envoyez soient bien signés et que vous avez correctement défini votre SPF, il suffit d'envoyer un email à check-auth@verifier.port25.com
(IPv6 + IPv4).
Pour vérifier si votre serveur supporte bien l'IPv6, envoyez un email à test@doesnotwork.eu
et attendez la réponse automatique.