Installer DomainKeys sur Postfix (Debian Etch, Amavisd-new...)
Par Yves Tannier le dimanche, novembre 4 2007, 13:58 - Le pingouin - Lien permanent
Mise à jour le 12 mars 2008 : le même billet adapté pour DKIM est disponible : Installer la signature DKIM sur Postfix avec DKIMproxy.
Dans ma lutte incessante pour que mes messages n'aient pas comme destination finale les dossiers "courrier indésirable" des "grands" fournisseurs tels que Yahoo!, Hotmail/MSN, Gmail ect... Je vous propose aujourd'hui l'installation de la signature Domainkeys sur vos mails.
DomainKeys est un protocole de communication créé par Yahoo! (et défini par une RFC 4870). Wikipedia vous donnera un plus d'informations sur le sujet : DomainKeys sur Wikipedia
Même s'il fonctionne totalement et est déployé sur de nombreux serveurs, sachez qu'il est maintenant remplacé par une RFC plus "globale" : DKIM (Domain Keys Identified Mail). J'aborderais les différences et l'implémentation de DKIM dans un autre post.
D'autres liens :
- Prouver et sécuriser l'identité des expéditeurs par Yahoo!
- DomainKey Implementor's Tools and Library for email servers & clients
DomainKeys bien reconnu chez Yahoo! (forcément ;))

Voici la configuration du serveur de messagerie sur lequel se base ce tutoriel :
Nous allons mettre en place la configuration suivante :
postfix -> dkfilter -> postfix -> amavis -> postfix
Dkfilter est un proxy de signature et de vérification des signatures pour DomainKeys.
Ceci peut paraitre un peu lourd en regardant le schéma, mais postfix gère ce type de configuration très bien via les content filter
Comme je suis gentil et que l'informaticien est souvent fainéant, j'ai écris ce howto avec plein de copier/coller 
Installer dkfilter
Il n'existe, à l'heure où j'écris ces lignes, pas de paquet Debian Etch pour dkfilter mais l'installation est relativement simple.
Installez les modules perl suivant (ici, via cpan) :
perl -MCPAN -e shell install Crypt::OpenSSL::RSA install Mail::Address install MIME::Base64 install Net::DNS install Net::Server install Test::More install AppConfig::File
Placez vous dans /usr/src/
cd /usr/src/
Téléchargez dkfilter
wget http://jason.long.name/dkfilter/dkfilter-0.11.tar.gz
Décompressez l'archive
tar zxvf dkfilter-0.11.tar.gz
Patcher pour l'utilisation de dkfilter sur plusieurs domaines
Pour mon installation, j'ai besoin que Domain Keys soit utilisable pour plusieurs domaines sur le même serveur.
Ca tombe bien, un gentil contributeur nous propose un patch de dkfilter pour gérer les différentes clés et paramètres par domaine depuis un simple fichier de configuration.
Téléchargez donc le patch en question :
wget -P /usr/src/dkfilter-0.11/scripts/ http://jason.long.name/dkfilter/config_file.patch
Patchez le programme :
cd /usr/src/dkfilter-0.11/scripts/ patch < config_file.patch
Ensuite, créez le répertoire d'installation de dkfilter dans /usr/local par exemple :
mkdir /usr/local/dkfilter
Lancez le "configure" en précisant dans l'option votre répertoire d'installation :
./configure --prefix=/usr/local/dkfilter
Installez
make install
Si il n'y a pas d'erreur, vous pouvez continuer. Vous devez voir dans /usr/local/dkfilter, un dossier lib/ et un dossier bin/
ls -l /usr/local/dkfilter
Créer l'utilisateur et le groupe dkfilter
adduser dkfilter --no-create-home --disabled-password --disabled-login
Installer le script de démarrage de dkfilter
Un script d'exemple est fourni dans l'archive de dkfilter. On le copie dans /etc/init.d/.
cp /usr/scr/dkfilter-0.11/sample-dkfilter-init-script.sh /etc/init.d/dkfilter
Il faut ensuite modifier le script pour l'adapter à votre configuration et au patch de gestion multi-domaines. On édite donc le script.
vi /etc/init.d/dkfilter
Voici la partie modifiée du fichier :
...
DKFILTERUSER=dkfilter
DKFILTERGROUP=dkfilter
DKFILTERDIR=/usr/local/dkfilter
HOSTNAME=`hostname -f`
DOMAIN=`hostname -d`
DKFILTER_IN_ARGS="
--hostname=$HOSTNAME
127.0.0.1:12025 127.0.0.1:12026"
DKFILTER_OUT_ARGS="
--configfile=/etc/dkfilter.conf
--headers
127.0.0.1:12027 127.0.0.1:12028"
...
Soyez vigilant sur :
- les ports de dkfilter.ini (vérification des signatures des mails entrants)
- les ports de dkfilter.out (signature des mails sortants)
- le chemin vers le fichier de configuration.
- le groupe et l'utilisateur dkfilter créés précédemment
- la modification de l'argument --configfile pour prendre en compte votre fichier de configuration qui sera créé plus bas.
Créer une clé publique/privée
Chaque domaine possèdera sa propre clé. On crée un dossier dans lequel on stockera les clés.
mkdir /urs/local/dkfilter/keys cd /urs/local/dkfilter/keys
On suppose que vous avez le paquet openssl installé et que votre domaine est exemple.tld
La clé privée
openssl genrsa -out exempletld.key 1024
La clé publique
openssl rsa -in exempletld.key -pubout -out exempletld_pub.key
Changer les droits sur la clé privée pour la rendre uniquement accessible à l'utilisateur dkfilter
chown dkfilter; exempletld.key chmod 640 exempletld.key
Ajouter l'enregistrement TXT à la zone DNS
Une fois la clé générée, il va falloir ajouter un enregistrement TXT à la zone de chaque domaine. Prenons l'exemple du domaine exemple.tld
On édite le fichier de zone /var/cache/bind/exemple.tld.hosts et on ajoute l'enregistrement TXT suivant. La valeur de "p=" correspond à la clé publique sur une seule ligne. Notez également le nom exempletld qui sera utile pour la suite (nous l'appellerons "selecteur").
; DomainKeys _domainkey.exemple.tld. IN TXT "t=y; o=-;" exempletld._domainkey.exemple.tld. IN TXT "g=; k=rsa; p=ici_la_cle_publique_hyper_longue;"
N'oubliez pas d'incrémenter le numéro de série de votre zone pour que les changements soient pris en compte et relancer bind :
/etc/init.d/bind9 restart
Vous pouvez vérifier la bonne configuration de votre zone sur le site officiel de DomainKeys :
Créer le fichier de configuration de dkfilter
Il faut maintenant créer le fichier de configuration qu'utilisera dkfilter au démarrage du service dans /ect/dkfilter.conf :
# ------------------------------------------ # exemple.tdl [domain] name = exemple.tdl method = simple selector = exempletld private_key = /usr/local/dkfilter/keys/exempletld.key
La ligne selector correspond au sélecteur indiqué dans la zone.
Lancer dkfilter
Avant d'envisager la configuration de Postfix, il faut vérifier que dkfilter se lance correctement :
/etc/init.d/dkfilter start
Si il n'y a pas d'erreur on vérifie que le service est fonctionnel :
ps aux | grep dkfilter
Il doit y avoir des lignes avec dkfilter.in et des lignes avec dkfilter.out. Vérifier également que les options sont correctes. Notamment l'appel au fichier de configuration.
Maintenant que la zone est modifié, dkfilter installé et fonctionnel, nous pouvons enfin passer à la configuration de postfix.
Configurer de Postfix
Dans ma configuration, avant l'installation de DomainKeys, j'utilise déjà Amavisd-new pour le filtrage antivirus (clamav) et antispam (spamassassin et dspam).
Edit le 25 février : on me demande comment s'effectue la vérification de la signature des mails entrants dans ma configuration. C'est en fait Amavis via SpamAssassin et l'intégration du module CPAN Mail::Dkim qui effectue cette vérification. Si vous utilisez déjà SpamAssassin via Amavis, Il suffit d'activer et de configurer le module DKIM dans le fichier /etc/spamassassin/v312.pre. On peux donc, dans ce cas, se poser la question de l"utilité de lancer également le process dkfilter.in dans cette configuration...
J'ajoute donc dkfilter dans le process avant l'analyse par Amavis.
Dans le main.cf, je remplace :
content_filter = amavis:[127.0.0.1]:10024
par :
content_filter = dksign:[127.0.0.1]:12027
[Je ne sais pas pourquoi mais si je ne précise pas le content_filter dans le main.cf, les mails envoyés par des process locaux (par exemple, la fonction mail de PHP) ne passe pas par amavis et dkfilter]
Dans le master.cf, voici la configuration :
Au début du fichier
# relayer sur dksign sur le port 10028
smtp inet n - - - 200 smtpd
-o receive_override_options=no_address_mappings
-o content_filter=dksign:[127.0.0.1]:12027
# Le smtp securise SSL
smtps inet n - - - - smtpd
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o content_filter=dksign:[127.0.0.1]:12027
-o receive_override_options=no_address_mappings
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
# envoyer directement a dksign
submission inet n - n - - smtpd
-o smtpd_etrn_restrictions=reject
-o smtpd_sasl_auth_enable=yes
-o content_filter=dksign:[127.0.0.1]:12027
-o receive_override_options=no_address_mappings
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
#-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
A la fin
# Pour amavis
amavis unix - - - - 20 smtp
-o smtp_helo_timeout=300
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
127.0.0.1:10025 inet n - - - - smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o strict_rfc821_envelopes=yes
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtpd_bind_address=127.0.0.1
-o disable_dns_lookups=yes
#
# signature domainkeys
#
dksign unix - - n - 10 smtp
-o smtp_send_xforward_command=yes
-o smtp_discard_ehlo_keywords=8bitmime
#
# signature domainkeys
#
127.0.0.1:12028 inet n - n - 10 smtpd
-o content_filter=amavis:[127.0.0.1]:10024
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
Vous pouvez ensuite relancer postfix
/etc/init.d/postfix restart
Vérifier la signature
Envoyez un mail et regardez dans les logs :
tail -f /var/log/mail.info
Vous devez avoir pour un message envoyé par une adresse de exemple.tld :
DomainKeys signing - signed; from=<yves@exemple.tld>, message-id=...
Pour les autres :
DomainKeys signing - skipped (wrong sender domain); from=<test@autredomain.tld
Vous pouvez également vérifier votre configuration en envoyant un mail à l'adresse : check-auth ici_le_chez verifier.port25.com. Cette sympathique adresse vous renvoi les informations sur l'installation des différents protocoles d'authentification des mails sur votre domaine.
Vous devez également avoir les informations sur DomainKeys dans l'entête du message signé :
DomainKey-Signature : a=rsa-sha1; h=Received:Message-ID:Date:From:Organization:User-Agent:MIME-Version:To:Subject:Content-Type:Content-Transfer-Encoding; b=LhoN2HSlL...6mkkDXfIw=; c=simple; d=exemple.tld; q=dns; s=exempletld
Voilà, peut-être que vos messages ne finiront plus dans les spambox ;). n'hésitez pas à me signaler les erreurs présentent dans ce howto.
Commentaires
Magnifique tutorial, mais je suis sous gentoo (en plus version ovh)
Personne n'a ca sous la main, avec qmail ?
Ce domainkeys, je ne m'en sort pas
encore bravo pour ton tuto
Merci
Pour gentoo, il ne doit pas y avoir beaucoup de truc qui change par rapport à Debian hormis les chemins et les scripts de démarrage. Pour qmail, je ne connais vraiment pas assez pour t'aider ! Et les howto sur DomainKeys sont assez rare...
Bon courage !
Bonjour, Tout d'abord, excusez les Français de babelfish ! De regarder vos config, vous faites seulement dksigning, et l'amavisd, et le dkverification a-t-il été enlevé ? Comment réalisez-vous l'amavisd, dksigning et le dkverification avec cette config ? Tous les ressembler de content_filter à eux passent par dksigning seulement !
Bonjour,
La "dkverification" est intégrée dans amavisd via Spamassassin et le module CPAN Mail::DKIM (sur Debian Etch, le fichier spamassassin/v312.pre contient loadplugin Mail::SpamAssassin::Plugin::DKIM). C'est une erreur de mon howto... Mais je prépare un nouveau howto pour dkimproxy et la signature DKIM+DomainKeys (cette semaine)...
(my bad english
Bonjour,
Puisse-je avoir contact avec vous ? je souffre avec ce domainkeys.
Merci pour votre retour urgent.