Signer ses emails avec DKIM
jeudi 28 janvier 2010 à 02:15 par Dju - 4389 lectures
Si vous avez un serveur mail, utilisant postfix, alors voici un outil très pratique pour prouver la provenance des emails envoyés par votre serveur, en leur collant une signature numérique, fonctionnant avec une clé publique/privée.
Cela permettra ainsi d'affirmer que vos emails sont bien envoyés par vous, et également de filtrer les emails ayant une signature incorrecte.
D'abord, comment ça marche ?
on créée un enregistrement DNS sur son domaine dans lequel on indiquera une clé publique, accessible à tout le monde.
En interne, lors de l'envoi d'un email, le serveur utilisera une clé privée pour signer le mail.
Ainsi, à l'autre bout, le serveur recevant le mail pourra, via votre clé publique, vérifier et authentifier sa provenance 
On commence par l'installer de manière classique :
aptitude install dkim-filter
Le fichier de configuration principale se trouve dans /etc/dkim-filter.conf et voici le contenu à indiquer pour une config. standard et fonctionnelle.
# Log to syslog Syslog yes # Sign for example.com with key in /etc/dkim-filter/private.key using selector 'dkim' (e.g. dkim._domainkey.example.com) Domain vorte_domaine.com KeyFile /etc/dkim-filter/private.key Selector dkim InternalHosts /etc/dkim-internal-hosts # Common settings. See dkim-filter.conf(5) for more information. AutoRestart no Background yes Canonicalization simple DNSTimeout 5 Mode sv SignatureAlgorithm rsa-sha256 SubDomains no #ASPDiscard no #Version rfc4871 X-Header no
les lignes importantes :
- Domain: indique le domaine pour lequel la signature sera ajoutée à l'email. si plusieurs, les mettre à la suite en les séparant par une virgule
- KeyFile: le chemin vers le fichier contenant votre clé privée
- Selector: le nom de l'enregistrement dns dans lequel allez chercher la clé publique
- Mode: s pour signer les emails sortants et v pour vérifier les entrants.
- SubDomaines: no si pas de sous domaines, yes si vous en avez et que vous souhaitez également avoir les emails signés
- X-Header: ajouter un header dans le mail pour indiquer le logiciel qui signe les mails
- InternalHosts: optionnel, fichier contenant la ou les adresses IP des machines utilisant votre postfix en relai pour envoyer des mails. une adresse ip par ligne, ou un masque de sous réseau (exemple 192.168.0.0/24)
Ensuite, on édite le fichier /etc/default/dkim-filter dans lequel on configure sur quelle adresse ip et port le démon va écouter.
par défaut, on a plusieurs lignes commentées, et une non commentée :
SOCKET=inet:8891@localhost
Signifie que le démon écoutera en local sur 127.0.0.1 sur le port 8891
A présent, on va générer notre couple de clé privée/publique.
mkdir /etc/dkim-filter
cd /etc/dkim-filter
openssl genrsa -out private.key 1024
openssl rsa -in private.key -pubout -out public.key
Attention à garder très précieusement la clé privée. vous devez être le seul à la connaitre sous peine de voir votre authenticité remise en cause lors d"envois d'emails....
Maintenant, on va déclarer notre enregistrement DNS, qui est de type TXT, et de nom selecteur._domainkey.votre_domaine.com
"selecteur" correspond à la ligne Selector indiqué dans dkim-filter.conf. En l'occurrence dkim.
Si vous aviez mis dans votre fichier "Selector machin", alors votre enregistrement txt aura comme nom machin._domainkey.votre_domaine.com
Pour ceux qui ont un Bind comme serveur DNS, voici la ligne à rajouter dans la zone décrivant votre domaine.
dkim._domainkey.votre_domaine.com IN TXT "k=rsa; t=y; p=votre_clé_publique;"
remplacez "votre_clé_publique" par le contenu de votre fichier public.key, en n'oubliant pas d'enlever la 1è ligne (-BEGIN RSA PRIVATE KEY-) et la dernière (-END RSA PRIVATE KEY-)
Une fois votre démon dkim-filter configuré aux p'tis oignons, redémarrez le service
/etc/init.d/dkim-filter restart
Enfin, on va configurer postfix pour lui indiquer de passer les emails sortant à dkim-filter afin de les signer.
On édite le fichier /etc/postfix/main.conf et on rajoute ces quelques lignes :
milter_default_action = accept milter_protocol = 2 smtpd_milters = inet:localhost:8891 non_smtpd_milters = inet:localhost:8891
Puis on redémarre postfix pour valider
/etc/init.d/postfix restart
Et voila ! maintenant, il ne reste plus qu'à envoyer un email depuis votre serveur pour vérifier qu'il est bien signé.
Vous devriez retrouver quelque chose comme ça dans les headers:
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=votre_domaine.com; s=dkim; t=1264638542; bh=CUY18yi5KBUf/CwX9/rU/h/Vq4lY/pH69p31s2CUvUc=; h=From:To:Subject:Date:Mime-Version:Content-Type: Content-Transfer-Encoding:Message-id; b=nzkf/UE8TrZlKLKnzass8LgwbDJ54kqEMu3lOz7Sq2dMhsMuRyEgQuDWr36qmpD1T kLto5zqX8iYuM0Z81KLf598rLLATCqnm5fr3neKEMyjc7+iANjpAnAl/wBRnnHPZbs zTxiG+0vdN03Kg2/eDUxgmmxMU4pctBG6rLsDpRY
et si le serveur qui reçoit le mail a également une vérification dkim, alors vous aurez un autre header ressemblant à ça ;:
Authentication-Results: mail.votre_domaine.org; dkim=pass (1024-bit key; insecure key) header.i=@votre_domaine.com; dkim-adsp=none (insecure policy)
Une autre bonne solution pour le tester est d'envoyer un mail sur une adresse gmail.
En le consultant depuis le webmail Gmail, vous trouverez en haut une ligne en plus disant signé par votre_domaine.com
Et la, c'est gagné ! 
Plus d'infos sur wikipedia et le site officiel
Commentaires
Billet très utile, je le garde sous le coude pour mon prochain serveur
sinon y'a aussi un article sur le SPF, sur system-linux.eu (http://www.system-linux.eu/index.ph...), en complément de celui-ci
Sinon, toujours pas décidé pour ton futur serveur ?
ton billet est très sympa je vais l'essayer sur redhat/centos et je le publierai sur www.system-linux.eu avec ton accord biensur.
salut gangan

no problèmo, c'est fait pour
par contre, sur une distro autre que debian/ubuntu, les dossiers/fichiers ne seront ptêt pas forcément les mêmes ... à voir
Bonjour,
Merci pour le tuto, mais cela ne fonctionne pas à 100% chez moi.
Si on envoi via un client de messagerie sur le serveur, le mail est bien signé, par contre si l'envoi se fait depuis le serveur, via la fonction mail de php, aucune signature n'apparait... ??
Une idée ?
salut elcanux,
quelle adresse de smtp as tu renseigné dans ton php.ini ?
si tu mets 127.0.0.1 ça devrait le faire.
à moins que tu utilises le fichier InternalHosts, dans lequel tu aurais omis de mettre 127.0.0.1 ?
Merci de la réponse, j'ai bien localhost dans le php.ini, mais j'ai réussi à corriger le problème en mettant dans le virtualhost d'apache le code suivant :
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f webmaster@mondomaine.com -F webmaster@mondomaine.com"
Ha, la commande sendmail... bien vu
On peut aussi la configurer dans le php.ini à la ligne "sendmail_path="
Marrant, je n'ai pas eu à configurer ça sur le php de mon ubuntu server...
Cela doit être du au fait que je force postfix à mettre @mondomaine.com à l'adresse d'émetteur si on ne définit pas un from complet.
or, php doit, quand tu envoies un mail, mettre un emetteur générique, du style www-data@localhost, ce qui ne sera pas signé car pas ton domaine.
Pour ce faire, tu peux ajouter dans le main.cf de ton postfix la ligne
myorigin=/etc/mailname
et dans ce fichier mailname, tu mets tondomaine.com.
Ainsi, si tu envoies un mails sans définir un from, ou en mettant un incomplet, par exemple juste "root", ca rajoutera @tondomaine.com après
merci pour ce tuto simple et efficace,
juste une petite typo: private.key et non private-key dans la génération de la clé publique.
oops, bien vu stéphane.
c'est corrigé, merci
Bjr,
Je n'arrive pas à faire tourner la signature dkim, je crois que le pb est au niveau du nom de domaine. Je suis hébergé chez sivit (un serveur vds), et mon nom de domaine est chez gandi. Avec l'interface de ce dernier je ne peux pas ajouter un champ TXT, je suis allé chercher du côté de l'interface du gestionnaire de mon VDS et je pense que j'ai trouvé, j'ai ajouté ceci :
http://www.casimages.com/img.php?i=...
Je ne suis pas sûr de la manip effectuée !!
En envoyant à une adresse Google, je ne trouve pas "signé par ...", purtant je trouve bien "DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=..." !! J'ai testé avec ceci :
http://www.myiptest.com/staticpages...
il confirme bien qu'il n'y pas de signateur dkim
le plus bizarre c'est que google m'affiche les données suivantes :
...dkim=neutral (no signature) ...
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple...
en envoyant depuis un nom de domaine qui n'a pas de signature dkim, dans ma boite gmail je n'ai aucune mention au nom DKIM !! je ne comprend plus
je viens d'essayer un truc : j'ai supprimé le champ TXT et rien n'a changé! une idée de ce que ça voudrait dire ??
Bonjour sami,

normalement, la clé publique doit impérativement être mise dans un champs dns TXT sur votre domaine. sans quoi ça ne peut pas fonctionner.
donc à priori, si le screenshot ci dessus montre l'interface de gestino de sivit et non gandi, cela ne changera malheureusement rien
j'utilise pas gandi mais ça doit être possible d'ajouter un champs txt, non ? si au pire gandi t'en empêches, et que tu n'as pas peur de mettre les mains dans le cambouis, tu peux t'installer un bind sur ton serveur et gérer toi meme ton nom de domaine
Merci Dju pour la réponse. J'ai envoyé un mail à Gandi, ils me disent qu'il faut passer par leurs DNS pour pouvoir ajouter un champs TXT, mais si je n'utilise plus les DNS de mon serveur, le nom de domaine ne pointera plus sur mon serveur ... ou est-ce que je me trompe !! Les services http, ftp, pop... ne fonctionneront plus je pense non ?
Sami, que ce soit les DNS de gandi qui gèrent ton domaine, ou un bind sur ton serveur, cela revient au meme.
L'important est d'avoir la clé dkim publique dans un champs xxx._domainkey de type TXT sur ton domaine.
Actuellement, je comprends que t'utilises ton serveur comme DNS. dans ce cas la édite le fichier de ta zone et rajoute le txt, ça sera good
Salut,
J'ai enfin pu installer DKIM, le problème provenait en fait de l'interface de SIVIT de gestion du serveur, bref j'ai modifié manuellement le fichier de zone de BIND et ça sembler fonctionner PARTIELLEMENT : gmail n'indique pas que le mail est signé, pourtant il y a bien ceci dans le header du mail :
...
Authentication-Results: mx.google.com; ... dkim=pass (test mode) ...
J'ai comparé avec un mail envoyé depuis une boite gmail et j'ai vu qu'il y a une signature DKIM mais aussi DomainKey ... je pensais que c'était la même chose non ??? sinon est-ce que tu as un bon tuto pour installer domainKey sur postfix ?
En effet, j'ai envoyé un mail à check-auth[AT]verifier.port25.com
et voilà ce que j'ai :
SPF check: neutral
DomainKeys check: neutral
DKIM check: pass
Sender-ID check: neutral
SpamAssassin check: ham
Donc il faut maintenant installer DomainKeys
et d'après les tutos que j'ai vu, c'est plus difficile que ton tuto de DKIM
...
autre question : quand j'envoie via SquirrelMail, le mail est bien signé, mais quand je passe par la fonction mail() de php ça ne marche plus !! C'est quoi le problème ?
Bonjour,
Je n'arrive pas non plus à signer mes emails je n'est pas de message d'erreur mais les mail arrivent toujours non signés chez Gmail, peut on voir les messages d'erreurs? Si ou comment?
Merci
@Romain : cet article permet d'installer uniquement la signature DKIM, c'est pour ça que google ne dit rien concernant la signature, il faut aussi configurer la signature DomainKeys de yahoo.
Pour tester je te conseille d'envoyer un mail à check-auth[AT]verifier.port25.com (voir un de mes précedents posts), c'est mieux que de tester avec une boite gmail ou yahoo
Pour installer DK : http://www.howtoforge.com/how-to-im...
Bonsoir

@sami: effectivement, dkim et dkey sont 2 choses différentes. je m'étais un peu penché la dessus, et dkim est plus simple à installer, et aussi plus populaire. d'ou mon choix
@Romain: pour que les emails sortants soient signées, il faut impérativement mettre en from une adresse @tondomaine.com, déclaré dans la configuration de dkim. si tu envoies ton mail avec dans le from un autre domaine, ça ne fonctionnera pas. Enfin, vérifie dans ton php.ini le smtp utilisée, et le from par défaut. il ne doit pas être avec ton domaine déclaré dans dkim. (et voir plus haut le problème de elcanux)