Aller au contenu principal

RFC 7208 - Sender Policy Framework (SPF)

  • Statut: Proposed Standard
  • Publié: April 2014
  • Stream: IETF
  • Remplace: RFC4408
  • Errata: Pas d'errata

Informations de base​

  • Numéro RFC: 7208
  • Titre: Sender Policy Framework (SPF) for Authorizing Use of Domains in Email
  • Titre français: Cadre de Politique de l'Expéditeur
  • Date de publication: Avril 2014
  • Statut: PROPOSED STANDARD (Norme proposée)
  • Auteur: S. Kitterman

Résumé (Abstract)​

SPF permet aux propriétaires de domaines de spécifier via des enregistrements DNS quels serveurs de messagerie sont autorisés à envoyer des e-mails pour ce domaine. Les destinataires peuvent interroger les enregistrements SPF pour vérifier si les e-mails proviennent de serveurs autorisés, aidant ainsi à détecter et bloquer l'usurpation d'e-mails.

Contents​

Appendices (Annexes)​

Aperçu du SPF​

Qu'est-ce que le SPF?​

Définition:

SPF = Sender Policy Framework (Cadre de Politique de l'Expéditeur)
Fonction: Vérification des serveurs de messagerie autorisés
Méthode: Enregistrements DNS TXT
Objectif:
✓ Prévenir l'usurpation d'e-mail
✓ Réduire le spam
✓ Améliorer la délivrabilité des e-mails

Trio de sécurité e-mail:
1. SPF (ce RFC) - Vérifie le serveur d'envoi
2. DKIM (RFC 6376) - Vérifie le contenu de l'e-mail
3. DMARC (RFC 7489) - Politique et rapports unifiés

Principe de fonctionnement:

Expéditeur (example.com):
1. Publie un enregistrement SPF dans le DNS
example.com. IN TXT "v=spf1 ip4:203.0.113.1 -all"
→ Seul 203.0.113.1 est autorisé

2. Le serveur de messagerie envoie normalement des e-mails
MAIL FROM: `<[email protected]>`

Destinataire:
1. Extrait le domaine de l'expéditeur
MAIL FROM: [email protected] → Domaine: example.com

2. Interroge l'enregistrement SPF
Requête DNS: enregistrement TXT example.com

3. Vérifie l'IP du serveur d'envoi
IP du serveur d'envoi: 203.0.113.1
Enregistrement SPF autorise: ip4:203.0.113.1
→ Correspondance!

4. Résultat SPF:
Pass ✓ → Serveur autorisé
Fail ✗ → Serveur non autorisé

SPF vs DKIM vs DMARC​

Comparaison des fonctionnalités:

SPF (RFC 7208):
- Vérifie: IP du serveur d'envoi
- Emplacement: SMTP MAIL FROM
- Enregistrement DNS: TXT
- Limitation: Les e-mails transférés échouent

DKIM (RFC 6376):
- Vérifie: Signature numérique de l'e-mail
- Emplacement: En-tête DKIM-Signature
- Enregistrement DNS: TXT (_domainkey)
- Limitation: Nécessite une configuration correcte des clés

DMARC (RFC 7489):
- Vérifie: Alignement SPF + DKIM
- Emplacement: En-tête From
- Enregistrement DNS: TXT (_dmarc)
- Fonction: Politique + Rapports

Utilisation combinée:
SPF + DKIM → DMARC réussi → Protection optimale

Format d'enregistrement SPF​

Syntaxe de base​

v=spf1 <mechanisms> <qualifiers> <modifiers>

Exemple:
v=spf1 ip4:192.0.2.0/24 include:_spf.example.com -all

Composants:
- v=spf1: Identifiant de version (requis, toujours spf1)
- mechanisms: Mécanismes de correspondance
- qualifiers: Qualificateurs de résultat
- modifiers: Modificateurs

Mécanismes (Mechanisms)​

1. all:

Définition: Correspond à toutes les IPs
Utilisation: Généralement comme politique par défaut à la fin

Exemples:
v=spf1 -all Toutes les IPs non autorisées (le plus strict)
v=spf1 ~all Toutes les IPs en échec doux (recommandé)
v=spf1 +all Toutes les IPs autorisées (non recommandé!)

2. ip4/ip6:

Définition: Adresses IP ou plages explicites

Exemples:
v=spf1 ip4:203.0.113.1 -all
→ Seul 203.0.113.1 est autorisé

v=spf1 ip4:192.0.2.0/24 -all
→ Autorise 192.0.2.0-192.0.2.255

v=spf1 ip6:2001:db8::1 -all
→ Autorise l'adresse IPv6

v=spf1 ip4:203.0.113.0/24 ip4:198.51.100.0/24 -all
→ Autorise plusieurs plages

3. a:

Définition: Enregistrements A/AAAA du domaine actuel

Exemples:
v=spf1 a -all
→ Autorise les IPs de l'enregistrement A d'example.com

v=spf1 a:mail.example.com -all
→ Autorise les IPs de l'enregistrement A de mail.example.com

v=spf1 a/24 -all
→ Autorise le réseau /24 de l'IP de l'enregistrement A d'example.com

4. mx:

Définition: Enregistrements MX du domaine actuel

Exemples:
v=spf1 mx -all
→ Autorise les IPs des serveurs MX d'example.com

v=spf1 mx:example.com -all
→ Autorise les IPs des serveurs MX d'example.com

v=spf1 mx/24 -all
→ Autorise le réseau /24 des serveurs MX

5. include:

Définition: Inclut l'enregistrement SPF d'un autre domaine

Exemples:
v=spf1 include:_spf.google.com -all
→ Autorise les serveurs de messagerie Google (Gmail for Business)

v=spf1 include:spf.protection.outlook.com -all
→ Autorise les serveurs de messagerie Microsoft 365

Plusieurs includes:
v=spf1 include:_spf.google.com include:spf.protection.outlook.com -all

Attention: Limite de 10 recherches DNS maximum!

6. exists:

Définition: Correspond si le domaine spécifié a un enregistrement A

Exemple:
v=spf1 exists:%\{i}.spamhaus.example.com -all
→ Utilisation avancée, généralement pour les vérifications de liste noire anti-spam

Expansion de macro:
%\{i} = IP du serveur d'envoi (inversée)

7. ptr (non recommandé):

Définition: Requête DNS inverse

Exemple:
v=spf1 ptr:example.com -all

Problèmes:
❌ Mauvaises performances (nécessite une requête DNS inverse)
❌ Fiabilité faible
❌ RFC déconseille explicitement son utilisation

Alternative: Utilisez ip4/ip6 ou include

Qualificateurs (Qualifiers)​

Symbole | Nom | Signification | Utilisation recommandée
--------|-----|---------------|------------------------
+ | Pass | Réussi (par défaut) | Serveurs autorisés
- | Fail | Échec | Rejeter l'e-mail
~ | SoftFail | Échec doux | Accepter mais marquer
? | Neutral | Neutre | Pas de politique claire

Exemples:
v=spf1 +ip4:203.0.113.1 -all
↑pass explicite ↑échec explicite

v=spf1 ip4:203.0.113.1 ~all
↑+ par défaut ↑échec doux

v=spf1 ?all
↑neutre (équivalent à pas de SPF)

Recommandations d'utilisation des qualificateurs:

+ (Pass): 
✓ Serveurs de messagerie autorisés
Exemple: +ip4:203.0.113.1

- (Fail):
✓ -all final (strict)
✓ Interdire explicitement certaines IPs
Exemple: -all

~ (SoftFail):
✓ ~all final (souple, recommandé au début)
✓ Utiliser pendant la période de transition
Exemple: ~all

? (Neutral):
✗ Rarement utilisé
✗ Équivalent à pas de politique

Modificateurs (Modifiers)​

1. redirect:

Définition: Redirection vers l'enregistrement SPF d'un autre domaine

Exemple:
example.com: v=spf1 redirect=_spf.example.com
_spf.example.com: v=spf1 ip4:203.0.113.1 -all

Objectif:
✓ Gestion centralisée du SPF
✓ Plusieurs domaines partagent une politique

Attention:
- Aucun autre mécanisme ne peut suivre redirect
- Ne peut pas être utilisé avec all

2. exp:

Définition: Explication (texte d'explication en cas d'échec SPF)

Exemple:
v=spf1 -all exp=explain.example.com

Enregistrement TXT explain.example.com:
"This domain does not send email"

Objectif:
✓ Fournir des messages d'erreur conviviaux
- Rarement utilisé en pratique

Exemples d'enregistrements SPF​

Configurations de base​

1. Un seul serveur de messagerie:

v=spf1 ip4:203.0.113.1 -all

Explication:
- Seul 203.0.113.1 peut envoyer des e-mails
- Autres IPs sont rejetées

2. Utilisation des enregistrements MX:

v=spf1 mx -all

Explication:
- Autorise les serveurs MX du domaine à envoyer des e-mails
- S'adapte automatiquement aux changements MX

3. Plusieurs plages IP:

v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.0/24 -all

Explication:
- Autorise deux réseaux de classe C
- Adapté au déploiement multi-datacenter

Services tiers​

4. Google Workspace (Gmail for Business):

v=spf1 include:_spf.google.com -all

Explication:
- Utilise Google pour envoyer des e-mails
- Inclut l'enregistrement SPF de Google

5. Microsoft 365:

v=spf1 include:spf.protection.outlook.com -all

6. SendGrid:

v=spf1 include:sendgrid.net -all

7. Mailchimp:

v=spf1 include:servers.mcsv.net -all

Configurations mixtes​

8. Serveur propre + Tiers:

v=spf1 ip4:203.0.113.1 include:_spf.google.com -all

Explication:
- Serveur propre: 203.0.113.1
- Google Workspace: include

9. Plusieurs services tiers:

v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:sendgrid.net -all

Attention: Chaque include compte pour une recherche DNS

10. Domaine n'envoyant pas d'e-mails:

v=spf1 -all

Explication:
- Le domaine n'envoie pas d'e-mails
- Empêche l'usurpation
- Adapté aux domaines en réception seulement

Sous-domaines​

11. Configuration séparée des sous-domaines:

example.com: v=spf1 ip4:203.0.113.1 -all
mail.example.com: v=spf1 include:_spf.google.com -all

Explication:
- Le domaine principal utilise son propre serveur
- Le sous-domaine mail utilise Google

12. Héritage de sous-domaine (sans enregistrement SPF):

Si mail.example.com n'a pas d'enregistrement SPF:
→ Utilise l'enregistrement SPF d'example.com

Si pas d'héritage souhaité:
mail.example.com: v=spf1 -all

Processus de vérification SPF​

Étapes de vérification du destinataire​

// Pseudo-code de vérification SPF
async function checkSPF(clientIP, sender, helo) {
// 1. Extraire le domaine
const domain = sender.split('@')[1]; // [email protected] → example.com

// 2. Interroger l'enregistrement SPF
const spfRecord = await queryDNS(domain, 'TXT', 'v=spf1');

if (!spfRecord) {
return 'none'; // Pas d'enregistrement SPF
}

// 3. Analyser l'enregistrement SPF
const mechanisms = parseSPF(spfRecord);

// 4. Vérifier les mécanismes un par un
for (const mechanism of mechanisms) {
const result = await evaluateMechanism(mechanism, clientIP, domain);

if (result !== null) {
return result; // Correspondance trouvée, retourner le résultat
}
}

return 'neutral'; // Pas de correspondance
}

// Évaluer un seul mécanisme
async function evaluateMechanism(mechanism, clientIP, domain) {
const { type, value, qualifier } = mechanism;

switch (type) {
case 'ip4':
if (isInIPRange(clientIP, value)) {
return mapQualifier(qualifier); // +pass, -fail, ~softfail
}
break;

case 'a':
const aRecords = await queryDNS(value || domain, 'A');
if (aRecords.includes(clientIP)) {
return mapQualifier(qualifier);
}
break;

case 'mx':
const mxRecords = await queryDNS(value || domain, 'MX');
for (const mx of mxRecords) {
const mxIPs = await queryDNS(mx, 'A');
if (mxIPs.includes(clientIP)) {
return mapQualifier(qualifier);
}
}
break;

case 'include':
const includeResult = await checkSPF(clientIP, `user@${value}`, null);
if (includeResult === 'pass') {
return mapQualifier(qualifier);
}
break;

case 'all':
return mapQualifier(qualifier);
}

return null; // Pas de correspondance
}

Résultats SPF​

Valeur de retour   | Signification         | Traitement recommandé
-------------------|-----------------------|----------------------
none | Pas d'enregistrement | Accepter (confiance réduite)
| SPF |
neutral | Politique explicite | Accepter
| aucune |
pass | Réussi | Accepter
fail | Échec | Rejeter
softfail | Échec doux | Accepter mais marquer
temperror | Erreur temporaire | Réessayer plus tard
permerror | Erreur permanente | Rejeter

Exemples de réponses SMTP:
pass: 250 OK (SPF pass)
fail: 550 SPF check failed
softfail: 250 OK (ajouter en-tête X-SPF: softfail)

Limites de recherche DNS​

Limite de 10 recherches​

Problème:

La vérification SPF effectue au maximum 10 recherches DNS
Dépassement de la limite → permerror (Erreur permanente)

Compte pour les 10 recherches:
✓ include
✓ a
✓ mx
✓ exists
✓ redirect

Ne compte pas:
✗ ip4/ip6 (correspondance directe)
✗ all (correspondance directe)

Exemple - Limite dépassée:

v=spf1 
include:_spf1.example.com ← 1
include:_spf2.example.com ← 2
include:_spf3.example.com ← 3
include:_spf4.example.com ← 4
include:_spf5.example.com ← 5
include:_spf6.example.com ← 6
include:_spf7.example.com ← 7
include:_spf8.example.com ← 8
include:_spf9.example.com ← 9
include:_spf10.example.com ← 10
include:_spf11.example.com ← Dépassé! permerror
-all

Si un include contient d'autres includes, ceux-ci comptent aussi!

Solutions:

1. Utiliser ip4/ip6 au lieu de a/mx
❌ v=spf1 a mx -all (2 recherches)
✓ v=spf1 ip4:203.0.113.1 ip4:198.51.100.1 -all (0 recherche)

2. Fusionner les includes
❌ include:service1.com include:service2.com
✓ Maintenir son propre enregistrement SPF contenant toutes les IPs

3. SPF Flattening (Aplatissement SPF)
Interroger régulièrement les IPs des includes, convertir en ip4/ip6

Outil SPF Flattening​

// Exemple SPF Flattening
async function flattenSPF(domain) {
const spf = await querySPF(domain);
const ips = [];

// Analyser SPF
const mechanisms = parseSPF(spf);

for (const mech of mechanisms) {
if (mech.type === 'ip4' || mech.type === 'ip6') {
ips.push(mech.value);
} else if (mech.type === 'include') {
// Interroger récursivement les includes
const includeIPs = await resolveInclude(mech.value);
ips.push(...includeIPs);
} else if (mech.type === 'a') {
const aRecords = await queryDNS(mech.value, 'A');
ips.push(...aRecords.map(ip => `ip4:${ip}`));
} else if (mech.type === 'mx') {
const mxRecords = await queryDNS(mech.value, 'MX');
for (const mx of mxRecords) {
const mxIPs = await queryDNS(mx, 'A');
ips.push(...mxIPs.map(ip => `ip4:${ip}`));
}
}
}

// Générer SPF aplati
return `v=spf1 ${ips.join(' ')} -all`;
}

// Utilisation
const flatSPF = await flattenSPF('example.com');
console.log('Flattened SPF:', flatSPF);
// v=spf1 ip4:74.125.0.0/16 ip4:209.85.128.0/17 ip4:216.58.192.0/19 -all

Outils pratiques​

Générateur d'enregistrement SPF​

class SPFBuilder {
constructor(domain) {
this.domain = domain;
this.mechanisms = [];
this.modifier = null;
}

addIP(ip) {
if (ip.includes(':')) {
this.mechanisms.push(`ip6:${ip}`);
} else {
this.mechanisms.push(`ip4:${ip}`);
}
return this;
}

addIPRange(cidr) {
if (cidr.includes(':')) {
this.mechanisms.push(`ip6:${cidr}`);
} else {
this.mechanisms.push(`ip4:${cidr}`);
}
return this;
}

useA() {
this.mechanisms.push('a');
return this;
}

useMX() {
this.mechanisms.push('mx');
return this;
}

include(domain) {
this.mechanisms.push(`include:${domain}`);
return this;
}

setDefault(qualifier) {
const qualifiers = { pass: '+all', fail: '-all', softfail: '~all', neutral: '?all' };
this.mechanisms.push(qualifiers[qualifier] || '-all');
return this;
}

redirect(domain) {
this.modifier = `redirect=${domain}`;
return this;
}

build() {
let spf = 'v=spf1';

if (this.mechanisms.length > 0) {
spf += ' ' + this.mechanisms.join(' ');
}

if (this.modifier) {
spf += ' ' + this.modifier;
}

return spf;
}

countLookups() {
let count = 0;
for (const mech of this.mechanisms) {
if (mech.startsWith('include:') || mech.startsWith('a') ||
mech.startsWith('mx') || mech.startsWith('exists:')) {
count++;
}
}
if (this.modifier && this.modifier.startsWith('redirect=')) {
count++;
}
return count;
}
}

// Exemple d'utilisation
const spf = new SPFBuilder('example.com')
.addIP('203.0.113.1')
.addIPRange('192.0.2.0/24')
.include('_spf.google.com')
.include('spf.protection.outlook.com')
.setDefault('fail')
.build();

console.log('SPF Record:', spf);
console.log('DNS Lookups:', spf.countLookups());

// Sortie:
// SPF Record: v=spf1 ip4:203.0.113.1 ip4:192.0.2.0/24 include:_spf.google.com include:spf.protection.outlook.com -all
// DNS Lookups: 2

Outil de vérification SPF​

const dns = require('dns').promises;

class SPFChecker {
async check(domain, ip) {
try {
// Interroger l'enregistrement SPF
const records = await dns.resolveTxt(domain);
const spfRecord = records.find(r =>
r.join('').startsWith('v=spf1')
);

if (!spfRecord) {
return { result: 'none', message: 'No SPF record found' };
}

const spf = spfRecord.join('');
console.log('SPF Record:', spf);

// Analyser et vérifier
const result = await this.evaluate(spf, ip, domain);

return result;

} catch (err) {
return { result: 'temperror', message: err.message };
}
}

async evaluate(spf, ip, domain, depth = 0) {
if (depth > 10) {
return { result: 'permerror', message: 'Too many DNS lookups' };
}

const parts = spf.split(/\s+/);

for (const part of parts) {
if (part === 'v=spf1') continue;

// Extraire le qualificateur
let qualifier = '+';
let mechanism = part;

if (['+', '-', '~', '?'].includes(part[0])) {
qualifier = part[0];
mechanism = part.slice(1);
}

// Vérifier le mécanisme
if (mechanism.startsWith('ip4:')) {
const range = mechanism.slice(4);
if (this.isIPInRange(ip, range)) {
return this.mapResult(qualifier);
}
} else if (mechanism.startsWith('include:')) {
const includeDomain = mechanism.slice(8);
const includeRecords = await dns.resolveTxt(includeDomain);
const includeSPF = includeRecords.find(r =>
r.join('').startsWith('v=spf1')
);

if (includeSPF) {
const result = await this.evaluate(
includeSPF.join(''),
ip,
includeDomain,
depth + 1
);

if (result.result === 'pass') {
return this.mapResult(qualifier);
}
}
} else if (mechanism === 'all' || mechanism === '-all' ||
mechanism === '~all' || mechanism === '?all') {
return this.mapResult(qualifier);
}
// D'autres mécanismes peuvent être ajoutés ici...
}

return { result: 'neutral', message: 'No match found' };
}

isIPInRange(ip, range) {
// Version simplifiée, l'environnement de production nécessite une implémentation complète
if (!range.includes('/')) {
return ip === range;
}
// Implémentation de correspondance CIDR omise...
return false;
}

mapResult(qualifier) {
const map = {
'+': { result: 'pass', message: 'SPF pass' },
'-': { result: 'fail', message: 'SPF fail' },
'~': { result: 'softfail', message: 'SPF softfail' },
'?': { result: 'neutral', message: 'SPF neutral' }
};
return map[qualifier] || map['+'];
}
}

// Utilisation
const checker = new SPFChecker();
const result = await checker.check('example.com', '203.0.113.1');
console.log('SPF Check Result:', result);

Meilleures pratiques de déploiement​

1. Déploiement progressif​

Phase 1: Mode surveillance
v=spf1 ?all
ou
v=spf1 ~all

Objectif: Collecter des données, observer quels serveurs envoient des e-mails
Durée: 2-4 semaines

Phase 2: Échec doux
v=spf1 ip4:x.x.x.x include:provider.com ~all

Objectif: Marquer mais ne pas rejeter les e-mails non autorisés
Durée: 4-8 semaines

Phase 3: Mode strict
v=spf1 ip4:x.x.x.x include:provider.com -all

Objectif: Rejeter les e-mails non autorisés

2. Erreurs courantes​

❌ Erreur 1: Oublier -all
v=spf1 ip4:203.0.113.1
→ Équivalent à v=spf1 ip4:203.0.113.1 ?all
→ Toute IP est neutral

✓ Correct:
v=spf1 ip4:203.0.113.1 -all

❌ Erreur 2: Plusieurs enregistrements SPF
example.com TXT "v=spf1 ip4:203.0.113.1 -all"
example.com TXT "v=spf1 include:provider.com -all"
→ permerror

✓ Correct: Fusionner en un seul
v=spf1 ip4:203.0.113.1 include:provider.com -all

❌ Erreur 3: Plus de 10 recherches
v=spf1 include:a include:b include:c ... (trop)

✓ Correct: Utiliser ip4 directement ou flattening

❌ Erreur 4: Utilisation de ptr
v=spf1 ptr:example.com -all
→ Mauvaises performances, non recommandé

✓ Correct: Utiliser ip4 ou include

3. Tests et vérification​

# Outils de test en ligne de commande

# 1. Interroger l'enregistrement SPF
dig example.com TXT | grep "v=spf1"
ou
nslookup -type=TXT example.com

# 2. Utiliser des outils en ligne
# - https://mxtoolbox.com/spf.aspx
# - https://www.kitterman.com/spf/validate.html

# 3. Envoyer un e-mail de test
# Envoyer à votre propre boîte e-mail, vérifier l'en-tête:
# Received-SPF: pass ...

Intégration avec DKIM/DMARC​

Configuration complète de sécurité e-mail​

1. Enregistrement SPF:
example.com. IN TXT "v=spf1 ip4:203.0.113.1 include:_spf.google.com -all"

2. Enregistrement DKIM:
default._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0..."

3. Enregistrement DMARC:
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]"

Résultat:
- SPF vérifie le serveur d'envoi ✓
- DKIM vérifie le contenu de l'e-mail ✓
- DMARC unifie la politique ✓
→ Triple protection!

Références​

RFCs liés au SPF:

  • [RFC 7208] SPF ← Ce document
  • [RFC 7489] DMARC
  • [RFC 6376] DKIM

Ressources connexes:


Résumé: SPF est la première ligne de défense pour la sécurité des e-mails. Par des enregistrements DNS, les serveurs d'envoi sont autorisés et l'usurpation d'e-mail est efficacement prévenue. Combiné avec DKIM et DMARC, un système complet de sécurité e-mail est créé. Rappelez-vous: Commencez avec l'échec doux et renforcez progressivement vers le mode strict, et respectez la limite de 10 recherches DNS!


1. Introduction​

L'infrastructure de messagerie actuelle a la caractéristique que tout hôte injectant des messages dans le système peut utiliser n'importe quel nom de domaine DNS dans les divers identifiants spécifiés dans [RFC5321] et [RFC5322]. Bien que cette caractéristique soit avantageuse dans certains cas, elle constitue un obstacle majeur à la réduction des e-mails en masse non sollicités (UBE, Unsolicited Bulk Email, également connu sous le nom de spam). De plus, les ADMD (comme décrit dans [RFC5598]) sont légitimement préoccupés par le fait que d'autres entités puissent facilement utiliser leurs noms de domaine, souvent avec des intentions malveillantes.

Ce document définit un protocole par lequel un ADMD peut autoriser des hôtes à utiliser son nom de domaine dans les identités "MAIL FROM" ou "HELO". Les ADMD conformes publient des enregistrements Sender Policy Framework (SPF) dans le DNS, spécifiant quels hôtes sont autorisés à utiliser leurs noms, et les destinataires de messagerie conformes utilisent les enregistrements SPF publiés pour tester l'autorisation d'un agent de transfert de messagerie (MTA, Mail Transfer Agent) émetteur utilisant une identité "HELO" ou "MAIL FROM" donnée lors d'une transaction de messagerie.

Un autre avantage pour les destinataires de messagerie est qu'après avoir validé l'utilisation d'une identité, des décisions de politique locale concernant les e-mails peuvent être prises sur la base du domaine de l'expéditeur plutôt que sur la base de l'adresse IP de l'hôte. Cela est avantageux car la réputation d'un nom de domaine peut être plus précise que la réputation d'une adresse IP d'hôte, car le nom de domaine pourrait être plus stable sur une plus longue période. De plus, si l'identité revendiquée ne peut pas être validée, la politique locale peut prendre des mesures plus fermes contre de tels e-mails, comme les rejeter.

1.1 Terminology (Terminologie)​

1.1.1 Key Words (Mots-clés)​

Les mots-clés "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" et "OPTIONAL" dans ce document doivent être interprétés comme décrit dans [RFC2119].

1.1.2 Imported Definitions (Définitions importées)​

ABNF (Augmented Backus-Naur Form) est défini dans [RFC5234], les jetons "ALPHA", "DIGIT" et "SP" (espace) y sont également définis.

Les jetons "Local-part", "Domain" et "Mailbox" sont définis dans [RFC5321].

"dot-atom", "quoted-string", "comment", "CFWS" (Comment Folded White Space), "FWS" (Folded White Space) et "CRLF" (Carriage-Return/Line-Feed) sont définis dans [RFC5322].

1.1.3 MAIL FROM Definition (Définition MAIL FROM)​

Ce document concerne l'identité de l'expéditeur du message, comme décrit dans [RFC5321]:

La transaction commence par la commande MAIL, qui fournit l'identité de l'expéditeur.

Comme cette identité a de nombreux autres noms, il est important de choisir un nom qui soit:

  1. Couramment utilisé

  2. Clairement défini

Par conséquent, le terme "MAIL FROM" sera utilisé dans ce document, défini comme l'identité RFC5321.MailFrom (Reverse-Path) décrite dans [RFC5598].

1.1.4 HELO Definition (Définition HELO)​

Ce document utilise également l'identité HELO/EHLO. L'identité "HELO" provient de la commande SMTP HELO ou EHLO (voir [RFC5321]). Comme HELO et EHLO peuvent être utilisés de manière interchangeable dans de nombreux cas, ils sont généralement identifiés comme "HELO" dans ce document. Cela signifie RFC5321.HELO/.EHLO tel que défini dans [RFC5598]. Ces commandes fournissent l'identité du client SMTP (hôte émetteur) pour la session SMTP.

1.2 check_host()​

La section 4 présente un algorithme utilisé pour évaluer la politique SPF par rapport à une transaction de messagerie entrante. Dans les premières implémentations, cet algorithme était codé dans une fonction appelée check_host(). Ce nom est utilisé dans ce document comme symbole de l'algorithme d'évaluation SPF, mais bien sûr, les implémenteurs ne sont pas tenus d'utiliser ce nom.


2. Operational Overview (Aperçu opérationnel)​

2.1 Publishing Authorization (Publication de l'autorisation)​

Les domaines conformes SPF publient des enregistrements SPF valides comme décrit dans la section 3. Ces enregistrements autorisent les MTA qui y sont spécifiés à utiliser le nom de domaine associé dans les identités "HELO" et "MAIL FROM".

Les résultats SPF peuvent être utilisés pour prendre des déterminations positives (la source est autorisée) et négatives (la source n'est pas autorisée). Si un ADMD choisit de publier un enregistrement SPF et souhaite soutenir les destinataires dans la prise de décisions d'autorisation négatives, il doit publier un enregistrement se terminant par "-all" ou redirigeant vers un autre qui le fait; sinon, aucune détermination définitive sur l'autorisation ne peut être faite. La section 10 discute des problèmes potentiels et des mesures d'atténuation liés aux décisions négatives.

Les ADMD souhaitant déclarer qu'aucun hôte n'est autorisé à utiliser leur nom de domaine DNS dans les commandes HELO ou MAIL FROM pendant les sessions SMTP peuvent publier un tel enregistrement SPF pour les noms de domaine qui ne sont ni utilisés dans la partie domaine des adresses e-mail ni destinés à envoyer des e-mails.

Lors de modifications des enregistrements SPF, il faut veiller à ce qu'il y ait une période de transition pendant laquelle l'ancienne politique reste valide jusqu'à ce que tous les e-mails légitimes puissent raisonnablement être supposés avoir été vérifiés. La section 4.5.4.1 de [RFC5321] discute de la durée pendant laquelle les messages peuvent rester en transit. Bien que les vérifications hors ligne soient possibles, plus la vérification est proche du moment de transmission original, plus il est probable d'obtenir un résultat SPF correspondant à l'intention de l'ADMD émetteur au moment de l'envoi du message.

2.2 Checking Authorization (Vérification de l'autorisation)​

Les destinataires de messagerie peuvent effectuer un ensemble de vérifications SPF pour chaque e-mail reçu. Une vérification SPF teste l'autorisation de l'hôte client à envoyer des e-mails avec une identité donnée. Typiquement, de telles vérifications sont effectuées par le MTA récepteur, mais elles peuvent être effectuées ailleurs dans la chaîne de traitement du courrier tant que les informations requises sont disponibles et fiables. Les identités "MAIL FROM" et "HELO" sont vérifiées respectivement conformément aux sections 2.4 et 2.3.

Il n'est pas recommandé de vérifier d'autres identités contre les enregistrements SPF version 1 sans approbation explicite de l'ADMD publiant, car on sait que certaines situations donnent des résultats incorrects. Par exemple, presque toutes les listes de diffusion réécrivent l'identité "MAIL FROM" (voir section 10.3), mais certaines ne modifient aucune autre identité dans le message. Les documents définissant d'autres identités doivent définir des méthodes d'approbation explicite.

Les destinataires de messagerie peuvent inclure les vérifications SPF dans le cadre d'un ensemble de tests plus large sur le courrier entrant. Les résultats d'autres tests peuvent influencer si une vérification SPF particulière est effectuée. Par exemple, trouver l'adresse IP de l'hôte émetteur sur une liste blanche locale peut entraîner le saut de tous les autres tests et l'acceptation de tous les e-mails de cet hôte.

Lorsqu'un destinataire de messagerie décide d'effectuer une vérification SPF, il doit utiliser la fonction check_host() correctement implémentée (section 4) et évaluer avec les paramètres corrects. Bien que l'ensemble du test soit optionnel, une fois la décision prise de l'effectuer, il doit être effectué comme prescrit pour préserver les sémantiques correctes entre les éditeurs et les destinataires.

Pour effectuer le test, le destinataire de messagerie doit évaluer la fonction check_host() avec les paramètres décrits dans la section 4.1.

Bien que les domaines invalides, mal formés ou inexistants entraînent le retour de "none" par les vérifications SPF (car aucun enregistrement SPF n'est trouvé), la politique de nombreux MTA depuis longtemps est de rejeter les e-mails de tels domaines, en particulier dans le cas d'un "MAIL FROM" invalide. Le rejet de l'e-mail empêche un moyen de contourner les enregistrements SPF.

Les implémentations doivent veiller à extraire correctement le <domain> des données fournies avec la commande SMTP MAIL FROM, car de nombreux MTA acceptent encore des choses comme le routage source (voir l'annexe C de [RFC5321]), le %-hack (voir [RFC1123]) et les chemins bang (voir [RFC1983]). Ces fonctionnalités obsolètes ont été utilisées de manière malveillante pour contourner les systèmes de sécurité.

2.3 The "HELO" Identity (L'identité "HELO")​

Il est recommandé que les vérificateurs SPF vérifient non seulement l'identité "MAIL FROM" mais aussi l'identité "HELO" séparément en appliquant la fonction check_host() (section 4) à l'identité "HELO" comme <domain>. La vérification de "HELO" peut favoriser des résultats cohérents et peut réduire l'utilisation des ressources DNS. Si une détermination définitive sur un message peut être faite sur la base de la vérification de "HELO", les ressources DNS pour traiter le "MAIL FROM" normalement plus complexe peuvent être évitées. De plus, comme les enregistrements SPF publiés pour l'identité "HELO" se réfèrent à un seul hôte, lorsqu'ils sont disponibles, ils sont une source très fiable du statut d'autorisation de l'hôte. Si les deux doivent être vérifiés, il est recommandé de vérifier d'abord "HELO" puis "MAIL FROM".

Notez que les exigences sur le domaine présenté dans la commande EHLO ou HELO pour les expéditeurs ne sont pas toujours claires, et les vérificateurs SPF doivent être prêts à ce que l'identité soit un littéral d'adresse IP (voir section 4.1.3 de [RFC5321]) ou simplement mal formée. Cette vérification SPF ne peut être effectuée que si la chaîne "HELO" est un nom de domaine multi-étiquettes valide.

2.4 The "MAIL FROM" Identity (L'identité "MAIL FROM")​

Si la vérification "HELO" n'a pas été effectuée ou n'a pas atteint un résultat de politique définitif, le vérificateur SPF doit vérifier l'identité "MAIL FROM" en appliquant la fonction check_host() à l'identité "MAIL FROM" comme <domain>.

[RFC5321] permet que le chemin inverse soit vide (voir section 4.5.5 dans [RFC5321]). Dans ce cas, il n'y a pas de boîte aux lettres d'expéditeur explicite, et de tels messages peuvent être supposés être des messages de notification du système de messagerie lui-même. Lorsque le chemin inverse est vide, ce document définit l'identité "MAIL FROM" comme la boîte aux lettres composée de la partie locale "postmaster" et de l'identité "HELO" (qui peut ou non avoir été vérifiée séparément auparavant).

2.5 Location of Checks (Emplacement des vérifications)​

Les vérifications d'autorisation doivent être effectuées pendant le traitement de la transaction SMTP qui reçoit l'e-mail. Cela réduit la complexité de la détermination de l'adresse IP correcte à utiliser comme entrée pour check_host() et permet de retourner les erreurs directement au MTA émetteur via les réponses SMTP. L'annexe D de [RFC7001] offre une discussion plus complète sur ce sujet.

Les vérifications d'autorisation sont effectuées pendant la transaction SMTP au moment de la commande MAIL et utilisent la valeur MAIL FROM et l'adresse IP du client. Effectuer des vérifications à un moment ultérieur ou avec d'autres entrées peut entraîner les problèmes suivants:

  • Il peut être difficile d'extraire avec précision les informations requises à partir d'en-têtes potentiellement usurpés.

  • Les e-mails légitimes peuvent échouer à la vérification d'autorisation parce que la politique de l'expéditeur a changé.

Générer des avis de non-livraison à des identités usurpées ayant échoué à la vérification d'autorisation constitue normalement du backscatter, c'est-à-dire des avis de rejet de harcèlement inutilisables. Les opérateurs sont fortement encouragés à éviter de telles pratiques. La section 2 de [RFC3834] décrit le backscatter et les problèmes qu'il cause.

2.6 Results of Evaluation (Résultats de l'évaluation)​

La section 4 définit check_host(), une définition de fonction modèle qui utilise les entrées définies ci-dessus et la politique d'expéditeur publiée dans le DNS pour arriver à des conclusions sur l'autorisation du client. Les vérificateurs SPF implémentent quelque chose de sémantiquement équivalent à la fonction définie ici.

Cette section énumère et définit brièvement les sorties possibles de cette fonction. Cependant, notez que le protocole n'établit pas d'exigences normatives pour le traitement d'un résultat particulier. Les options de traitement pour chaque résultat sont discutées dans la section 8.

2.6.1 None​

Un résultat de "none" signifie que (a) aucun nom de domaine DNS syntaxiquement valide n'a pu être extrait de la session SMTP pour être utilisé comme <domain> à autoriser, ou (b) aucun enregistrement SPF n'a été récupéré du DNS.

2.6.2 Neutral (Neutre)​

Un résultat "neutral" signifie que l'ADMD a explicitement déclaré qu'il n'affirme pas si l'adresse IP est autorisée ou non.

2.6.3 Pass (Réussi)​

Un résultat "pass" est une déclaration explicite que le client est autorisé à injecter du courrier avec l'identité donnée.

2.6.4 Fail (Échec)​

Un résultat "fail" est une déclaration explicite que le client n'est pas autorisé à utiliser le domaine dans l'identité donnée.

2.6.5 Softfail (Échec doux)​

Un résultat "softfail" est une déclaration faible de l'ADMD publiant que l'hôte pourrait ne pas être autorisé. Il n'a pas publié une politique plus forte et plus explicite qui entraînerait un "fail".

2.6.6 Temperror (Erreur temporaire)​

Un résultat "temperror" signifie que le vérificateur SPF a rencontré une erreur transitoire (généralement DNS) lors de l'exécution de la vérification. Une nouvelle tentative ultérieure peut réussir sans action supplémentaire de l'opérateur DNS.

2.6.7 Permerror (Erreur permanente)​

Un résultat "permerror" signifie que l'enregistrement publié du domaine n'a pas pu être interprété correctement. Cela indique une condition d'erreur qui nécessite définitivement l'intervention de l'opérateur DNS pour être résolue.


3. SPF Records (Enregistrements SPF)​

Un enregistrement SPF est un enregistrement DNS qui déclare quels hôtes sont autorisés (et lesquels ne le sont pas) à utiliser le nom de domaine dans les identités "HELO" et "MAIL FROM". Grossièrement, l'enregistrement divise les hôtes en ensembles autorisés et non autorisés (bien que certains hôtes puissent ne appartenir à aucune des deux catégories).

Les enregistrements SPF sont représentés comme une seule chaîne de texte trouvée dans le RDATA d'un seul enregistrement de ressource DNS TXT; plusieurs enregistrements SPF avec le même nom de propriétaire ne sont pas autorisés. Le format de l'enregistrement et le processus de sélection des enregistrements sont décrits ci-dessous dans la section 4. Un exemple d'enregistrement est le suivant:

v=spf1 +mx a:colo.example.com/28 -all

Cet enregistrement a la version "spf1" et contient trois directives: "+mx", "a:colo.example.com/28" (implicite "+"), et "-all".

Chaque enregistrement SPF est placé dans l'arbre DNS au nom de propriétaire auquel il appartient, et non dans un sous-domaine sous le nom de propriétaire. Ceci est similaire aux enregistrements SRV [RFC2782].

L'exemple de cette section pourrait être publié par la ligne suivante dans un fichier de zone de domaine:

example.com. TXT "v=spf1 +mx a:colo.example.com/28 -all"

Comme les enregistrements TXT ont plusieurs usages, notez les autres enregistrements TXT publiés là pour d'autres usages. Ils peuvent causer des problèmes de limites de taille (voir section 3.4), et il faut veiller à s'assurer que seuls les enregistrements SPF sont utilisés pour le traitement SPF.

Les ADMD qui publient des enregistrements SPF devraient maintenir au minimum la quantité d'informations DNS nécessaires pour évaluer l'enregistrement. Les sections 4.6.4 et 10.1.1 donnent quelques conseils sur le mécanisme "include" et les modificateurs "redirect" chaînés.

3.1 DNS Resource Records (Enregistrements de ressources DNS)​

Les enregistrements SPF doivent être publiés uniquement en tant qu'enregistrements de ressources (RR) DNS TXT (type 16) [RFC1035]. Le contenu en caractères de l'enregistrement est encodé en [US-ASCII]. La phase d'expérimentation SPF prenait en charge l'utilisation d'un type de RR DNS alternatif, mais cela a maintenant été abandonné.

En 2003, lorsque SPF a été développé pour la première fois, les exigences pour l'attribution d'un nouveau type de RR DNS étaient plus strictes qu'aujourd'hui. De plus, le support pour le déploiement facile de nouveaux types de RR DNS dans les serveurs DNS et les systèmes de configuration n'était pas largement déployé. Par conséquent, les développeurs de SPF ont trouvé plus facile et plus pratique d'utiliser le type de RR TXT pour stocker les enregistrements SPF.

Lors de l'examen de [RFC4408], le groupe de travail SPFbis a conclu que son modèle de transition à double type de RR était fondamentalement défectueux car il ne contenait pas de type de RR universel que les implémenteurs devaient fournir et vérifier. De nombreuses alternatives ont été envisagées pour résoudre ce problème, mais finalement le groupe de travail a conclu que la probabilité d'une migration vers le type de RR SPF dans un avenir prévisible était très faible et que la meilleure solution à ce problème d'interopérabilité était de retirer le support du type de RR SPF de SPF version 1. Pour plus d'informations, voir l'annexe A de [RFC6686].

Les circonstances entourant le déploiement initial de SPF il y a une décennie étaient uniques. Si une mise à jour de SPF qui ne réutilise pas les enregistrements SPF existants est développée à l'avenir, elle pourrait utiliser le type de RR SPF. L'utilisation par SPF du type de RR TXT pour stocker des données structurées ne doit en aucun cas être considérée comme un précédent pour les futurs concepteurs de protocoles. Une discussion plus approfondie des considérations de conception lors de l'utilisation de nouveaux types de RR DNS peut être trouvée dans [RFC5507].

3.2 Multiple DNS Records (Enregistrements DNS multiples)​

Un nom de domaine ne doit jamais avoir plusieurs enregistrements qui entraîneraient une vérification d'autorisation à sélectionner plusieurs enregistrements. Voir la section 4.5 pour les règles de sélection.

3.3 Multiple Strings in a Single DNS Record (Chaînes multiples dans un seul enregistrement DNS)​

Comme défini dans [RFC1035] sections 3.3 et 3.3.14, un seul enregistrement DNS de texte peut être composé de plusieurs chaînes. Si un enregistrement publié contient plusieurs chaînes de caractères, l'enregistrement doit être traité comme ces chaînes concaténées sans ajout d'espaces. Par exemple:

IN TXT "v=spf1 .... first" "second string..."

est équivalent à:

IN TXT "v=spf1 .... firstsecond string..."

Les enregistrements TXT contenant plusieurs chaînes sont utiles pour construire des enregistrements qui dépassent la longueur maximale de 255 octets pour une chaîne de caractères dans un seul enregistrement TXT.

3.4 Record Size (Taille d'enregistrement)​

Les enregistrements SPF publiés pour un nom de domaine donné devraient être maintenus suffisamment petits pour que le résultat de requête pour celui-ci tienne dans 512 octets. Sinon, il est possible de dépasser les limites du protocole DNS. Cette limite UDP est définie dans [RFC1035] section 2.3.4, bien qu'elle ait été augmentée par [RFC2671]. Rester en dessous de 512 octets devrait empêcher les anciennes implémentations DNS de basculer vers TCP et permettre l'utilisation d'UDP sans support EDNS0 [RFC6891]. Comme la taille de réponse dépend de nombreuses choses en dehors de la portée de ce document, seuls les conseils suivants peuvent être donnés: si la taille du message DNS, la longueur combinée des noms DNS et du texte de tous les enregistrements d'un type donné est inférieure à 450 octets, alors la réponse DNS devrait tenir dans un paquet UDP. En raison des pare-feu et d'autres problèmes qui interfèrent avec le fonctionnement DNS sur TCP ou l'utilisation d'EDNS0, les enregistrements trop longs pour tenir dans un seul paquet UDP peuvent être silencieusement ignorés par les validateurs SPF.

Notez que lors du calcul de la taille de réponse pour une requête au format TXT, tous les autres enregistrements TXT publiés au nom de domaine doivent être pris en compte. De même, les tailles de réponse de toutes les requêtes liées à SPF doivent être évaluées pour tenir dans un seul paquet UDP de 512 octets (c'est-à-dire, taille de message DNS limitée à 450 octets).

3.5 Wildcard Records (Enregistrements génériques)​

L'utilisation d'enregistrements génériques pour la publication est découragée, et si elles sont utilisées, il faut faire preuve de prudence. Si une zone contient des enregistrements MX génériques, elle peut souhaiter publier une déclaration générique, mais doit être soumise aux mêmes exigences et problèmes. En particulier, la déclaration doit être répétée pour tout hôte avec des enregistrements RR quelconques et leurs sous-domaines. Considérez l'exemple de [RFC1034] section 4.3.3. Sur cette base, nous pouvons faire ce qui suit:

EXAMPLE.COM. MX 10 A.EXAMPLE.COM
EXAMPLE.COM. TXT "v=spf1 a:A.EXAMPLE.COM -all"

*.EXAMPLE.COM. MX 10 A.EXAMPLE.COM
*.EXAMPLE.COM. TXT "v=spf1 a:A.EXAMPLE.COM -all"

A.EXAMPLE.COM. A 203.0.113.1
A.EXAMPLE.COM. MX 10 A.EXAMPLE.COM
A.EXAMPLE.COM. TXT "v=spf1 a:A.EXAMPLE.COM -all"

*.A.EXAMPLE.COM. MX 10 A.EXAMPLE.COM
*.A.EXAMPLE.COM. TXT "v=spf1 a:A.EXAMPLE.COM -all"

Pour chaque nom dans la zone, l'enregistrement SPF doit être listé deux fois: une fois pour ce nom et une fois avec un générique pour couvrir l'arbre sous ce nom, afin de couvrir tous les domaines utilisés dans le courrier sortant.


4. The check_host() Function (La fonction check_host())​

Cette description n'est pas une définition d'interface de programmation d'application, mais une description de fonction pour illustrer l'algorithme. Les implémentations SPF conformes doivent produire des résultats sémantiquement équivalents à cette description.

La fonction check_host() récupère les enregistrements SPF, les analyse et les évalue pour déterminer si un hôte particulier est autorisé ou non autorisé à envoyer des courriers avec une identité donnée. L'ADMD de réception effectuant cette vérification doit évaluer correctement la fonction check_host() comme décrit ici.

Les implémentations peuvent utiliser un algorithme différent de l'algorithme canonique défini ici, tant que les résultats sont identiques dans tous les cas.

4.1 Arguments (Arguments)​

La fonction check_host() prend les arguments suivants:

<ip> - L'adresse IP du client SMTP qui envoie le courrier, soit IPv4 soit IPv6.

<domain> - Le domaine qui fournit les informations d'autorisation recherchées; initialement la partie domaine de l'identité "MAIL FROM" ou "HELO".

<sender> - L'identité "MAIL FROM" ou "HELO".

Pour les évaluations récursives, la partie domaine de <sender> peut différer de l'argument <domain> lors de la première évaluation de check_host(). Dans la plupart des autres cas, elle sera la même (voir section 5.2 ci-dessous). La limite de requête DNS globale pour les termes SPF décrite dans la section 4.6.4 doit être suivie comme une limite globale unique sur toutes les évaluations, pas seulement pour une instance d'évaluation récursive unique.

Notez que l'argument <domain> peut ne pas être un nom de domaine bien formé. Par exemple, si le chemin inverse est vide, le domaine EHLO/HELO et ses problèmes associés sont utilisés (voir section 2.3). Dans ces cas, check_host() est défini dans la section 4.3 pour retourner un résultat "none".

4.2 Results (Résultats)​

La fonction check_host() peut retourner l'un des plusieurs résultats décrits dans la section 2.6. L'action à entreprendre en fonction du résultat est déterminée par la politique locale du destinataire. Ceci est discuté dans la section 8.

4.3 Initial Processing (Traitement initial)​

Si <domain> est mal formaté (par exemple, longueur d'étiquette supérieure à 63 caractères, étiquettes de longueur nulle non terminales, etc.) ou n'est pas un nom de domaine multi-étiquettes, ou si la requête DNS retourne "Name Error" (RCODE 3, également connu sous le nom de "NXDOMAIN" [RFC2308]), check_host() retourne immédiatement le résultat "none". Les RCODE DNS sont définis dans [RFC1035]. Un domaine bien formé est un nom de domaine pleinement qualifié tel que défini dans [RFC1983]. C'est-à-dire que dans le DNS, ils sont implicitement qualifiés par rapport à la racine (voir section 3.1 de [RFC1034]). Les noms de domaine internationalisés doivent être encodés en A-label, comme décrit dans la section 2.3 de [RFC5890].

Si <sender> n'a pas de local-part, remplacez le local-part par la chaîne "postmaster".

4.4 Record Lookup (Recherche d'enregistrement)​

En fonction de la manière dont l'enregistrement est publié (voir section 3 ci-dessus), une requête DNS pour le nom <domain> est nécessaire, uniquement pour le type TXT.

Si la requête DNS retourne une défaillance du serveur (RCODE 2) ou une autre erreur (RCODE ni 0 ni 3), ou si la requête expire, check_host() se termine immédiatement avec le résultat "temperror".

4.5 Selecting Records (Sélection des enregistrements)​

Les enregistrements commencent par une partie version:

record = version terms *SP
version = "v=spf1"

En commençant par l'ensemble d'enregistrements retourné par la requête, supprimez les enregistrements qui ne commencent pas par une partie version de exactement "v=spf1". Notez que la partie version est terminée par un caractère SP ou la fin de l'enregistrement. Par exemple, un enregistrement avec une partie version "v=spf10" ne correspond pas et est supprimé.

Si l'ensemble d'enregistrements résultant ne contient aucun enregistrement, check_host() produit un résultat "none". Si l'ensemble d'enregistrements résultant contient plusieurs enregistrements, check_host() produit un résultat "permerror".

4.6 Record Evaluation (Évaluation de l'enregistrement)​

La fonction check_host() analyse et interprète l'enregistrement SPF pour trouver un résultat pour le test actuel. Tout d'abord, la syntaxe de l'enregistrement est validée, et si des erreurs de syntaxe sont présentes n'importe où dans l'enregistrement, check_host() retourne immédiatement le résultat "permerror" sans interprétation ou évaluation supplémentaire.

4.6.1 Term Evaluation (Évaluation des termes)​

Il existe deux types de termes: les mécanismes (définis dans la section 5) et les modificateurs (définis dans la section 6). Les enregistrements contiennent une liste ordonnée de ceux-ci, comme spécifié dans la notation de forme de Backus-Naur augmentée (ABNF) suivante.

terms = *( 1*SP ( directive / modifier ) )

directive = [ qualifier ] mechanism
qualifier = "+" / "-" / "?" / "~"
mechanism = ( all / include
/ a / mx / ptr / ip4 / ip6 / exists )
modifier = redirect / explanation / unknown-modifier
unknown-modifier = name "=" macro-string
; where name is not any known modifier

name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )

La plupart des mécanismes autorisent un caractère ":" ou "/" après le nom.

Les modificateurs contiennent toujours un caractère égal ('=') immédiatement après le nom et avant tout caractère ":" ou "/" qui pourrait faire partie d'un macro-string.

Un terme qui ne contient aucun des caractères "=", ":" ou "/" est un mécanisme, tel que défini dans la section 5.

Selon la notation ABNF telle que définie dans [RFC5234], les noms de mécanismes et de modificateurs ne sont pas sensibles à la casse.

4.6.2 Mechanisms (Mécanismes)​

Chaque mécanisme est considéré dans l'ordre de gauche à droite. S'il n'y a plus de mécanismes, le résultat est le résultat par défaut décrit dans la section 4.7.

Lorsqu'un mécanisme est évalué, trois choses peuvent se produire: il peut correspondre, ne pas correspondre ou retourner une exception.

S'il correspond, le traitement se termine et la valeur du qualificateur est retournée comme résultat pour cet enregistrement. S'il ne correspond pas, le traitement continue avec le mécanisme suivant. S'il retourne une exception, le traitement du mécanisme se termine et la valeur d'exception est retournée.

Les qualificateurs possibles et les résultats qu'ils provoquent pour check_host() sont les suivants:

"+" pass
"-" fail
"~" softfail
"?" neutral

Le qualificateur est optionnel et vaut par défaut "+".

Lorsque le mécanisme correspond et que le qualificateur est "-", un résultat "fail" est retourné et la chaîne d'explication est calculée comme décrit dans la section 6.2.

La section 5 décrit les mécanismes spécifiques.

4.6.3 Modifiers (Modificateurs)​

Les modificateurs ne sont pas des mécanismes. Ils ne retournent pas de correspondance ou de non-correspondance. Au lieu de cela, ils fournissent des informations supplémentaires. Bien que les modificateurs n'affectent pas directement l'évaluation de l'enregistrement, le modificateur "redirect" a un impact après l'évaluation de tous les mécanismes.

4.6.4 DNS Lookup Limits (Limites de recherche DNS)​

Certains mécanismes et modificateurs (collectivement appelés "termes") provoquent des requêtes DNS lors de l'évaluation, tandis que d'autres non. Les termes suivants provoquent des requêtes DNS: les mécanismes "include", "a", "mx", "ptr" et "exists", ainsi que le modificateur "redirect". Les implémentations SPF doivent limiter le nombre total de ces termes à 10 pendant une évaluation SPF, pour éviter une charge déraisonnable sur le DNS. Si cette limite est dépassée, l'implémentation doit retourner "permerror". Les autres termes -- les mécanismes "all", "ip4" et "ip6", ainsi que le modificateur "exp" -- ne provoquent pas de requêtes DNS lors de l'évaluation SPF (le modificateur "exp" ne provoque une requête qu'à un moment ultérieur), et leur utilisation n'est pas soumise à cette limite.

Lors de l'évaluation du mécanisme "mx", le nombre d'enregistrements de ressources "MX" interrogés est inclus dans la limite globale ci-dessus de 10 mécanismes/modificateurs provoquant des requêtes DNS. En plus de cette limite, l'évaluation de chaque enregistrement "MX" ne doit absolument pas entraîner l'interrogation de plus de 10 enregistrements d'adresses -- enregistrements de ressources "A" ou "AAAA". Si cette limite est dépassée, le mécanisme "mx" doit produire un résultat "permerror".

Lors de l'évaluation du mécanisme "ptr" ou de la macro %\{p}, le nombre d'enregistrements de ressources "PTR" interrogés est inclus dans la limite globale ci-dessus de 10 mécanismes/modificateurs provoquant des requêtes DNS. En plus de cette limite, l'évaluation de chaque enregistrement "PTR" ne doit absolument pas entraîner l'interrogation de plus de 10 enregistrements d'adresses -- enregistrements de ressources "A" ou "AAAA". Si cette limite est dépassée, tous les enregistrements sauf les 10 premiers doivent être ignorés.

La raison de la différence est que l'ensemble et le contenu des enregistrements MX sont sous le contrôle de l'ADMD de publication, tandis que l'ensemble et le contenu des enregistrements PTR sont sous le contrôle du propriétaire de l'adresse IP qui établit réellement la connexion.

Ces limites sont par mécanisme ou macro dans un enregistrement et s'ajoutent aux limites de requête spécifiées ci-dessus.

Un MTA ou un autre processeur devrait imposer une limite de temps écoulé maximum pour l'évaluation de check_host(). Une telle limite devrait permettre au moins 20 secondes. Si une telle limite est dépassée, le résultat d'autorisation devrait être "temperror".

Comme mentionné à la fin de la section 11.1, dans certains cas, il peut être utile de limiter le nombre de "termes" qui renvoient des requêtes DNS retournant une réponse positive (RCODE 0) avec un compte de réponses de 0, ou une réponse "Name Error" (RCODE 3). Celles-ci sont parfois collectivement appelées "void lookups". Les implémentations SPF devraient limiter les "void lookups" à deux. Les implémentations peuvent choisir de rendre une telle limite configurable. Dans ce cas, il est recommandé que la valeur par défaut soit deux. Le dépassement de la limite produit un résultat "permerror".

4.7 Default Result (Résultat par défaut)​

Si aucun des mécanismes ne correspond et qu'il n'y a pas de modificateur "redirect", check_host() retourne le résultat "neutral", comme si "?all" était spécifié comme dernière directive. Si un modificateur "redirect" est présent, check_host() continue comme défini dans la section 6.1.

Il est préférable d'utiliser un modificateur "redirect" ou un mécanisme "all" pour terminer explicitement le traitement. Bien qu'il y ait un "?all" implicite à la fin de chaque enregistrement qui ne se termine pas explicitement, cela aide les efforts de débogage lorsqu'il est fourni explicitement.

Exemple:

v=spf1 +mx -all

Ou

v=spf1 +mx redirect=_spf.example.com

4.8 Domain Specification (Spécification de domaine)​

Plusieurs de ces mécanismes et modificateurs ont une partie <domain-spec>. La chaîne est soumise à une expansion de macro (voir section 7). La chaîne résultante est la représentation habituelle d'un nom DNS pleinement qualifié: une séquence d'étiquettes séparées par des points. Ce domaine est appelé <target-name> dans le reste de ce document.

Note: Le résultat de l'expansion de macro n'est soumis à aucun échappement supplémentaire. Par conséquent, cet outil ne peut pas produire tous les caractères légaux dans les étiquettes DNS (par exemple, les caractères de contrôle). Cependant, cet outil est suffisamment puissant pour exprimer les noms d'hôtes légaux et les étiquettes utilitaires courantes utilisées dans le DNS (par exemple, "_spf").

Pour plusieurs mécanismes, <domain-spec> est optionnel. S'il n'est pas fourni, le <domain> des arguments check_host() (voir section 4.1) est utilisé comme <target-name>. "domain" et <target-name> sont syntaxiquement identiques après l'expansion des macros. "domain" est la valeur d'entrée pour check_host(), tandis que <target-name> est calculé par check_host().

L'évaluation de check_host() avec un domaine syntaxiquement invalide est indéfinie.

Note: Ce document et son prédécesseur ne contiennent aucune disposition pour la gestion correcte des <domain-spec> syntaxiquement invalides (éventuellement le résultat d'une expansion de macro) selon [RFC1035]. Des exemples incluent les noms avec des étiquettes vides comme "foo..example.com" et les étiquettes d'une longueur supérieure à 63 caractères. Certaines implémentations choisissent de traiter de telles erreurs comme une non-correspondance et ignorent donc ces noms, tandis que d'autres implémentations retournent une exception "permerror".


5. Mechanism Definitions (Définitions des mécanismes)​

Cette section définit deux types de mécanismes: les mécanismes de cadre de langage de base et les mécanismes spécifiant l'expéditeur.

Les mécanismes de base facilitent le cadre du langage. Ils ne spécifient pas un type particulier de schéma d'autorisation. Les mécanismes de base sont les suivants:

all
include

Les mécanismes spécifiant l'expéditeur sont utilisés pour identifier un ensemble d'adresses <ip> qui sont autorisées ou non autorisées à envoyer des messages avec <domain>. Les mécanismes spécifiant l'expéditeur sont les suivants:

a
mx
ptr (do not use)
ip4
ip6
exists

Les conventions suivantes s'appliquent à tous les mécanismes qui effectuent à tout moment une comparaison entre <target-name> et une adresse IP:

Si aucune longueur de préfixe CIDR n'est donnée dans la directive, <target-name> est comparé à l'adresse IP pour l'égalité. (Ici, CIDR est le routage inter-domaine sans classe, décrit dans [RFC4632].)

Si une longueur de préfixe CIDR est spécifiée, seul le nombre spécifié de bits de poids fort de <target-name> est comparé à l'adresse IP pour l'égalité.

Lorsqu'un mécanisme récupère des adresses d'hôte à comparer avec <ip>, les enregistrements "A" sont récupérés lorsque <ip> est IPv4, et les enregistrements "AAAA" sont récupérés lorsque <ip> est une adresse IPv6. Les implémentations SPF sur les serveurs IPv6 doivent gérer les enregistrements "AAAA" et "A" pour les clients sur des adresses IPv6 mappées IPv4 [RFC4291]. Les adresses IPv4 sont répertoriées uniquement dans l'enregistrement SPF avec le mécanisme "ip4".

Plusieurs mécanismes dépendent des informations récupérées du DNS. Pour ces requêtes DNS, sauf indication contraire, si le serveur DNS renvoie une erreur (RCODE ni 0 ni 3) ou si la requête expire, le mécanisme s'arrête et le check_host() de niveau supérieur renvoie "temperror". Si le serveur renvoie "Name Error" (RCODE 3), l'évaluation du mécanisme continue comme si le serveur renvoyait sans erreur (RCODE 0) et zéro enregistrement de réponse.

5.1 "all"​

all = "all"

Le mécanisme "all" est un test qui correspond toujours. Il est utilisé comme mécanisme le plus à droite dans l'enregistrement pour fournir une valeur par défaut explicite.

Exemple:

v=spf1 a mx -all

Les mécanismes après "all" ne sont jamais testés. Les mécanismes répertoriés après "all" doivent être ignorés. Lorsqu'un mécanisme "all" est présent dans l'enregistrement, tout modificateur "redirect" (Section 6.1) doit être ignoré, quel que soit l'ordre relatif des termes.

5.2 "include"​

include = "include" ":" domain-spec

Le mécanisme "include" déclenche une évaluation récursive de check_host().

  1. <domain-spec> est étendu selon la Section 7.

  2. check_host() est évalué avec la chaîne résultante comme <domain>. Les paramètres <ip> et <sender> restent les mêmes que dans l'évaluation actuelle de check_host().

  3. L'évaluation récursive renvoie une correspondance, une non-correspondance ou une erreur.

  4. Si elle renvoie une correspondance, le mécanisme "include" utilise le résultat approprié (par exemple, include ou +include produit un résultat "pass", -include produit "fail").

  5. Si elle renvoie une non-correspondance ou une erreur, le check_host() parent reprend le traitement selon le tableau suivant et restaure la valeur <domain> précédente.

Rétrospectivement, le nom "include" était un mauvais choix. Seul le résultat d'évaluation de l'enregistrement SPF référencé est utilisé, plutôt que d'inclure littéralement les mécanismes de l'enregistrement référencé dans le premier enregistrement. Par exemple, l'évaluation d'une directive "-all" dans l'enregistrement référencé ne termine pas le traitement global et n'entraîne pas nécessairement un "fail" global. (De meilleurs noms pour ce mécanisme auraient été "if-match", "on-match", etc.)

Le mécanisme "include" permet à un domaine de spécifier plusieurs domaines administrativement indépendants. Par exemple, le domaine de vanité "example.net" pourrait envoyer des messages en utilisant les serveurs des domaines administrativement indépendants example.com et example.org.

Example.net pourrait dire

IN TXT "v=spf1 include:example.com include:example.org -all"

Cela demanderait à check_host() de vérifier efficacement les enregistrements d'example.com et d'example.org pour un résultat "pass". Ce n'est que si l'hôte n'est autorisé par aucun de ces deux domaines que le résultat serait "fail".

Le fait que ce mécanisme corresponde, ne corresponde pas ou renvoie une exception dépend du résultat de l'évaluation récursive de check_host():

+---------------------------------+---------------------------------+
| A recursive check_host() result | Causes the "include" mechanism |
| of: | to: |
+---------------------------------+---------------------------------+
| pass | match |
| | |
| fail | not match |
| | |
| softfail | not match |
| | |
| neutral | not match |
| | |
| temperror | return temperror |
| | |
| permerror | return permerror |
| | |
| none | return permerror |
+---------------------------------+---------------------------------+

Le mécanisme "include" est destiné à franchir les frontières administratives. Lorsqu'il reste au sein d'une seule autorité administrative, "include" n'est généralement pas le meilleur choix. Par exemple, si example.com et example.org sont gérés par la même entité, et si l'ensemble des hôtes autorisés pour les deux domaines est "mx:example.com", alors example.org pourrait spécifier "include:example.com", mais il serait préférable de spécifier "redirect=example.com" ou même "mx:example.com".

Avec le mécanisme "include", il est possible d'autoriser un ensemble administrativement externe d'hôtes, mais la détermination de la politique de l'expéditeur reste une fonction de l'enregistrement SPF du domaine d'origine (déterminé par le mécanisme "all" dans cet enregistrement). Le modificateur "redirect" est plus approprié pour consolider l'autorisation et la politique en un ensemble commun à partager au sein d'un ADMD. Redirect ressemble plus à un élément de code commun à partager entre les enregistrements au sein d'un seul ADMD. Les hôtes autorisés et les politiques de n'importe quel nombre de domaines peuvent être contrôlés depuis un seul enregistrement.

5.3 "a"​

Ce mécanisme correspond lorsque <ip> est l'une des adresses IP de <target-name>. Pour clarifier, cela signifie que le mécanisme "a" correspond également aux enregistrements AAAA.

a = "a" [ ":" domain-spec ] [ dual-cidr-length ]

Une requête d'adresse est effectuée pour <target-name> en utilisant le type de requête (A ou AAAA) approprié pour le type de connexion (IPv4 ou IPv6). <ip> est comparé aux adresses renvoyées. Si une adresse correspond, le mécanisme correspond.

5.4 "mx"​

Ce mécanisme correspond lorsque <ip> est l'un des hôtes MX du nom de domaine.

mx = "mx" [ ":" domain-spec ] [ dual-cidr-length ]

check_host() effectue d'abord une requête MX pour <target-name>. Ensuite, il effectue une requête d'adresse pour chaque nom MX renvoyé. <ip> est comparé à chaque adresse IP renvoyée. Pour éviter les attaques par déni de service (DoS), les limites de traitement définies dans la Section 4.6.4 doivent être respectées. Si la limite de requête MX est dépassée, "permerror" est renvoyé et l'évaluation se termine. Si une adresse correspond, le mécanisme correspond.

Note sur les MX implicites: Si <target-name> n'a pas d'enregistrements MX, check_host() ne doit absolument pas appliquer la règle MX implicite de [RFC5321], c'est-à-dire interroger les enregistrements A ou AAAA pour le même nom.

5.5 "ptr" (do not use) ("ptr" (ne pas utiliser))​

Ce mécanisme teste si le mappage inverse DNS de <ip> existe et pointe correctement vers un nom de domaine dans un domaine particulier. Ce mécanisme ne devrait pas être publié. Voir les notes à la fin de cette section pour plus d'informations.

ptr = "ptr" [ ":" domain-spec ]

Le nom de <ip> est recherché à l'aide de la procédure suivante:

  • Effectuez un mappage inverse DNS pour <ip>: recherchez l'enregistrement PTR correspondant dans "in-addr.arpa.", si l'adresse est IPv4, ou dans "ip6.arpa.", si elle est IPv6.

  • Pour chaque enregistrement renvoyé, validez le nom de domaine en recherchant son adresse IP. Pour éviter les attaques DoS, les limites de traitement PTR définies dans la Section 4.6.4 doivent être appliquées. Si les limites sont dépassées, terminez le traitement et le mécanisme ne correspond pas.

  • Si <ip> est parmi les adresses IP renvoyées, ce nom de domaine est validé.

Vérifiez tous les noms de domaine validés pour voir s'ils correspondent à <target-name> ou sont des sous-domaines de <target-name>. S'il y a des correspondances, ce mécanisme correspond. Si aucun nom de domaine validé ne peut être trouvé, ou si aucun nom de domaine validé ne correspond ou n'est un sous-domaine de <target-name>, ce mécanisme ne peut pas correspondre. Si une erreur DNS se produit lors de l'exécution de la requête PTR RR, ce mécanisme ne peut pas correspondre. Si une erreur DNS se produit lors de l'exécution d'une requête A RR, ce nom de domaine est ignoré et la recherche continue.

Ce mécanisme correspond lorsque:

  • <target-name> est un sous-domaine du nom de domaine validé, ou

  • <target-name> et le nom de domaine validé sont identiques.

Par exemple, "mail.example.com" est dans le domaine "example.com", mais "mail.bad-example.com" ne l'est pas.

Note: Ce mécanisme est lent, pas aussi fiable que d'autres mécanismes en cas d'erreurs DNS, et impose une charge importante aux serveurs de noms .arpa. En cas d'utilisation, des enregistrements PTR appropriés doivent être configurés pour les hôtes du domaine, et le mécanisme "ptr" devrait être l'un des derniers mécanismes vérifiés. Après plusieurs années d'expérience de déploiement SPF, la conclusion a été tirée qu'il est inutile et que des alternatives plus fiables devraient être utilisées. Cependant, il reste une partie du protocole SPF, donc les implémentations check_host() conformes doivent le prendre en charge.

5.6 "ip4" and "ip6" ("ip4" et "ip6")​

Ces mécanismes testent si <ip> est contenu dans un réseau IP donné.

ip4 = "ip4" ":" ip4-network [ ip4-cidr-length ]
ip6 = "ip6" ":" ip6-network [ ip6-cidr-length ]

ip4-cidr-length = "/" ("0" / %x31-39 0*1DIGIT) ; value range 0-32
ip6-cidr-length = "/" ("0" / %x31-39 0*2DIGIT) ; value range 0-128
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]

ip4-network = qnum "." qnum "." qnum "." qnum
qnum = DIGIT ; 0-9
/ %x31-39 DIGIT ; 10-99
/ "1" 2DIGIT ; 100-199
/ "2" %x30-34 DIGIT ; 200-249
/ "25" %x30-35 ; 250-255
; as per conventional dotted-quad notation, e.g., 192.0.2.0

ip6-network = <as per [RFC5952], Section 4>
; e.g., 2001:db8::cd30

Comparez <ip> au réseau donné. Si les bits de poids fort de la longueur du préfixe CIDR correspondent, le mécanisme correspond.

Si ip4-cidr-length est omise, elle est traitée comme "/32". Si ip6-cidr-length est omise, elle est traitée comme "/128". Il n'est pas autorisé d'omettre des parties de l'adresse IP au lieu d'utiliser la notation CIDR. C'est-à-dire, utilisez 192.0.2.0/24 au lieu de 192.0.2.

5.7 "exists"​

Ce mécanisme est utilisé pour construire un nom de domaine arbitraire pour une requête d'enregistrement DNS A. Il permet des schémas complexes impliquant des parties arbitraires de l'enveloppe de message pour déterminer ce qui est autorisé.

exists = "exists" ":" domain-spec

<domain-spec> est étendu selon la Section 7. Le nom de domaine résultant est utilisé pour une requête DNS A RR (même si le type de connexion est IPv6). Si des enregistrements A sont renvoyés, ce mécanisme correspond.

Les domaines peuvent utiliser ce mécanisme pour spécifier des requêtes arbitrairement complexes. Par exemple, supposons qu'example.com publie l'enregistrement:

v=spf1 exists:%\{ir}.%\{l1r+-}._spf.%\{d} -all

<target-name> pourrait s'étendre à "1.2.0.192.someuser._spf.example.com". Cela permet de prendre des décisions granulaires au niveau de l'utilisateur et de l'adresse IP du client.


6. Modifier Definitions (Définitions des modificateurs)​

Les modificateurs sont des paires nom/valeur qui fournissent des informations supplémentaires. Les modificateurs ont toujours un "=" séparant le nom et la valeur.

Les modificateurs définis dans ce document ("redirect" et "exp") devraient apparaître à la fin de l'enregistrement, après tous les mécanismes, bien qu'ils puissent syntaxiquement apparaître n'importe où dans l'enregistrement. L'ordre de ces deux modificateurs n'a pas d'importance. Ces deux modificateurs ne doivent absolument pas apparaître plus d'une fois dans un enregistrement. S'ils le font, check_host() se termine avec un résultat "permerror".

Les modificateurs non reconnus doivent être ignorés, peu importe où ou combien de fois ils apparaissent. Cela permet aux implémentations conformes à ce document de gérer correctement les enregistrements avec des modificateurs définis dans d'autres spécifications.

6.1 redirect: Redirected Query (redirect: Requête redirigée)​

Le modificateur "redirect" est destiné à consolider l'autorisation et la politique en un ensemble commun à partager au sein d'un seul ADMD. Les hôtes autorisés et les politiques de n'importe quel nombre de domaines peuvent être contrôlés depuis un seul enregistrement.

redirect = "redirect" "=" domain-spec

Si tous les mécanismes ne correspondent pas et qu'un modificateur "redirect" est présent, le traitement se déroule comme suit:

La partie <domain-spec> de la partie redirect est étendue selon les règles de macro de la Section 7. Ensuite, check_host() est évalué avec la chaîne résultante comme <domain>. Les paramètres <ip> et <sender> restent les mêmes que dans l'évaluation actuelle de check_host().

Le résultat de cette nouvelle évaluation de check_host() est alors traité comme le résultat de l'évaluation actuelle, sauf que si aucun enregistrement SPF n'est trouvé ou si <target-name> est mal formaté, le résultat est "permerror" au lieu de "none".

Notez que le domaine de la nouvelle requête peut lui-même spécifier un traitement redirect.

Cet outil est destiné aux organisations qui souhaitent appliquer le même enregistrement à plusieurs domaines. Par exemple:

la.example.com. TXT "v=spf1 redirect=_spf.example.com"
ny.example.com. TXT "v=spf1 redirect=_spf.example.com"
sf.example.com. TXT "v=spf1 redirect=_spf.example.com"
_spf.example.com. TXT "v=spf1 mx:example.com -all"

Dans cet exemple, le courrier de l'un de ces trois domaines est décrit par le même enregistrement. Cela peut être un avantage administratif.

Note: En général, le domaine "A" ne peut pas utiliser de manière fiable une redirection vers un autre domaine "B" qui n'est pas sous le même contrôle administratif. Puisque <domain> reste inchangé, il n'y a aucune garantie que l'enregistrement au domaine "B" fonctionnera correctement pour les boîtes aux lettres du domaine "A", en particulier si le domaine "B" utilise des mécanismes qui impliquent le local-part. La directive "include" serait généralement plus appropriée.

Pour plus de clarté, tout modificateur "redirect" devrait apparaître comme dernier terme dans l'enregistrement. Si un mécanisme "all" est présent n'importe où dans l'enregistrement, tout modificateur "redirect" doit être ignoré.

6.2 exp: Explanation (exp: Explication)​

explanation = "exp" "=" domain-spec

Si check_host() aboutit à "fail" en raison d'un mécanisme correspondant (tel que "-all") et qu'un modificateur "exp" est présent, la chaîne d'explication renvoyée est calculée comme décrit ci-dessous. Si aucun modificateur "exp" n'est présent, soit une chaîne d'explication par défaut, soit une chaîne d'explication vide doit être renvoyée à l'application appelante.

<domain-spec> subit une expansion de macro (voir Section 7) et devient <target-name>. Le RRset DNS TXT pour <target-name> est récupéré.

S'il y a des erreurs de traitement DNS (n'importe quel RCODE différent de 0), ou si aucun enregistrement n'est renvoyé, ou si plus d'un enregistrement est renvoyé, ou s'il y a des erreurs de syntaxe dans la chaîne d'explication, continuez comme si aucun modificateur "exp" n'avait été donné.

Les chaînes de l'enregistrement TXT récupéré sont concaténées sans espaces puis traitées comme une explain-string, qui subit une expansion de macro. Ce résultat final est la chaîne d'explication. Les implémentations peuvent limiter la longueur de la chaîne d'explication résultante pour tenir compte d'autres contraintes de protocole et/ou de limites de traitement raisonnables. Puisque la chaîne d'explication est destinée à être utilisée dans les réponses SMTP, et que la Section 2.4 de [RFC5321] indique que les réponses sont [US-ASCII], la chaîne d'explication doit être limitée à [US-ASCII].

Le logiciel qui évalue check_host() peut utiliser cette chaîne pour communiquer des informations du domaine de publication sous forme de message court ou d'URL. Le logiciel devrait indiquer clairement que la chaîne d'explication provient d'un tiers. Par exemple, il pourrait préfixer l'explication avec la chaîne de macro "%\{o} explains: ", comme montré dans l'exemple de la Section 8.4.

Supposons qu'example.com ait cet enregistrement:

v=spf1 mx -all exp=explain._spf.%\{d}

Voici quelques exemples d'enregistrements TXT d'explication possibles à explain._spf.example.com:

"Mail from example.com should only be sent by its own servers."

-- un message simple et constant

"%\{i} is not one of %\{d}'s designated mail servers."

-- un message qui contient plus d'informations, y compris l'adresse IP qui a échoué à la vérification

"See http://%\{d}/why.html?s=%\{S}&i=%\{I}"

-- un exemple complexe utilisant les paramètres de check_host() pour construire une URL afin qu'une page Web avec des instructions détaillées et personnalisées puisse être générée

Note: Pendant la récursion dans un mécanisme "include", le modificateur "exp" de <target-name> ne doit absolument pas être utilisé. À l'inverse, lors de l'exécution d'un modificateur "redirect", le modificateur "exp" du domaine d'origine ne doit absolument pas être utilisé. Cela est dû au fait que "include" est destiné à franchir les frontières administratives, et l'explication à fournir devrait être celle de l'ADMD récepteur, tandis que "redirect" est destiné comme outil pour consolider les enregistrements de politique au sein d'un ADMD, et donc l'explication redirigée est celle qui devrait avoir la priorité.


7. Macros (Macros)​

Lors de l'évaluation des enregistrements de politique SPF, certaines séquences de caractères sont destinées à être remplacées par des paramètres du message ou de la connexion. Ces séquences de caractères sont appelées "macros".

7.1 Formal Specification (Spécification formelle)​

La description ABNF des macros est la suivante:

domain-spec = macro-string domain-end
domain-end = ( "." toplabel [ "." ] ) / macro-expand

explain-string = *( macro-string / SP )

macro-string = *( macro-expand / macro-literal )
macro-literal = %x21-24 / %x26-7E
; visible characters except "%"

macro-expand = ( "%\{" macro-letter transformers *delimiter "}" )
/ "%%" / "%_" / "%-"

macro-letter = "s" / "l" / "o" / "d" / "i" / "p" / "h" /
"c" / "r" / "t" / "v"

transformers = *DIGIT [ "r" ]
delimiter = "." / "-" / "+" / "," / "/" / "_" / "="

toplabel = ( *alphanum ALPHA *alphanum ) /
( 1*alphanum "-" *( alphanum / "-" ) alphanum )
; LDH rule plus additional TLD restrictions
; (see [RFC5890], Section 2.3.1)

alphanum = ALPHA / DIGIT

ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
DIGIT = %x30-39 ; 0-9

7.2 Macro Definitions (Définitions des macros)​

Les lettres de macro disponibles et leurs significations sont les suivantes:

  • s = <sender>
  • l = local-part de <sender>
  • o = domain de <sender>
  • d = <domain>
  • i = <ip>
  • p = le nom de domaine validé de <ip>
  • v = la chaîne in-addr.arpa pour les requêtes PTR, "in-addr" pour ip4, "ip6" pour ip6
  • h = domaine HELO/EHLO

7.3 Macro Processing Details (Détails du traitement des macros)​

Cette section détaille le processus d'expansion des macros.

La chaîne macro en cours d'expansion est décomposée en fragments qui commencent soit par le caractère "%", soit qui sont constitués de tous les autres caractères. Les fragments qui commencent par "%" sont appelés "expansions de macro". Tous les autres fragments sont appelés "littéraux de macro".

Chaque expansion de macro est remplacée (étendue) pour produire la chaîne résultat. Les étiquettes de nom DNS dans cette chaîne résultat sont séparées par des caractères ".", et chaque étiquette doit être constituée de la règle LDH (Lettre-Chiffre-Trait d'union): elle doit être entièrement composée de lettres ASCII minuscules, de chiffres ASCII et/ou de traits d'union. Les littéraux de macro sont repris tels quels dans le résultat. Aucun caractère n'est inséré entre les expansions de macro et les littéraux de macro.

Outre l'expansion, aucun échappement ou autre post-traitement n'est effectué sur la chaîne résultat; elle est utilisée telle quelle. Notez que cela signifie que les caractères ASCII NUL ne sont pas nécessaires et qu'aucun mécanisme n'est fourni pour produire de tels caractères dans la chaîne résultat.

Les lettres de macro sont étendues à leurs valeurs définies, comme décrit dans la Section 7.2, avec les transformations suivantes. La syntaxe de transformation est définie par le composant transformers.

r transformer:

La lettre "r" indique que la valeur doit être inversée avant l'expansion. Pour les adresses IPv6 et les noms de domaine, l'inversion est effectuée au niveau des délimiteurs de point. Pour les adresses IPv4, l'inversion est effectuée au niveau des limites de point.

DIGIT transformer:

Un ou plusieurs chiffres indiquent combien de parties séparées par des points doivent être extraites de la fin de la valeur. Si des chiffres sont présents, cela indique le nombre d'étiquettes à utiliser, à partir de la droite (valeur la plus significative).

Si aucun chiffre n'est spécifié, toutes les étiquettes sont utilisées. Le chiffre zéro indique qu'une chaîne vide doit être utilisée. La chaîne est tronquée après l'application des transformateurs.

Delimiters:

Un ou plusieurs délimiteurs indiquent quels caractères doivent être remplacés par le délimiteur "." après l'application d'autres transformateurs. Notez que les délimiteurs ne font pas naturellement partie de la valeur; ils sont appliqués lors de l'expansion de la macro. Voici les délimiteurs et leurs expansions:

  • %\{s} = <sender>
  • %\{o} = partie domaine de <sender>
  • %\{d} = <domain>
  • %\{d4} = les quatre dernières étiquettes de <domain>
  • %\{d4r} = les quatre dernières étiquettes de <domain>, inversées
  • %\{l} = local-part de <sender>
  • %\{l-} = local-part, "." remplacé par "-"
  • %\{lr} = local-part, inversé
  • %\{lr-} = local-part, inversé, "." remplacé par "-"
  • %\{l1r-} = la première partie de local-part, inversée, "." remplacé par "-"

7.4 Expansion Examples (Exemples d'expansion)​

Voici quelques exemples d'expansion de macros. Supposons:

<sender> = [email protected]
<domain> = email.example.com
<ip> = 192.0.2.3

Exemples d'expansion de macros:

MacroRésultat d'expansion
%\{s}[email protected]
%\{o}email.example.com
%\{d}email.example.com
%\{d4}email.example.com
%\{d3}email.example.com
%\{d2}example.com
%\{d1}com
%\{dr}com.example.email
%\{d2r}example.email
%\{l}strong-bad
%\{l-}strong-bad
%\{lr}strong-bad
%\{lr-}strong-bad
%\{l1r-}strong-bad
%\{ir}.%\{v}._spf.%\{d2}3.2.0.192.in-addr._spf.example.com
%\{lr-}.lp._spf.%\{d2}strong-bad.lp._spf.example.com
%\{lr-}.lp.%\{ir}.%\{v}._spf.%\{d2}strong-bad.lp.3.2.0.192.in-addr._spf.example.com
%\{ir}.%\{v}.%\{l1r-}.lp._spf.%\{d2}3.2.0.192.in-addr.strong-bad.lp._spf.example.com
%\{d2}.trusted-domains.example.netexample.com.trusted-domains.example.net

8. Result Handling (Gestion des résultats)​

Cette section discute de la manière dont les implémentations SPF devraient traiter les différents résultats possibles de check_host(). Elle est uniquement consultative, car les politiques locales du site peuvent décider de prendre des mesures différentes pour des résultats particuliers.

8.1 None​

Le retour de "none" signifie qu'aucune politique d'expéditeur applicable n'a été trouvée correspondant au domaine interrogé. Ce résultat devrait être traité comme équivalent à "SPF n'existe pas"; c'est-à-dire qu'il n'y a pas de politique à évaluer.

Les MTA récepteurs ne devraient pas rejeter les e-mails sur la base de ce résultat. Bien que l'échec de la vérification SPF puisse entraîner un rejet, le résultat "none" ne devrait pas servir de base au rejet car il ne fournit aucune information sur l'autorisation de l'expéditeur.

8.2 Neutral​

Le retour de "neutral" signifie que le propriétaire du domaine a explicitement déclaré qu'il n'affirme pas si l'hôte émetteur est autorisé ou non. Ce résultat devrait être traité comme équivalent au résultat "none"; la vérification SPF ne peut ni confirmer ni nier l'autorisation de l'hôte.

Les MTA récepteurs ne devraient pas rejeter les e-mails sur la base de ce résultat.

8.3 Pass​

Le retour de "pass" signifie que le client a réussi le test de politique d'expéditeur. Le MTA récepteur peut continuer avec d'autres tests anti-spam.

Les MTA récepteurs ne devraient définitivement pas rejeter les e-mails sur la base de ce résultat.

8.4 Fail​

Le retour de "fail" signifie que le client n'a pas réussi le test de politique d'expéditeur. Le MTA récepteur peut rejeter l'e-mail.

Si l'ADMD publiant choisit de retourner une chaîne d'explication (en utilisant le modificateur "exp"), cette chaîne devrait être retournée dans le cadre de la réponse SMTP. Si aucune chaîne d'explication n'est fournie, le MTA récepteur devrait utiliser une explication générique.

Il est recommandé d'inclure des informations sur le domaine publiant ainsi que des informations de contact pour ce domaine (si disponibles) dans la réponse SMTP retournée à l'expéditeur. Cela aide au débogage et peut éventuellement aider à éviter que des e-mails légitimes ne soient bloqués.

Exemple de réponse SMTP:

550-5.7.1 SPF MAIL FROM check failed:
550-5.7.1 The domain example.com explains:
550 5.7.1 Please see http://www.example.com/mailpolicy.html

8.5 Softfail​

Le retour de "softfail" signifie que l'hôte pourrait ne pas être autorisé à envoyer des e-mails, mais la transition n'est pas encore terminée.

Les MTA récepteurs ne devraient pas rejeter les e-mails sur la base de ce résultat, mais peuvent les marquer comme suspects d'une manière ou d'une autre. Par exemple, le MTA récepteur peut placer l'e-mail dans un dossier de spam ou ajouter un en-tête.

8.6 Temperror​

Le retour de "temperror" signifie qu'une erreur temporaire s'est produite pendant l'évaluation SPF. Le MTA récepteur devrait accepter l'e-mail mais peut souhaiter réessayer la vérification SPF plus tard.

Par exemple, si le serveur DNS est temporairement indisponible, le destinataire peut souhaiter accepter l'e-mail et réévaluer la politique SPF à un moment ultérieur.

8.7 Permerror​

Le retour de "permerror" signifie qu'une erreur permanente s'est produite pendant l'évaluation SPF. Cela peut être dû à une erreur de syntaxe dans l'enregistrement SPF du domaine ou à d'autres problèmes de configuration.

Le MTA récepteur peut rejeter l'e-mail, mais devrait également enregistrer des informations sur l'erreur pour aider à diagnostiquer le problème.


9. Recording the Result (Enregistrement du résultat)​

Après qu'une vérification SPF a été effectuée, le serveur de réception doit enregistrer le résultat pour le traitement et l'analyse ultérieurs.


9.1 The Received-SPF Header Field (Le champ d'en-tête Received-SPF)​

Le serveur de réception DEVRAIT enregistrer le résultat de la vérification SPF dans un champ d'en-tête Received-SPF. Ce champ est ajouté au message électronique et fournit un enregistrement permanent de l'évaluation SPF.

Syntax (Syntaxe)​

Received-SPF: result
[comment]
receiver=receiving-domain;
identity=identity;
envelope-from=<sender>;
helo=helo-identity;
client-ip=client-ip-address;
[receiver-policy-explanation]

Field Components (Composants du champ)​

  • result: Le résultat de la vérification SPF (None, Neutral, Pass, Fail, SoftFail, TempError, PermError)
  • receiver: Le nom d'hôte du serveur de messagerie récepteur
  • identity: Quelle identité a été vérifiée (mailfrom, helo)
  • envelope-from: L'adresse MAIL FROM
  • helo: L'identité HELO/EHLO
  • client-ip: L'adresse IP du client

Example (Exemple)​

Received-SPF: pass (example.com: domain of [email protected]
designates 192.0.2.1 as permitted sender)
receiver=mail.example.com;
identity=mailfrom;
[email protected];
helo=mail.example.com;
client-ip=192.0.2.1

9.2 SPF Results in Authentication-Results (Résultats SPF dans Authentication-Results)​

Le destinataire PEUT également utiliser le champ d'en-tête Authentication-Results (défini dans RFC 7001) pour enregistrer les résultats SPF aux côtés d'autres méthodes d'authentification de messagerie comme DKIM et DMARC.

Example (Exemple)​

Authentication-Results: mail.example.com;
spf=pass [email protected]

9.3 Local Policy Storage (Stockage de politique locale)​

Les serveurs de réception PEUVENT stocker les résultats SPF pour une utilisation interne dans des journaux, des bases de données ou des systèmes de réputation. Ces enregistrements peuvent être utilisés pour:

  • Filtrage du spam: Utilisation des résultats SPF comme signal pour l'évaluation du spam
  • Rapports: Génération de statistiques et de tendances SPF
  • Réputation: Construction de la réputation de l'expéditeur basée sur la conformité SPF
  • Médico-légal: Analyse de l'abus de messagerie et des tentatives de phishing

9.4 Downstream Processing (Traitement en aval)​

Les résultats SPF doivent être préservés tout au long du chemin de transmission de messagerie. Si un serveur de réception transfère un message à un autre serveur, le champ d'en-tête Received-SPF original doit être conservé afin que les systèmes en aval puissent voir le résultat de la vérification SPF d'origine.


10. Effects on Infrastructure (Effets sur l'infrastructure)​

La mise en œuvre de SPF peut avoir divers impacts sur l'infrastructure de messagerie et DNS. Les administrateurs doivent être conscients de ces impacts potentiels.


10.1 DNS Server Load (Charge du serveur DNS)​

Les vérifications SPF nécessitent des requêtes DNS supplémentaires, ce qui peut augmenter la charge sur les serveurs DNS. Pour chaque message électronique entrant, le destinataire doit:

  • Interroger l'enregistrement SPF du domaine expéditeur
  • Effectuer des recherches DNS supplémentaires pour les mécanismes (A, MX, PTR, EXISTS, INCLUDE)
  • Effectuer des requêtes récursives pour les mécanismes include:

Mitigation (Atténuation)​

  • Mise en cache DNS: Utilisation appropriée des valeurs TTL pour minimiser les requêtes redondantes
  • Limites de recherche: SPF limite le nombre de recherches DNS à 10 pour éviter une charge excessive
  • Conception efficace des enregistrements SPF: Minimisation du nombre de mécanismes et d'includes

10.2 Large Volume Mailing (Envoi de gros volumes)​

Les organisations qui envoient de grands volumes de messages électroniques doivent s'assurer que leurs enregistrements SPF:

  • Couvrent toutes les adresses IP d'envoi autorisées: Inclusion de tous les serveurs de messagerie légitimes, tiers et services cloud
  • Sont correctement structurés: Éviter PermError ou trop de recherches DNS
  • Sont régulièrement mis à jour: Lorsque l'infrastructure d'envoi change

Third-Party Senders (Expéditeurs tiers)​

Les organisations utilisant des services de messagerie tiers (par exemple, plates-formes marketing, services cloud) doivent autoriser ces services dans leurs enregistrements SPF:

v=spf1 include:_spf.example.com include:_spf.thirdparty.com -all

10.3 Email Forwarding (Transfert de courrier électronique)​

SPF peut causer des problèmes avec les scénarios de transfert de courrier électronique:

Problème: Lorsqu'un destinataire transfère un message électronique à un autre destinataire, l'adresse IP d'envoi change (maintenant le serveur de transfert), mais l'adresse MAIL FROM reste l'originale. Cela entraîne des échecs SPF.

Solutions (Solutions)​

  • SRS (Sender Rewriting Scheme): Réécriture de l'adresse MAIL FROM pendant le transfert
  • SPF Neutral ou SoftFail: Utilisation de ~all au lieu de -all pour réduire l'impact
  • Intégration DMARC: Utilisation de DMARC avec DKIM pour gérer les scénarios de transfert

10.4 Mailing Lists (Listes de diffusion)​

Les listes de diffusion sont confrontées à des défis similaires au transfert de courrier électronique:

  • Le serveur de liste de diffusion transfère des messages d'un expéditeur d'origine à de nombreux abonnés
  • L'adresse MAIL FROM reste souvent celle de l'expéditeur d'origine, mais l'IP d'envoi est le serveur de liste de diffusion

Best Practices (Meilleures pratiques)​

  • Réécriture MAIL FROM: Le logiciel de liste de diffusion devrait réécrire l'adresse MAIL FROM vers le domaine de la liste de diffusion
  • Signature DKIM: Les listes de diffusion devraient ajouter leurs propres signatures DKIM
  • En-tête List-ID: Utilisation de List-ID et d'autres en-têtes pour identifier l'origine de la liste de diffusion

10.5 IPv6 Considerations (Considérations IPv6)​

SPF prend en charge à la fois IPv4 et IPv6. Les administrateurs devraient:

  • Inclure des mécanismes ip6: Si l'infrastructure d'envoi prend en charge IPv6
v=spf1 ip4:192.0.2.0/24 ip6:2001:db8::/32 -all
  • Maintenir des entrées doubles: S'assurer que les plages IPv4 et IPv6 sont couvertes
  • Enregistrements DNS AAAA: S'assurer que les mécanismes A et MX résolvent correctement les adresses IPv6

10.6 Subdomain Policies (Politiques de sous-domaines)​

Par défaut, les sous-domaines n'héritent pas des enregistrements SPF de leur domaine parent. Chaque sous-domaine envoyant des messages électroniques a besoin de son propre enregistrement SPF, ou le domaine parent devrait publier un enregistrement générique:

*.example.com. IN TXT "v=spf1 -all"

Cela empêche les attaquants d'utiliser des sous-domaines inexistants pour l'usurpation d'identité.


11. Security Considerations (Considérations de sécurité)​

SPF fournit des améliorations de sécurité importantes pour le courrier électronique, mais présente également certaines limitations et risques de sécurité potentiels.


11.1 Security Strengths (Forces en matière de sécurité)​

SPF offre les avantages de sécurité suivants:

Email Source Authentication (Authentification de la source de courrier électronique)​

SPF permet aux destinataires de vérifier qu'un message électronique provient d'un serveur de messagerie autorisé pour un domaine donné. Cela réduit:

  • Usurpation de domaine: Empêche les attaquants de prétendre envoyer depuis des domaines légitimes
  • Phishing: Rend plus difficile pour les attaquants de créer des messages électroniques qui semblent provenir de sources fiables
  • Spam: Aide à identifier les messages électroniques indésirables provenant d'expéditeurs non autorisés

Lightweight and Scalable (Léger et évolutif)​

SPF utilise l'infrastructure DNS existante, ce qui facilite le déploiement et la maintenance sans nécessiter de nouveaux protocoles ou serveurs.


11.2 Security Limitations (Limitations de sécurité)​

SPF présente des limitations importantes que les administrateurs doivent comprendre:

Does Not Authenticate Message Content (N'authentifie pas le contenu du message)​

SPF valide uniquement l'identité MAIL FROM (Envelope From), pas l'en-tête From que les utilisateurs finaux voient. Les attaquants peuvent toujours:

  • Falsifier l'en-tête From et utiliser un domaine différent dans le champ From visible
  • Contourner SPF en utilisant leur propre domaine avec un enregistrement SPF valide

Solution: Utilisez DMARC avec SPF pour appliquer l'alignement de l'en-tête From.

Does Not Protect Message Integrity (Ne protège pas l'intégrité du message)​

SPF ne fournit pas de signatures cryptographiques ou de vérifications d'intégrité pour le contenu du courrier électronique. Les attaquants peuvent modifier le contenu du message pendant le transit.

Solution: Utilisez DKIM pour la signature cryptographique du message et la protection de l'intégrité.

Forwarding Issues (Problèmes de transfert)​

Comme discuté dans la section 10.3, SPF échoue avec le transfert de courrier électronique et les scénarios de liste de diffusion, car l'IP d'envoi change mais l'identité MAIL FROM reste la même.

Solution: Utilisez SRS (Sender Rewriting Scheme) ou la gestion de politique DMARC.


11.3 DNS Security (Sécurité DNS)​

SPF repose sur DNS, qui peut être vulnérable à diverses attaques:

DNS Spoofing and Cache Poisoning (Usurpation DNS et empoisonnement du cache)​

Les attaquants peuvent tenter de manipuler les réponses DNS pour contourner ou tromper les vérifications SPF.

Atténuation: Utilisez DNSSEC pour l'authentification cryptographique des réponses DNS.

DNS Lookup Amplification (Amplification des recherches DNS)​

Les enregistrements SPF peuvent être conçus pour provoquer des recherches DNS excessives, conduisant à des attaques par déni de service (DoS).

Atténuation: SPF impose une limite de 10 recherches DNS par vérification. Les implémentations doivent appliquer cette limite et abandonner avec PermError si elle est dépassée.


11.4 Privacy Considerations (Considérations de confidentialité)​

Les vérifications SPF nécessitent des requêtes DNS qui révèlent l'adresse IP de l'expéditeur:

  • Les administrateurs de domaine peuvent enregistrer les requêtes DNS et recueillir des informations sur les IP d'envoi
  • Les FAI et les résolveurs DNS peuvent surveiller le trafic de requêtes SPF

Ce ne sont généralement pas de graves problèmes de confidentialité, mais les administrateurs doivent en être conscients.


11.5 DoS Attacks (Attaques DoS)​

Les vérifications SPF nécessitent des recherches DNS, qui peuvent être exploitées pour des attaques DoS:

Excessive DNS Queries (Requêtes DNS excessives)​

Les attaquants peuvent envoyer des messages électroniques avec des enregistrements SPF complexes qui déclenchent de nombreuses recherches DNS, surchargeant les serveurs DNS du destinataire.

Atténuation: Appliquez la limite de 10 recherches et abandonnez le traitement avec PermError.

DNS Reflection Attacks (Attaques par réflexion DNS)​

Les attaquants peuvent abuser du traitement SPF pour amplifier les attaques par réflexion DNS.

Atténuation: Implémentez la limitation de débit et la surveillance des requêtes DNS.


11.6 Best Practices for Secure SPF Deployment (Meilleures pratiques pour un déploiement SPF sécurisé)​

Pour maximiser la sécurité des déploiements SPF:

  1. Use SPF with DKIM and DMARC (Utilisez SPF avec DKIM et DMARC): Combinez SPF avec DKIM pour la signature de message et DMARC pour l'application de politique.

  2. Deploy DNSSEC (Déployez DNSSEC): Sécurisez les réponses DNS avec DNSSEC pour prévenir l'usurpation DNS.

  3. Use Hard Fail Cautiously (Utilisez Hard Fail avec prudence): Commencez par ~all (SoftFail) pour les tests avant de passer à -all (Fail).

  4. Monitor and Maintain SPF Records (Surveillez et maintenez les enregistrements SPF): Mettez à jour régulièrement les enregistrements SPF lorsque l'infrastructure de messagerie change.

  5. Limit DNS Lookups (Limitez les recherches DNS): Gardez les enregistrements SPF simples et évitez les mécanismes include: et redirect: excessifs.

  6. Implement Logging and Monitoring (Implémentez la journalisation et la surveillance): Suivez les résultats de vérification SPF et enquêtez sur les anomalies.

  7. Educate Users (Éduquez les utilisateurs): Informez les utilisateurs sur le phishing et les limites de SPF dans la validation de l'en-tête From.


Appendix A. Extended Examples (Exemples étendus)​

Cet annexe fournit des exemples étendus d'enregistrements SPF, démontrant divers scénarios de configuration et meilleures pratiques.

A.1 Simple Examples (Exemples simples)​

A.1.1 Autoriser uniquement une seule adresse IP​

example.com. IN TXT "v=spf1 ip4:192.0.2.1 -all"

Explication: Seule l'adresse IP 192.0.2.1 est autorisée à envoyer des e-mails au nom d'example.com. Toutes les autres adresses IP entraîneront un résultat "fail".

A.1.2 Utilisation des enregistrements MX​

example.com. IN TXT "v=spf1 mx -all"

Explication: Autorise les serveurs de messagerie répertoriés dans les enregistrements MX d'example.com à envoyer des e-mails. Il s'agit d'une configuration courante car elle s'adapte automatiquement aux modifications des enregistrements MX.

A.1.3 Utilisation des enregistrements A​

example.com. IN TXT "v=spf1 a -all"

Explication: Autorise les adresses IP dans l'enregistrement A (ou AAAA pour IPv6) d'example.com à envoyer des e-mails.

A.1.4 Combinaison de plusieurs mécanismes​

example.com. IN TXT "v=spf1 mx a:mail.example.com ip4:192.0.2.0/24 -all"

Explication: Autorise les e-mails des sources suivantes:

  • Serveurs MX d'example.com
  • Enregistrement A de mail.example.com
  • N'importe quelle IP dans le réseau 192.0.2.0/24

A.1.5 Politique de soft-fail​

example.com. IN TXT "v=spf1 mx a ~all"

Explication: Utilise soft-fail (~all) au lieu de hard-fail (-all). Ceci est utile pendant la phase de test ou de migration. Les destinataires peuvent accepter les e-mails mais les marquer comme suspects.

A.2 Multiple Domain Example (Exemple multi-domaines)​

Pour les organisations avec plusieurs domaines utilisant la même infrastructure de messagerie:

example.com.     IN TXT "v=spf1 mx -all"
example.org. IN TXT "v=spf1 redirect=_spf.example.com"
example.net. IN TXT "v=spf1 redirect=_spf.example.com"
_spf.example.com. IN TXT "v=spf1 mx:example.com -all"

Explication:

  • example.com a son propre enregistrement SPF
  • example.org et example.net redirigent vers l'enregistrement SPF partagé
  • _spf.example.com contient la politique réelle

Avantages:

  • Gestion centralisée de la configuration des serveurs de messagerie
  • Une mise à jour unique affecte plusieurs domaines
  • Maintenance DNS réduite

A.3 DNS Blacklist (DNSBL) Style Example (Exemple de style liste noire DNS)​

Utilisation du mécanisme exists pour implémenter une fonctionnalité de type DNSBL:

example.com. IN TXT "v=spf1 exists:%\{ir}.%\{l1r+-}._spf.%\{d} -all"

Explication:

  • %\{ir}: Adresse IP inversée (par exemple, 192.0.2.1 devient 1.2.0.192)
  • %\{l1r+-}: Première partie du local-part de l'expéditeur, inversée, "." et "+" remplacés par "-"
  • %\{d}: Nom de domaine

Exemple d'expansion:

Si l'expéditeur est [email protected] envoyant depuis 192.0.2.1:

  • La macro s'étend à: 1.2.0.192.user._spf.example.com

Ensuite, ce nom de domaine est interrogé pour les enregistrements A. S'il existe, la vérification SPF réussit.

Cas d'usage:

  • Contrôle granulaire par utilisateur
  • Intégration avec base de données ou systèmes personnalisés
  • Décisions d'autorisation dynamiques

A.4 Multiple Requirements Example (Exemple d'exigences multiples)​

Configuration complexe combinant plusieurs mécanismes et modificateurs:

example.com. IN TXT "v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.0/24 include:_spf-servers.example.com include:_spf.google.com a:outbound.example.com mx ~all"

Explication:

  • ip4:192.0.2.0/24: Réseau de serveurs de messagerie internes
  • ip4:198.51.100.0/24: Réseau du centre de données de secours
  • include:_spf-servers.example.com: Inclure liste de serveurs supplémentaires
  • include:_spf.google.com: Utiliser Google Workspace
  • a:outbound.example.com: Serveur sortant spécifique
  • mx: Inclure les serveurs des enregistrements MX
  • ~all: Soft-fail pour tous les autres cas

Conception hiérarchique:

_spf-servers.example.com. IN TXT "v=spf1 ip4:203.0.113.0/24 ip4:198.51.100.128/25 -all"

Cela permet de diviser les grands enregistrements SPF en parties plus gérables.

A.5 Exemples de configuration de sous-domaines​

A.5.1 Sous-domaines avec des politiques différentes​

example.com.       IN TXT "v=spf1 mx -all"
mail.example.com. IN TXT "v=spf1 a -all"
shop.example.com. IN TXT "v=spf1 include:shopify.com -all"

Explication:

  • Le domaine principal utilise les enregistrements MX
  • Le sous-domaine mail utilise uniquement son enregistrement A
  • Le sous-domaine shop utilise un service tiers (Shopify)

A.5.2 Sous-domaines ne pouvant pas envoyer d'e-mails​

noreply.example.com. IN TXT "v=spf1 -all"
static.example.com. IN TXT "v=spf1 -all"

Explication: Déclare explicitement que ces sous-domaines ne peuvent pas envoyer d'e-mails, pour prévenir l'usurpation.

A.6 Exemples d'intégration de services tiers​

A.6.1 Utilisation de plusieurs fournisseurs de services de messagerie​

example.com. IN TXT "v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:sendgrid.net -all"

Explication:

  • Google Workspace pour les e-mails des employés
  • Microsoft 365 pour les partenaires
  • SendGrid pour les e-mails marketing

A.6.2 Vérification des limites de requêtes DNS​

L'exemple ci-dessus utilise 3 include, chacun pouvant déclencher des requêtes supplémentaires. Il faut s'assurer que le nombre total de requêtes ne dépasse pas 10.

Méthode de vérification:

# Vérifier le SPF de Google
dig _spf.google.com TXT

# Vérifier le SPF de Microsoft
dig spf.protection.outlook.com TXT

# Vérifier le SPF de SendGrid
dig sendgrid.net TXT

Calculer le nombre de mécanismes dans chaque include, en s'assurant que le total ≤ 10.

A.7 Exemples de mauvaise configuration (à éviter)​

A.7.1 ❌ Plusieurs enregistrements SPF (erreur)​

example.com. IN TXT "v=spf1 mx -all"
example.com. IN TXT "v=spf1 a -all"

Problème: Cela entraînera "permerror". Un domaine ne peut avoir qu'un seul enregistrement SPF.

Méthode correcte:

example.com. IN TXT "v=spf1 mx a -all"

A.7.2 ❌ -all manquant (non sécurisé)​

example.com. IN TXT "v=spf1 mx"

Problème: Pas de politique par défaut explicite, équivaut à ?all (neutre), aucune IP n'échouera.

Méthode correcte:

example.com. IN TXT "v=spf1 mx -all"

A.7.3 ❌ Dépassement de la limite de requêtes DNS​

example.com. IN TXT "v=spf1 include:a include:b include:c include:d include:e include:f include:g include:h include:i include:j include:k -all"

Problème: 11 include dépassent la limite de 10 requêtes, entraînant "permerror".

Solution: Utiliser l'aplatissement SPF ou utiliser directement les mécanismes ip4.

A.8 Exemple de configuration IPv6​

example.com. IN TXT "v=spf1 ip6:2001:db8::/32 ip4:192.0.2.0/24 mx -all"

Explication: Prend en charge les réseaux IPv6 et IPv4.

A.9 Exemple de chaîne d'explication​

example.com.         IN TXT "v=spf1 mx -all exp=explain._spf.%\{d}"
explain._spf.example.com. IN TXT "E-mail de %\{i}, mais cette IP n'est pas autorisée par %\{d}. Veuillez contacter postmaster@%\{d}."

Explication: Lorsque la vérification SPF échoue, le destinataire peut interroger la chaîne d'explication et l'afficher à l'utilisateur.

Après expansion de macro (supposons envoyé depuis 192.0.2.99):

"E-mail de 192.0.2.99, mais cette IP n'est pas autorisée par example.com. Veuillez contacter [email protected]."

A.10 Stratégie de test et de transition​

Phase 1: Mode surveillance (2-4 semaines)​

example.com. IN TXT "v=spf1 ?all"

Phase 2: Enregistrer les sources d'envoi réelles (2-4 semaines)​

example.com. IN TXT "v=spf1 ip4:192.0.2.0/24 include:provider.com ?all"

Phase 3: Soft-fail (4-8 semaines)​

example.com. IN TXT "v=spf1 ip4:192.0.2.0/24 include:provider.com ~all"

Phase 4: Mode strict (environnement de production)​

example.com. IN TXT "v=spf1 ip4:192.0.2.0/24 include:provider.com -all"

Recommandation: Surveiller les résultats des vérifications SPF à chaque phase pour s'assurer qu'aucun e-mail légitime n'est bloqué.


Appendix B. Changes in Implementation Requirements from RFC 4408 (Changements des exigences de mise en œuvre par rapport à RFC 4408)​

Cette annexe résume les principaux changements de RFC 7208 par rapport à son prédécesseur RFC 4408.

B.1 Changements majeurs​

B.1.1 Type RR SPF obsolète​

Exigence RFC 4408:

  • Publication simultanée d'enregistrements TXT et SPF (type 99)
  • Les implémentations doivent vérifier les deux types d'enregistrements

Changement RFC 7208:

  • Utiliser uniquement les enregistrements TXT (type 16)
  • Le type RR SPF n'est plus supporté
  • Implémentation et déploiement simplifiés

Raison: Taux d'adoption très faible du type RR SPF, système à double type causant des problèmes d'interopérabilité.

B.1.2 Clarification des limites de requêtes DNS​

RFC 4408:

  • Limite de requêtes DNS insuffisamment claire
  • Limite "void lookup" non définie

RFC 7208:

  • Définition claire de la limite de 10 requêtes DNS
  • Ajout de la limite "void lookup" (recommandé 2)
  • Description détaillée des limites supplémentaires pour les mécanismes MX et PTR

Limites spécifiques:

- Total requêtes DNS: ≤ 10 (include, a, mx, ptr, exists, redirect)
- Par mécanisme mx: ≤ 10 requêtes d'adresse
- Par mécanisme ptr: ≤ 10 requêtes d'adresse
- Void lookups: ≤ 2 (recommandé)
- Temps d'évaluation: ≥ 20 secondes (recommandé)

B.1.3 Traitement du "local-part"​

RFC 4408:

  • Traitement du local-part insuffisamment clair
  • Traitement du local-part vide non défini

RFC 7208:

  • Spécification claire: si <sender> n'a pas de local-part, utiliser "postmaster"
  • Amélioration du traitement du chemin inverse vide (<>)

Exemple:

MAIL FROM:<>
→ SPF utilise l'identité HELO, local-part est "postmaster"

B.1.4 Opposition forte au mécanisme "ptr"​

RFC 4408:

  • Mécanisme "ptr" autorisé mais non recommandé

RFC 7208:

  • Marqué clairement comme "do not use" (ne pas utiliser)
  • Avertissement ajouté dans le nom du mécanisme
  • Accent sur les problèmes de performance et de fiabilité

Raisons:

  • Requêtes DNS inverses lentes
  • Dépend de la configuration de tiers (propriétaire d'adresse IP)
  • Charge sur les serveurs de noms .arpa

B.1.5 Correction de la syntaxe des macros​

RFC 4408:

  • Définition de syntaxe de macro ambiguë

RFC 7208:

  • Définition ABNF améliorée
  • Clarification des règles d'expansion des macros
  • Correction des cas limites

B.1.6 Considérations de sécurité pour le modificateur "exp"​

RFC 4408:

  • Considérations de sécurité insuffisamment détaillées

RFC 7208:

  • Ajout d'avertissements de sécurité sur les chaînes d'explication externes
  • Recommandation de limiter la longueur des chaînes d'explication
  • Accent sur la nécessité d'identifier les explications comme provenant de tiers

B.2 Changements des exigences de mise en œuvre​

B.2.1 Changements MUST (Doit être implémenté)​

Nouvelles exigences:

  1. Les implémentations doivent interroger uniquement les enregistrements TXT (plus de SPF RR)
  2. Les implémentations doivent limiter le nombre total de requêtes DNS à 10
  3. Les implémentations doivent gérer la limite "void lookup"
  4. Les implémentations doivent retourner "permerror" en cas de dépassement des limites

Exigences supprimées:

  1. Support du type RR SPF plus nécessaire
  2. Logique de conversion pour enregistrements à double type plus nécessaire

B.2.2 Changements SHOULD (Devrait être implémenté)​

Nouvelles recommandations:

  1. Devrait implémenter un timeout d'évaluation (au moins 20 secondes)
  2. Devrait limiter "void lookup" à 2
  3. Devrait vérifier les identités HELO et MAIL FROM
  4. Devrait effectuer la vérification pendant la transaction SMTP

B.2.3 Changements MAY (Peut être implémenté)​

Nouvelles options:

  1. Peut utiliser des algorithmes non canoniques (tant que les résultats sont identiques)
  2. Peut configurer la limite "void lookup"
  3. Peut limiter la longueur des chaînes d'explication

B.3 Changements de terminologie​

B.3.1 Standardisation des noms d'identité​

RFC 4408:

  • Utilisait plusieurs noms: "MAIL FROM", "SMTP MAIL FROM", "reverse-path"
  • Terminologie incohérente

RFC 7208:

  • Utilisation uniforme de l'identité "MAIL FROM"
  • Définition claire comme RFC5321.MailFrom
  • Référence à la terminologie standard RFC 5598

B.3.2 Adoption de la terminologie "ADMD"​

RFC 4408:

  • Utilisait "domain owner", "sending domain"

RFC 7208:

  • Adoption de "ADMD" (Administrative Management Domain)
  • Description plus précise de la partie responsable

B.4 Amélioration des considérations de sécurité​

B.4.1 Nouveaux sujets de sécurité​

  1. Usurpation inter-utilisateurs (Section 11.4):

    • Non couvert dans RFC 4408
    • RFC 7208 discute explicitement des problèmes d'usurpation d'utilisateurs intra-domaine
  2. Exposition de la vie privée (Section 11.6):

    • Les macros dans les requêtes DNS peuvent divulguer des informations sensibles
    • Recommandation d'utiliser prudemment les macros contenant des informations sur l'expéditeur
  3. Sources d'informations non fiables (Section 11.5):

    • Discussion détaillée des risques des en-têtes et explications externes
    • Accent sur l'importance de la validation et du filtrage

B.4.2 Renforcement de la protection DoS​

RFC 4408:

  • Limites de requête de base

RFC 7208:

  • Mécanismes de protection multicouches
  • Valeurs limites claires
  • Recommandations de timeout
  • Limite "void lookup"

B.5 Changements d'enregistrement IANA​

B.5.1 Type RR SPF​

RFC 4408:

  • Enregistrement du type RR SPF (type 99)

RFC 7208:

  • Type RR SPF marqué comme obsolète
  • Recommandation d'utiliser uniquement les enregistrements TXT

B.5.2 Registre des modificateurs​

Nouveau RFC 7208:

  • Création du registre des modificateurs SPF
  • Processus d'enregistrement standardisé pour les nouveaux modificateurs
  • Exigence que les modificateurs inconnus doivent être ignorés

B.6 Améliorations de l'interopérabilité​

B.6.1 Clarification de la sélection d'enregistrement​

RFC 4408:

  • Traitement de plusieurs enregistrements peu clair

RFC 7208:

  • Spécification claire: plusieurs enregistrements SPF entraînent "permerror"
  • Règles améliorées de correspondance des chaînes de version
  • Clarification des règles de concaténation d'enregistrements (plusieurs chaînes)

B.6.2 Standardisation du traitement des erreurs​

Améliorations RFC 7208:

  • Toutes les situations d'erreur ont des résultats clairs
  • Traitement standardisé des erreurs DNS
  • Amélioration du traitement des timeouts

B.7 Rétrocompatibilité​

B.7.1 Changements compatibles​

La plupart des changements sont rétrocompatibles:

  • Format d'enregistrement TXT inchangé
  • Syntaxe des mécanismes et modificateurs essentiellement identique
  • Algorithme de base reste cohérent

B.7.2 Changements pouvant affecter la compatibilité​

  1. Suppression du type RR SPF:

    • Les anciennes implémentations peuvent encore interroger SPF RR
    • Recommandation: Supprimer les enregistrements SPF RR, conserver uniquement TXT
  2. Limites plus strictes:

    • La limite "void lookup" est nouvellement ajoutée
    • Certains anciens enregistrements peuvent dépasser les nouvelles limites
    • Recommandation: Optimiser les enregistrements SPF pour respecter les limites
  3. Opposition au mécanisme "ptr":

    • Doit toujours être supporté mais fortement découragé
    • Recommandation: Migrer vers d'autres mécanismes

B.8 Changements de structure du document​

Améliorations RFC 7208:

  • Organisation des chapitres plus claire
  • Exemples étendus ajoutés (Annexe A)
  • Recommandations de mise en œuvre ajoutées (Annexes C-G)
  • Présentation améliorée des définitions ABNF

B.9 Guide de migration​

Migration de RFC 4408 vers RFC 7208:​

Éditeurs:

  1. Supprimer les enregistrements SPF RR, conserver uniquement les enregistrements TXT
  2. Vérifier et optimiser le nombre de requêtes DNS (≤ 10)
  3. Remplacer le mécanisme "ptr" par "ip4" ou "ip6"
  4. Valider le nombre de "void lookup" (≤ 2)
  5. Tester si les enregistrements dépassent 512 octets

Destinataires:

  1. Arrêter d'interroger le type SPF RR
  2. Implémenter les nouvelles limites de requêtes DNS
  3. Implémenter la limite "void lookup"
  4. Mettre à jour la logique de traitement des erreurs
  5. Envisager l'implémentation d'un timeout d'évaluation

Tests:

# Utiliser un outil de validation SPF pour tester les enregistrements
# Par exemple: https://www.kitterman.com/spf/validate.html

# Vérifier le nombre de requêtes DNS
dig +short example.com TXT | grep "v=spf1"

# Valider la taille de l'enregistrement
dig example.com TXT | grep -A1 "ANSWER SECTION"

B.10 Mise à jour des documents de référence​

RFC 7208 fait référence à des normes mises à jour:

  • RFC 5321 (remplace RFC 2821)
  • RFC 5322 (remplace RFC 2822)
  • RFC 5234 (mise à jour ABNF)
  • RFC 5598 (terminologie d'architecture de messagerie)
  • RFC 5890 (noms de domaine internationalisés)

Appendix C. Further Testing Advice (Conseils de test supplémentaires)​

Cette annexe fournit des recommandations détaillées pour tester et valider les implémentations SPF.

C.1 Test des enregistrements SPF​

C.1.1 Validation de base​

Test de requête DNS:

# Interroger l'enregistrement SPF
dig example.com TXT | grep "v=spf1"

# Ou utiliser nslookup
nslookup -type=TXT example.com

# Ou utiliser host
host -t TXT example.com

Points de validation:

  • ✓ L'enregistrement commence par v=spf1
  • ✓ Un seul enregistrement SPF
  • ✓ Syntaxe correcte (pas de fautes de frappe)
  • ✓ Taille de l'enregistrement < 512 octets

C.1.2 Outils de validation en ligne​

Outils en ligne recommandés:

  1. Kitterman SPF Validator

    • URL: https://www.kitterman.com/spf/validate.html
    • Fonctionnalités: Vérification de syntaxe, comptage de requêtes DNS, détails d'analyse
  2. MXToolbox SPF Record Check

    • URL: https://mxtoolbox.com/spf.aspx
    • Fonctionnalités: Validation d'enregistrement, détection d'avertissements et d'erreurs
  3. DMARCIAN SPF Inspector

    • URL: https://dmarcian.com/spf-survey/
    • Fonctionnalités: Analyse approfondie, recommandations d'optimisation

Éléments à vérifier:

✓ Exactitude de la syntaxe
✓ Nombre de requêtes DNS (≤ 10)
✓ Nombre de void lookup (≤ 2)
✓ Longueur de l'enregistrement
✓ Validité des mécanismes
✓ Profondeur de la chaîne include

C.2 Test de l'implémentation de vérification SPF​

C.2.1 Scénarios de tests unitaires​

Cas de test 1: Correspondance IP de base

Enregistrement SPF: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: pass

IP de test: 192.0.2.2
Résultat attendu: fail

Cas de test 2: Plage CIDR

Enregistrement SPF: v=spf1 ip4:192.0.2.0/24 -all
IP de test: 192.0.2.100
Résultat attendu: pass

IP de test: 192.0.3.1
Résultat attendu: fail

Cas de test 3: Mécanisme MX

example.com enregistrement MX: 10 mail.example.com
mail.example.com enregistrement A: 192.0.2.10

Enregistrement SPF: v=spf1 mx -all
IP de test: 192.0.2.10
Résultat attendu: pass

Cas de test 4: Mécanisme Include

example.com: v=spf1 include:_spf.example.org -all
_spf.example.org: v=spf1 ip4:192.0.2.0/24 -all

IP de test: 192.0.2.50
Résultat attendu: pass

Cas de test 5: Soft-fail

Enregistrement SPF: v=spf1 ip4:192.0.2.1 ~all
IP de test: 203.0.113.1
Résultat attendu: softfail

C.2.2 Tests de cas limites​

MAIL FROM vide:

MAIL FROM: <>
HELO: mail.example.com
Attendu: Utiliser l'identité HELO, local-part est "postmaster"

Nom de domaine invalide:

MAIL FROM: [email protected]
Résultat attendu: none (ou permerror)

Timeout DNS:

Simuler un timeout DNS
Résultat attendu: temperror

Plusieurs enregistrements SPF:

example.com TXT "v=spf1 mx -all"
example.com TXT "v=spf1 a -all"
Résultat attendu: permerror

C.2.3 Tests de limites​

Test de limite de requêtes DNS:

# Pseudo-code
def test_dns_lookup_limit():
# Créer un enregistrement SPF avec 11 includes
spf = "v=spf1"
for i in range(11):
spf += f" include:domain{i}.example.com"
spf += " -all"

result = check_spf(spf, "192.0.2.1", "[email protected]")
assert result == "permerror"

Test de limite d'enregistrements MX:

# Créer un domaine avec 11 enregistrements MX
# Attendu: le mécanisme mx retourne permerror

Test de Void Lookup:

# Créer un include qui retourne NXDOMAIN
# Le comptage devrait être inclus dans la limite void lookup

C.3 Envoi d'e-mails de test​

C.3.1 Processus de test​

Étape 1: Préparer le domaine de test

test.example.com IN TXT "v=spf1 ip4:YOUR_IP -all"

Étape 2: Envoyer un e-mail de test

# Utiliser l'outil swaks
swaks --to [email protected] \
--from [email protected] \
--server smtp.example.com

# Ou utiliser telnet
telnet smtp.recipient.com 25
HELO test.example.com
MAIL FROM:`&lt;[email protected]&gt;`
RCPT TO:`&lt;[email protected]&gt;`
DATA
Subject: SPF Test
.
QUIT

Étape 3: Vérifier les en-têtes d'e-mail

Received-SPF: pass (recipient.com: domain of [email protected]
designates YOUR_IP as permitted sender)
client-ip=YOUR_IP;
[email protected];

C.3.2 Tests de différents scénarios​

Scénario 1: Test Pass

Configuration: Envoyer depuis une IP autorisée
En-tête attendu: Received-SPF: pass

Scénario 2: Test Fail

Configuration: Envoyer depuis une IP non autorisée
Attendu: L'e-mail est rejeté ou marqué
En-tête attendu: Received-SPF: fail

Scénario 3: Test SoftFail

Configuration: L'enregistrement SPF utilise ~all
Envoyer depuis une IP non autorisée
Attendu: L'e-mail est accepté mais marqué
En-tête attendu: Received-SPF: softfail

Scénario 4: Test Neutral

Configuration: L'enregistrement SPF utilise ?all
En-tête attendu: Received-SPF: neutral

C.4 Tests de macros​

C.4.1 Validation d'expansion de macros​

Cas de test:

Expéditeur: [email protected]
IP client: 192.0.2.100

Macro %\{s} → [email protected]
Macro %\{l} → user
Macro %\{o} → example.com
Macro %\{d} → example.com
Macro %\{i} → 192.0.2.100
Macro %\{ir} → 100.2.0.192
Macro %\{d2} → example.com
Macro %\{d1} → com

Test de macro complexe:

SPF: v=spf1 exists:%\{ir}.%\{l}._spf.%\{d} -all
Expéditeur: [email protected]
IP: 192.0.2.100

Étendu à: 100.2.0.192.user._spf.example.com
Validation: Interroger l'enregistrement A pour ce nom de domaine

C.4.2 Test de délimiteurs de macros​

Expéditeur: [email protected]

%\{l} → user+tag
%\{l-} → user-tag (+ remplacé par -)
%\{lr} → gat+resu (inversé)
%\{lr-} → gat-resu (inversé et remplacé)

C.5 Tests de performance​

C.5.1 Tests de temps de réponse​

Test de référence:

# Tester le temps de requête DNS
time dig example.com TXT

# Tester la vérification SPF complète
time spf_check example.com 192.0.2.1 [email protected]

Objectifs de performance:

  • Enregistrement simple (1-2 mécanismes): < 100ms
  • Enregistrement complexe (plusieurs includes): < 500ms
  • Temps maximum autorisé: 20 secondes

C.5.2 Tests de charge​

Simuler une haute concurrence:

import concurrent.futures
import time

def check_spf_concurrent(num_checks):
with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
futures = [
executor.submit(check_spf, "example.com", "192.0.2.1", "[email protected]")
for _ in range(num_checks)
]
results = [f.result() for f in futures]
return results

# Tester 1000 vérifications SPF concurrentes
start = time.time()
results = check_spf_concurrent(1000)
end = time.time()

print(f"1000 vérifications terminées en: {end - start} secondes")
print(f"Moyenne par vérification: {(end - start) / 1000 * 1000}ms")

C.6 Tests de régression​

C.6.1 Suite de tests​

Ensemble de tests minimal:

1. Scénarios pass/fail de base
2. Tous les 7 mécanismes (all, include, a, mx, ptr, ip4, ip6, exists)
3. Tous les 4 qualificateurs (+, -, ~, ?)
4. Les deux modificateurs (redirect, exp)
5. Expansion de macros
6. Gestion des erreurs (temperror, permerror)
7. Tests de limites (requêtes DNS, timeout)

Suite de tests RFC 7208:

# Utiliser la suite de tests officielle
git clone https://github.com/openspf/openspf.git
cd openspf/tests
./run_tests.sh

C.6.2 Intégration continue​

Exemple de configuration CI/CD:

# .github/workflows/spf-tests.yml
name: SPF Tests

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run SPF Tests
run: |
python -m pytest tests/test_spf.py
python tests/validate_spf_records.py

C.7 Test des problèmes courants​

C.7.1 Fonctionnalités de messagerie anciennes​

Source Routing:

MAIL FROM:&lt;@relay.example.com:[email protected]>
Attendu: Extraire correctement example.com comme domaine

%-hack:

MAIL FROM:&lt;user%[email protected]>
Attendu: Gérer correctement ou rejeter

Bang Path:

MAIL FROM:&lt;[email protected]>
Attendu: Gérer correctement ou rejeter

C.7.2 Noms de domaine internationalisés​

Test IDN:

Domaine: münchen.de
A-label: xn--mnchen-3ya.de
Enregistrement SPF: Doit utiliser A-label

Test: S'assurer de la conversion et de la requête correctes

C.7.3 Tests IPv6​

Formats d'adresse IPv6:

Format complet: 2001:0db8:0000:0000:0000:0000:0000:0001
Format compressé: 2001:db8::1
IPv4-mapped: ::ffff:192.0.2.1

SPF: v=spf1 ip6:2001:db8::/32 -all
Test: Tous les formats devraient correspondre correctement

C.8 Techniques de débogage​

C.8.1 Activer la journalisation détaillée​

Expéditeur:

# Postfix
postconf -e "smtpd_sender_login_maps = hash:/etc/postfix/sender_login"
postconf -e "smtpd_sender_restrictions = reject_sender_login_mismatch"
tail -f /var/log/mail.log

Destinataire:

# Activer la journalisation de débogage SPF
spf_debug_level = 5
tail -f /var/log/mail.log | grep SPF

C.8.2 Utiliser le traçage dig​

Tracer les requêtes SPF:

# Voir le processus complet de résolution DNS
dig +trace example.com TXT

# Voir la chaîne include
dig _spf.google.com TXT
dig _netblocks.google.com TXT

C.8.3 Utiliser les outils de débogage SPF​

Python pyspf:

import spf

result, explanation = spf.check2(
i='192.0.2.1',
s='[email protected]',
h='mail.example.com'
)

print(f"Résultat: {result}")
print(f"Explication: {explanation}")

Perl Mail::SPF:

use Mail::SPF;

my $spf_server = Mail::SPF::Server->new();
my $request = Mail::SPF::Request->new(
versions => [1],
scope => 'mfrom',
identity => '[email protected]',
ip_address => '192.0.2.1',
helo_identity => 'mail.example.com'
);

my $result = $spf_server->process($request);
print "Résultat: " . $result->code . "\n";

C.9 Surveillance de l'environnement de production​

C.9.1 Métriques de surveillance​

Métriques clés:

- Taux de pass SPF
- Taux de fail SPF
- Taux de softfail SPF
- Taux de temperror SPF (devrait être très faible)
- Taux de permerror SPF (devrait être 0)
- Temps de vérification moyen
- Taux de timeout DNS

C.9.2 Configuration des alertes​

Règles d'alerte recommandées:

- Taux de permerror > 0%: Alerte immédiate (erreur d'enregistrement SPF)
- Taux de temperror > 5%: Avertissement (problèmes DNS)
- Augmentation soudaine du taux de fail > 20%: Alerte (changement de configuration possible ou attaque)
- Temps de vérification moyen > 1 seconde: Avertissement (problème de performance)

C.9.3 Analyse des journaux​

Analyser les échecs SPF:

# Extraire les adresses IP avec SPF fail
grep "Received-SPF: fail" /var/log/mail.log | \
grep -oP 'client-ip=\K[0-9.]+' | \
sort | uniq -c | sort -rn

# Analyser les domaines d'expéditeur avec fail
grep "Received-SPF: fail" /var/log/mail.log | \
grep -oP 'envelope-from=\K[^;]+' | \
cut -d@ -f2 | sort | uniq -c | sort -rn

Générer un rapport:

# Générateur de rapport de statistiques SPF
def generate_spf_report(log_file):
results = {
'pass': 0, 'fail': 0, 'softfail': 0,
'neutral': 0, 'none': 0,
'temperror': 0, 'permerror': 0
}

with open(log_file) as f:
for line in f:
if 'Received-SPF:' in line:
for result in results:
if f'Received-SPF: {result}' in line:
results[result] += 1

total = sum(results.values())
for result, count in results.items():
percentage = (count / total * 100) if total > 0 else 0
print(f"{result}: {count} ({percentage:.2f}%)")

Appendix D. SPF/Mediator Interactions (Interactions SPF/Médiateur)​

Cette annexe discute de l'interaction entre SPF et les médiateurs de messagerie (comme les listes de diffusion et les services de transfert) et de leurs impacts.

D.1 Originating ADMDs (ADMD d'origine)​

L'ADMD d'origine est le domaine administratif qui envoie initialement le courrier. En présence de médiateurs, l'ADMD d'origine doit considérer les services de transfert et de listes par lesquels ses courriers peuvent passer.

D.1.1 Identification du problème​

Hypothèse de base SPF:

  • Les courriers sont envoyés directement des serveurs autorisés aux destinataires
  • L'identité MAIL FROM reste inchangée
  • L'adresse IP d'envoi est autorisée dans l'enregistrement SPF

Hypothèses brisées par les médiateurs:

  • Les courriers passent par des systèmes intermédiaires
  • Peuvent être renvoyés depuis une adresse IP différente
  • MAIL FROM peut être modifié ou rester inchangé

D.1.2 Choix pour l'expéditeur​

Option 1: Utiliser une politique SPF souple

example.com IN TXT "v=spf1 mx ~all"

Avantages:

  • Permet le transfert légitime
  • Réduit les faux positifs

Inconvénients:

  • Affaiblit la protection SPF
  • Plus facile à usurper

Option 2: S'appuyer sur d'autres méthodes d'authentification

Publier des signatures DKIM:
- DKIM reste valide lors du transfert
- Indépendant de l'adresse IP d'envoi
- Fonctionne avec DMARC

Option 3: Accepter les échecs SPF

example.com IN TXT "v=spf1 mx -all"
  • Accepter que certains courriers légitimes puissent être marqués ou rejetés
  • Compter sur les utilisateurs pour utiliser la bonne méthode d'envoi
  • Recommander aux utilisateurs de ne pas transférer mais d'utiliser "Envoyer une copie"

D.1.3 Meilleures pratiques​

Configuration recommandée:

1. Publier un enregistrement SPF strict (-all)
2. Implémenter simultanément la signature DKIM
3. Publier une politique DMARC
4. Éduquer les utilisateurs sur les problèmes de transfert

Exemple de configuration DMARC:

_dmarc.example.com IN TXT "v=DMARC1; p=quarantine; sp=quarantine; adkim=r; aspf=r; pct=100; rua=mailto:[email protected]"

Explication des paramètres:

  • adkim=r: Alignement DKIM souple
  • aspf=r: Alignement SPF souple
  • p=quarantine: Mettre en quarantaine en cas d'échec

D.2 Mediators (Médiateurs)​

Les médiateurs sont des systèmes qui modifient ou renvoient des courriers dans la chaîne de transmission. Les médiateurs courants incluent les listes de diffusion, les services de transfert et les systèmes de réponse automatique.

D.2.1 Listes de diffusion​

Problème:

Les listes de diffusion traditionnelles conservent le MAIL FROM original:

Original: MAIL FROM:`&lt;[email protected]&gt;`
Après liste: MAIL FROM:`&lt;[email protected]&gt;`
IP d'envoi: list-server.mailinglist.org

Vérification SPF:

Interroger l'enregistrement SPF d'example.com
Vérifier l'IP de list-server.mailinglist.org
Résultat: fail (IP n'est pas dans l'enregistrement SPF d'example.com)

D.2.2 Solutions​

Solution 1: Réécrire MAIL FROM (recommandé)

Réécrit: MAIL FROM:`&lt;[email protected]&gt;`
Reply-To: [email protected]

Avantages:

  • La vérification SPF réussit
  • Les rebonds reviennent au serveur de liste
  • Le destinataire peut identifier correctement

Inconvénients:

  • Modifie les informations de l'expéditeur original
  • Les utilisateurs doivent s'adapter à Reply-To

Exemple d'implémentation (Mailman):

# Configuration Mailman
from_is_list = 2 # Munge From, add Reply-To

Solution 2: Utiliser SRS (Sender Rewriting Scheme)

SRS est un schéma de réécriture plus complexe:

Original: [email protected]
Réécrit en: [email protected]

Format SRS:

SRS0=&lt;hash>=&lt;timestamp>=&lt;domain>=&lt;localpart>@&lt;forwarder>

Exemple:
[email protected]

Avantages:

  • Préserve les informations de l'expéditeur original (dans le local-part)
  • La vérification SPF réussit
  • Peut être tracé et vérifié

Inconvénients:

  • Implémentation complexe
  • Nécessite une base de données SRS
  • Le local-part devient difficile à lire

Solution 3: Utiliser DKIM au lieu de SPF

Configuration:

1. L'expéditeur original utilise la signature DKIM
2. Le serveur de liste conserve la signature originale
3. Le serveur de liste ajoute sa propre signature DKIM
4. Le destinataire vérifie DKIM (ignore l'échec SPF)

Configuration DMARC:

_dmarc.example.com IN TXT "v=DMARC1; p=none; adkim=r; aspf=r"
  • p=none: Pas d'application (permet l'échec SPF)
  • adkim=r: Alignement DKIM souple (permet la signature de liste)

D.2.3 Services de transfert de courrier​

Type 1: Transfert simple

Configuration utilisateur: [email protected] → [email protected]
Le service de transfert conserve: MAIL FROM:`&lt;[email protected]&gt;`
Envoie depuis l'IP du serveur de transfert

Problème SPF:

Gmail vérifie le SPF d'original.com
L'IP du serveur de transfert n'est pas dans l'enregistrement SPF
Résultat: fail

Solution A: Réécriture SRS

Le service de transfert utilise SRS:
MAIL FROM:&lt;[email protected]>

Solution B: Utiliser ~all au lieu de -all

original.com IN TXT "v=spf1 mx ~all"

Les courriers transférés obtiendront softfail au lieu de fail, plus susceptibles d'être acceptés.

Type 2: Fichier .forward

# ~/.forward
[email protected]

Problème identique au transfert simple.

Meilleures pratiques:

1. Les services de transfert devraient implémenter SRS
2. L'expéditeur original devrait utiliser DKIM
3. Les destinataires devraient considérer les résultats DKIM, pas seulement SPF

D.2.4 Systèmes de réponse automatique et de notification​

Problème:

Courrier original: [email protected] → [email protected]
Réponse automatique: MAIL FROM:`&lt;[email protected]&gt;`
(Envoyé depuis le serveur company.com)

La vérification SPF échouera.

Solution:

Envoyer des notifications avec MAIL FROM vide:
MAIL FROM:<>
From: Mail Delivery System `&lt;[email protected]&gt;`

Ou:

Utiliser une adresse locale:
MAIL FROM:`&lt;[email protected]&gt;`
From: Automatic Reply `&lt;[email protected]&gt;`
Reply-To: [email protected]

D.3 Receiving ADMDs (ADMD destinataires)​

L'ADMD destinataire doit gérer les courriers provenant de médiateurs et prendre des décisions appropriées.

D.3.1 Identification des courriers de médiateurs​

Identifiants:

1. Sauts intermédiaires dans les en-têtes Received
2. En-têtes List-* (listes de diffusion)
3. Precedence: bulk ou list
4. MAIL FROM au format SRS
5. Signature DKIM d'un service de liste connu

Exemple de logique de détection:

def is_mailing_list(message):
# Vérifier les en-têtes List-*
list_headers = [
'List-Id', 'List-Post', 'List-Unsubscribe',
'List-Help', 'List-Subscribe', 'List-Owner'
]

for header in list_headers:
if message.get(header):
return True

# Vérifier Precedence
if message.get('Precedence') in ['bulk', 'list']:
return True

# Vérifier SRS
mail_from = message.get('Return-Path', '')
if mail_from.startswith('SRS0=') or mail_from.startswith('SRS1='):
return True

return False

D.3.2 Recommandations de politique​

Politique 1: Traitement souple des courriers de liste

if is_mailing_list(message):
if spf_result == 'fail':
# Vérifier DKIM
if dkim_result == 'pass':
accept_message()
else:
# Vérifier la réputation de la liste
if list_is_trusted(list_id):
accept_message()
else:
quarantine_message()

Politique 2: S'appuyer sur DMARC

if dmarc_result == 'pass':
accept_message()
elif spf_result == 'fail' and dkim_result == 'fail':
reject_message()
else:
# SPF ou DKIM réussit
if is_mailing_list(message):
accept_message()
else:
apply_content_filtering()

Politique 3: Règles spécifiques à l'utilisateur

Les utilisateurs peuvent configurer des listes blanches:
- Listes de diffusion de confiance
- Adresses de transfert connues
- Traitement souple de domaines spécifiques

D.3.3 Recommandations d'implémentation​

Configuration SpamAssassin:

# Traitement souple des listes de diffusion
header LIST_ID exists:List-Id
score LIST_ID -0.1

# SPF fail mais avec en-tête List-Id
meta SPF_FAIL_LIST (SPF_FAIL && LIST_ID)
score SPF_FAIL_LIST 0.5

# SPF fail normal (sans en-tête de liste)
score SPF_FAIL 5.0

Configuration Postfix:

# smtpd_recipient_restrictions
reject_unauth_destination,
check_policy_service unix:private/spf-policy,
permit

# Le service de politique SPF peut identifier les courriers de liste et s'adapter

Configuration rspamd:

-- Configuration du module SPF
spf {
-- Appliquer un poids différent pour les listes de diffusion
symbol_fail = "R_SPF_FAIL";
symbol_softfail = "R_SPF_SOFTFAIL";

-- Règles personnalisées
custom_symbols = {
R_SPF_FAIL_LIST = {
score = 2.0,
description = "SPF failed but from mailing list",
condition = function(task)
local spf = task:get_symbol('R_SPF_FAIL')
local list_id = task:get_header('List-Id')
return spf and list_id
end
}
}
}

D.4 Recommandations d'interopérabilité​

D.4.1 Standardisation​

Utiliser des en-têtes standard:

Les listes de diffusion devraient ajouter:
- List-Id: &lt;list-name.domain.com>
- List-Post: &lt;mailto:[email protected]>
- List-Unsubscribe: &lt;mailto:[email protected]>
- Precedence: bulk

Signature DKIM:

Les serveurs de liste devraient:
1. Conserver la signature DKIM originale (si présente)
2. Ajouter leur propre signature DKIM
3. Ne pas modifier les en-têtes signés

D.4.2 Communication​

Notification de l'expéditeur:

Le service de liste devrait informer les abonnés:
- Les courriers seront renvoyés depuis le serveur de liste
- MAIL FROM sera réécrit
- Recommandation d'utiliser Reply-To pour répondre à la liste

Documentation du destinataire:

Documenter les politiques de réception:
- Comment les courriers de liste sont traités
- Mécanisme de liste blanche
- Options configurables par l'utilisateur

D.5 Direction du développement futur​

D.5.1 ARC (Authenticated Received Chain)​

RFC 8617 a introduit ARC:

ARC permet aux médiateurs d'ajouter des informations d'authentification:
- ARC-Seal: Signature du médiateur
- ARC-Message-Signature: Signature du message
- ARC-Authentication-Results: Résultats d'authentification

Exemple:

ARC-Seal: i=1; a=rsa-sha256; t=1234567890; cv=none;
d=mailinglist.org; s=arc-seal; b=...
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
d=mailinglist.org; s=arc-msg; h=from:to:subject; b=...
ARC-Authentication-Results: i=1; mailinglist.org;
spf=pass [email protected];
dkim=pass header.d=example.com

Avantages:

  • Préserve les résultats d'authentification originaux
  • Permet la vérification en chaîne
  • Les destinataires peuvent faire confiance aux médiateurs

D.5.2 Recommandations​

Pour les nouveaux déploiements:

  1. Implémenter DKIM et SPF
  2. Publier une politique DMARC
  3. Considérer le support ARC (si médiateur)
  4. Tester l'interopérabilité avec les listes de diffusion courantes

Pour les systèmes existants:

  1. Examiner la rigueur des politiques SPF
  2. Surveiller les rapports DMARC
  3. Identifier les sources problématiques (listes, transferts, etc.)
  4. Ajuster les politiques ou implémenter SRS

Appendix E. Mail Services (Services de messagerie)​

Cette annexe discute des considérations d'implémentation SPF pour différents scénarios de services de messagerie.

E.1 Web-Based Mail Services (Services de messagerie Web)​

E.1.1 Perspective du fournisseur de services​

Scénario: Fourniture de services de messagerie Web (comme Gmail, Yahoo Mail, Outlook.com)

Considérations SPF:

1. Les utilisateurs envoient des e-mails depuis plusieurs domaines
2. Tous les e-mails sont envoyés via les serveurs du fournisseur de services
3. Enregistrements SPF appropriés requis

Exemple de configuration:

# Domaine principal du fournisseur de services
mailprovider.com IN TXT "v=spf1 ip4:203.0.113.0/24 ip4:198.51.100.0/24 -all"

# Support pour les domaines personnalisés
# Les utilisateurs doivent inclure le fournisseur de services dans leur domaine
user-domain.com IN TXT "v=spf1 include:_spf.mailprovider.com -all"
_spf.mailprovider.com IN TXT "v=spf1 ip4:203.0.113.0/24 ip4:198.51.100.0/24 -all"

E.1.2 Configuration des domaines personnalisés​

Exigence de l'utilisateur: Utiliser un domaine personnalisé pour envoyer des e-mails via le service de messagerie Web

Étapes de configuration:

  1. Vérifier la propriété du domaine
Le fournisseur de services exige l'ajout d'un enregistrement de vérification:
_verification.user-domain.com IN TXT "provider-verification-code"
  1. Configurer SPF
user-domain.com IN TXT "v=spf1 include:_spf.mailprovider.com -all"
  1. Configurer DKIM
# Le fournisseur de services fournit la clé publique DKIM
selector._domainkey.user-domain.com IN TXT "v=DKIM1; k=rsa; p=MIGfMA0..."
  1. Configurer DMARC
_dmarc.user-domain.com IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"

E.2 Shared Hosting Services (Services d'hébergement partagé)​

E.2.1 Défis​

Problème: Plusieurs clients partagent la même adresse IP

hosting-provider.com: 203.0.113.10
customer1.com: Hébergé sur 203.0.113.10
customer2.com: Hébergé sur 203.0.113.10
customer3.com: Hébergé sur 203.0.113.10

Exigence SPF: Chaque domaine client doit autoriser l'IP partagée

E.2.2 Solutions​

Solution 1: Inclusion SPF unifiée

# Le fournisseur d'hébergement fournit
_spf.hosting-provider.com IN TXT "v=spf1 ip4:203.0.113.0/24 -all"

# Configuration du client
customer1.com IN TXT "v=spf1 include:_spf.hosting-provider.com -all"
customer2.com IN TXT "v=spf1 include:_spf.hosting-provider.com -all"
customer3.com IN TXT "v=spf1 include:_spf.hosting-provider.com -all"

Solution 2: Autorisation IP directe

# Chaque client configure indépendamment
customer1.com IN TXT "v=spf1 ip4:203.0.113.10 -all"
customer2.com IN TXT "v=spf1 ip4:203.0.113.10 -all"

Avantages: Simple, pas de dépendances Inconvénients: Lors d'un changement d'IP, tous les clients doivent mettre à jour

Solution 3: IP dédiée (recommandée pour les gros clients)

# Attribuer une IP dédiée aux clients importants
important-customer.com IN TXT "v=spf1 ip4:203.0.113.50 -all"

E.2.3 Meilleures pratiques​

Les fournisseurs d'hébergement devraient:

1. Fournir une documentation claire sur la configuration SPF
2. Générer automatiquement les enregistrements SPF (via le panneau de contrôle)
3. Informer les clients des changements d'adresse IP
4. Fournir des outils de validation SPF

Les clients devraient:

1. Utiliser la méthode include pour référencer le SPF du fournisseur d'hébergement
2. Valider régulièrement les enregistrements SPF
3. Surveiller la délivrabilité des e-mails

E.3 Enterprise Mail Systems (Systèmes de messagerie d'entreprise)​

E.3.1 Environnement complexe​

Scénario d'entreprise typique:

- Plusieurs centres de données
- Plusieurs serveurs de messagerie sortants
- Services de messagerie tiers (marketing, notifications, etc.)
- Serveurs de bureaux locaux
- Intégration de services cloud

Défis de configuration SPF:

1. Limite de requêtes DNS (10 fois)
2. Limite de taille d'enregistrement (512 octets)
3. Plusieurs départements/unités commerciales
4. Changements d'infrastructure fréquents

E.3.2 Architecture SPF d'entreprise​

Conception hiérarchique:

# Domaine principal
company.com IN TXT "v=spf1 include:_spf-internal.company.com include:_spf-external.company.com -all"

# Serveurs internes
_spf-internal.company.com IN TXT "v=spf1 ip4:10.0.0.0/8 ip4:203.0.113.0/24 -all"

# Services externes
_spf-external.company.com IN TXT "v=spf1 include:_spf.salesforce.com include:sendgrid.net include:mailchimp.com -all"

# Sous-domaines départementaux
marketing.company.com IN TXT "v=spf1 include:_spf-marketing.company.com -all"
_spf-marketing.company.com IN TXT "v=spf1 include:sendgrid.net include:mailchimp.com -all"

Gestion des plages IP:

# Centre de données A
_spf-dc-a.company.com IN TXT "v=spf1 ip4:203.0.113.0/25 -all"

# Centre de données B
_spf-dc-b.company.com IN TXT "v=spf1 ip4:198.51.100.0/25 -all"

# Agrégation
_spf-datacenters.company.com IN TXT "v=spf1 include:_spf-dc-a.company.com include:_spf-dc-b.company.com -all"

E.3.3 Stratégie d'aplatissement SPF​

Problème: Dépassement de la limite de 10 requêtes DNS

Solution: Aplatissement régulier

# Script d'automatisation
def flatten_spf_includes():
"""
Interroger régulièrement toutes les IP de domaine inclus
Générer un enregistrement SPF aplati
"""
includes = [
'_spf.salesforce.com',
'sendgrid.net',
'mailchimp.com'
]

ips = []
for domain in includes:
# Analyser l'enregistrement SPF et extraire les IP
ips.extend(resolve_spf_ips(domain))

# Générer un nouvel enregistrement SPF
spf_record = f"v=spf1 {' '.join([f'ip4:{ip}' for ip in ips])} -all"

# Mettre à jour DNS (via API)
update_dns_record('_spf-flattened.company.com', spf_record)

# Exécuter hebdomadairement

Note: Après aplatissement, mettre à jour régulièrement car les IP tierces peuvent changer

E.4 Email Marketing Services (Services de marketing par e-mail)​

E.4.1 Configuration du service​

Services courants:

  • SendGrid
  • Mailchimp
  • Amazon SES
  • Mailgun

Exemples de configuration SPF:

SendGrid:

company.com IN TXT "v=spf1 include:sendgrid.net -all"

Mailchimp:

company.com IN TXT "v=spf1 include:servers.mcsv.net -all"

Amazon SES:

company.com IN TXT "v=spf1 include:amazonses.com -all"

Utilisation combinée:

company.com IN TXT "v=spf1 mx include:sendgrid.net include:servers.mcsv.net -all"

E.4.2 Stratégie de sous-domaine​

Meilleure pratique: Utiliser un sous-domaine dédié pour les e-mails marketing

# Domaine principal (pour les e-mails professionnels importants)
company.com IN TXT "v=spf1 mx -all"

# Sous-domaine marketing
marketing.company.com IN TXT "v=spf1 include:sendgrid.net -all"

# Sous-domaine notifications
notifications.company.com IN TXT "v=spf1 include:amazonses.com -all"

Avantages:

1. Séparation de la réputation (les e-mails marketing n'affectent pas le domaine principal)
2. Gestion plus facile des enregistrements SPF
3. Meilleure surveillance et reporting
4. Conforme aux meilleures pratiques DMARC

E.4.3 Configuration DKIM​

Combiné avec SPF:

# SPF
marketing.company.com IN TXT "v=spf1 include:sendgrid.net -all"

# DKIM (fourni par SendGrid)
s1._domainkey.marketing.company.com IN CNAME s1.domainkey.u12345.wl.sendgrid.net
s2._domainkey.marketing.company.com IN CNAME s2.domainkey.u12345.wl.sendgrid.net

# DMARC
_dmarc.marketing.company.com IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:[email protected]"

E.5 Transactional Email Services (Services d'e-mail transactionnels)​

E.5.1 Scénario​

E-mails transactionnels:

  • Confirmation d'inscription
  • Réinitialisation de mot de passe
  • Notifications de commande
  • Factures et reçus

Fournisseurs de services:

  • Amazon SES
  • SendGrid
  • Mailgun
  • Postmark

E.5.2 Configuration​

Utiliser un sous-domaine dédié:

# Sous-domaine d'e-mail transactionnel
transactional.company.com IN TXT "v=spf1 include:_spf.mailgun.org -all"

# DKIM
smtp._domainkey.transactional.company.com IN TXT "v=DKIM1; k=rsa; p=..."

Configuration de l'application:

# Exemple Django
EMAIL_HOST = 'smtp.mailgun.org'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_FROM = '[email protected]'

# Envoyer un e-mail
send_mail(
subject='Password Reset',
message='Click here to reset...',
from_email='[email protected]',
recipient_list=['[email protected]']
)

E.5.3 Surveillance​

Métriques clés:

- Taux de livraison des e-mails
- Taux de rebond
- Taux de réussite SPF
- Taux de réussite DKIM
- Taux d'alignement DMARC
- Taux de plaintes

Paramètres d'alerte:

if delivery_rate &lt; 95%:
alert("Delivery rate dropped below 95%")

if spf_pass_rate &lt; 98%:
alert("SPF configuration issue detected")

E.6 Mobile and IoT Devices (Appareils mobiles et IoT)​

E.6.1 Défis​

Appareils mobiles:

- Adresses IP dynamiques
- Envoi via les réseaux des opérateurs
- Ne peuvent pas être listés dans SPF

Appareils IoT:

- Grand nombre d'appareils
- Distribués sur différents réseaux
- Envoi d'e-mail direct

E.6.2 Solutions​

Solution 1: Utiliser un relais SMTP

Appareil → Relais SMTP → Destinataire

Configuration:
- L'appareil se connecte au relais via l'authentification
- Serveur relais autorisé dans l'enregistrement SPF
- Le relais ajoute une signature DKIM

Configuration SPF:

iot-devices.company.com IN TXT "v=spf1 mx include:_spf-relay.company.com -all"
_spf-relay.company.com IN TXT "v=spf1 ip4:203.0.113.50 -all"

Solution 2: Envoi par API

Les appareils envoient des e-mails via l'API HTTP:
- Utiliser un service tiers (comme l'API SendGrid)
- Couvert par l'enregistrement SPF du fournisseur de services
- Aucun envoi SMTP direct depuis l'appareil requis

E.7 Best Practices Summary (Résumé des meilleures pratiques)​

E.7.1 Recommandations générales​

1. Utiliser des sous-domaines pour séparer différents types d'e-mails
2. Implémenter la triple protection SPF + DKIM + DMARC
3. Vérifier et mettre à jour régulièrement les enregistrements SPF
4. Surveiller les limites de requêtes DNS
5. Utiliser include au lieu de lister directement toutes les IP
6. Utiliser des IP dédiées pour les services critiques
7. Implémenter la surveillance de l'authentification des e-mails
8. Établir un processus de réponse aux incidents

E.7.2 Liste de vérification de configuration​

Vérifier avant publication:

□ Syntaxe de l'enregistrement SPF correcte
□ Nombre de requêtes DNS ≤ 10
□ Taille de l'enregistrement &lt; 512 octets
□ Tous les serveurs d'envoi autorisés
□ Utiliser des qualificatifs appropriés (-all ou ~all)
□ DKIM configuré
□ Politique DMARC publiée
□ E-mails de test envoyés et vérifiés

Surveillance continue:

□ Vérifier les rapports DMARC hebdomadairement
□ Surveiller la délivrabilité des e-mails
□ Suivre les erreurs SPF/DKIM
□ Vérifier les nouvelles sources d'envoi
□ Mettre à jour les modifications des services tiers

Appendix F. Test Suite (Suite de tests)​

Cette annexe fournit une suite de tests complète pour valider les implémentations SPF. Les tests couvrent divers scénarios pour s'assurer que les vérificateurs SPF fonctionnent correctement.

F.1 Basic Tests (Tests de base)​

F.1.1 Tests IP4 simples​

Test 1: Correspondance IP4 directe

Enregistrement SPF: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: pass

Test 2: Correspondance CIDR IP4

Enregistrement SPF: v=spf1 ip4:192.0.2.0/24 -all
IP de test: 192.0.2.128
Résultat attendu: pass

Test 3: Non-correspondance IP4

Enregistrement SPF: v=spf1 ip4:192.0.2.0/24 -all
IP de test: 192.0.3.1
Résultat attendu: fail

F.1.2 Tests IP6 simples​

Test 4: Correspondance IP6 directe

Enregistrement SPF: v=spf1 ip6:2001:db8::1 -all
IP de test: 2001:db8::1
Résultat attendu: pass

Test 5: Correspondance CIDR IP6

Enregistrement SPF: v=spf1 ip6:2001:db8::/32 -all
IP de test: 2001:db8::dead:beef
Résultat attendu: pass

Test 6: Non-correspondance IP6

Enregistrement SPF: v=spf1 ip6:2001:db8::/32 -all
IP de test: 2001:db9::1
Résultat attendu: fail

F.2 Mechanism Tests (Tests de mécanismes)​

F.2.1 Tests du mécanisme A​

Test 7: Mécanisme A - correspondance

Domaine: example.com
Enregistrement SPF: v=spf1 a -all
Enregistrement DNS A pour example.com: 192.0.2.1
IP de test: 192.0.2.1
Résultat attendu: pass

Test 8: Mécanisme A avec CIDR

Domaine: example.com
Enregistrement SPF: v=spf1 a/24 -all
Enregistrement DNS A pour example.com: 192.0.2.1
IP de test: 192.0.2.200
Résultat attendu: pass

Test 9: Mécanisme A avec spécification de domaine

Domaine: sender.example.com
Enregistrement SPF: v=spf1 a:mail.example.com -all
Enregistrement DNS A pour mail.example.com: 192.0.2.10
IP de test: 192.0.2.10
Résultat attendu: pass

F.2.2 Tests du mécanisme MX​

Test 10: Mécanisme MX - correspondance

Domaine: example.com
Enregistrement SPF: v=spf1 mx -all
Enregistrement DNS MX pour example.com: 10 mail.example.com
Enregistrement DNS A pour mail.example.com: 192.0.2.1
IP de test: 192.0.2.1
Résultat attendu: pass

Test 11: Mécanisme MX avec plusieurs enregistrements MX

Domaine: example.com
Enregistrement SPF: v=spf1 mx -all
Enregistrements DNS MX:
10 mail1.example.com → 192.0.2.1
20 mail2.example.com → 192.0.2.2
IP de test: 192.0.2.2
Résultat attendu: pass

Test 12: Mécanisme MX avec CIDR

Domaine: example.com
Enregistrement SPF: v=spf1 mx/24 -all
Enregistrement DNS MX: 10 mail.example.com
Enregistrement DNS A pour mail.example.com: 192.0.2.1
IP de test: 192.0.2.200
Résultat attendu: pass

F.2.3 Tests du mécanisme PTR (NE PAS UTILISER)​

Test 13: Mécanisme PTR - correspondance

Domaine: example.com
Enregistrement SPF: v=spf1 ptr -all
IP de test: 192.0.2.1
Enregistrement PTR pour 192.0.2.1: mail.example.com
Enregistrement A pour mail.example.com: 192.0.2.1
Résultat attendu: pass

Note: Le mécanisme PTR est obsolète et ne devrait pas être utilisé.

F.2.4 Tests du mécanisme EXISTS​

Test 14: Mécanisme EXISTS - trouvé

Domaine: example.com
Enregistrement SPF: v=spf1 exists:%\{i}.whitelist.example.com -all
IP de test: 192.0.2.1
Requête DNS A pour 192.0.2.1.whitelist.example.com: 127.0.0.2
Résultat attendu: pass

Test 15: Mécanisme EXISTS - non trouvé

Domaine: example.com
Enregistrement SPF: v=spf1 exists:%\{i}.whitelist.example.com -all
IP de test: 192.0.2.99
Requête DNS A pour 192.0.2.99.whitelist.example.com: NXDOMAIN
Résultat attendu: fail

F.2.5 Tests du mécanisme INCLUDE​

Test 16: INCLUDE - propagation simple de pass

Domaine: example.com
Enregistrement SPF: v=spf1 include:trusted.example.com -all
Enregistrement SPF pour trusted.example.com: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: pass

Test 17: INCLUDE - fail n'est pas propagé

Domaine: example.com
Enregistrement SPF: v=spf1 include:trusted.example.com -all
Enregistrement SPF pour trusted.example.com: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.99
Résultat attendu: fail (pas de include, mais de -all)

Test 18: INCLUDE - propagation de TempError

Domaine: example.com
Enregistrement SPF: v=spf1 include:trusted.example.com -all
Requête DNS pour trusted.example.com: serveur DNS indisponible
Résultat attendu: temperror

Test 19: INCLUDE - propagation de PermError

Domaine: example.com
Enregistrement SPF: v=spf1 include:trusted.example.com -all
Enregistrement SPF pour trusted.example.com: v=spf1 ip4:192.0.2.1 ip4:192.0.2.1 -all (invalide)
Résultat attendu: permerror

F.2.6 Tests du mécanisme ALL​

Test 20: ALL avec différents qualificatifs

+all: pass
-all: fail
~all: softfail
?all: neutral

F.3 Qualifier Tests (Tests de qualificatifs)​

Test 21: Qualificatif plus (+)

Enregistrement SPF: v=spf1 +ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: pass

Test 22: Qualificatif moins (-)

Enregistrement SPF: v=spf1 -ip4:192.0.2.1 ~all
IP de test: 192.0.2.1
Résultat attendu: fail

Test 23: Qualificatif tilde (~)

Enregistrement SPF: v=spf1 ~ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: softfail

Test 24: Qualificatif point d'interrogation (?)

Enregistrement SPF: v=spf1 ?ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: neutral

F.4 Modifier Tests (Tests de modificateurs)​

F.4.1 Tests du modificateur REDIRECT​

Test 25: REDIRECT - redirection de base

Domaine: example.com
Enregistrement SPF: v=spf1 redirect=_spf.example.com
Enregistrement SPF pour _spf.example.com: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: pass

Test 26: REDIRECT - ignoré après mécanisme

Domaine: example.com
Enregistrement SPF: v=spf1 ip4:192.0.2.1 redirect=_spf.example.com
IP de test: 192.0.2.1
Résultat attendu: pass (mécanisme correspond, redirect ignoré)

Test 27: REDIRECT - pas de correspondance

Domaine: example.com
Enregistrement SPF: v=spf1 redirect=_spf.example.com
Enregistrement SPF pour _spf.example.com: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.99
Résultat attendu: fail

F.4.2 Tests du modificateur EXP​

Test 28: EXP - récupération de chaîne d'explication

Domaine: example.com
Enregistrement SPF: v=spf1 ip4:192.0.2.1 -all exp=explain.example.com
Enregistrement DNS TXT pour explain.example.com: "Mail from %\{i} not allowed"
IP de test: 192.0.2.99
Résultat attendu: fail
Explication attendue: "Mail from 192.0.2.99 not allowed"

F.5 Macro Tests (Tests de macros)​

F.5.1 Expansion de macro de base​

Test 29: %\{s} - expéditeur

Domaine: example.com
MAIL FROM: [email protected]
Enregistrement SPF: v=spf1 exists:%\{s}.whitelist.example.com -all
Étendu à: exists:[email protected]

Test 30: %\{l} - partie locale

Domaine: example.com
MAIL FROM: [email protected]
Enregistrement SPF: v=spf1 exists:%\{l}.whitelist.example.com -all
Étendu à: exists:sender.whitelist.example.com

Test 31: %\{o} - domaine

Domaine: example.com
MAIL FROM: [email protected]
Enregistrement SPF: v=spf1 exists:%\{o}.whitelist.example.com -all
Étendu à: exists:example.com.whitelist.example.com

Test 32: %\{d} - domaine actuel

Domaine: mail.example.com
Enregistrement SPF: v=spf1 exists:%\{d}.whitelist.example.com -all
Étendu à: exists:mail.example.com.whitelist.example.com

Test 33: %\{i} - adresse IP

IP de test: 192.0.2.1
Enregistrement SPF: v=spf1 exists:%\{i}.whitelist.example.com -all
Étendu à: exists:192.0.2.1.whitelist.example.com

Test 34: %\{i} - adresse IPv6

IP de test: 2001:db8::1
Enregistrement SPF: v=spf1 exists:%\{i}.whitelist.example.com -all
Étendu à: exists:2001.0db8.0000.0000.0000.0000.0000.0001.whitelist.example.com

F.5.2 Transformateurs de macros​

Test 35: Transformateur d'inversion (r)

Domaine: mail.example.com
Macro: %\{d}
Normal: mail.example.com
Avec r: %\{dr}
Étendu à: com.example.mail

Test 36: Délimiteur et inversion

MAIL FROM: [email protected]
Macro: %\{or}
Étendu à: com.example.mail

Test 37: Spécification de chiffres

Domaine: mail.example.com
Macro: %\{d2}
Étendu à: example.com (2 derniers composants)

Test 38: Chiffres avec inversion

Domaine: mail.example.com
Macro: %\{d2r}
Étendu à: com.example

F.5.3 Encodage URL dans les macros​

Test 39: Caractères d'échappement URL

MAIL FROM: "test user"@example.com
Macro: %\{l}
Étendu à: test%20user

F.6 DNS Lookup Limit Tests (Tests de limite de requêtes DNS)​

Test 40: Limite de requêtes DNS - exactement 10

Enregistrement SPF: v=spf1 mx a include:d1.example.com include:d2.example.com ...
(total de 10 mécanismes nécessitant des requêtes DNS)
Résultat attendu: traité avec succès

Test 41: Limite de requêtes DNS - 11 dépassé

Enregistrement SPF: v=spf1 mx a include:d1.example.com ... (11 requêtes)
Résultat attendu: permerror

Test 42: Comptage des requêtes d'inclusion imbriquée

Domaine: example.com
SPF: v=spf1 include:a.example.com -all (1 requête)
a.example.com: v=spf1 include:b.example.com -all (1 requête)
b.example.com: v=spf1 mx a -all (2 requêtes)
Total des requêtes: 4
Résultat attendu: pass (si l'IP correspond)

F.7 Void Lookup Tests (Tests de requêtes vides)​

Test 43: Mécanisme A - pas d'enregistrements A

Domaine: example.com
Enregistrement SPF: v=spf1 a -all
Enregistrement DNS A pour example.com: (aucun)
IP de test: 192.0.2.1
Résultat attendu: fail (mécanisme ne correspond pas)
Requêtes vides: 1

Test 44: Mécanisme MX - pas d'enregistrements MX

Domaine: example.com
Enregistrement SPF: v=spf1 mx -all
Enregistrement DNS MX pour example.com: (aucun)
IP de test: 192.0.2.1
Résultat attendu: fail
Requêtes vides: 1

Test 45: Limite de requêtes vides - dépassée

Enregistrement SPF avec 3 mécanismes renvoyant chacun des requêtes vides
Résultat attendu: permerror (si la limite est 2)

F.8 Syntax Error Tests (Tests d'erreurs de syntaxe)​

Test 46: Version SPF manquante

Enregistrement SPF: ip4:192.0.2.1 -all
Résultat attendu: none (pas d'enregistrement SPF valide)

Test 47: Adresse IP invalide

Enregistrement SPF: v=spf1 ip4:999.999.999.999 -all
Résultat attendu: permerror

Test 48: Plage CIDR invalide

Enregistrement SPF: v=spf1 ip4:192.0.2.0/99 -all
Résultat attendu: permerror

Test 49: Modificateurs dupliqués

Enregistrement SPF: v=spf1 redirect=a.example.com redirect=b.example.com
Résultat attendu: permerror

Test 50: Modificateur inconnu (devrait être ignoré)

Enregistrement SPF: v=spf1 ip4:192.0.2.1 unknown=value -all
IP de test: 192.0.2.1
Résultat attendu: pass (modificateur inconnu ignoré)

F.9 Integration Tests (Tests d'intégration)​

Test 51: Scénario réaliste complexe

Domaine: company.com
Enregistrement SPF: v=spf1 mx include:_spf.google.com include:sendgrid.net -all

Configuration:
- Enregistrements MX: mail1.company.com (192.0.2.1), mail2.company.com (192.0.2.2)
- Le SPF de Google inclut plusieurs plages IP
- Le SPF de SendGrid inclut plusieurs plages IP

Cas de test:
1. IP 192.0.2.1: pass (correspondance mx)
2. IP de la plage Google: pass (correspondance include)
3. IP de la plage SendGrid: pass (correspondance include)
4. IP aléatoire: fail (-all)

Test 52: Traitement des sous-domaines

Domaine: mail.company.com
Enregistrement SPF pour company.com: v=spf1 -all
Enregistrement SPF pour mail.company.com: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: pass (le sous-domaine a son propre enregistrement SPF)

Test 53: Pas d'enregistrement SPF

Domaine: example.com
Enregistrement SPF: (aucun)
IP de test: 192.0.2.1
Résultat attendu: none

F.10 Edge Cases (Cas limites)​

Test 54: Partie locale vide

MAIL FROM: <>
HELO: mail.example.com
Enregistrement SPF pour mail.example.com: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: pass (identité HELO utilisée)

Test 55: Adresse IPv6 mappée IPv4

Enregistrement SPF: v=spf1 ip4:192.0.2.1 -all
IP de test: ::ffff:192.0.2.1 (IPv6 mappé IPv4)
Résultat attendu: pass (devrait être traité comme IPv4)

Test 56: CIDR /32 pour IPv4

Enregistrement SPF: v=spf1 ip4:192.0.2.1/32 -all
IP de test: 192.0.2.1
Résultat attendu: pass

Test 57: CIDR /128 pour IPv6

Enregistrement SPF: v=spf1 ip6:2001:db8::1/128 -all
IP de test: 2001:db8::1
Résultat attendu: pass

Test 58: Plusieurs enregistrements SPF (invalide)

Domaine: example.com
Enregistrements SPF:
v=spf1 ip4:192.0.2.1 -all
v=spf1 ip4:192.0.2.2 -all
Résultat attendu: permerror (plusieurs enregistrements SPF non autorisés)

F.11 Performance Tests (Tests de performances)​

Test 59: Profondeur maximale de requête DNS

Includes imbriqués jusqu'à une profondeur de 10
Vérifier que tous sont traités correctement

Test 60: Grandes plages CIDR

Enregistrement SPF: v=spf1 ip4:192.0.0.0/8 -all
IP de test: 192.255.255.255
Résultat attendu: pass

F.12 Test Result Summary Format (Format de résumé des résultats de test)​

Pour chaque exécution de test, les informations suivantes doivent être enregistrées:

ID de test: F.1.1-Test1
Description: Correspondance IP4 directe
Enregistrement SPF: v=spf1 ip4:192.0.2.1 -all
IP de test: 192.0.2.1
Résultat attendu: pass
Résultat réel: pass
Statut: RÉUSSI
Requêtes DNS: 1
Requêtes vides: 0
Temps de traitement: 45ms

Une implémentation SPF complète devrait réussir tous les tests de cette suite pour être considérée comme conforme à la RFC 7208.


Appendix G. Acknowledgements (Remerciements)​

Le développement du Sender Policy Framework (SPF) a été un effort collaboratif impliquant de nombreuses personnes et organisations de la communauté Internet.

G.1 Original Contributors (Contributeurs originaux)​

SPF est basé sur les idées de plusieurs propositions antérieures d'authentification de courrier électronique:

  • Designated Mailers Protocol (DMP): Proposé par Gordon Fecyk
  • Reverse MX (RMX): Proposé par Hadmut Danisch
  • Sender Permitted From (SPF): Proposé par Meng Weng Wong

Meng Weng Wong a joué un rôle essentiel dans l'unification de ces différentes approches en un cadre cohérent et a dirigé le développement initial de SPF.

G.2 RFC 4408 Contributors (Contributeurs RFC 4408)​

RFC 4408, la spécification SPF d'origine, a été rédigée par Meng Weng Wong et Mark Lentczner. De nombreux autres ont contribué à son développement:

Contributeurs techniques et réviseurs:

  • Stuart Cheshire
  • Claus Färber
  • Mark Lentczner
  • Wayne Schlitt
  • Julian Mehnle
  • Scott Kitterman

Participants du groupe de travail: Le groupe de travail IETF MARID (MTA Authorization Records in DNS) a apporté des contributions significatives au développement et à la discussion précoces des concepts SPF.

G.3 RFC 7208 Contributors (Contributeurs RFC 7208)​

Cette spécification actuelle (RFC 7208) a été rédigée par Scott Kitterman et basée sur RFC 4408. Les personnes suivantes ont contribué à cette mise à jour:

Contributeurs principaux:

  • Scott Kitterman (auteur principal)
  • Murray S. Kucherawy (contributeur et réviseur)

Réviseurs techniques et contributeurs:

  • Alessandro Vesely
  • Barry Leiba
  • Bron Gondwana
  • Franck Martin
  • John Levine
  • Michael Hammer
  • Pete Resnick
  • Steve Atkins
  • Stuart Cheshire

G.4 Community Contributions (Contributions de la communauté)​

La communauté SPF a activement contribué au développement, à l'implémentation et au déploiement de SPF:

Implémenteurs: De nombreux développeurs ont créé des bibliothèques et outils SPF dans divers langages de programmation, notamment:

  • Perl
  • Python
  • Java
  • C/C++
  • PHP
  • Ruby
  • Go

Fournisseurs de services: Les principaux fournisseurs de services de messagerie ont largement adopté SPF et ont aidé à affiner la spécification en fonction de l'expérience du monde réel:

  • Google (Gmail)
  • Microsoft (Outlook.com, Office 365)
  • Yahoo
  • AOL
  • Autres principaux fournisseurs de messagerie

Fournisseurs DNS: Les fournisseurs de services DNS ont développé des outils de gestion SPF et créé de la documentation pour faciliter l'adoption de SPF.

G.5 IETF Working Groups (Groupes de travail IETF)​

Plusieurs groupes de travail IETF ont contribué au développement de SPF:

Groupe de travail MARID (MTA Authorization Records in DNS):

  • Axé sur l'authentification des e-mails via DNS
  • A discuté de diverses approches de validation des expéditeurs
  • A fourni un forum pour le développement précoce de SPF

ASRG (Anti-Spam Research Group):

  • A évalué SPF dans le contexte des technologies anti-spam
  • A fourni des commentaires sur les considérations de sécurité et de confidentialité

Groupe de travail DKIM:

  • A travaillé sur des technologies d'authentification de messagerie complémentaires
  • A veillé à ce que SPF et DKIM fonctionnent bien ensemble

Groupe de travail DMARC:

  • A développé DMARC, qui intègre SPF et DKIM
  • A aidé à définir comment les résultats SPF sont utilisés dans les politiques d'authentification des e-mails

G.6 Tool and Library Developers (Développeurs d'outils et de bibliothèques)​

Les projets open source et développeurs suivants ont contribué de manière significative à l'écosystème SPF:

Bibliothèques SPF:

  • libspf2 (bibliothèque C) par le groupe de projet libspf2
  • Mail::SPF (module Perl) par Julian Mehnle et autres
  • pyspf (bibliothèque Python) par Stuart Gathman et Terence Way
  • spf4j (bibliothèque Java) par divers contributeurs

Outils de validation SPF:

  • Vérificateurs SPF en ligne de divers fournisseurs
  • Testeurs SPF en ligne de commande
  • Outils d'analyse DNS

Implémentations de serveurs de messagerie:

  • Intégration SPF Postfix
  • Support SPF Exim
  • Intégration SPF Sendmail
  • Implémentation SPF Microsoft Exchange

G.7 Documentation Contributors (Contributeurs à la documentation)​

De nombreuses personnes ont contribué à la documentation SPF, aux tutoriels et aux meilleures pratiques:

  • OpenSPF.org: Documentation et ressources SPF maintenues par la communauté
  • Listes de diffusion IETF: Discussions techniques détaillées et clarifications
  • Auteurs de blogs et rédacteurs techniques: Qui ont expliqué SPF à un public plus large
  • Documentations des fournisseurs DNS: Qui ont fourni des guides pratiques d'implémentation SPF

G.8 Testing and Deployment (Tests et déploiement)​

Organisations et personnes qui ont aidé aux tests et déploiements à grande échelle:

Adopteurs précoces:

  • Grands fournisseurs de services de messagerie qui ont testé SPF dans leurs réseaux
  • Organisations d'entreprise qui ont implémenté la validation SPF
  • ISP qui ont ajouté SPF comme composant de filtrage de spam

Tests d'interopérabilité:

  • Développeurs qui ont effectué des tests inter-implémentations
  • Organisations qui ont hébergé des suites de tests SPF
  • Contributeurs qui ont signalé des bogues et des problèmes d'interopérabilité

G.9 Special Thanks (Remerciements spéciaux)​

Remerciements spéciaux à:

  • Meng Weng Wong: Pour la conception SPF originale et son travail inlassable pour rassembler la communauté afin de développer la norme

  • Mark Lentczner: Pour la co-rédaction de la spécification RFC 4408 originale

  • Scott Kitterman: Pour avoir dirigé le processus de mise à jour de RFC 4408 vers RFC 7208 et pour la maintenance active continue de la communauté SPF

  • Wayne Schlitt: Pour ses contributions techniques approfondies et son expérience d'implémentation

  • Julian Mehnle: Pour le développement de bibliothèques SPF clés et la clarification de la spécification

La communauté Internet: À tous ceux qui ont utilisé, implémenté, discuté et contribué à améliorer l'authentification des e-mails.

G.10 Ongoing Work (Travaux en cours)​

Le développement de SPF se poursuit à travers:

  • Clarifications de spécifications: Discussions continues pour clarifier les cas limites
  • Mises à jour de bibliothèques: Maintenance active des implémentations SPF
  • Développement de meilleures pratiques: Guides évolutifs pour le déploiement SPF
  • Intégration avec d'autres normes: Coordination avec DKIM, DMARC et d'autres technologies de sécurité des e-mails

La communauté SPF reste active et engagée dans l'amélioration de l'authentification et de la sécurité des e-mails sur Internet.


Note finale: Cette spécification et le protocole SPF n'auraient pas été possibles sans les efforts d'innombrables bénévoles qui ont contribué leur temps, leur expertise et leurs ressources pour améliorer la sécurité des e-mails pour tous.