15 KiB
Résumé
Objectif du document
Description de plusieurs RFC intéressantes (ou non) autour des protocoles liés aux emails. Lorsque ces normes sont en application au Cr@ns (ou ont volontairement été repoussées à plus tard), les solutions techniques étudiées seront décrites.
Remarques préalables :
- SMTP est un protocole incontournable car largement utilisé. Malgré tous ses défauts, il restera important pendant un bon bout de temps. Pour cette raison, de nombreuses personnes ont cherché à augmenter la sécurité des emails tant bien que mal, en proposant de chiffrer les mails qui transitent d'un MTA à un autre, signant les mails émis par un serveur,... Toutes ces techniques sont mises en place autour du protocole mail, lequel ne change pas.
- Aujourd'hui, certains organismes influents ont le bon goût de rejeter les mails issus de serveurs n'implémentant pas les protocoles les plus importants. Quoi que l'on pense du poids de l'influence des géants, cela permet d'élever les standards qualités des autres. Serons-nous un jour spam-free ? Les publicités mentionnant nos informations personnelles (nom, préférences, ...) seront-elles un jour toutes chiffrées ? Je ne sais pas, mais je l'espère haha.
Au Cr@ns
Statut au Cr@ns ? | Adoption | |
---|---|---|
SPF | Implémenté | Large |
DKIM | Implémenté | Large |
SRS | Implémenté | ? |
DMARC | Non-implémenté | Large |
ARC | Non-implémenté | ? (Google l'utilise) |
MTA-STS | Non-implémenté | ? (MS, Méta et Google l'utilisent) |
DANE | Non-implémenté | Faible (requiert DNSSEC) |
Tous ce qui est discuté ci-dessous fonctionne de la manière suivante :
- l'infrastructure émettrice (le Cr@ns) publie des informations la concernant,
- les serveurs réceptionnant les mails (les
MX
des destinataires des mails émis par le Cr@ns) peuvent vérifier les mails à l'aide de ces informations.
NB : je parle d'infrastructure ou d'organisation émettrice et non pas de serveur émetteur car plus d'un service est souvent requis (e.g. un serveur DNS autoritaire, un serveur Web,...).
SPF
Le SPF (Sender Policy Framework) permet d'indiquer quels serveurs ont le droit
d'émettre des mails en crans.org
(ou tout autre domaine, bien entendu).
Implémentation (côté infrastructure émettrice)
Pour cela, nous publions un champ TXT
pour crans.org
. Voici le contenu que l'on
obtient pour quelques associations avec kdig -t TXT crans.org
(dig
peut être utilisé à la place de kdig
) :
Au Cr@ns :
v=spf1 mx ip4:185.230.79.1 ip6:2a0c:700:2:0:ec4:7aff:fe59:a1ad ip4:185.230.79.38
ip6:2a0c:700:2::ff:fe01:3502 ~all
Cela signifie que les serveurs mail du Cr@ns (mx
) et les adresses listées (et
celles-ci uniquement) ont le droit d'envoyer des mails dont la source
prétendue est ...@crans.org.
Utiliser ~all
permet d'indiquer que si un mail provient d'une autre IP, il ne
faut pas rejeter le mail, mais le mettre en permerror.
À l'April :
v=spf1 include:spf.mailjet.com mx ip4:62.73.5.35 include:spf.protection.outlook.com include:_spf.april.com ip4:37.71.69.68 ip4:37.71.69.69 ip4:37.71.69.70 include:_spf.salesforce.com -all
Idem, avec des champs include:...
en plus. Ces derniers permettent d'inclure
un autre enregistrement SPF (e.g. celui de spf.mailjet.com
).
Utiliser -all
permet de demander aux serveurs récepteurs de rejeter tout mail
ne satisfaisant pas ce test.
C'est une politique plus sévère que ~all
, qui a l'avantage de
filtrer plus efficacement les mails douteux et l'inconvénient
de risquer des pertes de mails plus ou moins importants,
en tout cas légitimes, émis par des domaines configurés
avec un respect des standards mail plus léger.
D'autres mécanismes et formats existent, mais nous ne les présentons pas ici. Se référer à la RFC ou la page Wikipédia pour leur description.
Vérification (côté serveur récepteur)
Lorsque redisdead
(le MX
du Cr@ns) reçoit un mail, nous demandons à un service
externe de vérifier le SPF (via la variable smtpd_recipient_restrictions
). Le
service externe tourne sur la même VM et est postfix-policyd-spf-python
.
TODO SRS
Note : les adresses générées par postsrsd
sont valides pendant 21 jours.
DKIM
Le protocole DKIM (Domain Key Identified Mail) permet au serveur émetteur de signer les mails, et au serveur récepteur de vérifier cette signature, en utilisant des méthodes de cryptographie asymétrique.
Implémentation (côté émetteur)
Serveur mail
Le serveur émetteur possède la clef privée. Il ajoute à tout mail sortant un champ à l'en-tête de la forme suivante :
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=crans.org; s=mail;
t=1702660809; bh=NqcDLO2gkZU0IxcV+mE7uZ2NRnN/yfceH73Q1nhaFg4=;
h=From:To:Subject:Date:From;
b=ZjomU0jkljKVwA6sUhUioCemnxh/OhSGgwwr57irEn39Gfbv8/cLF8jmHc3hmv4ly
fLvJdj7iVTkeGlTVeW72H93wEA0qrB6LHHz81YBeHPb8eg63zm+9soDSOaP91Gux8J
UgeY1PWXvfjdfe+MJX9JqnlBKqd4JRgpD8AXaO852Lrq+fLJy4ewLOc/3dAqpNMrTf
swi5y6vV5QH89cuFjpjWqF3UcuD4a20RCQIpU/j5K1sxr1CTbdKjgqlsq5mt9/JSKx
OcvZ5WTmgPwdimKKz0DfjAeXQBMac9d7V9Kb5LvCZx84kSbLQEKboGxpRRhNWGdBsK
f3YZXjmpe8cl8cpbvuvdKYWOE7E6fRGu/CwQEyEQYqmrmljiklSYPaG8IKs5uYWKrA
A2D4VTisIYOwGvdljFTQP5zfhPsi4OnNbiN3RVX475lCHNWbnFMh8OCF/ugLj30dyk
s8MLAzDyYlgaccOD0uZ6VsdGJ0LK8+TCKbsc5H1ynjg0VejmRyVzZJ5TzAjXrzS6CC
Lj9eQQex1IaO6d7uGe4P/ULghjSP90tgBcZVNFLlU3r59ylkVQyAu7THDr4CDaxFO0
63QE7/GNDE2vZv0K5gp5Yz2veVC3wyaP1dJzIoAzZc1kZRoWz6QK9cH1Bfmnlx9nUs
j+G+VLDQbxi2NuoYAD/I2naA=
Le bloc contient une liste de clefs-valeurs :
v
indique la version du protocole,d
le domaine attestant de la validité du mail,s
le nom du sélecteur (/Cf/. plus bas),b
etbh
contiennent les signatures.
Notes :
- Il est possible que le mail ne soit pas signé par le domaine correspondant à l'adresse d'envoi, puisqu'il est possible d'autoriser autrui à envoyer un mail à notre place (cf. SPF plus haut).
- Se référer à la page Wikipédia, ou à la RFC pour une liste exhaustive des clefs.
Serveur DNS
Il faut placer dans le serveur DNS un champ TXT dont la clef est
sélecteur._domainkey.domain
, où domain
(resp. sélecteur
) est la valeur de la
clef d
(resp. s
) définie plus haut.
Par exemple, pour le champ fourni plus haut, nous pouvons lire :
"v=DKIM1; k=rsa; "
"p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtwkNVd9Mmz8S4WcfuPk0X2drG39gS8" "
+uxAv8igRILgzWeN8j2hjeZesl8pm/1UTVU87bYcdfUgXiGfQy9nR5p/Vmt2kS7sXk9nsJ/VYENg"
"b3IJQ6paWupSTFMyeKycJ4ZHCEZB/bVvifoG6vLKqW5jpsfCiOcfdcgXATn0UPuVx9t93yRrhoEM"
"ntMv9TSodjqd3FKCtJUoh5cNQHo0T6dWKtxoIgNi/mvZ92D/IACwu/XOU+Rq9fnoEI8GukBQUR5A" "kP0B/
JrvwWXWX/3EjY8X37ljEX0XUdq/ShzTl5iK+CM83stgkFUQh/rpww5mnxYEW3X4uirJ7VJH" "mY4KPoIU
+2DPjLQj9Hz63CMWY3Ks2pXWzxD3V+GI1aJTMFOv2LeHnI3ScqFaKj9FR4ZKMb0OW2BE" "FBIY3J3aeo/
paRwdbVCMM7twDtZY9uInR/NhVa1v9hlOxwp4/2pGSKQYoN2CkAZ1Alzwf8M3EONL"
"KeiC43JLYwKH1uBB1oikSVhMnLjG0219XvfG/tphyoOqJR/bCc2rdv5pLwKUl4wVuygfpvOw12bc" "vnTfYuk/
BXzVHg9t4H8k/DJR6GAoeNAapXIS8AfAScF8QdKfplhKLJyQGJ6lQ75YD9IwRAN0oV+8" "NTjl46lI/C
+b7mpfXCew+p6YPwfNvV2shiR0Ez8ZGUQIcCAwEAAQ=="
Vérification (côté récepteur)
Côté réception (redisdead
pour nous), nous utilisons le milter (filtre pour
mail) fourni par opendkim
. Ce milter écoute en local et est appelé par postfix
.
Lors de la réception d'un mail, postfix demande à opendkim
quelle décision
prendre. Ce dernier va regarder les en-têtes du mail. Si il trouve une signature
DKIM, il va effectuer la requête DNS décrite plus haut et vérifier la signature
du mail (valeurs des clefs b
et bh
).
TODO DMARC
TODO ARC
MTA-STS
Le MTA-STS consiste à publier les protocoles de sécurité supportés par les serveur mail d'un certain domaine (pour nous, les mails en /...@crans.org/).
Contrairement au DANE
(décrit plus bas), ce protocole ne demande pas la mise en
place de DNSSEC. En revanche, il demande d'avoir un serveur Web accessible en
https
(pour nous, https://crans.org
doit être servi par un serveur Web).
Implémentation (côté infrastructure émettrice)
Dans la zone DNS
Il faut ajouter un champ TXT
accessible à _mts-sts.domain.tld
.
Quelques exemples :
- Gmail :
v=STSv1; id=20190429T010101;
, - Microsoft :
v=STSv1; id=20190225000000Z;
, - Outlook :
v=STSv1; id=20190225000000Z;
.
Sur le serveur Web
Il faut que le serveur Web associé serve un fichier texte accessible à l'adresse
https://mta-sts.domain.tld/.well-known/mta-sts.txt
Quelques exemples :
Le fichier texte contient une liste de clefs-valeurs. Ces clefs décrivent quel protocole sera utilisé.
Vérification côté récepteur
Est-il possible d'utiliser postfix-mta-sts-resolver
? N'ayant pas implémenté cette
solution pour le moment (ni au Cr@ns, ni personnellement), nous ne pouvons pas
commenter sur le sujet.
DANE
Actuellement, pour vérifier un certificat C
proposé par un serveur mail, il faut
faire confiance à un certificat racine, lequel est utilisé pour signer un autre
certificat (dit certificat intermédiaire), lequel est utilisé pour signer le
certificat C
. Pour vérifier C
, il faut
- faire confiance au certificat racine,
- vérifier les deux signatures sus-mentionnées.
DANE
est une norme permettant aux propriétaires de domaines de déclarer quels
cetificats doivent être acceptés pour quels services.
Note : cela n'est pas spécifique aux mails.
Implémentation (côté infrastructure émettrice)
Pour mettre en place DANE
, il suffit d'ajouter un champ DNS à sa zone :
- Il faut que la zone soit signée DNSSEC.
- Le champ à ajouter est :
- de type TLSA (TLS Authentication),
- de clef
_port._protoL4.domain.tld
. - de valeur
x y z t
, où :x
est appelécertificate usage
,y
est appeléselector
,z
est appelématching type
,t
est appelécertificate associated data
.
Format du champ TLSA
Certificate usage
L'objectif de ce champ est d'indiquer comment vérifier le certificat.
Valeur | Signification |
---|---|
0 | Le certificat doit être valide (root -> intermediate -> cert ), et associated data décrit l'un des certificats parents de cert |
1 | associated data décrit cert , et le certificat doit aussi être valide par rapport à un certificat racine de confiance. |
2 | associated data décrit un parent de cert . Ce parent est supposé de confiance, et cert doit bien être son descendant. |
3 | associated data décrit cert . Le certificat n'a pas besoin d'être valide par rapport à un certificat racine. Il a simplement besoin de correspondre à associated data . |
Selector
Ce champ décrit ce qui est décrit par associated data
.
Valeur | Signification |
---|---|
0 | Tout le certificat. |
1 | Seulement la clef publique. |
Matching type
Ce champ indique comment vérifier associated data
contre la donnée du certificat
(ou de la clef publique).
Valeur | Signification |
---|---|
0 | associated data doit être égal à la donnée. |
1 | associated data doit être égal au sha256 de la donnée. |
2 | associated data doit être égal au sha512 de la donnée. |
où la donnée est décrite par le selector
et le choix de certificat décrit par
le certificate usage
.
Certificate associated data
Chaîne de caractères au format hexadécimal.
Recommandation pour le Cr@ns
À titre personnel, j'utilise des champs TLSA en 3 0 1
. Je pense que le Cr@ns
peut faire la même chose (ou du 3 0 2
).
Mise en place
Hypothèses :
- le serveur DNS accepte des mises à jour DNS dynamiques de la part du serveur mail,
- le renouvellement du certificat utilise
certbot
.
Mise en place :
- Dans la confguration
certbot
,- passer en challenge DNS-01 et :
manual_auth_hook
: un script mettant en place le challenge,renew_hook
: script de déploiement du certificat, lequel ajoute un champ TLSA et place le certificat à déployer dans un dossier "staging",manual_cleanup_hook
: un script retirant le challengeacme
.
- passer en challenge DNS-01 et :
- Roll-over scheme : Un champ DNS a une durée de vie (TTL), généralement 1h. De ce fait, les requêtes de chalmp TLSA peuvent être en retard d'une heure (au plus). Il est done conseillé d'avoir le nouveau champ TLSA en place pendant deux TTL avant de (1) mettre en place le nouveau certificat et (2) retirer le vieux champ TLSA.
Je propose de mettre en place un timer systemd
qui serait activé "après
l'arrêt de certbot
pour plus de 2 TTLs". Ce timer lancerait un service, lequel
aurait une condition d'activation "un certificat existe dans le dossier
staging".
Exemple
dig +short TLSA _25._tcp.nanein.fr
=> 3 0 1 50E9221F066DCD1991ED9D3BA0AD10159F3585780F6FABBAE2942E43 37789FC8
Implémentation (côté serveur mail destinataire)
Côté serveur mail destinataire, la configuration est très simple (car nous utilisons Postfix). Cela se fait principalement via les options suivantes :
smtp_dns_supoprt_level
(valeurdnssec
)smtp_tls_dane_insecure_mx_policy
(valeurdane
)
D'autres options de Postfix peuvent être utilisées pour permettre un contrôle plus fin sur le comportement du service.