[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é.
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).
Cette méthode est conseillée dans le cas où on gère de nombreux domaines.
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.
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`).
Le fichier `SigningTable` indique quelle clé utiliser pour signer en fonction du champ `From:`.
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.
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 :
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) :
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 :
~~~
# sudo -u opendkim vim /etc/opendkim/domains_whitelist
+ # Indiquez ici les domaines pour lesquels OpenDKIM va signer les mails.
# sudo -u opendkim 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
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 :
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.
* Vérifier en envoyant un email vers un service externe : <https://dkimcore.org/tools/> ou <http://dkimvalidator.com/> ou <https://www.mail-tester.com/>.
**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 :
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 :
### 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.
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 :
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.