Aller au contenu principal

Configurer DANE/TLSA avec Postfix, Bind et Let's Encrypt

Par CaptainDNS
Publié le 22 février 2026

Schéma d'architecture montrant Postfix, Bind9 et Let's Encrypt connectés par DANE/TLSA
TL;DR
  • DANE/TLSA lie le certificat TLS de votre serveur mail à un enregistrement DNS signé par DNSSEC, éliminant la dépendance aux autorités de certification
  • La combinaison recommandée est 3 1 1 (DANE-EE, SPKI, SHA-256) : le hash TLSA survit aux renouvellements Let's Encrypt tant que la clé privée ne change pas
  • Postfix supporte nativement la vérification DANE sortante avec smtp_dns_support_level = dnssec et smtp_tls_security_level = dane
  • L'automatisation passe par un deploy-hook Certbot qui régénère le hash TLSA et recharge la zone Bind9 à chaque renouvellement
  • Vérifiez votre déploiement avec dig TLSA, openssl s_client et l'inspecteur DANE/TLSA CaptainDNS

Vous gérez un serveur mail Postfix et vous souhaitez protéger vos connexions SMTP contre les attaques de type downgrade ou man-in-the-middle ? DANE (DNS-based Authentication of Named Entities) est la réponse. En publiant un enregistrement TLSA dans votre zone DNS signée par DNSSEC, vous indiquez aux serveurs distants quel certificat TLS votre serveur doit présenter. Pas d'intermédiaire, pas d'autorité de certification à qui faire confiance : le DNS devient votre ancre de confiance.

Le problème concret avec Let's Encrypt : le certificat se renouvelle tous les 90 jours. Si le hash TLSA publié dans le DNS ne correspond plus au certificat présenté par Postfix, les serveurs qui vérifient DANE refuseront la connexion. Résultat : des emails bloqués sans message d'erreur visible pour l'expéditeur.

Ce tutoriel couvre la configuration complète de bout en bout : Postfix, Bind9, Let's Encrypt et DANE, avec l'automatisation du renouvellement pour éviter toute interruption de service.

Public visé : administrateurs système Linux gérant un serveur mail self-hosted, avec une connaissance de base de Postfix, DNS et de la ligne de commande. Pour les fondamentaux de DANE et TLSA, consultez notre guide complet DANE/TLSA (premier article de cette série, lien en bas de page).

Prérequis

Avant de commencer, vérifiez que vous disposez de :

ComposantVersion minimaleVérification
Debian/Ubuntu12+ / 22.04+cat /etc/os-release
Postfix3.4+ (support DANE natif)postconf mail_version
Bind99.18+ (DNSSEC inline-signing)named -v
Certbot2.0+certbot --version
DNSSEC actifZone signée + DS chez registrardig +dnssec captaindns.com SOA

DNSSEC est le préalable indispensable : sans zone signée, DANE n'a aucun effet. Bind9 9.18+ supporte l'inline-signing, qui simplifie considérablement la gestion des clés. Activez-le avant de poursuivre.

Ports et accès réseau

Vérifiez que votre pare-feu autorise les ports suivants :

  • Port 25 (SMTP) et optionnellement 587 (submission) pour Postfix
  • Port 80 ou 443 pour le challenge HTTP-01 de Let's Encrypt (ou challenge DNS-01 si le port 80 est indisponible)

Architecture de la stack Postfix, Bind9 et Let's Encrypt avec DANE/TLSA

Configurer DNSSEC avec Bind9

Si votre zone est déjà signée par DNSSEC, passez directement à Générer le certificat Let's Encrypt.

Voici la configuration minimale avec Bind9 et l'inline-signing.

Activer l'inline-signing

Dans votre fichier de configuration de zone (/etc/bind/named.conf.local ou équivalent) :

zone "captaindns.com" {
    type primary;
    file "/var/lib/bind/captaindns.com.zone";
    dnssec-policy default;
    inline-signing yes;
    key-directory "/var/lib/bind/keys";
};

Deux directives clés ici :

  • dnssec-policy default génère et fait tourner automatiquement les clés ZSK et KSK
  • inline-signing yes signe la zone à la volée sans modifier le fichier source

Publier le DS chez le registrar

Après le premier chargement de la zone, Bind9 génère les clés. Récupérez le DS record :

# Lister les clés générées
ls /var/lib/bind/keys/

# Extraire le DS record (adapter le nom du fichier KSK)
dnssec-dsfromkey /var/lib/bind/keys/Kcaptaindns.com.+013+xxxxx.key

Transmettez le DS record à votre registrar via son interface web ou son API. Délai de propagation habituel : quelques minutes à 48 heures selon le registrar.

Vérifier la chaîne DNSSEC

dig +dnssec +short captaindns.com SOA
# Doit retourner le SOA avec le flag "ad" (Authenticated Data)

dig +dnssec captaindns.com DNSKEY
# Doit retourner les DNSKEY avec les signatures RRSIG

Générer le certificat Let's Encrypt

Obtenir le certificat

# Installation de Certbot (si pas déjà installé)
apt install certbot

# Obtenir un certificat pour le hostname du serveur mail
certbot certonly --standalone -d mail.captaindns.com

Si le port 80 est déjà utilisé par un autre service, utilisez le plugin webroot ou le challenge DNS-01 :

# Alternative avec webroot (si Apache/Nginx tourne sur le serveur)
certbot certonly --webroot -w /var/www/html -d mail.captaindns.com

# Alternative avec challenge DNS (si port 80 indisponible)
certbot certonly --manual --preferred-challenges dns -d mail.captaindns.com

Configurer Postfix pour utiliser le certificat

Éditez /etc/postfix/main.cf :

# Certificat TLS (réception - smtpd)
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.captaindns.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.captaindns.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# Vérification DANE sortante (smtp)
smtp_dns_support_level = dnssec
smtp_tls_security_level = dane
smtp_tls_loglevel = 1

Attention à ne pas confondre les deux blocs :

  • smtpd_tls_* configure le TLS pour les connexions entrantes (votre serveur présente son certificat aux serveurs distants)
  • smtp_tls_* configure le TLS pour les connexions sortantes (Postfix vérifie le TLSA du domaine destinataire via DNSSEC)

Rechargez Postfix :

postfix reload

Créer l'enregistrement TLSA

Choisir les paramètres TLSA

La RFC 7672 (section 3.1) recommande la combinaison 3 1 1 pour SMTP :

ChampValeurSignification
Usage3 (DANE-EE)Vérification directe du certificat du serveur
Selector1 (SPKI)Hash de la clé publique (pas du certificat entier)
Matching type1 (SHA-256)Hash SHA-256

Pourquoi SPKI et pas le certificat entier ? Le hash SPKI ne change pas quand Let's Encrypt renouvelle le certificat, tant que la clé privée reste identique. Avec 3 0 1 (certificat entier), chaque renouvellement invaliderait le TLSA et couperait les connexions DANE.

Générer le hash TLSA

# Extraire le hash SPKI SHA-256 du certificat
openssl x509 -in /etc/letsencrypt/live/mail.captaindns.com/cert.pem \
  -pubkey -noout | \
  openssl pkey -pubin -outform DER | \
  openssl dgst -sha256 -binary | \
  xxd -p -c 64

Le résultat est un hash hexadécimal de 64 caractères (256 bits), par exemple :

a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890

Vous pouvez aussi utiliser le générateur DANE/TLSA CaptainDNS pour générer l'enregistrement sans commande.

Ajouter le TLSA dans la zone Bind9

Le nom de l'enregistrement TLSA suit le format _port._protocol.hostname (défini par la RFC 6698, section 1.1). Pour le port 25 (SMTP) :

_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890

Ajoutez cette ligne à votre fichier de zone, incrémentez le serial du SOA, puis rechargez :

# Recharger la zone (Bind9 signe automatiquement avec inline-signing)
rndc reload captaindns.com

Vérifier la publication

# Vérifier que le TLSA est publié et signé
dig +dnssec _25._tcp.mail.captaindns.com TLSA

# Résultat attendu : le TLSA avec les RRSIG

Automatiser le renouvellement

C'est la partie la plus critique de tout le déploiement. Un TLSA désynchronisé bloque silencieusement les emails entrants pour tous les expéditeurs qui vérifient DANE. Avec la combinaison 3 1 1 et --reuse-key, le hash SPKI survit aux renouvellements Let's Encrypt. Mais il faut le vérifier automatiquement et prévoir le cas où la clé change.

Stratégie de conservation de la clé

Point important : par défaut, Certbot génère une nouvelle clé privée à chaque renouvellement, ce qui invalide le hash TLSA. Pour conserver la même clé (et donc le même hash SPKI), ajoutez l'option --reuse-key :

# Forcer la réutilisation de la clé privée
certbot certonly --standalone -d mail.captaindns.com --reuse-key

Ou ajoutez dans /etc/letsencrypt/renewal/mail.captaindns.com.conf :

[renewalparams]
reuse_key = True

Deploy-hook pour la mise à jour automatique

Même avec --reuse-key, un filet de sécurité est indispensable. Le deploy-hook ci-dessous compare le hash SPKI du nouveau certificat avec celui publié dans le DNS. En cas de divergence, il met à jour le TLSA et recharge la zone automatiquement. Créez le script /etc/letsencrypt/renewal-hooks/deploy/update-tlsa.sh :

#!/bin/bash
# Deploy-hook Certbot : mise à jour TLSA si le hash SPKI change

DOMAIN="mail.captaindns.com"
ZONE="captaindns.com"
ZONE_FILE="/var/lib/bind/captaindns.com.zone"
CERT="/etc/letsencrypt/live/$DOMAIN/cert.pem"

# Calculer le nouveau hash SPKI SHA-256
NEW_HASH=$(openssl x509 -in "$CERT" -pubkey -noout | \
  openssl pkey -pubin -outform DER | \
  openssl dgst -sha256 -binary | \
  xxd -p -c 64)

# Récupérer le hash actuel dans le DNS
CURRENT_HASH=$(dig +short _25._tcp.$DOMAIN TLSA | awk '{print $4}')

if [ "$NEW_HASH" != "$CURRENT_HASH" ]; then
  echo "TLSA hash changed, updating zone..."

  # Remplacer le hash dans le fichier de zone
  sed -i "s/\(IN TLSA 3 1 1 \)[a-f0-9]\{64\}/\1$NEW_HASH/" "$ZONE_FILE"

  # Incrémenter le serial (format YYYYMMDDNN)
  CURRENT_SERIAL=$(grep -oP '\d{10}' "$ZONE_FILE" | head -1)
  NEW_SERIAL=$((CURRENT_SERIAL + 1))
  sed -i "s/$CURRENT_SERIAL/$NEW_SERIAL/" "$ZONE_FILE"

  # Recharger la zone
  rndc reload "$ZONE"

  echo "TLSA updated: $NEW_HASH"
else
  echo "TLSA hash unchanged, no update needed."
fi

# Recharger Postfix pour prendre le nouveau certificat
postfix reload

Rendez le script exécutable :

chmod +x /etc/letsencrypt/renewal-hooks/deploy/update-tlsa.sh

Tester le renouvellement

# Simuler un renouvellement (dry-run)
certbot renew --dry-run

# Forcer un renouvellement réel (pour tester le hook)
certbot renew --force-renewal

Flux de renouvellement automatique : Certbot renouvelle le certificat, le deploy-hook vérifie le hash SPKI et met à jour le TLSA dans Bind9 si nécessaire

Stratégie de rollover SPKI (changement de clé)

En cas de compromission de la clé ou de migration de serveur, vous devez régénérer la clé privée. Règle absolue : publiez le nouveau TLSA avant de déployer le nouveau certificat. La RFC 7671 (section 8.1) impose une période de double publication :

  1. Générer la nouvelle clé et calculer son hash SPKI
  2. Publier les deux TLSA dans la zone (ancien + nouveau)
  3. Attendre la propagation DNS (2x TTL minimum)
  4. Déployer le nouveau certificat
  5. Retirer l'ancien TLSA après propagation
; Double TLSA pendant la transition
_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 <ancien-hash>
_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 <nouveau-hash>

Vérifier la configuration

Un déploiement DANE incomplet est pire qu'une absence de DANE : les serveurs vérificateurs rejetteront vos connexions. Testez chaque couche séparément.

Vérification DNS

# Vérifier le TLSA
dig +short _25._tcp.mail.captaindns.com TLSA
# Attendu : 3 1 1 <hash-64-chars>

# Vérifier DNSSEC
dig +dnssec _25._tcp.mail.captaindns.com TLSA | grep -c "RRSIG"
# Attendu : >= 1

Vérification TLS

# Tester la connexion TLS avec vérification TLSA
openssl s_client -connect mail.captaindns.com:25 -starttls smtp \
  -dane_tlsa_domain mail.captaindns.com \
  -dane_tlsa_rrdata "3 1 1 $(dig +short _25._tcp.mail.captaindns.com TLSA | awk '{print $4}')"

Le résultat doit afficher Verification: OK et DANE TLSA 3 1 1 matched EE certificate. Si vous voyez Verification error, le hash TLSA ne correspond pas au certificat présenté par Postfix.

Vérification Postfix sortante

Vérifiez que Postfix vérifie bien DANE pour les emails sortants :

# Envoyer un email de test et vérifier les logs
echo "Test DANE" | mail -s "DANE test" test@gmail.com
grep "Verified TLS connection" /var/log/mail.log | tail -5

Les logs doivent mentionner dane dans le niveau de sécurité. Si vous voyez may ou encrypt, la résolution DNSSEC a échoué et Postfix revient au TLS opportuniste.

Vérification en ligne

Utilisez le vérificateur de syntaxe DANE/TLSA CaptainDNS pour valider la syntaxe de votre enregistrement, puis l'inspecteur DANE/TLSA CaptainDNS (lien dans le résumé ci-dessus) pour une vérification complète incluant la correspondance certificat/TLSA et la chaîne DNSSEC de bout en bout.

Plan d'action en 6 étapes

Déploiement DANE complet sur un serveur mail self-hosted en 6 étapes
  1. Configurer dnssec-policy default et inline-signing yes dans la zone Bind9. Publier le DS record chez le registrar. Vérifier la chaîne de confiance avec dig +dnssec.

  2. Exécuter certbot certonly --standalone -d mail.captaindns.com --reuse-key pour obtenir le certificat avec conservation de la clé privée.

  3. Éditer main.cf avec les chemins du certificat (smtpd_tls_*), activer la vérification DANE sortante (smtp_dns_support_level = dnssec, smtp_tls_security_level = dane).

  4. Générer le hash SPKI SHA-256 avec openssl, ajouter l'enregistrement _25._tcp.mail.captaindns.com. IN TLSA 3 1 1 &lt;hash&gt; dans la zone, recharger avec rndc reload.

  5. Créer le deploy-hook /etc/letsencrypt/renewal-hooks/deploy/update-tlsa.sh qui compare les hash SPKI et met à jour le TLSA si nécessaire. Tester avec certbot renew --force-renewal.

  6. Valider avec dig TLSA, openssl s_client -dane_tlsa_domain, les logs Postfix et l'inspecteur DANE/TLSA CaptainDNS.

FAQ

Comment générer un enregistrement TLSA pour Let's Encrypt ?

Utilisez la commande openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | xxd -p -c 64 pour extraire le hash SPKI SHA-256. Le résultat de 64 caractères hexadécimaux forme la donnée du TLSA avec les paramètres 3 1 1.

Faut-il mettre à jour le TLSA à chaque renouvellement Let's Encrypt ?

Non, si vous utilisez --reuse-key avec Certbot et la combinaison DANE-EE/SPKI (3 1 1). Le hash SPKI dépend de la clé publique, pas du certificat. Tant que la clé privée reste la même, le hash ne change pas. Mettez en place un deploy-hook de vérification par sécurité.

Comment activer la vérification DANE dans Postfix ?

Ajoutez smtp_dns_support_level = dnssec et smtp_tls_security_level = dane dans /etc/postfix/main.cf. Postfix vérifiera automatiquement les TLSA des domaines destinataires via DNSSEC. Si le TLSA est absent ou invalide, Postfix revient au TLS opportuniste.

DANE fonctionne-t-il avec des certificats auto-signés ?

Oui. Avec DANE-EE (usage 3), le certificat est validé par le TLSA dans le DNS, pas par une autorité de certification. Un certificat auto-signé avec un TLSA correct et une zone DNSSEC valide est accepté par les serveurs qui vérifient DANE.

Comment tester que DANE est correctement configuré ?

Trois niveaux de vérification : 1) dig +dnssec _25._tcp.mail.captaindns.com TLSA pour le DNS, 2) openssl s_client -connect mail.captaindns.com:25 -starttls smtp -dane_tlsa_domain pour la correspondance certificat/TLSA, 3) l'inspecteur DANE/TLSA CaptainDNS pour un rapport complet incluant la chaîne DNSSEC.

Bind est-il obligatoire ou peut-on utiliser un autre serveur DNS ?

Bind9 n'est pas obligatoire. Tout serveur DNS supportant DNSSEC fonctionne : NSD, Knot DNS, PowerDNS. Les principes sont identiques, seule la syntaxe de configuration change. Bind9 est utilisé dans ce tutoriel car il est le plus répandu sur les serveurs Linux et son inline-signing simplifie la gestion DNSSEC.

Que se passe-t-il si le TLSA ne correspond plus au certificat ?

Les serveurs qui vérifient DANE (comme Postfix avec dane ou Gmail) refuseront d'établir la connexion TLS et retomberont en mode non chiffré ou rejetteront le message selon leur politique. C'est pourquoi la double publication TLSA lors des rotations de clé est essentielle. Si votre TLSA est désynchronisé, retirez-le temporairement pour revenir au TLS opportuniste le temps de corriger.

📚 Guides DANE/TLSA connexes

Sources

Articles similaires