Serveur dédié : ajouter l’authentification SPF, Sender-ID et DKIM à Postfix et Bind9 avec opendkim

dkim-spf-200

Cela fait quelques années maintenant que mon serveur tourne et je trouvais le serveur de mail (postfix) bien fonctionnel plutôt bien jusqu’à ce que je reçoive des messages de la part de Gmail comme quoi les emails envoyés par le site sont considérés comme spam!

Et c’est à ce moment que l’on réalise qu’être bloqué par son fournisseur email, ce n’est pas cool du tout : à chaque fois qu’un nouveau commentaire est publié et que quelqu’un y est abonné, l’erreur se déclenche et le mail part en mail delivery service.

Voici le message type que l’on reçoit de Gmail dans ce cas:

Final-Recipient: rfc822; ***@gmail.com
Action: failed
Status: 5.7.1
Remote-MTA: dns; gmail-smtp-in.l.google.com
Diagnostic-Code: smtp; 550-5.7.1 Our system has detected an unusual rate of unsolicited mail originating from your IP address. To protect our users from spam, mail sent from your IP address has been blocked. Please visit
    https://support.google.com/mail/answer/81126 to review our Bulk Email Senders Guidelines. 

Lorsque l’on monte un serveur email, rien n’est sécurisé par défaut. Avec tout le spam en circulation, il y a des entêtes à ajouter lors de l’envoi pour que le courrier ne soit pas considéré comme indésirable :

dkim-spf-schema

Il est donc temps de sécuriser un peu notre serveur de mail.

Étape 1 : diagnostics

Sur le serveur dans le terminal, on envoie un mail de test :

mail  check-auth@verifier.port25.com

Résultat:

==========================================================
Summary of Results
==========================================================
SPF check:          softfail
DomainKeys check:   neutral
DKIM check:         neutral
Sender-ID check:    softfail
SpamAssassin check: ham

Du fail et du neutral, ce n’est pas trop bon! Nous allons commencer par activer SPF et Sender-ID.

Étape 2 : ajouter SPF et Sender-ID à BIND

Nous allons donc ajouter l’authentification SPF (Sender Policy Framework) à notre enregistrement DNS. On édite le fichier de configuration BIND de notre domaine :

nano /etc/bind/skyminds.net.hosts

Et on y ajoute à la fin du fichier :

;SPF
skyminds.net. IN TXT "v=spf1 ip4:IP4SERVEUR mx -all"
skyminds.net. IN SPF "v=spf1 ip4:IP4SERVEUR mx -all"
mail.skyminds.net. IN  TXT  "v=spf1 ip4:IP4SERVEUR a -all"
mail.skyminds.net. IN  SPF  "v=spf1 ip4:IP4SERVEUR a -all"

Remplacez IP4SERVEUR par l’IPv4 de votre serveur et skyminds.net par votre nom de domaine. Enregistrez le fichier et relancez BIND :

/etc/init.d/bind9 restart

On renvoie un mail de test :

mail  check-auth@verifier.port25.com

Nouveau résultat :

==========================================================
Summary of Results
==========================================================
SPF check:          pass
DomainKeys check:   neutral
DKIM check:         neutral
Sender-ID check:    pass
SpamAssassin check: ham

Pas mal, on vient d’activer le SPF et le Sender-ID en 2 minutes !

Étape 3 : installation de l’authentification DKIM

DKIM (DomainKeys Identified Mail) est une norme d’authentification fiable du nom de domaine de l’expéditeur d’un courrier électronique : DKIM fonctionne par signature cryptographique du corps du message et d’une partie de ses en-têtes.

Une signature DKIM vérifie donc l’authenticité du domaine expéditeur et garantit l’intégrité du message. Idéal pour lutter contre le spam.

1. On installe opendkim :

apt-get install opendkim opendkim-tools

Et on édite le fichier de configuration:

nano /etc/opendkim.conf

On supprime tout le contenu de ce fichier et on met :

 # Enable Logging
Syslog yes
SyslogSuccess yes
LogWhy yes

# User mask
UMask 002

# Always oversign From (sign using actual From and a null From to prevent
# malicious signatures header fields (From and/or others) between the signer and the verifier)
OversignHeaders From

# Our KeyTable and SigningTable
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable

# Trusted Hosts
ExternalIgnoreList /etc/opendkim/TrustedHosts
InternalHosts /etc/opendkim/TrustedHosts

# Hashing Algorithm
SignatureAlgorithm rsa-sha256

# Auto restart when the failure occurs. CAUTION: This may cause a tight fork loops
AutoRestart Yes
DNSTimeout  5

# Set the user and group to opendkim user
UserID opendkim:opendkim

# Specify the working socket
Socket inet:12345@localhost

Canonicalization relaxed/relaxed

2. On édite la configuration par défaut d’opendkim:

nano /etc/default/opendkim

Avec :

# Command-line options specified here will override the contents of
# /etc/opendkim.conf. See opendkim(8) for a complete list of options.
#DAEMON_OPTS=""
#
# Uncomment to specify an alternate socket
# Note that setting this will override any Socket value in opendkim.conf
#SOCKET="local:/var/run/opendkim/opendkim.sock" # default
#SOCKET="inet:54321" # listen on all interfaces on port 54321
SOCKET="inet:12345@localhost" # listen on loopback on port 12345
#SOCKET="inet:12345@192.0.2.1" # listen on 192.0.2.1 on port 12345

3. On crée un nouveau répertoire pour notre clé et on assigne les droits à l’utilisateur opendkim, du groupe opendkim:

mkdir -pv /etc/opendkim/skyminds.net/
chown -Rv opendkim:opendkim /etc/opendkim
chmod go-rwx /etc/opendkim/* 

Ensuite, on crée une paire de clés pour chaque domaine :

cd /etc/opendkim/skyminds.net/
opendkim-genkey -r -h rsa-sha256 -d skyminds.net -s mail -b 4096
mv -v mail.private mail
chown opendkim:opendkim *
chmod u=rw,go-rwx * 

Cela nous crée 2 fichiers : un fichier mail (clé privée) et un fichier mail.txt qui contiendra notre clé publique.

4. On ajoute notre clé publique à l’enregistrement DNS du domaine dans BIND:

nano /etc/bind/skyminds.net.hosts

On y copie notre clé publique (/etc/opendkim/skyminds.net/mail.txt) à la fin du fichier :

;DKIM
_domainkey.skyminds.net. IN TXT "t=y; o=-;"
mail._domainkey.skyminds.net. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6YG5lJXmZxgz1eFprQfEV8oqUjYceMNPctuhi/Fo+oE+4oeDwMTDyPJcGCuJMp2XZxL2X3a8/Q9g3StekiHWqPehY7cyrnYZg6ttTCdbJYGAc/t0rVCKut/2baiGw9lcMq5sbUG9YywEEI/rN4Fu0PCU1A6BkqtNAepPhDwVRAQIDAQAB; t=s"; ----- DKIM key mail for skyminds.net
_adsp._domainkey.skyminds.net. IN TXT "dkim=unknown"

On enregistre le fichier et on relance BIND :

/etc/init.d/bind9 restart

5. On associe les domaines avec les clés :

nano  /etc/opendkim/KeyTable

La syntaxe du fichier est la suivante :
KeyID Domain:Selector:PathToPrivateKey

Nous ajoutons donc :

skyminds.net skyminds.net:mail:/etc/opendkim/skyminds.net/mail

6. On édite ensuite la table des signatures :

nano /etc/opendkim/SigningTable

à laquelle on ajoute :

*@skyminds.net skyminds.net

7. On définit les domaines considérés comme trusted :

nano /etc/opendkim/TrustedHosts

Avec :

127.0.0.1
localhost
ns.kimsufi.com
skyminds.net

Il ne faut pas oublier d’ajouter le DNS de votre hébergeur (ns.kimsufi.com chez moi).

8. On applique maintenant les bons droits à nos fichiers :

chown opendkim:opendkim /etc/opendkim/KeyTable
chown opendkim:opendkim /etc/opendkim/SigningTable
chown opendkim:opendkim /etc/opendkim/TrustedHosts 

9. On édite maintenant la configuration Postfix :

nano /etc/postfix/main.cf

Et on rajoute :

# DKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:12345
non_smtpd_milters = $smtpd_milters

On redémarre bind, opendkim et postfix pour vérifier que tout va bien :

/etc/init.d/bind9 restart
/etc/init.d/opendkim restart
/etc/init.d/postfix restart

10. On vérifie qu’opendkim est bien lancé sur le serveur :

ps aux | grep dkim
netstat -tanp | grep dkim 

Étape 4 : tests et vérifications

Il faut maintenant attendre que la propagation DNS prenne effet, cela peut prendre quelques heures.

Vous pouvez lancer un test DKIM ici : http://www.brandonchecketts.com/emailtest.php

Vérifiez les erreurs mail dans les logs :

tail -f /var/log/mail.log

Envoyez-vous un email via le terminal. Voici ce que vous devriez obtenir :

dkim-spf-signed

Étape 5 : optimiser la vitesse d’envoi

Quelques jours après la réalisation et la mise en place du tutoriel, je me suis aperçu que Gmail grognait toujours à cause de la vitesse à laquelle étaient envoyés les emails, notamment lorsque beaucoup de gens sont abonnés aux commentaires : en cas de nouveau commentaire, une flopée de notifications partent au même moment – ce qui déclenche le message d’erreur chez Gmail.

Pour améliorer cela, on édite à nouveau le fichier de configuration postfix :

nano /etc/postfix/main.cf

Et on y rajoute :

# Matt : NOT TOO FAST COWBOY!
# This means that postfix will up to two concurrent
# connections per receiving domains. The default value is 20.
default_destination_concurrency_limit = 2
# Postfix will add a delay between each message to the same receiving domain.
default_destination_rate_delay = 5s
# Limit the number of recipients of each message.
# If a message had 20 recipients on the same domain, postfix will break it out
default_extra_recipient_limit = 3

Cela se connecte au maximum avec 2 connexions par domaine, avec un délai de 5 secondes entre chaque message s’ils sont envoyés au même domaine et on envoie par tranche de 3 messages. Un peu alambiqué mais cela semble satisfaire Google.

Voilà, c’est fini. Les messages de votre serveur de mail devraient maintenant être un peu plus acceptés dans les boîtes de réception !

Synopsis » Monter un serveur dédié de A à Z

  1. Serveur dédié : installation d’Apache, PHP, MySQL et Webmin
  2. Serveur dédié : créer la base de données MySQL et importer WordPress
  3. Serveur dédié : créer et activer un Virtual Host sous Apache
  4. Serveur dédié : changer les DNS du nom de domaine et le faire pointer vers le serveur
  5. Serveur dédié : sécurisation des services avec iptables et fail2ban
  6. Serveur dédié : sécurisation de la couche TCP/IP
  7. Serveur dédié : création d’un serveur mail Postfix (sécurisé avec Saslauthd et certificat SSL) et Courier (accès POP et IMAP) utilisant une base MySQL d’utilisateurs/domaines virtuels
  8. Serveur dédié : sécuriser Apache 2 avec ModSecurity
  9. Serveur dédié : CHMOD récursif sur des fichiers ou répertoires en ligne de commande
  10. Serveur dédié : installer APC comme système de cache et configurer Varnish comme reverse-proxy pour Apache pour améliorer les performances
  11. Serveur dédié : afficher la véritable IP derrière un reverse-proxy comme Varnish
  12. Serveur dédié : intégrer SSH à WordPress pour mettre à jour le core, les plugins et les thèmes
  13. Serveur dédié : installer la dernière version d’APC par SVN
  14. Serveur dédié : analyse des performances du serveur
  15. Serveur dédié : mettre à jour le noyau Debian de la Kimsufi
  16. Serveur dédié : sauvegarde automatique des fichiers avec Backup Manager sur le serveur de sauvegarde OVH
  17. Serveur dédié : configurer la limite mémoire pour PHP et Suhosin
  18. Bash : supprimer tous les fichiers et sous-répertoires d’un répertoire
  19. Serveur dédié : impossible de se connecter à un port distant
  20. Rsync: rapatrier les fichiers du serveur à la maison
  21. Bash : réparer les tables MySQL en cas de crash
  22. Serveur dédié : création d’une seedbox avec Transmission
  23. Serveur dédié : des paquets LAMP à jour sous Debian
  24. Serveur dédié : mise à jour vers Debian 7 Wheezy
  25. Serveur dédié : activer X11 forwarding pour SSH
  26. Serveur dédié : optimiser toutes les images JPG et PNG avec OptiPNG et JpegOptim
  27. Postfix : résoudre l’erreur “fatal: www-data(33): message file too big”
  28. Serveur dédié : mise en place de l’IPv6
  29. WordPress : accorder les bonnes permissions aux fichiers et dossiers avec chown et chmod
  30. WordPress : héberger les images sur un sous-domaine
  31. Serveur dédié : ajouter l’authentification SPF, Sender-ID et DKIM à Postfix et Bind9 avec opendkim
  32. Apache : lorsque le domaine seul (sans WWW) renvoie une erreur 403
  33. Serveur dédié : sécuriser Apache avec HTTPS (HTTP avec la couche TLS/SSL) en Perfect Forward Secrecy
  34. Serveur dédié : passer WordPress en HTTPS (TLS/SSL)
  35. Serveur dédié : configurer Webmin en TLS avec un certificat SSL
  36. Serveur dédié : configurer Transmission pour accéder au WebUI via TLS-SSL
  37. Serveur dédié : installer et configurer Varnish 4
  38. Serveur dédié : passage au mod FastCGI et PHP-FPM avec Apache MPM Worker
  39. Récupérer un serveur Kimsufi après un plantage de kernel avec le mode rescue OVH
  40. Serveur dédié : configurer Postfix et Courier pour utiliser TLS-SSL en Perfect Forward Secrecy
  41. Serveur dédié : retirer Varnish, devenu inutile avec HTTPS
  42. Serveur dédié : installer la dernière version d’OpenSSL sous Debian
  43. Serveur dédié : activer l’IP canonique du serveur sous Apache
  44. Serveur dédié : mise à jour vers PHP 5.6
  45. MySQL : convertir les tables MyISAM au format InnoDB
  46. Serveur dédié : optimiser toutes les images GIF avec GIFsicle
  47. Serveur dédié : migration de MySQL vers MariaDB
  48. BASH : lister, bloquer et débloquer des adresses IP avec iptables
  49. Serveur dédié : produire une meilleure réserve d’entropie avec haveged
  50. Serveur dédié : mettre en place DNSSEC pour sécuriser les DNS du domaine
  51. Serveur dédié : mise en place du protocole DANE
  52. 8 règles d’or pour bien déployer DNSSEC et DANE
  53. Serveur dédié : installer PHP7 FPM avec FastCGI sous Debian
  54. Serveur dédié : optimiser la couche TCP
  55. Fail2Ban: protéger Postfix contre les attaques DoS de types AUTH, UNKNOWN et EHLO
  56. Serveur dédié : mettre à jour Apache pour HTTP/2
  57. Serveur dédié : ajouter le domaine à la liste HSTS preload
  58. Serveur dédié : ajouter l’authentification DMARC à Postfix et BIND
  59. Serveur dédié : à la recherche de l’inode perdue ou comment résoudre le problème “no space left on device”
  60. Serveur dédié : installer NginX avec support HTTP2 et certificat SSL, PHP, MariaDB sous Debian

Vous voulez un site WordPress ou WooCommerce qui soit à la fois rapide et performant? Vous êtes au bon endroit.

Découvrez comment je peux booster votre site »

Articles conseillés :

15 pensées sur “Serveur dédié : ajouter l’authentification SPF, Sender-ID et DKIM à Postfix et Bind9 avec opendkim”

  1. Encore merci c’est vraiment simple et très complet l’ensemble des tutos sur la mise en place d’un système de messagerie, manque plus que la partie Spam et Antivirus ;-)

    Reply
  2. Je viens de le mettre en place sur un de nos serveurs qui était bloqué par Hotmail. Je te tiens au jus.

    Merci pour ce tuto.

    Reply
  3. Bonjour,

    J’ai un problème en essayant d’envoyer un mail depuis roundcube

    Erreur SMTP : [451] 4.7.1 Service unavailable – try again later

    Voici le log mail.log:

    Jul 13 02:43:55 vps179448 opendkim[20403]: OpenDKIM Filter: mi_stop=1
    Jul 13 02:43:55 vps179448 opendkim[20403]: OpenDKIM Filter v2.6.8 terminating with status 0, errno = 0
    Jul 13 02:43:57 vps179448 opendkim[20433]: OpenDKIM Filter v2.6.8 starting (args: -x /etc/opendkim.conf -u opendkim -P /var/run/opendkim/opendkim.pid)
    Jul 13 02:44:14 vps179448 postfix/smtpd[20442]: connect from localhost[127.0.0.1]
    Jul 13 02:44:14 vps179448 postfix/smtpd[20442]: 4A34A1410D8: client=localhost[127.0.0.1]
    Jul 13 02:44:14 vps179448 postfix/cleanup[20447]: 4A34A1410D8: message-id=
    Jul 13 02:44:14 vps179448 opendkim[20433]: badblock.fr: key data is not secure
    Jul 13 02:44:14 vps179448 opendkim[20433]: 4A34A1410D8: error loading key ‘badblock.fr’
    Jul 13 02:44:14 vps179448 postfix/cleanup[20447]: 4A34A1410D8: milter-reject: END-OF-MESSAGE from localhost[127.0.0.1]: 4.7.1 Service unavailable – try again later; from= to= proto=ESMTP helo=
    Jul 13 02:44:14 vps179448 postfix/smtpd[20442]: disconnect from localhost[127.0.0.1]

    Merci

    Reply
    • Salut micro_maniaque,

      Dans l’étape 3.3, vérifie que tu as bien attribué les droits à opendkim pour qu’il puisse charger la clé (chown et chmod).

      Reply
  4. Merci pour cet article

    pour DKIM, Comment faire pour rajouter un autre nom de domaine ? Peut tu nous nous expliquer stp?
    Encore merci pour ce tuto !

    Reply
  5. Personnellement j’ai ut cette erreur lors des tests :
    OpenSSL error: data too small for key size

    Pour la corriger à la génération de la clé DKIM j’ai utilisé ça plutôt, je comprend pas des masse la différence mais ça fonctionne :
    opendkim-genkey -s mail -d domaine.tld -b 2048

    Reply
    • Bonjour Nodoka,

      Effectivement, si l’on ne stipule pas le nombre de bits de la clé, elle est par défaut en 1024 bits, ce qui n’est plus suffisant aujourd’hui.

      Je viens d’éditer l’article afin de générer une clé de 4096 bits. Merci :)

      Reply
  6. Bonjour et merci beaucoup pour ce tuto !

    Je rencontre un problème : la clé DKIM n’est pas reconnue, du coup l’email passe encore plus pour un frauduleux que sans DKIM ^^

    dkimvalidator renvoie entre autre :

    Public Key DNS Lookup

    Building DNS Query for mail._domainkey.monsite.fr
    Retrieved this publickey from DNS:
    Validating Signature

    result = invalid
    Details: public key: not available

    J’ai également testé le opendkim-testkey :
    #opendkim-testkey -d monsite.fr -s mail -k /etc/opendkim/monsite.fr/mail -vvv
    opendkim-testkey: key loaded from /etc/opendkim/monsite.fr/mail
    opendkim-testkey: checking key 'mail._domainkey.monsite.fr'
    opendkim-testkey: 'mail._domainkey.monsite.fr' record not found

    Pourtant /etc/opendkim/monsite.fr/mail existe bien et contient la clé privée, et tous les autres fichiers sont configurés comme tu l’as montré…
    Une idée ?

    Ah oui seul changement que j’ai du effectuer, au niveau du bind. Une clé si longue n’est visiblement pas acceptée, il a donc fallu que je la coupe en plusieurs morceaux comme il peut être fait de temps en temps, ce qui donne un truc comme :
    mail._domainkey.monsite.fr IN TXT("v=DKIM1; h=rsa-sha256; k=rsa;" "p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsGzY8n+6uhKFtS+NEXL" "[PART2]" "[PART3]" "[PART4]" "gIIWgtUCyuQyMfe3JGxRVTz/9TbkfAELPxWN1HbJ6LZwncbpCvFGsfUVWs85M0Opw" "[PART5]" "[PART6]"... "[PART11]")
    (J’ai laissé 2 parties visibles pour donner l’idée de la présentation)

    Merci d’avance !

    Reply
    • (Pour le bind il manque un . à la fin de mail._domainkey.monsite.fr, c’est corrigé mais je ne pense pas que le problème vienne de là de toute façon…)

      Reply
    • Bon et bien autant pour moi, mon bug venait bien de là.

      Par contre, j’ai eu une nouvelle erreur juste après :

      opendkim-testkey -d monsite.fr -s mail -k /etc/opendkim/monsite.fr/mail -vvv
      opendkim-testkey: key loaded from /etc/opendkim/monsite.fr/mail
      opendkim-testkey: checking key 'mail._domainkey.monsite.fr'
      opendkim-testkey: unknown hash 'rsa-sha256'

      Que j’ai rapidement réglé en… Retirant la notion de h=rsa-sha256 dans l’entrée du bind (cette notion est abordée ici github.com/linode/docs/pull/620 )

      Merci encore pour le tuto !

      Reply

Opinions