Postfix et dkim

Table des matières

L’objectif est ici de mettre en place une infrastructure relai SMTP permettant de signer les emails avec DKIM. Tous les emails du domaine et du sous-domaine domain.tld seront signés.

  • admin@domain.tld
  • admin@sous.domain.tld

La configuration de la zone DNS sera réalisée sous OVH.

Introduction

Le protocole DKIM permet d’authentifier le serveur d’envoi SMTP auprès de différents pairs externes, ainsi que de s’assurer de la provenance d’un mail. La RFC6376 est la référence.

Pour simplifier, il s’appuie sur un enregistrement DNS de type TXT et d’une en-tête contenant la signature :

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=myDomain.tld;
	s=mail; t=1587627528;
	bh=sr2tZnTMq+RQUB0SsjkODH8xib0DlR/FxEdswzPuIOU=;
	h=Date:Subject:To:From:From;
	b=OL/dOjFpPQfG6n6N55YTXNaHIB/wVSIYeZxgE1WR8IfX424eTzsBWaghKd4M2SJRl
	 JrjJ1qEL1maWXCQwff2aMYbqA3oN3BOMh28hVmNvQcr8yYxeMlz8WpPI0clTyK7ArZ
	 Ykwu+XqUYr2Tju/n9de++3/OulPzSFHuPp8y3CWgdxd8LZtQjOENcQ2AJXmENi2jAj
	 oWOr2PyMm+pPVw0/YGhQ9caZ4q4slnt+Q2UDwwQT3ThPuL5qEaSZgg033SSDMd0fKT
	 Z75CRycLTR0ctZOifxcvy+iGr4YqMe35iGlbuR37HiYoLRuprz3TcchSdV1oKYN4Yw
	 xc4o91wFnHsxQ==
  • b : la signature numérique des contenus (en-têtes et corps de mail)
  • bh : hachage du corps
  • c : pour l’algorithme de canonicalisation d’en-tête et corps, cette valeur définit le niveau de tolérance que le serveur de destination devrait avoir lorsqu’un message contient ces modifications mineures.
  • d : l’identifiant de domaine responsable de la signature (SDID)
  • s : le sélecteur responsable de la signature (permet d’avoir plusieurs autorités pour signer et retrouver la correspondance dans la zone)
  • a : les algorithmes de signature utilisés
  • h : liste des champs d’en-tête signés

D’autres champs d’en-têtes optionnels sont disponibles, voir la RFC6376.

Le process de fonctionnement est le suivant :

alt

Principe de fonctionnement de DKIM

Dans la suite de cet article, j’exploite la solution opendkim pour signer et sur postfix pour l’envoi.

Les mails seront tous signés avec la même clé privée (pour simplifier la configuration).

Installation et configuration d’Opendkim

OpenDKIM est un démon écrit en C qui s’interface avec les MTAs courants (postfix, sendmail…). Il offre la possibilité de signer les mails relayés (mais également de contrôler des mails entrants).

Installation des paquets

apt-get install opendkim opendkim-tools

Génération du trousseau de clés

opendkim-genkey --subdomains -r -d domain.tld -D /etc/opendkim/keys --bits=2048 --selector=mail

Deux fichiers sont générés :

  • Une clé publique (mail.txt)
  • Une clé privée (mail.private)

On rend opendkim propriétaire du répertoire et on limite l’accès aux tiers :

chown opendkim:opendkim -R /etc/opendkim/keys/*
chmod 600 /etc/opendkim/keys/*

Configuration d’opendkim

/etc/opendkim.conf

OversignHeaders From
AutoRestart Yes
AutoRestartRate 10/1h
UMask 002
Syslog yes
SyslogSuccess Yes
LogWhy Yes

Canonicalization relaxed/simple

InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable

Mode s
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256

UserID opendkim:opendkim

Socket local:/var/spool/postfix/opendkim/opendkim.sock
SOCKET inet:8891@localhost
La propriété “Mode” déclare le mode de fonctionnement ; ici nous ne faisons que signer.
Le dialogue entre postfix et opendkim se fera par une socket écoutant en local.

InternalHosts

Ce fichier contient la liste des hôtes expéditeurs qui auront leurs mails signés.

/etc/opendkim/TrustedHosts

127.0.0.1
0.0.0.0/0

Dans l’exemple ci-dessus, on précise un subnet qui est l’ensemble des adresses IPv4 pour demander la signature pour tous les clients (en considérant que le contrôle des émetteurs est géré autre part).

Dans le cas contraire :

Apr 25 10:04:02 tcw-816898 opendkim[27115]: 68D899FF30: domain.tld [x.x.x.x] not internal
Apr 25 10:04:02 tcw-816898 opendkim[27115]: 68D899FF30: not authenticated

SigningTable

Correspondance des domaines et adresses emails avec leurs sélecteurs.

/etc/opendkim/SigningTable

*@domain.tld mail._domainkey.domain.tld
*@*.domain.tld mail._domainkey.domain.tld

KeyTable

Ce fichier assure la liaison de chaque domaine avec sa clé correspondante.

/etc/opendkim/KeyTable

mail._domainkey.domain.tld domain.tld:mail:/etc/opendkim/keys/mail.private

Configuration de postfix

On ajoute un nouveau milter afin que le démon opendkim prenne en charge la signature.

milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:localhost:8891

Le paramètre milter_default_action indique la façon dont Postfix interprète les erreurs des applications Milter, “accept” permet de ne pas bloquer email en cas de problème (cette stratégie est à adapter).

Configuration de la zone

Mise en place de la configuration des entrées DNS.

Attention sous OVH il faut bien déclarer une entrée DKIM et non TXT car le TXT est tronqué silencieusement.

alt

Déclaration entrée sous OVH (1/2)

alt

Déclaration entrée sous OVH (2/2)

Valider la configuration de la zone à l’aide de la commande dig.

dig mail._domainkey.mondomaine.tld TXT +short

"v=DKIM1; h=sha256; k=rsa; p=MIIBIevZgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2dQBhndz0uzSmN9VYOpclZQxeo1wpehn5Bx7Sqk26U3k2PUGTycRegtbrM6FC6Db3ObAfevZY0kv8IC34tOZ/z/vgtuPBI1Qi7jeFXToWQmjVT28LQWv8/h6FTghtgLqucKUNzW6T9p8lm0lK6534YPdjbArgAEpaVaO4eIQwajRD5Y0MdGsEw3Dm/qkHFCIUmZM+It0tHdkJB2DTXjWaYxqJBx5UibfSxnMof0l/ZPLA1GT/6HpCoF6t9LpvApuhiYb7LMPxa7wE9rjgOykFx403TSlrqoeGSWQ/Y4B0Xk1SuDcQ3V6W13cqRKVCyx9qDwC917iEtFP5t4mZY/OxQIDAQAB"

Attention à l’horloge de temps

La signature peut être considérée comme mauvaise si l’horloge n’est pas à la bonne heure.

X-Mail-DKIM: fail (Signature date is -19 seconds in the future.)

Validation du bon fonctionnement

Différents sites permettent de valider la signature comme :

alt

appmaildev

Ci-dessous un petit script pratique pour tester rapidement sa configuration :

#!/usr/bin/python3
import smtplib
from email.message import EmailMessage

sender="contact@domain.tld"
receivers="test-88didippt@srv1.mail-tester.com"
relay="127.0.0.1"
subject='Relay validation'

msg = EmailMessage()
msg.set_content('Only a few words ...')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receivers

s = smtplib.SMTP(relay)
s.send_message(msg)
s.quit()

Related