Postfix : ajouter une signature DKIM à ses e-mails avec OpenDKIM

OpenDKIM va nous permettre, de générer une signature DKIM pour notre domaine, et de l’appliquer à tous les e-mails qui vont transiter par notre Postfix, dont l’adresse de l’émetteur est sur notre domaine.

OpenDKIM

Installation

Il est dans les dépôts, alors on l’installe avec apt :

sudo apt -y install opendkim

Génération d’une clé DKIM

Utilisons opendkim-genkey qui va générer la clé privée et la clé publique nécessaire au fonctionnement de notre signature DKIM.
On utilise uniquement les paramètres qui nous intéressent :

  • -d (--domain) : indique le nom de domaine pour lequel on génère les clés. Ça permet d’ajouter un commentaire dans le fichier contenant la clé publique, pratique pour s’y retrouver.
  • -D (--directory) : donne le répertoire où seront générés les clés. Sous Debian, OpenDKIM utilise par défaut, /etc/domainkeys. Il faut cependant le préciser lors de la génération des clés
  • -r (--restricted) : restreint l’utilisation à la signature de courriels
  • -S (--nosubdomains) : les sous-domaines ne peuvent pas utiliser cette clé DKIM

Je n’ai volontairement pas définit de sélecteur, ni de longueur de clé, car sous Debian, le sélecteur par défaut est « default », et la longueur de la clé est de 2048 bits.

Ce qui nous donne :

opendkim-genkey -d 'mashi.fr' -D '/etc/dkimkeys/' -r -S

Cela va nous générer deux fichiers : dkim.private et dkim.txt dans /etc/dkimkeys

Création de l’enregistrement DNS contenant la clé DKIM

L’enregistrement DNS qui va contenir notre clé DKIM publique est un enregistrement de type TXT.
Son nom est obligatoirement composé du sélecteur indiqué à la génération des clés, suivi de ._domainkey, soit sans notre cas : default._domainkey

La valeur de cet enregistrement se trouve dans le fichier /etc/dkimkeys/dkim.txt.
Si vous avez accès au fichier de zone DNS de votre nom de domaine, vous pouvez y ajouter directement le contenu du fichier /etc/dkimkeys/dkim.txt.
Sinon vous devez copier la partie du fichier qui est entre parenthèses, en rouge dans l’exemple ci-après :

dkim._domainkey IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; t=s; s=email; "
          "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8a96FSMwTFVh4MpXte5B0upeRxD0UnyaeFdcfsGOQBmLAjPsowN0I6PCY3dPthZeVBOlR+gPNDYmk3D0xFvVDTV6HmFTkFBTMVd07XJTTiVoGnunKQQEvNuQKpRVlKhqP3U1+rNGtKpeU1umy5lB8zlAhGa0OcpQ/hA9oxegdW8hG53YTvrKogBVfHZIi/B4ZHILjr7znhETPK"
          "g6GfYIIv2kHndZVi3fjJUmXwuy+NEBDu85WDuRytuqwbqr4rwH5+7WAxQuNNsBABZCFFFWaHgGITKKrwlT32aJKN/beuktp4DNjvTbxPLhPIRs1VcHT+Ph/iLKnLfUOpq8kNm7jwIDAQAB" )  ; ----- DKIM key dkim for mashi.fr

Je vous recommande de supprimer les sauts de lignes, et de remplacer les tabulations par un simple espace, cependant, ne supprimez aucun guillemets, ils ont un rôle essentiel pour le serveur DNS de votre nom de domaine.

L’enregistrement se présente en définitive sous la forme suivante :

default._domainkey	 TXT	 "v=DKIM1; h=sha256; k=rsa; t=s; s=email; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8a96FSMwTFVh4MpXte5B0upeRxD0UnyaeFdcfsGOQBmLAjPsowN0I6PCY3dPthZeVBOlR+gPNDYmk3D0xFvVDTV6HmFTkFBTMVd07XJTTiVoGnunKQQEvNuQKpRVlKhqP3U1+rNGtKpeU1umy5lB8zlAhGa0OcpQ/hA9oxegdW8hG53YTvrKogBVfHZIi/B4ZHILjr7znhETPK" "g6GfYIIv2kHndZVi3fjJUmXwuy+NEBDu85WDuRytuqwbqr4rwH5+7WAxQuNNsBABZCFFFWaHgGITKKrwlT32aJKN/beuktp4DNjvTbxPLhPIRs1VcHT+Ph/iLKnLfUOpq8kNm7jwIDAQAB"

Vérification du fonctionnement de la clé

Une fois la propagation de l’enregistrement DNS contenant la clé DKIM propagé, on peut tester son fonctionnement avec la commande opendkim-testkey.
Il va récupérer la clé publique dans l’enregistrement DNS du domaine, avec le sélecteur fourni, et la comparer avec la clé privée qu’on lui donne.

Ses paramètres sont :

  • -d : le nom de domaine
  • -k : le chemin vers la clé privée
  • -s : le sélecteur DKIM

Dans notre cas :
opendkim-testkey -d 'mashi.fr' -k '/etc/dkimkeys/dkim.private' -s 'default'

Si tout se passe bien, la commande ne retournera rien. Vous pouvez passer à l’étape suivante.

A savoir : Si vous demander à la commande d’être un peu plus bavarde avec le paramètre « -v », alors elle vous indiquera que la clé n’est pas sécurisée (« key not secure »). Cela indique que l’enregistrement n’est pas protégé par DNSSEC, mais pas un dysfonctionnement au niveau du processus DKIM.

Configuration

On va éditer /etc/opendkim.conf pour définir les paramètres suivants :

  • Domain : Le nom de domaine pour lequel on veut une signature DKIM
  • Selector : Le sélecteur correspondant à la signature, qui sera ajouté dans les en-têtes des e-mails signés
  • KeyFile : Le fichier qui contient la clé privée
  • Socket : Le chemin vers le socket d’OpenDKIM. On doit l’éditer car Postfix s’exécute dans une « chroot »
Domain          mashi.fr
Selector        default
KeyFile         /etc/dkimkeys/dkim.private
Socket          local:/var/spool/postfix/opendkim/opendkim.sock

Il faut maintenant créer le répertoire du soket, et définir l’utilisateur opendkim comme propriétaire :

mkdir /var/spool/postfix/opendkim/ && chown opendkim /var/spool/postfix/opendkim/

Puis on relance OpenDKIM :
systemctl restart opendkim

Lier Postfix et OpenDKIM

OpenDKIM va servir de milter à Postfix.
Il ajoutera les en-têtes nécessaires aux e-mails que Postfix lui fera analyser.

Configuration de Postfix

On doit d’abord ajouter l’utilisateur postfix au groupe opendkim, pour que Postfix puisse accéder au socket d’OpenDKIM :

adduser postfix opendkim

puis on ajoute les paramètres non_smtpd_milters et smtpd_milters dans les paramètres de Postfix, avec pour valeur le chemin vers le socket d’OpenDKIM :

postconf 'non_smtpd_milters = unix:/opendkim/opendkim.sock'
postconf 'smtpd_milters = unix:/opendkim/opendkim.sock'

Et on recharge la configuration de Postfix :

postfix reload

Édition du DMARC

Comme nous avons maintenant une signature DKIM sur nos e-mails, on va modifier les informations DMARC de notre domaine, pour indiquer qu’il doit maintenant tenir compte de la signature DKIM, en plus du SPF déjà en place.

Modifions ça :

_dmarc  TXT  "v=DMARC1; p=quarantine; aspf=s; adkim=r; rua=mailto:postmaster@mashi.fr; ruf=mailto:postmaster@mashi.fr"

Par :

_dmarc	 TXT	"v=DMARC1; p=quarantine; aspf=s; adkim=s; rua=mailto:postmaster@mashi.fr; ruf=mailto:postmaster@mashi.fr"

Rien de très compliqué, on a juste remplacé « adkim=r; » par « adkim=s; », ce qui précise que le traitement par rapport au DKIM est maintenant strict, contre relaxed auparavant.

Test : Envoyer un e-mail vers une adresse de courriel distante

On va envoyer un e-mail vers une adresse e-mail externe. J’envoi un e-mail vers une adresse @gmail.com :

echo "Salut, ceci est le corps de mon un e-mail de test" | mail -s "Ceci est l'objet de mon e-mail de test" xxxxx.yyyyy@gmail.com

Et on affiche les dernières lignes de mail.log.

Jan 29 15:39:56 v1711 postfix/pickup[1450177]: 07C63321511: uid=1005 from=<olivier>
Jan 29 15:39:56 v1711 postfix/cleanup[1450181]: 07C63321511: message-id=<20220129143956.07C63321511@mail.mashi.fr>
Jan 29 15:39:56 v1711 opendkim[1448661]: 07C63321511: DKIM-Signature field added (s=default, d=mashi.fr)
Jan 29 15:39:56 v1711 postfix/qmgr[1450180]: 07C63321511: from=<olivier@mashi.fr>, size=450, nrcpt=1 (queue active)
Jan 29 15:39:56 v1711 postfix/smtp[1450183]: 07C63321511: to=<xxxxxxx.yyyyyy@gmail.com>, relay=gmail-smtp-in.l.google.com[142.250.145.27]:25, delay=0.41, delays=0.02/0/0.09/0.31, dsn=2.0.0, status=sent (250 2.0.0 OK  1643467196 b14si4597488edw.116 - gsmtp)
Jan 29 15:39:56 v1711 postfix/qmgr[1450180]: 07C63321511: removed

On peut voir maintenant qu’une ligne a été ajouté par OpenDKIM. Il nous informe qu’il a ajouté l’en-tête de signature DKIM et nous donne le sélecteur et le domaine concerné.

Du côté de Google, on voit aussi une information, qui nous indique la présence de la signature DKIM, et qu’elle est valide, dans notre courriel :

Informations détaillées visible via « Afficher l’original » dans l’interface Gmail

Conclusion

Les e-mails dont l’émetteur est sur notre nom de domaine disposent d’une signature DKIM.
Grâce à cela et le support de SPF et de DMARC, on met toutes les chances de notre côté pour optimiser la livraisons de nos courriels et réduire au maximum les problèmes d’usurpation d’e-mail.