wiki/HowtoOpenDKIM.md

453 lines
16 KiB
Markdown
Raw Normal View History

2018-11-02 00:47:29 +01:00
---
categories: email spam
title: Howto OpenDKIM
...
* Documentation : <http://opendkim.org/docs.html>
* opendkim.conf(5) : <http://opendkim.org/opendkim.conf.5.html>
[DKIM (DomainKeys Identified Mail)](https://fr.wikipedia.org/wiki/DomainKeys_Identified_Mail) est une norme qui décrit l'ajout d'une signature cryptographique dans les en-têtes d'un email envoyé.
2018-11-02 00:47:29 +01:00
DKIM signe les mails avec une clé privée stockée sur le serveur. La clé publique est mise à disposition dans un enregistrement DNS TXT et permet au destinataire de vérifier que le domaine contenu dans l'adresse d'expédition appartient bien à l'expéditeur.
La signature se fait à partir à de l'expéditeur contenu dans l'en-tête (`From:`), d'autres en-têtes au choix (sujet, date, etc.) et du corps du message.
[OpenDKIM](http://opendkim.org/) est logiciel libre permettant de vérifier et générer des signatures DKIM. Il implémente un service `milter` lui permettant notamment d'être utilisé avec [Postfix](HowtoPostfix).
La norme DKIM remplace DomainKey obsolète (utilisée à l'origine par Yahoo).
2018-11-02 00:47:29 +01:00
## Installation
~~~
# apt install opendkim opendkim-tools
# adduser opendkim ssl-cert
~~~
## Configuration
La configuration principale se trouve dans le fichier `/etc/opendkim.conf`.
**Note 1 : Attention, `/etc/opendkim.conf` et les fichiers dans `/etc/opendkim/` doivent appartenir à l'utilisateur et au groupe `opendkim`.**
**Note 2** : Depuis Debian 9, l'unité systemd charge seulement `/etc/opendkim.conf` et non plus `/etc/default/opendkim`.
Les options de configuration se combinent principalement sur deux modes :
2023-06-28 16:47:37 +02:00
* Configuration par adresse ou domaine d'expédition, avec plusieurs clés privées (conseillé) :
* KeyTable (liste des clés privées)
* SigningTable (clés privées à utiliser en fonction de l'adresse `From:`)
* Pas de Domain, ni KeyFile, ni de Selector.
* Configuration avec une seule clé privée :
* Domain (liste des domaines acceptés)
* KeyFile (clé privée)
* Selector (nom de la clé dans l'enregistrement DNS)
* Pas de KeyTable, ni de SigningTable
### Configuration par adresse ou domaine d'expédition, avec plusieurs clés privées (conseillé)
Cette méthode est conseillée dans le cas où on gère de nombreux domaines.
2023-06-28 16:47:37 +02:00
Elle évite de devoir changer en une fois les enregistrement TXT de tous les domaines (ils contiennent les clés publiques) en cas en de génération d'une nouvelle clé privée.
~~~
# cat /etc/opendkim.conf
UserID opendkim:opendkim
Syslog yes
#SyslogSuccess yes
#LogWhy yes
UMask 007
2018-11-02 00:47:29 +01:00
InternalHosts /etc/opendkim/dkim.peers
Mode sv
2018-11-02 00:47:29 +01:00
OversignHeaders From
2018-11-14 23:35:22 +01:00
#DisableADSP true
Socket inet:8891@localhost
PidFile /var/run/opendkim/opendkim.pid
2022-11-25 14:58:01 +01:00
RemoveOldSignatures yes
SigningTable refile:/etc/opendkim/SigningTable
KeyTable refile:/etc/opendkim/KeyTable
2018-11-02 00:47:29 +01:00
~~~
2023-06-28 16:44:33 +02:00
**Le fichier `/etc/opendkim/KeyTable` définit les clés privées et leur sélecteur :**
2018-11-02 00:47:29 +01:00
~~~
key1 example.com:key1_selector:/etc/ssl/private/dkim_example.com.key
key2 example.org:key2_selector:/etc/ssl/private/dkim_example.org.key
2018-11-02 00:47:29 +01:00
~~~
Un **sélecteur** est un mot clé qui sert aux clients à trouver le sous-domaine de l'enregistrement TXT qui contient la clé publique DKIM du domaine (via `<SELECTOR>._domainkey.example.com`).
Si on a plusieurs serveurs de messagerie (et donc plusieurs clé privées), des sélecteurs différents permettent d'avoir plusieurs clés publiques associées à un même domaine, dans des enregistrements TXT de différents sous-domaines.
2018-11-02 00:47:29 +01:00
2023-06-28 16:47:37 +02:00
Pour détecter automatiquement le domaine à utiliser dans la signature à partir du champ `From:` (pratique sur les serveurs avec beaucoup de domaines) :
2023-06-28 16:44:33 +02:00
~~~
key1 %:key1_selector:/etc/ssl/private/dkim_my_mail_server.key
~~~
**Le fichier `/etc/opendkim/SigningTable` indique quelle clé utiliser pour signer en fonction du champ `From:` :**
2018-11-02 00:47:29 +01:00
~~~
*@example.com key1
*@example.org key2
2018-11-02 00:47:29 +01:00
~~~
2023-06-28 16:44:33 +02:00
Les lignes sont traitées dans l'ordre, seul le premier match est utilisé, sauf si `MultipleSignatures` est activé.
Pour signer tous les mails avec la même clé :
~~~
* key1
~~~
**Pour générer les clés**, on utilise la commande :
2018-11-02 00:47:29 +01:00
~~~
# opendkim-genkey -h sha256 -b 4096 -D /etc/ssl/private/ -d example.com -s foo -v
2018-11-02 00:47:29 +01:00
opendkim-genkey: generating private key
opendkim-genkey: private key written to foo.private
opendkim-genkey: extracting public key
opendkim-genkey: DNS TXT record written to foo.txt
# mv /etc/ssl/private/foo.private /etc/ssl/private/dkim_example.com.key
# chown opendkim:opendkim /etc/ssl/private/dkim_example.com.key
# chmod 640 /etc/ssl/private/dkim_example.com.key
~~~
2023-06-28 16:44:33 +02:00
Il faut ensuite **publier l'enregistrement DNS** à partir du fichier `/etc/ssl/private/foo.txt` généré, en ajoutant la ligne suivante dans la zone DNS du domaine en question :
2018-11-02 00:47:29 +01:00
~~~
foo._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtdnoCyrwNyCAttQz0VaJq3cheWtki8KTfCwPu+QDcyv8IHLpQGK2UsEw03epEjTI/ijdyyVsElDPoqsCZ4+R3H5I41Vj8xcGLvqIaG3mbgOhcxuD+eEPR1K+JbSptwMiP/oja7VFyftQtx5XkQh8oj458WR/EE++SzjOGXOVmFYzf+LnNXJ/Rc0avAUPcTF1NmoU8IP52aKTvw"
"nrbPFhIPkUyIR1/5k+5h4ZJqY+2h+JqDuol0E73Yl79rsF5ycjwLtBCPsz80jzCpOF5YHkDx0CYPyTKoIA3eZlgOVSJPmDYUWCrj/9k2bL/nSL5EJoB/X/kQcLRTy83dqf+gzWd850yP9vpUQQ2d+Z1hdlAFvzVMboSNz12+au7kAglXmN47l9Z8igxVWJfl7BEsegQF8gYPB4yepSW3DtfxBC5zCjLYYN1xXabf3wZfeCF6yOoQk1C2yN"
"ThvBa4NyQDWizZGs4t9eHTR8QHMzJogPQQvyS45ILN1HHeikIQZP/lormmFQzq9X8sDGt4Edy8A3OMLjHom81tP6zxb4I8Pq0V4bEt4m4KA+K89A+b9cTD2Xr/wbqgQ1nwTcnEfGgBxbc3iRKkUnwhjeIocsxmwHqmDIVV8HKB5egUg8US/eo9al8w4JYEdzx9tETW/5dQOeLTMVw2N0/A7M9zVbBQEyuaMCAwEAAQ==" ) ; ----- DKIM key foo for example.com
2018-11-02 00:47:29 +01:00
~~~
On utilise le fichier `/etc/opendkim/dkim.peers` pour mettre la liste des adresses IP autorisées à envoyer des messages pour lesquels on va rajouter une signature DKIM (a priori des serveurs SMTP internes uniquement) :
~~~
127.0.0.1
2018-12-29 17:43:05 +01:00
::1
2018-11-02 00:47:29 +01:00
192.0.2.142
192.0.2.0/25
~~~
On ajuste les droits ainsi :
~~~
# chown -R opendkim:opendkim /etc/opendkim*
# chmod 640 /etc/opendkim.conf /etc/opendkim/*
# chmod 750 /etc/opendkim/
~~~
Et l'on peut enfin démarrer le démon :
~~~
# systemctl start opendkim
# opendkim -V | head -4
2018-11-14 23:35:22 +01:00
opendkim: OpenDKIM Filter v2.11.0
Compiled with OpenSSL 1.1.0f 25 May 2017
2018-11-02 00:47:29 +01:00
SMFI_VERSION 0x1000001
libmilter version 1.0.1
# systemctl status opendkim
2018-11-14 23:35:22 +01:00
● opendkim.service - OpenDKIM DomainKeys Identified Mail (DKIM) Milter
Loaded: loaded (/lib/systemd/system/opendkim.service; enabled; vendor preset: enabled)
Docs: man:opendkim(8)
man:opendkim.conf(5)
man:opendkim-genkey(8)
man:opendkim-genzone(8)
man:opendkim-testadsp(8)
man:opendkim-testkey
http://www.opendkim.org/docs.html
Process: 13917 ExecStart=/usr/sbin/opendkim -x /etc/opendkim.conf (code=exited, status=0/SUCCESS)
Main PID: 13918 (opendkim)
Tasks: 6 (limit: 7372)
2018-11-02 00:47:29 +01:00
CGroup: /system.slice/opendkim.service
2018-11-14 23:35:22 +01:00
└─13918 /usr/sbin/opendkim -x /etc/opendkim.conf
2018-11-02 00:47:29 +01:00
~~~
### Configuration avec une seule clé privée
Générer une paire de clés avec le sélecteur `dkim-<SERVER_NAME>` (par exemple) dans le répertoire `/etc/opendkim/keys/` :
~~~
2023-07-03 11:31:42 +02:00
# mkdir /etc/opendkim/keys
# sudo -u opendkim opendkim-genkey -h sha256 -b 4096 -D /etc/opendkim/keys/ -s dkim-<SERVER_NAME>
~~~
Cela met la clé privée dans `/etc/opendkim/keys/dkim-<SERVER_NAME>.private`, et l'enregistrement DNS TXT contenant la clé publique dans `/etc/opendkim/keys/dkim-<SERVER_NAME>.txt`
Créer les whitelistes :
~~~
2023-07-03 11:31:42 +02:00
# vim /etc/opendkim/domains_whitelist
+ # Indiquez ici les domaines pour lesquels OpenDKIM va signer les mails.
2023-07-03 11:31:42 +02:00
# vim /etc/opendkim/hosts_whitelist
+ # Indiquez ici les IPs/sous-réseaux des serveurs SMTP internes pour lesquels OpenDKIM va signer les mails.
+ 127.0.0.1
+ ::1
~~~
Ajuster la configuration générale dans `/etc/opendkim.conf` :
~~~
UserID opendkim:opendkim
Syslog yes
#SyslogSuccess yes
#LogWhy yes
UMask 007
Mode sv
OversignHeaders From
#DisableADSP true
Socket inet:8891@localhost
PidFile /var/run/opendkim/opendkim.pid
RemoveOldSignatures yes
# Liste les IPs des serveurs SMTP internes pour lesquels OpenDKIM va signer les mails
InternalHosts refile:/etc/opendkim/hosts_whitelist
ExternalIgnoreList refile:/etc/opendkim/hosts_whitelist
# Clé privée (générée avec "sudo -u opendkim opendkim-genkey -h sha256 -b 4096 -D /etc/opendkim/keys/ -s dkim-<SERVER_NAME>")
KeyFile /etc/opendkim/keys/dkim-<SERVER_NAME>.private
# Utilisé dans l'enregistrement DNS utilisé pour récupérer la clé publique ($selector._domainkey.$domain)
Selector dkim-<SERVER_NAME>
# Liste des domaines pour lesquels OpenDKIM va signer les mails (accepte les regex)
Domain refile:/etc/opendkim/domains_whitelist
~~~
Enfin, lancer le service OpenDKIM :
~~~
2023-07-03 11:31:42 +02:00
# systemctl start opendkim
# systemctl status opendkim
~~~
#### Ajouter un domaine à OpenDKIM
Ajouter le texte contenu dans le fichier `/etc/opendkim/keys/dkim-<SERVER_NAME>.txt` aux enregistrements DNS du domaine.
Cela va rendre la clé publique accessible via un enregistrement TXT du sous-domaine `dkim-<SERVER_NAME>._domainkey.$domain`.
On peut vérifier l'enregistrement DNS avec :
~~~
2023-07-03 11:31:42 +02:00
$ host -t TXT dkim-<SERVER_NAME>._domainkey.$domain
~~~
Puis, ajouter le domaine à la liste `/etc/opendkim/domains_whitelist` et redémarrer le service :
~~~
2023-07-03 11:31:42 +02:00
# vim /etc/opendkim/domains_whitelist
+ $domain
# systemctl restart opendkim
# systemctl status opendkim
~~~
## Ajout dans Postfix
2018-11-02 00:47:29 +01:00
Pour configurer avec [Postfix](HowtoPostfix) on ajoute simplement les instructions suivantes dans le fichier `/etc/postfix/main.cf` :
~~~
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = inet:127.0.0.1:8891
#milter_default_action=accept
# Pour accélérer les signatures, pas d'attente pour contacter le milter
in_flow_delay = 0s
2018-11-02 00:47:29 +01:00
~~~
Cela entraînera l'ajout d'un en-tête `DKIM-Signature:` à tous les messages qui correspondent à la configuration d'OpenDKIM.
Si vous utilisez l'option `Mode sv` ou `Mode v` dans la configuration d'OpenDKIM, cela entraînera une vérification des signatures DKIM des emails reçus, et l'ajout d'un en-tête du type :
~~~
Authentication-Results: antispam.example.com; dkim=pass
reason="1024-bit key; unprotected key"
header.d=example.com header.i=@example.com header.b=lJ7oU+Kk;
dkim-adsp=pass; dkim-atps=neutral
~~~
2018-11-02 00:47:29 +01:00
## Vérifications
### Vérifier la configuration
2018-11-02 00:47:29 +01:00
On peut vérifier que la configuration est correcte, notamment l'enregistrement DNS (si la commande ne renvoie rien, c'est que c'est OK) :
2018-11-02 00:47:29 +01:00
~~~
# opendkim-testkey -d example.com -s foo -k /etc/ssl/private/dkim_example.com.key -v
opendkim-testkey: /etc/ssl/private/dkim_example.com.key: WARNING: unsafe permissions
opendkim-testkey: key not secure
~~~
> *Note* : vous pouvez ignorer le warning des permissions si vous avez correctement ajusté les droits comme précisé plus haut
### Vérifier la signature DKIM d'un mail
2018-11-02 00:47:29 +01:00
Il faut envoyer un email de test avec un expéditeur d'en-tête correct. Par exemple, en ligne de commande :
2018-11-02 00:47:29 +01:00
~~~
$ telnet 127.0.0.1 25
HELO example.com
MAIL FROM: <noreply@example.com>
RCPT TO: <foo@example.org>
DATA
From: <noreply@example.com>
To: Foo <foo@example.org>
Subject: test DKIM
Ceci est un test
.
~~~
La source de l'email devrait avoir un en-tête supplémentaire du type :
2018-11-02 00:47:29 +01:00
~~~
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=example.com; s=foo;
t=1541094902; bh=xj6JF8HXzDkYeJ72cJNmx7FnTp5CeDo6y+MwRwIeNC4=;
h=Date:From:To:Subject:From;
b=lJ8oU+KkUBWEWVl/HpztFx5Hdv2rhqLP03JfJ1yqp3+TR3aZX+uOCI4MKqvonYzXM
kHl4YYsYT7fSnuSaF48feGbGQ1AauGKd2x9UKcBEBQq2cGLG7ahfXph/SF5eh7/psL
dXal6gCw6416bJQMBa9sb+zSA/9Avy3zQ0jGCALw=
~~~
Dans Thunderbird, le plugin `DKIM verifier` permet de vérifier les en-têtes DKIM des mails reçus.
Sinon, si vous avez accès à un email Gmail ou Yahoo, vous pouvez lui envoyer un email. En affichant le message original, vous pourrez vérifier la présence de `DKIM-Signature:`. Cela vous indiquera si la signature est correcte et acceptée.
2018-11-02 00:47:29 +01:00
### Vérifier via des services externes
* Vérifier (notamment) son enregistrement DNS pour DKIM : <https://toolbox.googleapps.com/apps/checkmx/> (2 premiers résultats à ignorer).
2018-11-02 00:47:29 +01:00
* Vérifier en envoyant un email vers un service externe : <https://dkimcore.org/tools/> ou <http://dkimvalidator.com/> ou <https://www.mail-tester.com/>.
2018-11-02 00:47:29 +01:00
## Monitoring
Il est important de s'assurer que le démon *opendkim* tourne en permanence.
### Nagios
Voici un check basique pour vérifier que le port TCP d'*opendkim* répond bien :
~~~
$ /usr/lib/nagios/plugins/check_tcp -H 127.0.0.1 -p 8891
2018-11-02 00:47:29 +01:00
~~~
### log2mail
Pour être alerté en cas de *warning: connect to Milter service inet:8891: Connection refused
2018-11-02 00:47:29 +01:00
on ajoute la configuration suivante au logiciel [log2mail](https://wiki.evolix.org/HowtoLog2mail) :
~~~
file = /var/log/syslog
pattern = "warning: connect to Milter service inet:8891: Connection refused"
2018-11-02 00:47:29 +01:00
mailto = alert@example.com
~~~
2018-11-02 00:47:29 +01:00
## FAQ
### opendkim: smfi_opensocket() failed
2018-11-02 00:47:29 +01:00
Si vous obtenez le message suivant au démarrage :
~~~
Starting OpenDKIM Milter: opendkim: smfi_opensocket() failed
~~~
C'est que la socket réseau est déjà occupée !
2018-11-02 00:47:29 +01:00
2018-11-02 00:47:29 +01:00
### ADSP (Author Domain Signing Practices)
**ADSP est désormais obsolète, et remplacé par la spécification [DMARC](https://fr.wikipedia.org/wiki/DMARC)
[ADSP](https://en.wikipedia.org/wiki/Author_Domain_Signing_Practices) est une extension à DKIM permettant d'indiquer le traitement à effectuer en cas de signature DKIM invalide ou absente.
Si l'on est sûr que tous les mails émis avec le nom de domaine utilisé sont bien signés avec DKIM, on peut l'indiquer via l'enregistrement DNS suivant, ce qui provoquera la pénalisation des emails sans signature :
~~~
_adsp._domainkey IN TXT "dkim=all"
~~~
On peut vérifier que l'enregistrement ADSP est bien pris en compte avec la commande suivante :
~~~
# opendkim-testadsp example.com
~~~
### Pas d'en-tête DKIM-Signature
2018-11-02 00:47:29 +01:00
Si vous ne constatez pas l'ajout de la signature DKIM, vérifiez votre configuration, vérifiez que vous utilisez bien un champ `From:` correct et correspondant à un domaine à signer.
Il peut aussi être intéressant d'activer les options suivantes dans `/etc/opendkim.conf` pour avoir davantage de logs :
~~~
Syslog yes
SyslogSuccess yes
LogWhy yes
~~~
### Logs de vérification
Il peut être intéressant d'activer l'option suivante /etc/opendkim.conf` pour avoir des logs pour chaque signature vérifiée par *opendkim* :
~~~
LogResults true
~~~
### Requêtes DNS externes pour ADSP
Attention, par défaut OpenDKIM effectue ses vérifications ADSP en faisant de multiples requêtes DNS sans utiliser le resolver local,
ce qui qui peut provoquer des ralentissements notamment si cela n'est pas autorisé au niveau firewall.
Nous conseillons de désactiver ces vérifications qui sont obsolètes :
~~~
DisableADSP true
~~~
### Gmail/Google et DKIM
Informations de Gmail/Google à propos de DKIM : <https://support.google.com/a/answer/174124?hl=fr>.
### Problème de header (dkim-filter: no sender header found)
Avec dkim-filter, en Debian 7, il se peux que, suite a une règle de ce type dans postfix :
~~~
/^received:/ IGNORE
~~~
cela casse dkim-filter, car il ne vois pas si le sender est correct dans le header du mail, et donc il ne sais pas si c'est un domaine qu'il doit signé ou pas.
2020-12-02 11:02:09 +01:00
2020-12-02 11:02:09 +01:00
### Regenérer la zone DNS
Lorsqu'une clé a déjà été générée mais que le fichier contenant la zone DNS n'est plus disponible, il est possible de la régénérer avec la commande suivante :
2020-12-02 11:02:09 +01:00
~~~
opendkim-genzone -F -d example.com /etc/opendkim/KeyTable
~~~
2023-02-03 15:48:43 +01:00
### body hash did not verify
Cette erreur vient du fait que le payload du message a été modifié par un serveur SMTP entre le départ et l'arrivée (inclus).
Cela peut venir de lignes trop longues (cf plus bas).
### Lignes trop longues
D'après <https://www.rfc-editor.org/rfc/rfc2822#section-2.1.1> les lignes d'un email ne doivent pas être trop longues sinon elles peuvent se faire découper par un serveur SMTP entre le départ et l'arrivée (inclus)... ce qui changer le payload du message car il aura notamment des sauts de ligne en plus.. et donc le body hash de la signature DKIM ne sera plus valide.