Passa al contenuto principale

RFC 7208 - Sender Policy Framework (SPF)

  • Stato: Proposed Standard
  • Pubblicato: April 2014
  • Stream: IETF
  • Sostituisce: RFC4408
  • Errata: Nessun errata

Informazioni di base​

  • Numero RFC: 7208
  • Titolo: Sender Policy Framework (SPF) for Authorizing Use of Domains in Email
  • Titolo italiano: Framework delle Politiche del Mittente
  • Data di pubblicazione: Aprile 2014
  • Stato: PROPOSED STANDARD (Standard proposto)
  • Autore: S. Kitterman

Sommario (Abstract)​

SPF consente ai proprietari di domini di specificare tramite record DNS quali server di posta sono autorizzati a inviare e-mail per quel dominio. I destinatari possono interrogare i record SPF per verificare se le e-mail provengono da server autorizzati, aiutando a rilevare e bloccare lo spoofing delle e-mail.

Contents​

Appendices (Appendici)​

Panoramica di SPF​

Cos'è SPF?​

Definizione:

SPF = Sender Policy Framework (Framework delle Politiche del Mittente)
Funzione: Verifica dei server di posta autorizzati
Metodo: Record DNS TXT
Scopo:
✓ Prevenire lo spoofing delle e-mail
✓ Ridurre lo spam
✓ Migliorare la consegnabilità delle e-mail

Trio di sicurezza e-mail:
1. SPF (questo RFC) - Verifica il server di invio
2. DKIM (RFC 6376) - Verifica il contenuto dell'e-mail
3. DMARC (RFC 7489) - Politica e rapporti unificati

Principio di funzionamento:

Mittente (example.com):
1. Pubblica record SPF nel DNS
example.com. IN TXT "v=spf1 ip4:203.0.113.1 -all"
→ Solo 203.0.113.1 è autorizzato

2. Il server di posta invia normalmente le e-mail
MAIL FROM: `<[email protected]>`

Destinatario:
1. Estrae il dominio del mittente
MAIL FROM: [email protected] → Dominio: example.com

2. Interroga il record SPF
Query DNS: record TXT example.com

3. Verifica l'IP del server di invio
IP del server di invio: 203.0.113.1
Record SPF consente: ip4:203.0.113.1
→ Corrispondenza!

4. Risultato SPF:
Pass ✓ → Server autorizzato
Fail ✗ → Server non autorizzato

SPF vs DKIM vs DMARC​

Confronto delle funzionalità:

SPF (RFC 7208):
- Verifica: IP del server di invio
- Posizione: SMTP MAIL FROM
- Record DNS: TXT
- Limitazione: Le e-mail inoltrate falliscono

DKIM (RFC 6376):
- Verifica: Firma digitale dell'e-mail
- Posizione: Header DKIM-Signature
- Record DNS: TXT (_domainkey)
- Limitazione: Richiede configurazione corretta delle chiavi

DMARC (RFC 7489):
- Verifica: Allineamento SPF + DKIM
- Posizione: Header From
- Record DNS: TXT (_dmarc)
- Funzione: Politica + Rapporti

Uso combinato:
SPF + DKIM → DMARC superato → Protezione ottimale

Formato del record SPF​

Sintassi di base​

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

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

Componenti:
- v=spf1: Identificatore di versione (richiesto, sempre spf1)
- mechanisms: Meccanismi di corrispondenza
- qualifiers: Qualificatori di risultato
- modifiers: Modificatori

Meccanismi (Mechanisms)​

1. all:

Definizione: Corrisponde a tutti gli IP
Utilizzo: Normalmente come politica predefinita alla fine

Esempi:
v=spf1 -all Tutti gli IP non consentiti (più rigoroso)
v=spf1 ~all Tutti gli IP softfail (raccomandato)
v=spf1 +all Tutti gli IP consentiti (non raccomandato!)

2. ip4/ip6:

Definizione: Indirizzi IP o intervalli espliciti

Esempi:
v=spf1 ip4:203.0.113.1 -all
→ Solo 203.0.113.1 è consentito

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

v=spf1 ip6:2001:db8::1 -all
→ Consente indirizzo IPv6

v=spf1 ip4:203.0.113.0/24 ip4:198.51.100.0/24 -all
→ Consente intervalli multipli

3. a:

Definizione: Record A/AAAA del dominio corrente

Esempi:
v=spf1 a -all
→ Consente IP dal record A di example.com

v=spf1 a:mail.example.com -all
→ Consente IP dal record A di mail.example.com

v=spf1 a/24 -all
→ Consente la rete /24 dell'IP del record A di example.com

4. mx:

Definizione: Record MX del dominio corrente

Esempi:
v=spf1 mx -all
→ Consente IP dei server MX di example.com

v=spf1 mx:example.com -all
→ Consente IP dei server MX di example.com

v=spf1 mx/24 -all
→ Consente la rete /24 dei server MX

5. include:

Definizione: Include il record SPF di un altro dominio

Esempi:
v=spf1 include:_spf.google.com -all
→ Consente server di posta Google (Gmail for Business)

v=spf1 include:spf.protection.outlook.com -all
→ Consente server di posta Microsoft 365

Include multipli:
v=spf1 include:_spf.google.com include:spf.protection.outlook.com -all

Attenzione: Limite massimo di 10 ricerche DNS!

6. exists:

Definizione: Corrisponde se il dominio specificato ha un record A

Esempio:
v=spf1 exists:%\{i}.spamhaus.example.com -all
→ Uso avanzato, normalmente per controlli di blacklist anti-spam

Espansione macro:
%\{i} = IP del server di invio (invertito)

7. ptr (non raccomandato):

Definizione: Query DNS inversa

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

Problemi:
❌ Prestazioni scadenti (richiede query DNS inversa)
❌ Bassa affidabilità
❌ RFC sconsiglia esplicitamente l'uso

Alternativa: Usare ip4/ip6 o include

Qualificatori (Qualifiers)​

Simbolo | Nome | Significato | Uso raccomandato
--------|------|-------------|------------------
+ | Pass | Superato (predefinito) | Server autorizzati
- | Fail | Fallito | Rifiuta e-mail
~ | SoftFail | Fallimento morbido | Accetta ma marca
? | Neutral | Neutrale | Nessuna politica chiara

Esempi:
v=spf1 +ip4:203.0.113.1 -all
↑pass esplicito ↑fail esplicito

v=spf1 ip4:203.0.113.1 ~all
↑+ predefinito ↑softfail

v=spf1 ?all
↑neutrale (equivalente a nessun SPF)

Raccomandazioni per l'uso dei qualificatori:

+ (Pass): 
✓ Server di posta autorizzati
Esempio: +ip4:203.0.113.1

- (Fail):
✓ -all finale (rigoroso)
✓ Vietare esplicitamente certi IP
Esempio: -all

~ (SoftFail):
✓ ~all finale (permissivo, raccomandato inizialmente)
✓ Usare durante il periodo di transizione
Esempio: ~all

? (Neutral):
✗ Usato raramente
✗ Equivalente a nessuna politica

Modificatori (Modifiers)​

1. redirect:

Definizione: Reindirizzamento al record SPF di un altro dominio

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

Scopo:
✓ Gestione centralizzata di SPF
✓ Più domini condividono una politica

Attenzione:
- Nessun altro meccanismo può seguire redirect
- Non può essere usato insieme ad all

2. exp:

Definizione: Spiegazione (testo di spiegazione in caso di fallimento SPF)

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

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

Scopo:
✓ Fornire messaggi di errore user-friendly
- Raramente usato nella pratica

Esempi di record SPF​

Configurazioni di base​

1. Un solo server di posta:

v=spf1 ip4:203.0.113.1 -all

Spiegazione:
- Solo 203.0.113.1 può inviare e-mail
- Altri IP vengono rifiutati

2. Uso dei record MX:

v=spf1 mx -all

Spiegazione:
- Consente ai server MX del dominio di inviare e-mail
- Si adatta automaticamente ai cambiamenti MX

3. Intervalli IP multipli:

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

Spiegazione:
- Consente due reti di classe C
- Adatto per distribuzione multi-datacenter

Servizi di terze parti​

4. Google Workspace (Gmail for Business):

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

Spiegazione:
- Usa Google per inviare e-mail
- Include il record SPF di 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

Configurazioni miste​

8. Server proprio + Terze parti:

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

Spiegazione:
- Server proprio: 203.0.113.1
- Google Workspace: include

9. Servizi di terze parti multipli:

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

Attenzione: Ogni include conta come una ricerca DNS

10. Dominio che non invia e-mail:

v=spf1 -all

Spiegazione:
- Il dominio non invia e-mail
- Previene lo spoofing
- Adatto per domini solo in ricezione

Sottodomini​

11. Configurazione separata dei sottodomini:

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

Spiegazione:
- Il dominio principale usa il proprio server
- Il sottodominio mail usa Google

12. Ereditarietà del sottodominio (senza record SPF):

Se mail.example.com non ha un record SPF:
→ Usa il record SPF di example.com

Se non si desidera l'ereditarietà:
mail.example.com: v=spf1 -all

Processo di verifica SPF​

Passaggi di verifica del destinatario​

// Pseudo-codice di verifica SPF
async function checkSPF(clientIP, sender, helo) {
// 1. Estrarre il dominio
const domain = sender.split('@')[1]; // [email protected] → example.com

// 2. Interrogare il record SPF
const spfRecord = await queryDNS(domain, 'TXT', 'v=spf1');

if (!spfRecord) {
return 'none'; // Nessun record SPF
}

// 3. Analizzare il record SPF
const mechanisms = parseSPF(spfRecord);

// 4. Verificare i meccanismi uno per uno
for (const mechanism of mechanisms) {
const result = await evaluateMechanism(mechanism, clientIP, domain);

if (result !== null) {
return result; // Corrispondenza trovata, restituire il risultato
}
}

return 'neutral'; // Nessuna corrispondenza
}

// Valutare un singolo meccanismo
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; // Nessuna corrispondenza
}

Risultati SPF​

Valore di ritorno | Significato          | Trattamento raccomandato
------------------|----------------------|-------------------------
none | Nessun record SPF | Accettare (fiducia ridotta)
neutral | Politica esplicita | Accettare
| nessuna |
pass | Superato | Accettare
fail | Fallito | Rifiutare
softfail | Fallimento morbido | Accettare ma marcare
temperror | Errore temporaneo | Riprovare più tardi
permerror | Errore permanente | Rifiutare

Esempi di risposte SMTP:
pass: 250 OK (SPF pass)
fail: 550 SPF check failed
softfail: 250 OK (aggiungere header X-SPF: softfail)

Limiti di ricerca DNS​

Limite di 10 ricerche​

Problema:

La verifica SPF esegue al massimo 10 ricerche DNS
Superamento del limite → permerror (Errore permanente)

Conta per le 10 ricerche:
✓ include
✓ a
✓ mx
✓ exists
✓ redirect

Non conta:
✗ ip4/ip6 (corrispondenza diretta)
✗ all (corrispondenza diretta)

Esempio - Limite superato:

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 ← Superato! permerror
-all

Se un include contiene altri include, anche questi contano!

Soluzioni:

1. Usare ip4/ip6 invece di a/mx
❌ v=spf1 a mx -all (2 ricerche)
✓ v=spf1 ip4:203.0.113.1 ip4:198.51.100.1 -all (0 ricerche)

2. Unire gli include
❌ include:service1.com include:service2.com
✓ Mantenere il proprio record SPF contenente tutti gli IP

3. SPF Flattening (Appiattimento SPF)
Interrogare regolarmente gli IP degli include, convertire in ip4/ip6

Strumento SPF Flattening​

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

// Analizzare 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') {
// Interrogare ricorsivamente gli include
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}`));
}
}
}

// Generare SPF appiattito
return `v=spf1 ${ips.join(' ')} -all`;
}

// Utilizzo
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

Strumenti pratici​

Generatore di record 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;
}
}

// Esempio di utilizzo
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());

// Output:
// 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

Strumento di verifica SPF​

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

class SPFChecker {
async check(domain, ip) {
try {
// Interrogare il record 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);

// Analizzare e verificare
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;

// Estrarre il qualificatore
let qualifier = '+';
let mechanism = part;

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

// Verificare il meccanismo
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);
}
// Altri meccanismi possono essere aggiunti qui...
}

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

isIPInRange(ip, range) {
// Versione semplificata, l'ambiente di produzione richiede un'implementazione completa
if (!range.includes('/')) {
return ip === range;
}
// Implementazione di corrispondenza CIDR omessa...
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['+'];
}
}

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

Migliori pratiche per la distribuzione​

1. Distribuzione graduale​

Fase 1: Modalità monitoraggio
v=spf1 ?all
o
v=spf1 ~all

Scopo: Raccogliere dati, osservare quali server inviano e-mail
Durata: 2-4 settimane

Fase 2: Fallimento morbido
v=spf1 ip4:x.x.x.x include:provider.com ~all

Scopo: Marcare ma non rifiutare e-mail non autorizzate
Durata: 4-8 settimane

Fase 3: Modalità rigorosa
v=spf1 ip4:x.x.x.x include:provider.com -all

Scopo: Rifiutare e-mail non autorizzate

2. Errori comuni​

❌ Errore 1: Dimenticare -all
v=spf1 ip4:203.0.113.1
→ Equivalente a v=spf1 ip4:203.0.113.1 ?all
→ Qualsiasi IP è neutrale

✓ Corretto:
v=spf1 ip4:203.0.113.1 -all

❌ Errore 2: Record SPF multipli
example.com TXT "v=spf1 ip4:203.0.113.1 -all"
example.com TXT "v=spf1 include:provider.com -all"
→ permerror

✓ Corretto: Unire in uno solo
v=spf1 ip4:203.0.113.1 include:provider.com -all

❌ Errore 3: Più di 10 ricerche
v=spf1 include:a include:b include:c ... (troppi)

✓ Corretto: Usare ip4 direttamente o flattening

❌ Errore 4: Uso di ptr
v=spf1 ptr:example.com -all
→ Prestazioni scadenti, non raccomandato

✓ Corretto: Usare ip4 o include

3. Test e verifica​

# Strumenti di test da riga di comando

# 1. Interrogare il record SPF
dig example.com TXT | grep "v=spf1"
o
nslookup -type=TXT example.com

# 2. Usare strumenti online
# - https://mxtoolbox.com/spf.aspx
# - https://www.kitterman.com/spf/validate.html

# 3. Inviare un'e-mail di test
# Inviare alla propria casella di posta, verificare l'header:
# Received-SPF: pass ...

Integrazione con DKIM/DMARC​

Configurazione completa della sicurezza e-mail​

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

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

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

Risultato:
- SPF verifica il server di invio ✓
- DKIM verifica il contenuto dell'e-mail ✓
- DMARC unifica la politica ✓
→ Tripla protezione!

Riferimenti​

RFC relativi a SPF:

  • [RFC 7208] SPF ← Questo documento
  • [RFC 7489] DMARC
  • [RFC 6376] DKIM

Risorse correlate:


Sommario: SPF è la prima linea di difesa per la sicurezza delle e-mail. Tramite record DNS, i server di invio sono autorizzati e lo spoofing delle e-mail è efficacemente prevenuto. Combinato con DKIM e DMARC, si crea un sistema completo di sicurezza e-mail. Ricorda: Inizia con il fallimento morbido e rafforza gradualmente verso la modalità rigorosa, e rispetta il limite di 10 ricerche DNS!


1. Introduction (Introduzione)​

L'infrastruttura di posta elettronica attuale ha la caratteristica che qualsiasi host che inietta messaggi nel sistema può utilizzare qualsiasi nome di dominio DNS nei vari identificatori specificati in [RFC5321] e [RFC5322]. Sebbene questa caratteristica sia vantaggiosa in alcuni casi, rappresenta un ostacolo importante nella riduzione delle e-mail di massa non richieste (UBE, Unsolicited Bulk Email, noto anche come spam). Inoltre, gli ADMD (come descritto in [RFC5598]) sono comprensibilmente preoccupati che altre entità possano facilmente utilizzare i loro nomi di dominio, spesso con intenti malevoli.

Questo documento definisce un protocollo attraverso il quale un ADMD può autorizzare gli host a utilizzare il suo nome di dominio nelle identità "MAIL FROM" o "HELO". Gli ADMD conformi pubblicano record Sender Policy Framework (SPF) nel DNS, specificando quali host sono autorizzati a utilizzare i loro nomi, e i destinatari di posta conformi utilizzano i record SPF pubblicati per testare l'autorizzazione di un agente di trasferimento di posta (MTA, Mail Transfer Agent) mittente che utilizza una determinata identità "HELO" o "MAIL FROM" durante una transazione di posta.

Un ulteriore vantaggio per i destinatari di posta è che, dopo aver validato l'uso di un'identità, le decisioni di politica locale riguardanti le e-mail possono essere prese sulla base del dominio del mittente piuttosto che sulla base dell'indirizzo IP dell'host. Questo è vantaggioso perché la reputazione di un nome di dominio può essere più accurata della reputazione di un indirizzo IP dell'host, poiché il nome di dominio potrebbe essere più stabile su un periodo di tempo più lungo. Inoltre, se l'identità dichiarata non può essere validata, la politica locale può adottare misure più severe contro tali e-mail, come rifiutarle.

1.1 Terminology (Terminologia)​

1.1.1 Key Words (Parole chiave)​

Le parole chiave "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" e "OPTIONAL" in questo documento devono essere interpretate come descritto in [RFC2119].

1.1.2 Imported Definitions (Definizioni importate)​

ABNF (Augmented Backus-Naur Form) è definito in [RFC5234], i token "ALPHA", "DIGIT" e "SP" (spazio) sono anch'essi definiti lì.

I token "Local-part", "Domain" e "Mailbox" sono definiti in [RFC5321].

"dot-atom", "quoted-string", "comment", "CFWS" (Comment Folded White Space), "FWS" (Folded White Space) e "CRLF" (Carriage-Return/Line-Feed) sono definiti in [RFC5322].

1.1.3 MAIL FROM Definition (Definizione MAIL FROM)​

Questo documento riguarda l'identità del mittente del messaggio, come descritto in [RFC5321]:

La transazione inizia con il comando MAIL, che fornisce l'identità del mittente.

Poiché questa identità ha molti altri nomi, è importante scegliere un nome che sia:

  1. Comunemente usato

  2. Chiaramente definito

Pertanto, il termine "MAIL FROM" sarà utilizzato in questo documento, definito come l'identità RFC5321.MailFrom (Reverse-Path) descritta in [RFC5598].

1.1.4 HELO Definition (Definizione HELO)​

Questo documento utilizza anche l'identità HELO/EHLO. L'identità "HELO" deriva dal comando SMTP HELO o EHLO (vedi [RFC5321]). Poiché HELO ed EHLO possono essere utilizzati in modo intercambiabile in molti casi, sono generalmente identificati come "HELO" in questo documento. Questo significa RFC5321.HELO/.EHLO come definito in [RFC5598]. Questi comandi forniscono l'identità del client SMTP (host mittente) per la sessione SMTP.

1.2 check_host()​

La sezione 4 presenta un algoritmo utilizzato per valutare la politica SPF rispetto a una transazione di posta in arrivo. Nelle prime implementazioni, questo algoritmo era codificato in una funzione chiamata check_host(). Questo nome è utilizzato in questo documento come simbolo dell'algoritmo di valutazione SPF, ma naturalmente gli implementatori non sono tenuti a utilizzare questo nome.


2. Operational Overview (Panoramica operativa)​

2.1 Publishing Authorization (Pubblicazione dell'autorizzazione)​

I domini conformi SPF pubblicano record SPF validi come descritto nella sezione 3. Questi record autorizzano i MTA specificati ad utilizzare il nome di dominio associato nelle identità "HELO" e "MAIL FROM".

I risultati SPF possono essere utilizzati per effettuare determinazioni sia positive (la fonte è autorizzata) che negative (la fonte non è autorizzata). Se un ADMD sceglie di pubblicare un record SPF e desidera supportare i destinatari nelle decisioni di autorizzazione negativa, deve pubblicare un record che termina con "-all" o che reindirizza a un altro che lo fa; altrimenti, non può essere fatta alcuna determinazione definitiva sull'autorizzazione. La sezione 10 discute problemi potenziali e misure di mitigazione relative alle decisioni negative.

Gli ADMD che desiderano dichiarare che nessun host è autorizzato ad utilizzare il loro nome di dominio DNS nei comandi HELO o MAIL FROM durante le sessioni SMTP possono pubblicare un tale record SPF per i nomi di dominio che non sono né utilizzati nella parte dominio degli indirizzi e-mail né previsti per inviare e-mail.

Quando si apportano modifiche ai record SPF, bisogna prestare attenzione ad assicurare che vi sia un periodo di transizione durante il quale la vecchia politica rimane valida fino a quando tutte le e-mail legittime possano ragionevolmente essere supposte essere state verificate. La sezione 4.5.4.1 di [RFC5321] discute per quanto tempo i messaggi possono rimanere in transito. Sebbene le verifiche offline siano possibili, più la verifica è vicina al momento di trasmissione originale, più è probabile ottenere un risultato SPF corrispondente all'intento dell'ADMD mittente al momento dell'invio del messaggio.

2.2 Checking Authorization (Verifica dell'autorizzazione)​

I destinatari di posta possono eseguire un insieme di verifiche SPF per ogni e-mail ricevuta. Una verifica SPF testa l'autorizzazione dell'host client a inviare posta con un'identità data. Tipicamente, tali verifiche sono eseguite dal MTA ricevente, ma possono essere eseguite altrove nella catena di elaborazione della posta finché le informazioni richieste sono disponibili e affidabili. Le identità "MAIL FROM" e "HELO" sono verificate rispettivamente secondo le sezioni 2.4 e 2.3.

Non è raccomandato verificare altre identità contro i record SPF versione 1 senza approvazione esplicita dell'ADMD pubblicante, poiché è noto che alcune situazioni danno risultati errati. Ad esempio, quasi tutte le mailing list riscrivono l'identità "MAIL FROM" (vedere sezione 10.3), ma alcune non modificano nessuna altra identità nel messaggio. I documenti che definiscono altre identità devono definire metodi di approvazione esplicita.

I destinatari di posta possono includere le verifiche SPF come parte di un insieme più ampio di test sulla posta in arrivo. I risultati di altri test possono influenzare se viene eseguita una particolare verifica SPF. Ad esempio, trovare l'indirizzo IP dell'host mittente in una whitelist locale può portare a saltare tutti gli altri test e accettare tutta la posta da quell'host.

Quando un destinatario di posta decide di eseguire una verifica SPF, deve utilizzare la funzione check_host() correttamente implementata (sezione 4) e valutare con i parametri corretti. Sebbene l'intero test sia opzionale, una volta presa la decisione di eseguirlo, deve essere eseguito come prescritto per preservare le semantiche corrette tra editori e destinatari.

Per eseguire il test, il destinatario di posta deve valutare la funzione check_host() con i parametri descritti nella sezione 4.1.

Sebbene domini non validi, mal formati o inesistenti portino le verifiche SPF a restituire "none" (poiché nessun record SPF viene trovato), la politica di molti MTA da tempo è di rifiutare le e-mail da tali domini, in particolare nel caso di "MAIL FROM" non valido. Rifiutare l'e-mail previene un modo per aggirare i record SPF.

Le implementazioni devono prestare attenzione ad estrarre correttamente il <domain> dai dati forniti con il comando SMTP MAIL FROM, poiché molti MTA accettano ancora cose come il source routing (vedere appendice C di [RFC5321]), il %-hack (vedere [RFC1123]) e i percorsi bang (vedere [RFC1983]). Queste caratteristiche obsolete sono state utilizzate in modo malevolo per aggirare i sistemi di sicurezza.

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

Si raccomanda che i verificatori SPF non solo verifichino l'identità "MAIL FROM" ma verifichino anche l'identità "HELO" separatamente applicando la funzione check_host() (sezione 4) all'identità "HELO" come <domain>. La verifica di "HELO" può favorire risultati coerenti e può ridurre l'uso delle risorse DNS. Se può essere fatta una determinazione definitiva su un messaggio sulla base della verifica di "HELO", le risorse DNS per elaborare il "MAIL FROM" normalmente più complesso possono essere evitate. Inoltre, poiché i record SPF pubblicati per l'identità "HELO" si riferiscono a un singolo host, quando disponibili, sono una fonte molto affidabile dello stato di autorizzazione dell'host. Se entrambi devono essere verificati, si raccomanda di verificare prima "HELO" e poi "MAIL FROM".

Si noti che i requisiti sul dominio presentato nel comando EHLO o HELO per i mittenti non sono sempre chiari, e i verificatori SPF devono essere preparati al fatto che l'identità sia un letterale di indirizzo IP (vedere sezione 4.1.3 di [RFC5321]) o semplicemente mal formata. Questa verifica SPF può essere eseguita solo se la stringa "HELO" è un nome di dominio multi-etichetta valido.

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

Se la verifica "HELO" non è stata eseguita o non ha raggiunto un risultato di politica definitivo, il verificatore SPF deve verificare l'identità "MAIL FROM" applicando la funzione check_host() all'identità "MAIL FROM" come <domain>.

[RFC5321] consente che il percorso inverso sia vuoto (vedere sezione 4.5.5 in [RFC5321]). In questo caso, non c'è una casella di posta del mittente esplicita, e tali messaggi possono essere assunti essere messaggi di notifica dal sistema di posta stesso. Quando il percorso inverso è vuoto, questo documento definisce l'identità "MAIL FROM" come la casella di posta composta dalla parte locale "postmaster" e dall'identità "HELO" (che può o non può essere stata verificata separatamente in precedenza).

2.5 Location of Checks (Posizione delle verifiche)​

Le verifiche di autorizzazione dovrebbero essere eseguite durante l'elaborazione della transazione SMTP che riceve l'e-mail. Questo riduce la complessità nel determinare l'indirizzo IP corretto da utilizzare come input per check_host() e consente di restituire gli errori direttamente al MTA mittente tramite le risposte SMTP. L'appendice D di [RFC7001] offre una discussione più completa su questo argomento.

Le verifiche di autorizzazione sono eseguite durante la transazione SMTP al momento del comando MAIL e utilizzano il valore MAIL FROM e l'indirizzo IP del client. Eseguire verifiche in un momento successivo o con altri input può portare ai seguenti problemi:

  • Può essere difficile estrarre accuratamente le informazioni richieste da header potenzialmente falsificati.

  • Le e-mail legittime possono fallire la verifica di autorizzazione perché la politica del mittente è cambiata.

Generare notifiche di mancata consegna a identità falsificate che hanno fallito la verifica di autorizzazione costituisce normalmente backscatter, cioè notifiche di rifiuto moleste inutilizzabili. Gli operatori sono fortemente incoraggiati ad evitare tali pratiche. La sezione 2 di [RFC3834] descrive il backscatter e i problemi che causa.

2.6 Results of Evaluation (Risultati della valutazione)​

La sezione 4 definisce check_host(), una definizione di funzione modello che utilizza gli input definiti sopra e la politica del mittente pubblicata nel DNS per arrivare a conclusioni sull'autorizzazione del client. I verificatori SPF implementano qualcosa di semanticamente equivalente alla funzione definita qui.

Questa sezione elenca e definisce brevemente le possibili uscite di questa funzione. Tuttavia, si noti che il protocollo non stabilisce requisiti normativi per il trattamento di un risultato particolare. Le opzioni di trattamento per ogni risultato sono discusse nella sezione 8.

2.6.1 None​

Un risultato di "none" significa che (a) nessun nome di dominio DNS sintatticamente valido è stato estratto dalla sessione SMTP per essere utilizzato come <domain> da autorizzare, o (b) nessun record SPF è stato recuperato dal DNS.

2.6.2 Neutral (Neutrale)​

Un risultato "neutral" significa che l'ADMD ha dichiarato esplicitamente di non affermare se l'indirizzo IP è autorizzato o meno.

2.6.3 Pass (Superato)​

Un risultato "pass" è una dichiarazione esplicita che il client è autorizzato a iniettare posta con l'identità data.

2.6.4 Fail (Fallito)​

Un risultato "fail" è una dichiarazione esplicita che il client non è autorizzato ad utilizzare il dominio nell'identità data.

2.6.5 Softfail (Fallimento morbido)​

Un risultato "softfail" è una dichiarazione debole dell'ADMD pubblicante che l'host potrebbe non essere autorizzato. Non ha pubblicato una politica più forte e più esplicita che porterebbe a un "fail".

2.6.6 Temperror (Errore temporaneo)​

Un risultato "temperror" significa che il verificatore SPF ha incontrato un errore transitorio (solitamente DNS) durante l'esecuzione della verifica. Un nuovo tentativo in un momento successivo può avere successo senza ulteriori azioni da parte dell'operatore DNS.

2.6.7 Permerror (Errore permanente)​

Un risultato "permerror" significa che il record pubblicato del dominio non è stato interpretato correttamente. Questo indica una condizione di errore che richiede definitivamente l'intervento dell'operatore DNS per essere risolta.


3. SPF Records (Record SPF)​

Un record SPF è un record DNS che dichiara quali host sono autorizzati (e quali non lo sono) a utilizzare il nome di dominio nelle identità "HELO" e "MAIL FROM". In linea generale, il record divide gli host in insiemi autorizzati e non autorizzati (sebbene alcuni host possano non appartenere a nessuna delle due categorie).

I record SPF sono rappresentati come una singola stringa di testo trovata nell'RDATA di un singolo record di risorsa DNS TXT; non sono consentiti record SPF multipli con lo stesso nome proprietario. Il formato del record e il processo di selezione dei record sono descritti di seguito nella sezione 4. Un record di esempio è il seguente:

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

Questo record ha versione "spf1" e contiene tre direttive: "+mx", "a:colo.example.com/28" (implicito "+"), e "-all".

Ogni record SPF è posizionato nell'albero DNS al nome proprietario a cui appartiene, non in un sottodominio sotto il nome proprietario. Questo è simile ai record SRV [RFC2782].

L'esempio in questa sezione potrebbe essere pubblicato dalla seguente riga in un file di zona del dominio:

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

Poiché i record TXT hanno usi multipli, notare gli altri record TXT pubblicati lì per altri scopi. Possono causare problemi di limiti di dimensione (vedere sezione 3.4), e si deve prestare attenzione ad assicurarsi che solo i record SPF siano utilizzati per l'elaborazione SPF.

Gli ADMD che pubblicano record SPF dovrebbero mantenere al minimo la quantità di informazioni DNS necessarie per valutare il record. Le sezioni 4.6.4 e 10.1.1 forniscono alcuni consigli sul meccanismo "include" e sui modificatori "redirect" concatenati.

3.1 DNS Resource Records (Record di risorse DNS)​

I record SPF devono essere pubblicati esclusivamente come record di risorse (RR) DNS TXT (tipo 16) [RFC1035]. Il contenuto in caratteri del record è codificato come [US-ASCII]. La fase di sperimentazione SPF supportava l'uso di un tipo di RR DNS alternativo, ma questo è stato ora abbandonato.

Nel 2003, quando SPF fu sviluppato per la prima volta, i requisiti per l'assegnazione di un nuovo tipo di RR DNS erano più severi di oggi. Inoltre, il supporto per il facile dispiegamento di nuovi tipi di RR DNS nei server DNS e nei sistemi di configurazione non era ampiamente distribuito. Pertanto, gli sviluppatori di SPF trovarono più facile e pratico utilizzare il tipo di RR TXT per memorizzare i record SPF.

Durante la revisione di [RFC4408], il gruppo di lavoro SPFbis concluse che il suo modello di transizione a doppio tipo di RR era fondamentalmente difettoso perché non conteneva un tipo di RR universale che gli implementatori dovevano fornire e verificare. Furono considerate molte alternative per risolvere questo problema, ma alla fine il gruppo di lavoro concluse che la probabilità di una migrazione al tipo di RR SPF in un futuro prevedibile era molto bassa e che la migliore soluzione a questo problema di interoperabilità era rimuovere il supporto per il tipo di RR SPF da SPF versione 1. Per ulteriori informazioni, vedere l'appendice A di [RFC6686].

Le circostanze attorno al dispiegamento iniziale di SPF un decennio fa erano uniche. Se in futuro viene sviluppato un aggiornamento di SPF che non riutilizza i record SPF esistenti, potrebbe utilizzare il tipo di RR SPF. L'uso da parte di SPF del tipo di RR TXT per memorizzare dati strutturati non deve in alcun modo essere considerato un precedente per i futuri progettisti di protocolli. Un'ulteriore discussione delle considerazioni di progettazione quando si utilizzano nuovi tipi di RR DNS può essere trovata in [RFC5507].

3.2 Multiple DNS Records (Record DNS multipli)​

Un nome di dominio non deve mai avere record multipli che porterebbero una verifica di autorizzazione a selezionare record multipli. Vedere la sezione 4.5 per le regole di selezione.

3.3 Multiple Strings in a Single DNS Record (Stringhe multiple in un singolo record DNS)​

Come definito in [RFC1035] sezioni 3.3 e 3.3.14, un singolo record DNS di testo può essere composto da stringhe multiple. Se un record pubblicato contiene stringhe di caratteri multiple, il record deve essere trattato come queste stringhe concatenate senza aggiunta di spazi. Ad esempio:

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

è equivalente a:

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

I record TXT contenenti stringhe multiple sono utili per costruire record che superano la lunghezza massima di 255 ottetti per una stringa di caratteri in un singolo record TXT.

3.4 Record Size (Dimensione del record)​

I record SPF pubblicati per un dato nome di dominio dovrebbero essere mantenuti sufficientemente piccoli affinché il risultato della query per esso si adatti in 512 ottetti. Altrimenti, è possibile superare i limiti del protocollo DNS. Questo limite UDP è definito in [RFC1035] sezione 2.3.4, sebbene sia stato aumentato da [RFC2671]. Rimanere sotto i 512 ottetti dovrebbe impedire alle implementazioni DNS più vecchie di passare a TCP e consentire l'uso di UDP senza supporto EDNS0 [RFC6891]. Poiché la dimensione della risposta dipende da molte cose al di fuori dello scopo di questo documento, può essere data solo la seguente guida: se la dimensione del messaggio DNS, la lunghezza combinata dei nomi DNS e del testo di tutti i record di un dato tipo è inferiore a 450 ottetti, allora la risposta DNS dovrebbe adattarsi in un pacchetto UDP. A causa di firewall e altri problemi che interferiscono con il funzionamento DNS su TCP o l'uso di EDNS0, i record troppo lunghi per adattarsi in un singolo pacchetto UDP possono essere silenziosamente ignorati dai validatori SPF.

Si noti che nel calcolare la dimensione della risposta per una query in formato TXT, tutti gli altri record TXT pubblicati al nome di dominio devono essere considerati. Allo stesso modo, le dimensioni delle risposte di tutte le query relative a SPF devono essere valutate per adattarsi in un singolo pacchetto UDP di 512 ottetti (cioè, dimensione del messaggio DNS limitata a 450 ottetti).

3.5 Wildcard Records (Record wildcard)​

L'uso di record wildcard per la pubblicazione è scoraggiato, e se vengono utilizzati, si deve usare cautela. Se una zona contiene record MX wildcard, potrebbe voler pubblicare una dichiarazione wildcard, ma deve essere soggetta agli stessi requisiti e problemi. In particolare, la dichiarazione deve essere ripetuta per qualsiasi host con record RR qualsiasi e i loro sottodomini. Consideriamo l'esempio da [RFC1034] sezione 4.3.3. Su questa base, possiamo fare quanto segue:

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"

Per ogni nome all'interno della zona, il record SPF deve essere elencato due volte: una volta per quel nome e una volta con un wildcard per coprire l'albero sotto quel nome, per coprire tutti i domini utilizzati nella posta in uscita.


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

Questa descrizione non è una definizione dell'interfaccia di programmazione dell'applicazione, ma una descrizione di funzione per illustrare l'algoritmo. Le implementazioni SPF conformi devono produrre risultati semanticamente equivalenti a questa descrizione.

La funzione check_host() recupera i record SPF, li analizza e li valuta per determinare se un particolare host è autorizzato o non autorizzato a inviare posta con una determinata identità. L'ADMD ricevente che esegue questo controllo deve valutare correttamente la funzione check_host() come descritto qui.

Le implementazioni possono utilizzare un algoritmo diverso dall'algoritmo canonico definito qui, purché i risultati siano identici in tutti i casi.

4.1 Arguments (Argomenti)​

La funzione check_host() accetta i seguenti argomenti:

<ip> - L'indirizzo IP del client SMTP che invia la posta, sia IPv4 che IPv6.

<domain> - Il dominio che fornisce le informazioni di autorizzazione ricercate; inizialmente la parte dominio dell'identità "MAIL FROM" o "HELO".

<sender> - L'identità "MAIL FROM" o "HELO".

Per valutazioni ricorsive, la parte dominio di <sender> può differire dall'argomento <domain> quando check_host() viene valutato per la prima volta. Nella maggior parte degli altri casi, sarà lo stesso (vedere sezione 5.2 sotto). Il limite globale di query DNS per i termini SPF descritto nella sezione 4.6.4 deve essere tracciato come un singolo limite globale su tutte le valutazioni, non solo per una singola istanza di valutazione ricorsiva.

Si noti che l'argomento <domain> potrebbe non essere un nome di dominio ben formato. Ad esempio, se il percorso inverso è vuoto, viene utilizzato il dominio EHLO/HELO con i suoi problemi associati (vedere sezione 2.3). In questi casi, check_host() è definito nella sezione 4.3 per restituire un risultato "none".

4.2 Results (Risultati)​

La funzione check_host() può restituire uno dei diversi risultati descritti nella sezione 2.6. L'azione da intraprendere in base al risultato è determinata dalla politica locale del destinatario. Questo è discusso nella sezione 8.

4.3 Initial Processing (Elaborazione iniziale)​

Se <domain> è formattato in modo errato (ad esempio, lunghezza dell'etichetta superiore a 63 caratteri, etichette di lunghezza zero non terminali, ecc.) o non è un nome di dominio multi-etichetta, o se la query DNS restituisce "Name Error" (RCODE 3, noto anche come "NXDOMAIN" [RFC2308]), check_host() restituisce immediatamente il risultato "none". Gli RCODE DNS sono definiti in [RFC1035]. Un dominio ben formato è un nome di dominio completamente qualificato come definito in [RFC1983]. Cioè, nel DNS, sono implicitamente qualificati rispetto alla radice (vedere sezione 3.1 di [RFC1034]). I nomi di dominio internazionalizzati devono essere codificati come A-label, come descritto nella sezione 2.3 di [RFC5890].

Se <sender> non ha una local-part, sostituire la local-part con la stringa "postmaster".

4.4 Record Lookup (Ricerca del record)​

A seconda di come viene pubblicato il record (vedere sezione 3 sopra), è necessaria una query DNS per il nome <domain>, solo per il tipo TXT.

Se la query DNS restituisce un guasto del server (RCODE 2) o un altro errore (RCODE né 0 né 3), o se la query scade, check_host() termina immediatamente con il risultato "temperror".

4.5 Selecting Records (Selezione dei record)​

I record iniziano con una parte versione:

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

Partendo dall'insieme di record restituito dalla query, scartare i record che non iniziano con una parte versione di esattamente "v=spf1". Si noti che la parte versione è terminata da un carattere SP o dalla fine del record. Ad esempio, un record con una parte versione "v=spf10" non corrisponde e viene scartato.

Se l'insieme di record risultante non contiene record, check_host() produce un risultato "none". Se l'insieme di record risultante contiene più record, check_host() produce un risultato "permerror".

4.6 Record Evaluation (Valutazione del record)​

La funzione check_host() analizza e interpreta il record SPF per trovare un risultato per il test corrente. Innanzitutto, la sintassi del record viene convalidata e, se sono presenti errori di sintassi in qualsiasi punto del record, check_host() restituisce immediatamente il risultato "permerror" senza ulteriore interpretazione o valutazione.

4.6.1 Term Evaluation (Valutazione dei termini)​

Esistono due tipi di termini: meccanismi (definiti nella sezione 5) e modificatori (definiti nella sezione 6). I record contengono un elenco ordinato di questi, come specificato nella seguente notazione di forma di Backus-Naur aumentata (ABNF).

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 maggior parte dei meccanismi consente un carattere ":" o "/" dopo il nome.

I modificatori contengono sempre un carattere uguale ('=') immediatamente dopo il nome e prima di qualsiasi carattere ":" o "/" che potrebbe far parte di un macro-string.

Un termine che non contiene nessuno dei caratteri "=", ":" o "/" è un meccanismo, come definito nella sezione 5.

Secondo la notazione ABNF come definita in [RFC5234], i nomi di meccanismi e modificatori non fanno distinzione tra maiuscole e minuscole.

4.6.2 Mechanisms (Meccanismi)​

Ogni meccanismo viene considerato in ordine da sinistra a destra. Se non ci sono più meccanismi, il risultato è il risultato predefinito descritto nella sezione 4.7.

Quando viene valutato un meccanismo, possono verificarsi tre cose: può corrispondere, non corrispondere o restituire un'eccezione.

Se corrisponde, l'elaborazione termina e il valore del qualificatore viene restituito come risultato per questo record. Se non corrisponde, l'elaborazione continua con il meccanismo successivo. Se restituisce un'eccezione, l'elaborazione del meccanismo termina e il valore dell'eccezione viene restituito.

I possibili qualificatori e i risultati che causano per check_host() sono i seguenti:

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

Il qualificatore è opzionale e il valore predefinito è "+".

Quando il meccanismo corrisponde e il qualificatore è "-", viene restituito un risultato "fail" e la stringa di spiegazione viene calcolata come descritto nella sezione 6.2.

La sezione 5 descrive i meccanismi specifici.

4.6.3 Modifiers (Modificatori)​

I modificatori non sono meccanismi. Non restituiscono corrispondenza o non corrispondenza. Invece, forniscono informazioni aggiuntive. Sebbene i modificatori non influenzino direttamente la valutazione del record, il modificatore "redirect" ha un impatto dopo la valutazione di tutti i meccanismi.

4.6.4 DNS Lookup Limits (Limiti di ricerca DNS)​

Alcuni meccanismi e modificatori (collettivamente chiamati "termini") causano query DNS durante la valutazione, mentre altri no. I seguenti termini causano query DNS: i meccanismi "include", "a", "mx", "ptr" e "exists", nonché il modificatore "redirect". Le implementazioni SPF devono limitare il numero totale di questi termini a 10 durante una valutazione SPF, per evitare un carico irragionevole sul DNS. Se questo limite viene superato, l'implementazione deve restituire "permerror". Altri termini -- i meccanismi "all", "ip4" e "ip6", nonché il modificatore "exp" -- non causano query DNS durante la valutazione SPF (il modificatore "exp" causa una query solo in un momento successivo), e il loro utilizzo non è soggetto a questo limite.

Durante la valutazione del meccanismo "mx", il numero di record di risorse "MX" interrogati è incluso nel limite globale sopra di 10 meccanismi/modificatori che causano query DNS. Oltre a questo limite, la valutazione di ciascun record "MX" non deve assolutamente comportare l'interrogazione di più di 10 record di indirizzi -- record di risorse "A" o "AAAA". Se questo limite viene superato, il meccanismo "mx" deve produrre un risultato "permerror".

Durante la valutazione del meccanismo "ptr" o della macro %\{p}, il numero di record di risorse "PTR" interrogati è incluso nel limite globale sopra di 10 meccanismi/modificatori che causano query DNS. Oltre a questo limite, la valutazione di ciascun record "PTR" non deve assolutamente comportare l'interrogazione di più di 10 record di indirizzi -- record di risorse "A" o "AAAA". Se questo limite viene superato, tutti i record tranne i primi 10 devono essere ignorati.

Il motivo della differenza è che l'insieme e il contenuto dei record MX sono sotto il controllo dell'ADMD di pubblicazione, mentre l'insieme e il contenuto dei record PTR sono sotto il controllo del proprietario dell'indirizzo IP che stabilisce effettivamente la connessione.

Questi limiti sono per meccanismo o macro in un record e si aggiungono ai limiti di query specificati sopra.

Un MTA o un altro processore dovrebbe imporre un limite di tempo trascorso massimo per la valutazione di check_host(). Tale limite dovrebbe consentire almeno 20 secondi. Se tale limite viene superato, il risultato di autorizzazione dovrebbe essere "temperror".

Come menzionato alla fine della sezione 11.1, in alcuni casi può essere utile limitare il numero di "termini" che restituiscono query DNS che restituiscono una risposta positiva (RCODE 0) con un conteggio delle risposte di 0, o una risposta "Name Error" (RCODE 3). Questi sono talvolta collettivamente chiamati "void lookups". Le implementazioni SPF dovrebbero limitare i "void lookups" a due. Le implementazioni possono scegliere di rendere tale limite configurabile. In questo caso, si raccomanda che il valore predefinito sia due. Il superamento del limite produce un risultato "permerror".

4.7 Default Result (Risultato predefinito)​

Se nessuno dei meccanismi corrisponde e non c'è un modificatore "redirect", check_host() restituisce il risultato "neutral", come se "?all" fosse specificato come ultima direttiva. Se è presente un modificatore "redirect", check_host() continua come definito nella sezione 6.1.

È preferibile utilizzare un modificatore "redirect" o un meccanismo "all" per terminare esplicitamente l'elaborazione. Sebbene ci sia un "?all" implicito alla fine di ogni record che non termina esplicitamente, aiuta gli sforzi di debug quando viene fornito esplicitamente.

Esempio:

v=spf1 +mx -all

Oppure

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

4.8 Domain Specification (Specifica del dominio)​

Diversi di questi meccanismi e modificatori hanno una parte <domain-spec>. La stringa è sottoposta a espansione di macro (vedere sezione 7). La stringa risultante è la rappresentazione abituale di un nome DNS completamente qualificato: una sequenza di etichette separate da punti. Questo dominio è chiamato <target-name> nel resto di questo documento.

Nota: Il risultato dell'espansione della macro non è soggetto ad alcun ulteriore escaping. Pertanto, questo strumento non può produrre tutti i caratteri legali nelle etichette DNS (ad esempio, caratteri di controllo). Tuttavia, questo strumento è sufficientemente potente per esprimere nomi host legali ed etichette di utilità comuni utilizzate nel DNS (ad esempio, "_spf").

Per diversi meccanismi, <domain-spec> è opzionale. Se non viene fornito, il <domain> dagli argomenti check_host() (vedere sezione 4.1) viene utilizzato come <target-name>. "domain" e <target-name> sono sintatticamente identici dopo l'espansione delle macro. "domain" è il valore di input per check_host(), mentre <target-name> è calcolato da check_host().

La valutazione di check_host() con un dominio sintatticamente non valido è indefinita.

Nota: Questo documento e il suo predecessore non contengono alcuna disposizione per la gestione corretta di <domain-spec> sintatticamente non validi (possibilmente il risultato di un'espansione di macro) secondo [RFC1035]. Gli esempi includono nomi con etichette vuote come "foo..example.com" ed etichette con una lunghezza superiore a 63 caratteri. Alcune implementazioni scelgono di trattare tali errori come non corrispondenza e quindi ignorano tali nomi, mentre altre implementazioni restituiscono un'eccezione "permerror".


5. Mechanism Definitions (Definizioni dei meccanismi)​

Questa sezione definisce due tipi di meccanismi: meccanismi di struttura del linguaggio di base e meccanismi di specifica del mittente.

I meccanismi di base facilitano la struttura del linguaggio. Non specificano un particolare tipo di schema di autorizzazione. I meccanismi di base sono i seguenti:

all
include

I meccanismi di specifica del mittente sono utilizzati per identificare un insieme di indirizzi <ip> che sono autorizzati o non autorizzati a inviare messaggi con <domain>. I meccanismi di specifica del mittente sono i seguenti:

a
mx
ptr (do not use)
ip4
ip6
exists

Le seguenti convenzioni si applicano a tutti i meccanismi che eseguono in qualsiasi momento un confronto tra <target-name> e un indirizzo IP:

Se non viene fornita alcuna lunghezza del prefisso CIDR nella direttiva, <target-name> viene confrontato con l'indirizzo IP per l'uguaglianza. (Qui, CIDR è il routing tra domini senza classi, descritto in [RFC4632].)

Se viene specificata una lunghezza del prefisso CIDR, solo il numero specificato di bit di ordine superiore di <target-name> viene confrontato con l'indirizzo IP per l'uguaglianza.

Quando un meccanismo recupera indirizzi host da confrontare con <ip>, vengono recuperati record "A" quando <ip> è IPv4 e vengono recuperati record "AAAA" quando <ip> è un indirizzo IPv6. Le implementazioni SPF su server IPv6 devono gestire sia i record "AAAA" che "A" per i client su indirizzi IPv6 mappati IPv4 [RFC4291]. Gli indirizzi IPv4 sono elencati solo nel record SPF con il meccanismo "ip4".

Diversi meccanismi dipendono da informazioni recuperate dal DNS. Per queste query DNS, se non diversamente specificato, se il server DNS restituisce un errore (RCODE né 0 né 3) o se la query scade, il meccanismo si arresta e il check_host() di livello superiore restituisce "temperror". Se il server restituisce "Name Error" (RCODE 3), la valutazione del meccanismo continua come se il server restituisse senza errori (RCODE 0) e zero record di risposta.

5.1 "all"​

all = "all"

Il meccanismo "all" è un test che corrisponde sempre. Viene utilizzato come meccanismo più a destra nel record per fornire un valore predefinito esplicito.

Esempio:

v=spf1 a mx -all

I meccanismi dopo "all" non vengono mai testati. I meccanismi elencati dopo "all" devono essere ignorati. Quando un meccanismo "all" è presente nel record, qualsiasi modificatore "redirect" (Sezione 6.1) deve essere ignorato, indipendentemente dall'ordine relativo dei termini.

5.2 "include"​

include = "include" ":" domain-spec

Il meccanismo "include" innesca una valutazione ricorsiva di check_host().

  1. <domain-spec> viene espanso secondo la Sezione 7.

  2. check_host() viene valutato con la stringa risultante come <domain>. I parametri <ip> e <sender> rimangono gli stessi della valutazione corrente di check_host().

  3. La valutazione ricorsiva restituisce corrispondenza, non corrispondenza o errore.

  4. Se restituisce corrispondenza, il meccanismo "include" utilizza il risultato appropriato (ad esempio, include o +include produce un risultato "pass", -include produce "fail").

  5. Se restituisce non corrispondenza o errore, il check_host() genitore riprende l'elaborazione secondo la tabella seguente e ripristina il valore <domain> precedente.

Retrospettivamente, il nome "include" è stata una scelta sbagliata. Viene utilizzato solo il risultato di valutazione del record SPF riferito, piuttosto che includere letteralmente i meccanismi del record riferito nel primo record. Ad esempio, la valutazione di una direttiva "-all" nel record riferito non termina l'elaborazione complessiva e non porta necessariamente a un "fail" complessivo. (Nomi migliori per questo meccanismo sarebbero stati "if-match", "on-match", ecc.)

Il meccanismo "include" consente a un dominio di specificare più domini amministrativamente indipendenti. Ad esempio, il dominio di vanità "example.net" potrebbe inviare messaggi utilizzando i server dei domini amministrativamente indipendenti example.com ed example.org.

Example.net potrebbe dire

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

Questo indicherebbe a check_host() di verificare efficacemente i record di example.com ed example.org per un risultato "pass". Solo se l'host non è autorizzato da nessuno di questi due domini il risultato sarebbe "fail".

Se questo meccanismo corrisponde, non corrisponde o restituisce un'eccezione dipende dal risultato della valutazione ricorsiva di 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 |
+---------------------------------+---------------------------------+

Il meccanismo "include" è destinato a attraversare i confini amministrativi. Quando si rimane all'interno di una singola autorità amministrativa, "include" di solito non è la scelta migliore. Ad esempio, se example.com ed example.org sono gestiti dalla stessa entità e se l'insieme degli host autorizzati per entrambi i domini è "mx:example.com", allora example.org potrebbe specificare "include:example.com", ma sarebbe meglio specificare "redirect=example.com" o anche "mx:example.com".

Con il meccanismo "include", è possibile autorizzare un insieme amministrativamente esterno di host, ma la determinazione della politica del mittente rimane una funzione del record SPF del dominio originale (determinato dal meccanismo "all" in quel record). Il modificatore "redirect" è più appropriato per consolidare l'autorizzazione e la politica in un insieme comune da condividere all'interno di un ADMD. Redirect è più simile a un elemento di codice comune da condividere tra i record all'interno di un singolo ADMD. Gli host autorizzati e le politiche di un numero qualsiasi di domini possono essere controllati da un singolo record.

5.3 "a"​

Questo meccanismo corrisponde quando <ip> è uno degli indirizzi IP di <target-name>. Per chiarire, questo significa che il meccanismo "a" corrisponde anche ai record AAAA.

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

Viene eseguita una query di indirizzo per <target-name> utilizzando il tipo di query (A o AAAA) appropriato per il tipo di connessione (IPv4 o IPv6). <ip> viene confrontato con gli indirizzi restituiti. Se un indirizzo corrisponde, il meccanismo corrisponde.

5.4 "mx"​

Questo meccanismo corrisponde quando <ip> è uno degli host MX del nome di dominio.

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

check_host() esegue prima una query MX per <target-name>. Quindi esegue una query di indirizzo per ciascun nome MX restituito. <ip> viene confrontato con ogni indirizzo IP restituito. Per prevenire attacchi di negazione del servizio (DoS), devono essere rispettati i limiti di elaborazione definiti nella Sezione 4.6.4. Se viene superato il limite di query MX, viene restituito "permerror" e la valutazione termina. Se un indirizzo corrisponde, il meccanismo corrisponde.

Nota sugli MX impliciti: Se <target-name> non ha record MX, check_host() non deve assolutamente applicare la regola MX implicita di [RFC5321], cioè interrogare i record A o AAAA per lo stesso nome.

5.5 "ptr" (do not use) ("ptr" (non utilizzare))​

Questo meccanismo testa se il mapping inverso DNS di <ip> esiste e punta correttamente a un nome di dominio all'interno di un dominio particolare. Questo meccanismo non dovrebbe essere pubblicato. Vedere le note alla fine di questa sezione per ulteriori informazioni.

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

Il nome per <ip> viene cercato utilizzando la seguente procedura:

  • Eseguire un mapping inverso DNS per <ip>: cercare il record PTR corrispondente in "in-addr.arpa.", se l'indirizzo è IPv4, o in "ip6.arpa.", se è IPv6.

  • Per ogni record restituito, validare il nome di dominio cercando il suo indirizzo IP. Per prevenire attacchi DoS, devono essere applicati i limiti di elaborazione PTR definiti nella Sezione 4.6.4. Se i limiti vengono superati, terminare l'elaborazione e il meccanismo non corrisponde.

  • Se <ip> è tra gli indirizzi IP restituiti, questo nome di dominio è validato.

Verificare tutti i nomi di dominio validati per vedere se corrispondono a <target-name> o sono sottodomini di <target-name>. Se ci sono corrispondenze, questo meccanismo corrisponde. Se non possono essere trovati nomi di dominio validati, o se nessun nome di dominio validato corrisponde o è un sottodominio di <target-name>, questo meccanismo non può corrispondere. Se si verifica un errore DNS durante l'esecuzione della query PTR RR, questo meccanismo non può corrispondere. Se si verifica un errore DNS durante l'esecuzione di una query A RR, questo nome di dominio viene saltato e la ricerca continua.

Questo meccanismo corrisponde quando:

  • <target-name> è un sottodominio del nome di dominio validato, o

  • <target-name> e il nome di dominio validato sono identici.

Ad esempio, "mail.example.com" è all'interno del dominio "example.com", ma "mail.bad-example.com" non lo è.

Nota: Questo meccanismo è lento, non affidabile come altri meccanismi in caso di errori DNS e impone un carico pesante sui server dei nomi .arpa. Se utilizzato, devono essere configurati record PTR appropriati per gli host del dominio e il meccanismo "ptr" dovrebbe essere uno degli ultimi meccanismi verificati. Dopo diversi anni di esperienza di distribuzione SPF, si è concluso che è inutile e dovrebbero essere utilizzate alternative più affidabili. Tuttavia, rimane parte del protocollo SPF, quindi le implementazioni check_host() conformi devono supportarlo.

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

Questi meccanismi testano se <ip> è contenuto in una rete IP data.

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

Confrontare <ip> con la rete data. Se i bit di ordine superiore della lunghezza del prefisso CIDR corrispondono, il meccanismo corrisponde.

Se ip4-cidr-length viene omessa, viene trattata come "/32". Se ip6-cidr-length viene omessa, viene trattata come "/128". Non è consentito omettere parti dell'indirizzo IP invece di utilizzare la notazione CIDR. Cioè, utilizzare 192.0.2.0/24 invece di 192.0.2.

5.7 "exists"​

Questo meccanismo è utilizzato per costruire un nome di dominio arbitrario per una query di record DNS A. Consente schemi complessi che coinvolgono parti arbitrarie della busta del messaggio per determinare cosa è consentito.

exists = "exists" ":" domain-spec

<domain-spec> viene espanso secondo la Sezione 7. Il nome di dominio risultante viene utilizzato per una query DNS A RR (anche se il tipo di connessione è IPv6). Se vengono restituiti record A, questo meccanismo corrisponde.

I domini possono utilizzare questo meccanismo per specificare query arbitrariamente complesse. Ad esempio, supponiamo che example.com pubblichi il record:

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

<target-name> potrebbe espandersi a "1.2.0.192.someuser._spf.example.com". Ciò consente di prendere decisioni granulari a livello di utente e indirizzo IP del client.


6. Modifier Definitions (Definizioni dei modificatori)​

I modificatori sono coppie nome/valore che forniscono informazioni aggiuntive. I modificatori hanno sempre un "=" che separa il nome e il valore.

I modificatori definiti in questo documento ("redirect" e "exp") dovrebbero apparire alla fine del record, dopo tutti i meccanismi, sebbene possano sintatticamente apparire ovunque nel record. L'ordine di questi due modificatori è irrilevante. Questi due modificatori non devono assolutamente apparire più di una volta in un record. Se lo fanno, check_host() termina con un risultato "permerror".

I modificatori non riconosciuti devono essere ignorati, indipendentemente da dove o quante volte appaiono. Ciò consente alle implementazioni conformi a questo documento di gestire correttamente i record con modificatori definiti in altre specifiche.

6.1 redirect: Redirected Query (redirect: Query reindirizzata)​

Il modificatore "redirect" è destinato a consolidare l'autorizzazione e la politica in un insieme comune da condividere all'interno di un singolo ADMD. Gli host autorizzati e le politiche di un numero qualsiasi di domini possono essere controllati da un singolo record.

redirect = "redirect" "=" domain-spec

Se tutti i meccanismi non corrispondono e un modificatore "redirect" è presente, il trattamento procede come segue:

La parte <domain-spec> della parte redirect viene espansa secondo le regole macro della Sezione 7. Quindi check_host() viene valutato con la stringa risultante come <domain>. I parametri <ip> e <sender> rimangono gli stessi dell'attuale valutazione di check_host().

Il risultato di questa nuova valutazione di check_host() viene quindi trattato come il risultato della valutazione corrente, tranne che se non viene trovato alcun record SPF o se <target-name> è formattato male, il risultato è "permerror" invece di "none".

Si noti che il dominio della nuova query può esso stesso specificare un trattamento redirect.

Questo strumento è destinato alle organizzazioni che desiderano applicare lo stesso record a più domini. Ad esempio:

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"

In questo esempio, la posta da uno qualsiasi di questi tre domini è descritta dallo stesso record. Questo può essere un vantaggio amministrativo.

Nota: In generale, il dominio "A" non può utilizzare in modo affidabile un reindirizzamento a un altro dominio "B" che non è sotto lo stesso controllo amministrativo. Poiché <domain> rimane invariato, non vi è alcuna garanzia che il record al dominio "B" funzionerà correttamente per le caselle di posta nel dominio "A", in particolare se il dominio "B" utilizza meccanismi che coinvolgono il local-part. La direttiva "include" sarebbe generalmente più appropriata.

Per chiarezza, qualsiasi modificatore "redirect" dovrebbe apparire come ultimo termine nel record. Se un meccanismo "all" è presente ovunque nel record, qualsiasi modificatore "redirect" deve essere ignorato.

6.2 exp: Explanation (exp: Spiegazione)​

explanation = "exp" "=" domain-spec

Se check_host() risulta in "fail" a causa di un meccanismo corrispondente (come "-all") e un modificatore "exp" è presente, la stringa di spiegazione restituita viene calcolata come descritto di seguito. Se non è presente alcun modificatore "exp", deve essere restituita all'applicazione chiamante una stringa di spiegazione predefinita o una stringa di spiegazione vuota.

<domain-spec> viene sottoposto a espansione macro (vedere Sezione 7) e diventa <target-name>. Il RRset DNS TXT per <target-name> viene recuperato.

Se ci sono errori di elaborazione DNS (qualsiasi RCODE diverso da 0), o se non vengono restituiti record, o se viene restituito più di un record, o se ci sono errori di sintassi nella stringa di spiegazione, continuare come se non fosse stato fornito alcun modificatore "exp".

Le stringhe del record TXT recuperato vengono concatenate senza spazi e quindi elaborate come explain-string, che viene sottoposta a espansione macro. Questo risultato finale è la stringa di spiegazione. Le implementazioni possono limitare la lunghezza della stringa di spiegazione risultante per consentire altri vincoli di protocollo e/o limiti di elaborazione ragionevoli. Poiché la stringa di spiegazione è destinata all'uso nelle risposte SMTP e la Sezione 2.4 di [RFC5321] afferma che le risposte sono [US-ASCII], la stringa di spiegazione deve essere limitata a [US-ASCII].

Il software che valuta check_host() può utilizzare questa stringa per comunicare informazioni dal dominio di pubblicazione sotto forma di messaggio breve o URL. Il software dovrebbe rendere chiaro che la stringa di spiegazione proviene da una terza parte. Ad esempio, potrebbe anteporre alla spiegazione la stringa macro "%\{o} explains: ", come mostrato nell'esempio della Sezione 8.4.

Supponiamo che example.com abbia questo record:

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

Ecco alcuni esempi di possibili record TXT di spiegazione a explain._spf.example.com:

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

-- un messaggio semplice e costante

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

-- un messaggio che contiene più informazioni, incluso l'indirizzo IP che ha fallito il controllo

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

-- un esempio complesso che utilizza i parametri di check_host() per costruire un URL in modo che possa essere generata una pagina Web con istruzioni dettagliate e personalizzate

Nota: Durante la ricorsione in un meccanismo "include", il modificatore "exp" da <target-name> non deve assolutamente essere utilizzato. Al contrario, quando si esegue un modificatore "redirect", il modificatore "exp" dal dominio originale non deve assolutamente essere utilizzato. Ciò è dovuto al fatto che "include" è destinato a attraversare i confini amministrativi e la spiegazione da fornire dovrebbe essere quella dell'ADMD ricevente, mentre "redirect" è destinato come strumento per consolidare i record di politica all'interno di un ADMD, e quindi la spiegazione reindirizzata è quella che dovrebbe avere la priorità.


7. Macros (Macro)​

Durante la valutazione dei record di politica SPF, alcune sequenze di caratteri sono destinate a essere sostituite da parametri del messaggio o della connessione. Queste sequenze di caratteri sono chiamate "macro".

7.1 Formal Specification (Specifica formale)​

La descrizione ABNF per le macro è la seguente:

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 (Definizioni delle macro)​

Le lettere di macro disponibili e i loro significati sono i seguenti:

  • s = <sender>
  • l = local-part di <sender>
  • o = domain di <sender>
  • d = <domain>
  • i = <ip>
  • p = il nome di dominio validato di <ip>
  • v = la stringa in-addr.arpa per le query PTR, "in-addr" per ip4, "ip6" per ip6
  • h = dominio HELO/EHLO

7.3 Macro Processing Details (Dettagli dell'elaborazione delle macro)​

Questa sezione descrive in dettaglio il processo di espansione delle macro.

La stringa macro in fase di espansione viene suddivisa in frammenti che iniziano con il carattere "%" o sono costituiti da tutti gli altri caratteri. I frammenti che iniziano con "%" sono chiamati "espansioni di macro". Tutti gli altri frammenti sono chiamati "letterali di macro".

Ogni espansione di macro viene sostituita (espansa) per produrre la stringa risultato. Le etichette dei nomi DNS in questa stringa risultato sono separate da caratteri ".", e ogni etichetta deve essere costituita dalla regola LDH (Letter-Digit-Hyphen): deve essere interamente composta da lettere ASCII minuscole, cifre ASCII e/o trattini. I letterali di macro vengono ripresi invariati nel risultato. Nessun carattere viene inserito tra le espansioni di macro e i letterali di macro.

Oltre all'espansione, non viene eseguito alcun escape o altra post-elaborazione sulla stringa risultato; viene utilizzata così com'è. Si noti che ciò significa che i caratteri ASCII NUL non sono necessari e non viene fornito alcun meccanismo per produrre tali caratteri nella stringa risultato.

Le lettere di macro vengono espanse ai loro valori definiti, come descritto nella Sezione 7.2, con le seguenti trasformazioni. La sintassi di trasformazione è definita dal componente transformers.

r transformer:

La lettera "r" indica che il valore deve essere invertito prima dell'espansione. Per gli indirizzi IPv6 e i nomi di dominio, l'inversione viene eseguita a livello di delimitatori di punto. Per gli indirizzi IPv4, l'inversione viene eseguita a livello di confini di punto.

DIGIT transformer:

Una o più cifre indicano quante parti separate da punti devono essere estratte dalla fine del valore. Se sono presenti cifre, questo indica il numero di etichette da utilizzare, partendo da destra (valore più significativo).

Se non viene specificata alcuna cifra, vengono utilizzate tutte le etichette. La cifra zero indica che deve essere utilizzata una stringa vuota. La stringa viene troncata dopo l'applicazione dei trasformatori.

Delimiters:

Uno o più delimitatori indicano quali caratteri devono essere sostituiti con il delimitatore "." dopo l'applicazione di altri trasformatori. Si noti che i delimitatori non sono una parte naturale del valore; vengono applicati durante l'espansione della macro. Ecco i delimitatori e le loro espansioni:

  • %\{s} = <sender>
  • %\{o} = parte dominio di <sender>
  • %\{d} = <domain>
  • %\{d4} = le ultime quattro etichette di <domain>
  • %\{d4r} = le ultime quattro etichette di <domain>, invertite
  • %\{l} = local-part di <sender>
  • %\{l-} = local-part, "." sostituito da "-"
  • %\{lr} = local-part, invertito
  • %\{lr-} = local-part, invertito, "." sostituito da "-"
  • %\{l1r-} = la prima parte di local-part, invertita, "." sostituito da "-"

7.4 Expansion Examples (Esempi di espansione)​

Ecco alcuni esempi di espansione di macro. Supponiamo:

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

Esempi di espansione di macro:

MacroRisultato dell'espansione
%\{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 (Gestione dei risultati)​

Questa sezione discute come le implementazioni SPF dovrebbero gestire i vari possibili risultati di check_host(). È solo consultiva, poiché le politiche locali del sito possono decidere di intraprendere azioni diverse per risultati particolari.

8.1 None​

Il ritorno di "none" significa che non è stata trovata alcuna politica del mittente applicabile corrispondente al dominio interrogato. Questo risultato dovrebbe essere trattato come equivalente a "SPF non esiste"; cioè, non c'è alcuna politica da valutare.

Gli MTA riceventi non dovrebbero rifiutare le e-mail sulla base di questo risultato. Sebbene il fallimento della verifica SPF possa portare al rifiuto, il risultato "none" non dovrebbe servire da base per il rifiuto poiché non fornisce alcuna informazione sull'autorizzazione del mittente.

8.2 Neutral​

Il ritorno di "neutral" significa che il proprietario del dominio ha dichiarato esplicitamente di non affermare se l'host mittente è autorizzato o meno. Questo risultato dovrebbe essere trattato come equivalente al risultato "none"; la verifica SPF non può né confermare né negare l'autorizzazione dell'host.

Gli MTA riceventi non dovrebbero rifiutare le e-mail sulla base di questo risultato.

8.3 Pass​

Il ritorno di "pass" significa che il client ha superato il test della politica del mittente. L'MTA ricevente può continuare con altri test anti-spam.

Gli MTA riceventi non dovrebbero definitivamente rifiutare le e-mail sulla base di questo risultato.

8.4 Fail​

Il ritorno di "fail" significa che il client non ha superato il test della politica del mittente. L'MTA ricevente può rifiutare l'e-mail.

Se l'ADMD pubblicante sceglie di restituire una stringa di spiegazione (utilizzando il modificatore "exp"), tale stringa dovrebbe essere restituita come parte della risposta SMTP. Se non viene fornita alcuna stringa di spiegazione, l'MTA ricevente dovrebbe utilizzare una spiegazione generica.

Si raccomanda di includere informazioni sul dominio pubblicante nonché informazioni di contatto per quel dominio (se disponibili) nella risposta SMTP restituita al mittente. Questo aiuta nel debug e può potenzialmente aiutare a prevenire il blocco di e-mail legittime.

Esempio di risposta 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​

Il ritorno di "softfail" significa che l'host potrebbe non essere autorizzato a inviare e-mail, ma la transizione non è ancora completa.

Gli MTA riceventi non dovrebbero rifiutare le e-mail sulla base di questo risultato, ma possono contrassegnarle come sospette in qualche modo. Ad esempio, l'MTA ricevente può mettere l'e-mail in una cartella spam o aggiungere un'intestazione.

8.6 Temperror​

Il ritorno di "temperror" significa che si è verificato un errore temporaneo durante la valutazione SPF. L'MTA ricevente dovrebbe accettare l'e-mail ma potrebbe voler riprovare la verifica SPF più tardi.

Ad esempio, se il server DNS è temporaneamente non disponibile, il destinatario può voler accettare l'e-mail e rivalutare la politica SPF in un momento successivo.

8.7 Permerror​

Il ritorno di "permerror" significa che si è verificato un errore permanente durante la valutazione SPF. Questo può essere dovuto a un errore di sintassi nel record SPF del dominio o ad altri problemi di configurazione.

L'MTA ricevente può rifiutare l'e-mail, ma dovrebbe anche registrare informazioni sull'errore per aiutare a diagnosticare il problema.


9. Recording the Result (Registrazione del risultato)​

Dopo che un controllo SPF è stato eseguito, il server di ricezione dovrebbe registrare il risultato per l'elaborazione e l'analisi successive.


9.1 The Received-SPF Header Field (Il campo di intestazione Received-SPF)​

Il server di ricezione DOVREBBE registrare il risultato della verifica SPF in un campo di intestazione Received-SPF. Questo campo viene aggiunto al messaggio di posta elettronica e fornisce una registrazione permanente della valutazione SPF.

Syntax (Sintassi)​

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 (Componenti del campo)​

  • result: Il risultato del controllo SPF (None, Neutral, Pass, Fail, SoftFail, TempError, PermError)
  • receiver: Il nome host del server di posta ricevente
  • identity: Quale identità è stata verificata (mailfrom, helo)
  • envelope-from: L'indirizzo MAIL FROM
  • helo: L'identità HELO/EHLO
  • client-ip: L'indirizzo IP del client

Example (Esempio)​

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 (Risultati SPF in Authentication-Results)​

Il destinatario PUÒ anche utilizzare il campo di intestazione Authentication-Results (definito in RFC 7001) per registrare i risultati SPF insieme ad altri metodi di autenticazione della posta elettronica come DKIM e DMARC.

Example (Esempio)​

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

9.3 Local Policy Storage (Archiviazione delle policy locali)​

I server di ricezione POSSONO memorizzare i risultati SPF per uso interno in log, database o sistemi di reputazione. Questi record possono essere utilizzati per:

  • Filtraggio dello spam: Utilizzo dei risultati SPF come segnale per la valutazione dello spam
  • Reporting: Generazione di statistiche e tendenze SPF
  • Reputazione: Costruzione della reputazione del mittente basata sulla conformità SPF
  • Analisi forense: Analisi di abusi di posta elettronica e tentativi di phishing

9.4 Downstream Processing (Elaborazione a valle)​

I risultati SPF dovrebbero essere preservati durante l'intero percorso di trasmissione della posta elettronica. Se un server di ricezione inoltra un messaggio a un altro server, il campo di intestazione Received-SPF originale dovrebbe essere mantenuto in modo che i sistemi a valle possano vedere il risultato della verifica SPF originale.


10. Effects on Infrastructure (Effetti sull'infrastruttura)​

L'implementazione di SPF può avere vari impatti sull'infrastruttura di posta elettronica e DNS. Gli amministratori dovrebbero essere consapevoli di questi potenziali impatti.


10.1 DNS Server Load (Carico del server DNS)​

Le verifiche SPF richiedono query DNS aggiuntive, il che può aumentare il carico sui server DNS. Per ogni messaggio di posta elettronica in arrivo, il destinatario deve:

  • Interrogare il record SPF del dominio mittente
  • Eseguire ricerche DNS aggiuntive per i meccanismi (A, MX, PTR, EXISTS, INCLUDE)
  • Eseguire query ricorsive per i meccanismi include:

Mitigation (Mitigazione)​

  • Caching DNS: Uso appropriato dei valori TTL per minimizzare le query ridondanti
  • Limiti di ricerca: SPF limita il numero di ricerche DNS a 10 per prevenire un carico eccessivo
  • Progettazione efficiente dei record SPF: Minimizzazione del numero di meccanismi e include

10.2 Large Volume Mailing (Invio di grandi volumi)​

Le organizzazioni che inviano grandi volumi di messaggi di posta elettronica dovrebbero assicurarsi che i loro record SPF:

  • Coprano tutti gli indirizzi IP di invio autorizzati: Inclusione di tutti i server di posta legittimi, terze parti e servizi cloud
  • Siano correttamente strutturati: Evitare PermError o troppe ricerche DNS
  • Siano regolarmente aggiornati: Quando l'infrastruttura di invio cambia

Third-Party Senders (Mittenti di terze parti)​

Le organizzazioni che utilizzano servizi di posta elettronica di terze parti (ad esempio, piattaforme di marketing, servizi cloud) devono autorizzare questi servizi nei loro record SPF:

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

10.3 Email Forwarding (Inoltro di posta elettronica)​

SPF può causare problemi con gli scenari di inoltro di posta elettronica:

Problema: Quando un destinatario inoltra un messaggio di posta elettronica a un altro destinatario, l'indirizzo IP di invio cambia (ora il server di inoltro), ma l'indirizzo MAIL FROM rimane l'originale. Ciò porta a fallimenti SPF.

Solutions (Soluzioni)​

  • SRS (Sender Rewriting Scheme): Riscrittura dell'indirizzo MAIL FROM durante l'inoltro
  • SPF Neutral o SoftFail: Utilizzo di ~all invece di -all per ridurre l'impatto
  • Integrazione DMARC: Utilizzo di DMARC con DKIM per gestire gli scenari di inoltro

10.4 Mailing Lists (Liste di distribuzione)​

Le liste di distribuzione affrontano sfide simili all'inoltro di posta elettronica:

  • Il server della lista di distribuzione inoltra messaggi da un mittente originale a molti abbonati
  • L'indirizzo MAIL FROM rimane spesso quello del mittente originale, ma l'IP di invio è il server della lista di distribuzione

Best Practices (Migliori pratiche)​

  • Riscrittura MAIL FROM: Il software della lista di distribuzione dovrebbe riscrivere l'indirizzo MAIL FROM nel dominio della lista di distribuzione
  • Firma DKIM: Le liste di distribuzione dovrebbero aggiungere le proprie firme DKIM
  • Intestazione List-ID: Utilizzo di List-ID e altre intestazioni per identificare l'origine della lista di distribuzione

10.5 IPv6 Considerations (Considerazioni IPv6)​

SPF supporta sia IPv4 che IPv6. Gli amministratori dovrebbero:

  • Includere meccanismi ip6: Se l'infrastruttura di invio supporta IPv6
v=spf1 ip4:192.0.2.0/24 ip6:2001:db8::/32 -all
  • Mantenere voci doppie: Assicurarsi che sia gli intervalli IPv4 che IPv6 siano coperti
  • Record DNS AAAA: Assicurarsi che i meccanismi A e MX risolvano correttamente gli indirizzi IPv6

10.6 Subdomain Policies (Policy per i sottodomini)​

Per impostazione predefinita, i sottodomini non ereditano i record SPF dal loro dominio genitore. Ogni sottodominio che invia messaggi di posta elettronica ha bisogno del proprio record SPF, oppure il dominio genitore dovrebbe pubblicare un record wildcard:

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

Questo impedisce agli aggressori di utilizzare sottodomini inesistenti per lo spoofing.


11. Security Considerations (Considerazioni sulla sicurezza)​

SPF fornisce miglioramenti importanti della sicurezza per la posta elettronica, ma presenta anche alcune limitazioni e potenziali rischi per la sicurezza.


11.1 Security Strengths (Punti di forza della sicurezza)​

SPF offre i seguenti vantaggi in termini di sicurezza:

Email Source Authentication (Autenticazione della fonte di posta elettronica)​

SPF consente ai destinatari di verificare che un messaggio di posta elettronica provenga da un server di posta autorizzato per un determinato dominio. Ciò riduce:

  • Spoofing del dominio: Impedisce agli aggressori di fingere di inviare da domini legittimi
  • Phishing: Rende più difficile per gli aggressori creare messaggi di posta elettronica che sembrano provenire da fonti fidate
  • Spam: Aiuta a identificare i messaggi di posta elettronica indesiderati provenienti da mittenti non autorizzati

Lightweight and Scalable (Leggero e scalabile)​

SPF utilizza l'infrastruttura DNS esistente, il che lo rende facile da implementare e mantenere senza richiedere nuovi protocolli o server.


11.2 Security Limitations (Limitazioni di sicurezza)​

SPF presenta limitazioni importanti che gli amministratori devono comprendere:

Does Not Authenticate Message Content (Non autentica il contenuto del messaggio)​

SPF valida solo l'identità MAIL FROM (Envelope From), non l'intestazione From che gli utenti finali vedono. Gli aggressori possono ancora:

  • Falsificare l'intestazione From e utilizzare un dominio diverso nel campo From visibile
  • Bypassare SPF utilizzando il proprio dominio con un record SPF valido

Soluzione: Utilizzare DMARC con SPF per applicare l'allineamento dell'intestazione From.

Does Not Protect Message Integrity (Non protegge l'integrità del messaggio)​

SPF non fornisce firme crittografiche o controlli di integrità per il contenuto della posta elettronica. Gli aggressori possono modificare il contenuto del messaggio durante il transito.

Soluzione: Utilizzare DKIM per la firma crittografica del messaggio e la protezione dell'integrità.

Forwarding Issues (Problemi di inoltro)​

Come discusso nella sezione 10.3, SPF fallisce con l'inoltro di posta elettronica e gli scenari di lista di distribuzione, poiché l'IP di invio cambia ma l'identità MAIL FROM rimane la stessa.

Soluzione: Utilizzare SRS (Sender Rewriting Scheme) o gestione della policy DMARC.


11.3 DNS Security (Sicurezza DNS)​

SPF si basa su DNS, che può essere vulnerabile a vari attacchi:

DNS Spoofing and Cache Poisoning (Spoofing DNS e avvelenamento della cache)​

Gli aggressori possono tentare di manipolare le risposte DNS per bypassare o ingannare i controlli SPF.

Mitigazione: Utilizzare DNSSEC per l'autenticazione crittografica delle risposte DNS.

DNS Lookup Amplification (Amplificazione delle ricerche DNS)​

I record SPF possono essere progettati per causare ricerche DNS eccessive, portando ad attacchi di tipo Denial of Service (DoS).

Mitigazione: SPF impone un limite di 10 ricerche DNS per verifica. Le implementazioni devono applicare questo limite e interrompere con PermError se viene superato.


11.4 Privacy Considerations (Considerazioni sulla privacy)​

Le verifiche SPF richiedono query DNS che rivelano l'indirizzo IP del mittente:

  • Gli amministratori di dominio possono registrare le query DNS e raccogliere informazioni sugli IP di invio
  • Gli ISP e i resolver DNS possono monitorare il traffico delle query SPF

Questi generalmente non sono gravi problemi di privacy, ma gli amministratori dovrebbero esserne consapevoli.


11.5 DoS Attacks (Attacchi DoS)​

Le verifiche SPF richiedono ricerche DNS, che possono essere sfruttate per attacchi DoS:

Excessive DNS Queries (Query DNS eccessive)​

Gli aggressori possono inviare messaggi di posta elettronica con record SPF complessi che attivano molte ricerche DNS, sovraccaricando i server DNS del destinatario.

Mitigazione: Applicare il limite di 10 ricerche e interrompere l'elaborazione con PermError.

DNS Reflection Attacks (Attacchi di riflessione DNS)​

Gli aggressori possono abusare dell'elaborazione SPF per amplificare gli attacchi di riflessione DNS.

Mitigazione: Implementare la limitazione della frequenza e il monitoraggio delle query DNS.


11.6 Best Practices for Secure SPF Deployment (Migliori pratiche per la distribuzione sicura di SPF)​

Per massimizzare la sicurezza delle distribuzioni SPF:

  1. Use SPF with DKIM and DMARC (Utilizzare SPF con DKIM e DMARC): Combinare SPF con DKIM per la firma del messaggio e DMARC per l'applicazione della policy.

  2. Deploy DNSSEC (Distribuire DNSSEC): Proteggere le risposte DNS con DNSSEC per prevenire lo spoofing DNS.

  3. Use Hard Fail Cautiously (Utilizzare Hard Fail con cautela): Iniziare con ~all (SoftFail) per i test prima di passare a -all (Fail).

  4. Monitor and Maintain SPF Records (Monitorare e mantenere i record SPF): Aggiornare regolarmente i record SPF quando l'infrastruttura di posta cambia.

  5. Limit DNS Lookups (Limitare le ricerche DNS): Mantenere i record SPF semplici ed evitare meccanismi include: e redirect: eccessivi.

  6. Implement Logging and Monitoring (Implementare la registrazione e il monitoraggio): Tracciare i risultati della verifica SPF e indagare sulle anomalie.

  7. Educate Users (Educare gli utenti): Informare gli utenti sul phishing e sui limiti di SPF nella convalida dell'intestazione From.


Appendix A. Extended Examples (Esempi estesi)​

Questa appendice fornisce esempi estesi di record SPF, dimostrando vari scenari di configurazione e migliori pratiche.

A.1 Simple Examples (Esempi semplici)​

A.1.1 Consentire solo un singolo indirizzo IP​

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

Spiegazione: Solo l'indirizzo IP 192.0.2.1 è autorizzato a inviare e-mail per conto di example.com. Tutti gli altri indirizzi IP porteranno a un risultato "fail".

A.1.2 Utilizzo dei record MX​

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

Spiegazione: Consente ai server di posta elencati nei record MX di example.com di inviare e-mail. Questa è una configurazione comune perché si adatta automaticamente alle modifiche dei record MX.

A.1.3 Utilizzo dei record A​

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

Spiegazione: Consente agli indirizzi IP nel record A (o AAAA per IPv6) di example.com di inviare e-mail.

A.1.4 Combinazione di più meccanismi​

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

Spiegazione: Consente e-mail dalle seguenti fonti:

  • Server MX di example.com
  • Record A di mail.example.com
  • Qualsiasi IP nella rete 192.0.2.0/24

A.1.5 Politica di soft-fail​

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

Spiegazione: Utilizza soft-fail (~all) invece di hard-fail (-all). Questo è utile durante la fase di test o migrazione. I destinatari possono accettare le e-mail ma contrassegnarle come sospette.

A.2 Multiple Domain Example (Esempio multi-dominio)​

Per le organizzazioni con più domini che utilizzano la stessa infrastruttura di posta:

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"

Spiegazione:

  • example.com ha il proprio record SPF
  • example.org ed example.net reindirizzano al record SPF condiviso
  • _spf.example.com contiene la politica effettiva

Vantaggi:

  • Gestione centralizzata della configurazione dei server di posta
  • Un singolo aggiornamento influenza più domini
  • Manutenzione DNS ridotta

A.3 DNS Blacklist (DNSBL) Style Example (Esempio di stile blacklist DNS)​

Utilizzo del meccanismo exists per implementare funzionalità simili a DNSBL:

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

Spiegazione:

  • %\{ir}: Indirizzo IP invertito (ad esempio, 192.0.2.1 diventa 1.2.0.192)
  • %\{l1r+-}: Prima parte del local-part del mittente, invertita, "." e "+" sostituiti da "-"
  • %\{d}: Nome di dominio

Esempio di espansione:

Se il mittente è [email protected] che invia da 192.0.2.1:

  • La macro si espande a: 1.2.0.192.user._spf.example.com

Quindi questo nome di dominio viene interrogato per i record A. Se esiste, la verifica SPF ha successo.

Casi d'uso:

  • Controllo granulare basato sull'utente
  • Integrazione con database o sistemi personalizzati
  • Decisioni di autorizzazione dinamiche

A.4 Multiple Requirements Example (Esempio di requisiti multipli)​

Configurazione complessa che combina più meccanismi e modificatori:

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"

Spiegazione:

  • ip4:192.0.2.0/24: Rete server di posta interni
  • ip4:198.51.100.0/24: Rete data center di backup
  • include:_spf-servers.example.com: Includere lista server aggiuntivi
  • include:_spf.google.com: Utilizzare Google Workspace
  • a:outbound.example.com: Server in uscita specifico
  • mx: Includere server dei record MX
  • ~all: Soft-fail per tutti gli altri casi

Progettazione gerarchica:

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

Questo consente di dividere i grandi record SPF in parti più gestibili.

A.5 Esempi di configurazione sottodomini​

A.5.1 Sottodomini con politiche diverse​

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"

Spiegazione:

  • Il dominio principale utilizza i record MX
  • Il sottodominio mail utilizza solo il suo record A
  • Il sottodominio shop utilizza un servizio di terze parti (Shopify)

A.5.2 Sottodomini che non inviano e-mail​

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

Spiegazione: Dichiara esplicitamente che questi sottodomini non inviano e-mail, per prevenire la contraffazione.

A.6 Esempi di integrazione servizi di terze parti​

A.6.1 Utilizzo di più fornitori di servizi di posta elettronica​

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

Spiegazione:

  • Google Workspace per e-mail dei dipendenti
  • Microsoft 365 per i partner
  • SendGrid per e-mail di marketing

A.6.2 Verifica dei limiti delle query DNS​

L'esempio sopra utilizza 3 include, ognuno dei quali può attivare query aggiuntive. È necessario assicurarsi che il numero totale di query non superi 10.

Metodo di verifica:

# Verificare SPF di Google
dig _spf.google.com TXT

# Verificare SPF di Microsoft
dig spf.protection.outlook.com TXT

# Verificare SPF di SendGrid
dig sendgrid.net TXT

Calcolare il numero di meccanismi in ogni include, assicurandosi che il totale ≤ 10.

A.7 Esempi di configurazione errata (da evitare)​

A.7.1 ❌ Record SPF multipli (errore)​

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

Problema: Questo porterà a "permerror". Un dominio può avere solo un record SPF.

Metodo corretto:

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

A.7.2 ❌ -all mancante (non sicuro)​

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

Problema: Nessuna politica predefinita esplicita, equivale a ?all (neutrale), nessun IP fallirà.

Metodo corretto:

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

A.7.3 ❌ Superamento del limite di query 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"

Problema: 11 include superano il limite di 10 query, portando a "permerror".

Soluzione: Utilizzare l'appiattimento SPF o utilizzare direttamente i meccanismi ip4.

A.8 Esempio di configurazione IPv6​

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

Spiegazione: Supporta sia reti IPv6 che IPv4.

A.9 Esempio di stringa di spiegazione​

example.com.         IN TXT "v=spf1 mx -all exp=explain._spf.%\{d}"
explain._spf.example.com. IN TXT "E-mail da %\{i}, ma questo IP non è autorizzato da %\{d}. Contattare postmaster@%\{d}."

Spiegazione: Quando la verifica SPF fallisce, il destinatario può interrogare la stringa di spiegazione e mostrarla all'utente.

Dopo l'espansione macro (supponendo invio da 192.0.2.99):

"E-mail da 192.0.2.99, ma questo IP non è autorizzato da example.com. Contattare [email protected]."

A.10 Strategia di test e transizione​

Fase 1: Modalità monitoraggio (2-4 settimane)​

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

Fase 2: Registrare fonti di invio effettive (2-4 settimane)​

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

Fase 3: Soft-fail (4-8 settimane)​

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

Fase 4: Modalità rigorosa (ambiente di produzione)​

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

Raccomandazione: Monitorare i risultati della verifica SPF in ogni fase per assicurarsi che nessuna e-mail legittima venga bloccata.


Appendix B. Changes in Implementation Requirements from RFC 4408 (Modifiche dei requisiti di implementazione rispetto a RFC 4408)​

Questa appendice riassume i principali cambiamenti di RFC 7208 rispetto al suo predecessore RFC 4408.

B.1 Cambiamenti principali​

B.1.1 Tipo RR SPF deprecato​

Requisito RFC 4408:

  • Pubblicazione simultanea di record TXT e SPF (tipo 99)
  • Le implementazioni devono verificare entrambi i tipi di record

Cambiamento RFC 7208:

  • Utilizzare solo record TXT (tipo 16)
  • Il tipo RR SPF non è più supportato
  • Implementazione e distribuzione semplificate

Motivo: Tasso di adozione molto basso del tipo RR SPF, sistema a doppio tipo che causava problemi di interoperabilità.

B.1.2 Chiarimento dei limiti di query DNS​

RFC 4408:

  • Limite di query DNS descritto in modo insufficientemente chiaro
  • Limite "void lookup" non definito

RFC 7208:

  • Definizione chiara del limite di 10 query DNS
  • Aggiunto limite "void lookup" (raccomandato 2)
  • Descrizione dettagliata dei limiti aggiuntivi per i meccanismi MX e PTR

Limiti specifici:

- Query DNS totali: ≤ 10 (include, a, mx, ptr, exists, redirect)
- Per meccanismo mx: ≤ 10 query di indirizzo
- Per meccanismo ptr: ≤ 10 query di indirizzo
- Void lookups: ≤ 2 (raccomandato)
- Tempo di valutazione: ≥ 20 secondi (raccomandato)

B.1.3 Gestione del "local-part"​

RFC 4408:

  • Gestione del local-part insufficientemente chiara
  • Gestione del local-part vuoto non definita

RFC 7208:

  • Specifica chiara: se <sender> non ha local-part, utilizzare "postmaster"
  • Miglioramento della gestione del percorso inverso vuoto (<>)

Esempio:

MAIL FROM:<>
→ SPF utilizza l'identità HELO, local-part è "postmaster"

B.1.4 Forte opposizione al meccanismo "ptr"​

RFC 4408:

  • Meccanismo "ptr" consentito ma non raccomandato

RFC 7208:

  • Chiaramente contrassegnato come "do not use" (non utilizzare)
  • Avvertimento aggiunto nel nome del meccanismo
  • Enfasi sui problemi di prestazioni e affidabilità

Motivi:

  • Query DNS inverse lente
  • Dipende dalla configurazione di terze parti (proprietario indirizzo IP)
  • Carico sui server dei nomi .arpa

B.1.5 Correzione della sintassi delle macro​

RFC 4408:

  • Definizione della sintassi delle macro ambigua

RFC 7208:

  • Definizione ABNF migliorata
  • Chiarimento delle regole di espansione delle macro
  • Corretti casi limite

B.1.6 Considerazioni di sicurezza per il modificatore "exp"​

RFC 4408:

  • Considerazioni di sicurezza insufficientemente dettagliate

RFC 7208:

  • Aggiunti avvertimenti di sicurezza sulle stringhe di spiegazione esterne
  • Raccomandazione di limitare la lunghezza delle stringhe di spiegazione
  • Enfasi sulla necessità di identificare le spiegazioni come provenienti da terze parti

B.2 Cambiamenti dei requisiti di implementazione​

B.2.1 Cambiamenti MUST (Deve essere implementato)​

Nuovi requisiti:

  1. Le implementazioni devono interrogare solo record TXT (non più SPF RR)
  2. Le implementazioni devono limitare il numero totale di query DNS a 10
  3. Le implementazioni devono gestire il limite "void lookup"
  4. Le implementazioni devono restituire "permerror" in caso di superamento dei limiti

Requisiti rimossi:

  1. Supporto del tipo RR SPF non più necessario
  2. Logica di conversione per record a doppio tipo non più necessaria

B.2.2 Cambiamenti SHOULD (Dovrebbe essere implementato)​

Nuove raccomandazioni:

  1. Dovrebbe implementare timeout di valutazione (almeno 20 secondi)
  2. Dovrebbe limitare "void lookup" a 2
  3. Dovrebbe verificare le identità HELO e MAIL FROM
  4. Dovrebbe effettuare la verifica durante la transazione SMTP

B.2.3 Cambiamenti MAY (Può essere implementato)​

Nuove opzioni:

  1. Può utilizzare algoritmi non canonici (purché i risultati siano identici)
  2. Può configurare il limite "void lookup"
  3. Può limitare la lunghezza delle stringhe di spiegazione

B.3 Cambiamenti di terminologia​

B.3.1 Standardizzazione dei nomi delle identità​

RFC 4408:

  • Utilizzava più nomi: "MAIL FROM", "SMTP MAIL FROM", "reverse-path"
  • Terminologia incoerente

RFC 7208:

  • Utilizzo uniforme dell'identità "MAIL FROM"
  • Definizione chiara come RFC5321.MailFrom
  • Riferimento alla terminologia standard RFC 5598

B.3.2 Adozione della terminologia "ADMD"​

RFC 4408:

  • Utilizzava "domain owner", "sending domain"

RFC 7208:

  • Adozione di "ADMD" (Administrative Management Domain)
  • Descrizione più precisa della parte responsabile

B.4 Miglioramento delle considerazioni di sicurezza​

B.4.1 Nuovi argomenti di sicurezza​

  1. Contraffazione tra utenti (Sezione 11.4):

    • Non coperto in RFC 4408
    • RFC 7208 discute esplicitamente i problemi di contraffazione degli utenti intra-dominio
  2. Esposizione della privacy (Sezione 11.6):

    • Le macro nelle query DNS possono divulgare informazioni sensibili
    • Raccomandazione di utilizzare con cautela le macro contenenti informazioni sul mittente
  3. Fonti di informazioni non attendibili (Sezione 11.5):

    • Discussione dettagliata dei rischi di intestazioni e spiegazioni esterne
    • Enfasi sull'importanza della validazione e del filtraggio

B.4.2 Rafforzamento della protezione DoS​

RFC 4408:

  • Limiti di query di base

RFC 7208:

  • Meccanismi di protezione a più livelli
  • Valori limite chiari
  • Raccomandazioni di timeout
  • Limite "void lookup"

B.5 Cambiamenti di registrazione IANA​

B.5.1 Tipo RR SPF​

RFC 4408:

  • Registrazione del tipo RR SPF (tipo 99)

RFC 7208:

  • Tipo RR SPF contrassegnato come obsoleto
  • Raccomandazione di utilizzare solo record TXT

B.5.2 Registro dei modificatori​

Nuovo RFC 7208:

  • Creazione del registro dei modificatori SPF
  • Processo di registrazione standardizzato per nuovi modificatori
  • Requisito che i modificatori sconosciuti devono essere ignorati

B.6 Miglioramenti dell'interoperabilità​

B.6.1 Chiarimento della selezione dei record​

RFC 4408:

  • Gestione di più record poco chiara

RFC 7208:

  • Specifica chiara: più record SPF portano a "permerror"
  • Regole migliorate di corrispondenza delle stringhe di versione
  • Chiarimento delle regole di concatenazione dei record (stringhe multiple)

B.6.2 Standardizzazione della gestione degli errori​

Miglioramenti RFC 7208:

  • Tutte le situazioni di errore hanno risultati chiari
  • Gestione standardizzata degli errori DNS
  • Miglioramento della gestione dei timeout

B.7 Retrocompatibilità​

B.7.1 Cambiamenti compatibili​

La maggior parte dei cambiamenti sono retrocompatibili:

  • Formato record TXT invariato
  • Sintassi dei meccanismi e modificatori essenzialmente identica
  • Algoritmo di base rimane coerente

B.7.2 Cambiamenti che possono influire sulla compatibilità​

  1. Rimozione del tipo RR SPF:

    • Le vecchie implementazioni potrebbero ancora interrogare SPF RR
    • Raccomandazione: Rimuovere i record SPF RR, mantenere solo TXT
  2. Limiti più rigorosi:

    • Il limite "void lookup" è appena aggiunto
    • Alcuni vecchi record potrebbero superare i nuovi limiti
    • Raccomandazione: Ottimizzare i record SPF per rispettare i limiti
  3. Opposizione al meccanismo "ptr":

    • Deve ancora essere supportato ma fortemente sconsigliato
    • Raccomandazione: Migrare ad altri meccanismi

B.8 Cambiamenti della struttura del documento​

Miglioramenti RFC 7208:

  • Organizzazione dei capitoli più chiara
  • Esempi estesi aggiunti (Appendice A)
  • Raccomandazioni di implementazione aggiunte (Appendici C-G)
  • Presentazione migliorata delle definizioni ABNF

B.9 Guida alla migrazione​

Migrazione da RFC 4408 a RFC 7208:​

Editori:

  1. Rimuovere i record SPF RR, mantenere solo i record TXT
  2. Verificare e ottimizzare il numero di query DNS (≤ 10)
  3. Sostituire il meccanismo "ptr" con "ip4" o "ip6"
  4. Validare il numero di "void lookup" (≤ 2)
  5. Testare se i record superano 512 ottetti

Destinatari:

  1. Smettere di interrogare il tipo SPF RR
  2. Implementare i nuovi limiti di query DNS
  3. Implementare il limite "void lookup"
  4. Aggiornare la logica di gestione degli errori
  5. Considerare l'implementazione del timeout di valutazione

Test:

# Utilizzare uno strumento di validazione SPF per testare i record
# Ad esempio: https://www.kitterman.com/spf/validate.html

# Verificare il numero di query DNS
dig +short example.com TXT | grep "v=spf1"

# Validare la dimensione del record
dig example.com TXT | grep -A1 "ANSWER SECTION"

B.10 Aggiornamento dei documenti di riferimento​

RFC 7208 fa riferimento a standard aggiornati:

  • RFC 5321 (sostituisce RFC 2821)
  • RFC 5322 (sostituisce RFC 2822)
  • RFC 5234 (aggiornamento ABNF)
  • RFC 5598 (terminologia dell'architettura di posta)
  • RFC 5890 (nomi di dominio internazionalizzati)

Appendix C. Further Testing Advice (Ulteriori consigli per i test)​

Questa appendice fornisce raccomandazioni dettagliate per testare e validare le implementazioni SPF.

C.1 Test dei record SPF​

C.1.1 Validazione di base​

Test di query DNS:

# Interrogare il record SPF
dig example.com TXT | grep "v=spf1"

# O utilizzare nslookup
nslookup -type=TXT example.com

# O utilizzare host
host -t TXT example.com

Punti di validazione:

  • ✓ Il record inizia con v=spf1
  • ✓ Solo un record SPF
  • ✓ Sintassi corretta (nessun errore di battitura)
  • ✓ Dimensione del record < 512 ottetti

C.1.2 Strumenti di validazione online​

Strumenti online consigliati:

  1. Kitterman SPF Validator

    • URL: https://www.kitterman.com/spf/validate.html
    • Funzionalità: Verifica della sintassi, conteggio query DNS, dettagli di analisi
  2. MXToolbox SPF Record Check

    • URL: https://mxtoolbox.com/spf.aspx
    • Funzionalità: Validazione record, rilevamento avvisi ed errori
  3. DMARCIAN SPF Inspector

    • URL: https://dmarcian.com/spf-survey/
    • Funzionalità: Analisi approfondita, raccomandazioni di ottimizzazione

Elementi da verificare:

✓ Correttezza della sintassi
✓ Numero di query DNS (≤ 10)
✓ Numero di void lookup (≤ 2)
✓ Lunghezza del record
✓ Validità dei meccanismi
✓ Profondità della catena include

C.2 Test dell'implementazione della verifica SPF​

C.2.1 Scenari di test unitari​

Caso di test 1: Corrispondenza IP di base

Record SPF: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: pass

IP di test: 192.0.2.2
Risultato atteso: fail

Caso di test 2: Range CIDR

Record SPF: v=spf1 ip4:192.0.2.0/24 -all
IP di test: 192.0.2.100
Risultato atteso: pass

IP di test: 192.0.3.1
Risultato atteso: fail

Caso di test 3: Meccanismo MX

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

Record SPF: v=spf1 mx -all
IP di test: 192.0.2.10
Risultato atteso: pass

Caso di test 4: Meccanismo Include

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

IP di test: 192.0.2.50
Risultato atteso: pass

Caso di test 5: Soft-fail

Record SPF: v=spf1 ip4:192.0.2.1 ~all
IP di test: 203.0.113.1
Risultato atteso: softfail

C.2.2 Test di casi limite​

MAIL FROM vuoto:

MAIL FROM: <>
HELO: mail.example.com
Atteso: Utilizzare identità HELO, local-part è "postmaster"

Nome di dominio non valido:

MAIL FROM: [email protected]
Risultato atteso: none (o permerror)

Timeout DNS:

Simulare un timeout DNS
Risultato atteso: temperror

Record SPF multipli:

example.com TXT "v=spf1 mx -all"
example.com TXT "v=spf1 a -all"
Risultato atteso: permerror

C.2.3 Test di limiti​

Test del limite di query DNS:

# Pseudo-codice
def test_dns_lookup_limit():
# Creare un record SPF con 11 include
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 del limite di record MX:

# Creare un dominio con 11 record MX
# Atteso: il meccanismo mx restituisce permerror

Test di Void Lookup:

# Creare un include che restituisce NXDOMAIN
# Il conteggio dovrebbe essere incluso nel limite void lookup

C.3 Invio di e-mail di test​

C.3.1 Processo di test​

Passo 1: Preparare il dominio di test

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

Passo 2: Inviare un'e-mail di test

# Utilizzare lo strumento swaks
swaks --to [email protected] \
--from [email protected] \
--server smtp.example.com

# O utilizzare 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

Passo 3: Verificare le intestazioni dell'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 Test di diversi scenari​

Scenario 1: Test Pass

Configurazione: Inviare da IP autorizzato
Intestazione attesa: Received-SPF: pass

Scenario 2: Test Fail

Configurazione: Inviare da IP non autorizzato
Atteso: L'e-mail viene rifiutata o contrassegnata
Intestazione attesa: Received-SPF: fail

Scenario 3: Test SoftFail

Configurazione: Il record SPF utilizza ~all
Inviare da IP non autorizzato
Atteso: L'e-mail viene accettata ma contrassegnata
Intestazione attesa: Received-SPF: softfail

Scenario 4: Test Neutral

Configurazione: Il record SPF utilizza ?all
Intestazione attesa: Received-SPF: neutral

C.4 Test delle macro​

C.4.1 Validazione dell'espansione delle macro​

Caso di test:

Mittente: [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 di macro complessa:

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

Espanso a: 100.2.0.192.user._spf.example.com
Validazione: Interrogare il record A per questo nome di dominio

C.4.2 Test di delimitatori delle macro​

Mittente: [email protected]

%\{l} → user+tag
%\{l-} → user-tag (+ sostituito da -)
%\{lr} → gat+resu (invertito)
%\{lr-} → gat-resu (invertito e sostituito)

C.5 Test di prestazioni​

C.5.1 Test di tempo di risposta​

Test di riferimento:

# Testare il tempo di query DNS
time dig example.com TXT

# Testare la verifica SPF completa
time spf_check example.com 192.0.2.1 [email protected]

Obiettivi di prestazioni:

  • Record semplice (1-2 meccanismi): < 100ms
  • Record complesso (più include): < 500ms
  • Tempo massimo consentito: 20 secondi

C.5.2 Test di carico​

Simulare alta concorrenza:

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

# Testare 1000 verifiche SPF concorrenti
start = time.time()
results = check_spf_concurrent(1000)
end = time.time()

print(f"1000 verifiche completate in: {end - start} secondi")
print(f"Media per verifica: {(end - start) / 1000 * 1000}ms")

C.6 Test di regressione​

C.6.1 Suite di test​

Set di test minimo:

1. Scenari pass/fail di base
2. Tutti i 7 meccanismi (all, include, a, mx, ptr, ip4, ip6, exists)
3. Tutti i 4 qualificatori (+, -, ~, ?)
4. Entrambi i modificatori (redirect, exp)
5. Espansione delle macro
6. Gestione degli errori (temperror, permerror)
7. Test dei limiti (query DNS, timeout)

Suite di test RFC 7208:

# Utilizzare la suite di test ufficiale
git clone https://github.com/openspf/openspf.git
cd openspf/tests
./run_tests.sh

C.6.2 Integrazione continua​

Esempio di configurazione 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 dei problemi comuni​

C.7.1 Funzionalità di posta obsolete​

Source Routing:

MAIL FROM:&lt;@relay.example.com:[email protected]>
Atteso: Estrarre correttamente example.com come dominio

%-hack:

MAIL FROM:&lt;user%[email protected]>
Atteso: Gestire correttamente o rifiutare

Bang Path:

MAIL FROM:&lt;[email protected]>
Atteso: Gestire correttamente o rifiutare

C.7.2 Nomi di dominio internazionalizzati​

Test IDN:

Dominio: münchen.de
A-label: xn--mnchen-3ya.de
Record SPF: Deve utilizzare A-label

Test: Assicurarsi della conversione e query corrette

C.7.3 Test IPv6​

Formati di indirizzo IPv6:

Formato completo: 2001:0db8:0000:0000:0000:0000:0000:0001
Formato compresso: 2001:db8::1
IPv4-mapped: ::ffff:192.0.2.1

SPF: v=spf1 ip6:2001:db8::/32 -all
Test: Tutti i formati dovrebbero corrispondere correttamente

C.8 Tecniche di debug​

C.8.1 Abilitare la registrazione dettagliata​

Mittente:

# 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

Destinatario:

# Abilitare la registrazione di debug SPF
spf_debug_level = 5
tail -f /var/log/mail.log | grep SPF

C.8.2 Utilizzare il tracciamento dig​

Tracciare le query SPF:

# Visualizzare il processo completo di risoluzione DNS
dig +trace example.com TXT

# Visualizzare la catena include
dig _spf.google.com TXT
dig _netblocks.google.com TXT

C.8.3 Utilizzare strumenti di debug SPF​

Python pyspf:

import spf

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

print(f"Risultato: {result}")
print(f"Spiegazione: {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 "Risultato: " . $result->code . "\n";

C.9 Monitoraggio dell'ambiente di produzione​

C.9.1 Metriche di monitoraggio​

Metriche chiave:

- Tasso di pass SPF
- Tasso di fail SPF
- Tasso di softfail SPF
- Tasso di temperror SPF (dovrebbe essere molto basso)
- Tasso di permerror SPF (dovrebbe essere 0)
- Tempo di verifica medio
- Tasso di timeout DNS

C.9.2 Configurazione degli avvisi​

Regole di avviso consigliate:

- Tasso di permerror > 0%: Avviso immediato (errore record SPF)
- Tasso di temperror > 5%: Avvertimento (problemi DNS)
- Aumento improvviso del tasso di fail > 20%: Avviso (possibile cambio di configurazione o attacco)
- Tempo di verifica medio > 1 secondo: Avvertimento (problema di prestazioni)

C.9.3 Analisi dei log​

Analizzare i fallimenti SPF:

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

# Analizzare domini mittente con fail
grep "Received-SPF: fail" /var/log/mail.log | \
grep -oP 'envelope-from=\K[^;]+' | \
cut -d@ -f2 | sort | uniq -c | sort -rn

Generare un rapporto:

# Generatore di rapporto statistiche 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 (Interazioni SPF/Mediatore)​

Questa appendice discute l'interazione tra SPF e mediatori di posta (come mailing list e servizi di inoltro) e i loro impatti.

D.1 Originating ADMDs (ADMD di origine)​

L'ADMD di origine è il dominio amministrativo che invia inizialmente la posta. In presenza di mediatori, l'ADMD di origine deve considerare i servizi di inoltro e lista attraverso cui le sue mail possono passare.

D.1.1 Identificazione del problema​

Presupposto base SPF:

  • Le mail vengono inviate direttamente dai server autorizzati ai destinatari
  • L'identità MAIL FROM rimane invariata
  • L'indirizzo IP mittente è autorizzato nel record SPF

Presupposti infranti dai mediatori:

  • Le mail passano attraverso sistemi intermedi
  • Possono essere rinviate da un indirizzo IP diverso
  • MAIL FROM può essere modificato o rimanere invariato

D.1.2 Scelte per il mittente​

Opzione 1: Utilizzare una politica SPF permissiva

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

Vantaggi:

  • Consente l'inoltro legittimo
  • Riduce i falsi positivi

Svantaggi:

  • Indebolisce la protezione SPF
  • Più facile da falsificare

Opzione 2: Affidarsi ad altri metodi di autenticazione

Pubblicare firme DKIM:
- DKIM rimane valido durante l'inoltro
- Indipendente dall'indirizzo IP mittente
- Funziona con DMARC

Opzione 3: Accettare i fallimenti SPF

example.com IN TXT "v=spf1 mx -all"
  • Accettare che alcune mail legittime possano essere contrassegnate o rifiutate
  • Fare affidamento sugli utenti per utilizzare il metodo di invio corretto
  • Raccomandare agli utenti di non inoltrare ma di usare "Invia copia"

D.1.3 Migliori pratiche​

Configurazione raccomandata:

1. Pubblicare un record SPF rigoroso (-all)
2. Implementare simultaneamente la firma DKIM
3. Pubblicare una politica DMARC
4. Educare gli utenti sui problemi di inoltro

Esempio di configurazione DMARC:

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

Spiegazione dei parametri:

  • adkim=r: Allineamento DKIM rilassato
  • aspf=r: Allineamento SPF rilassato
  • p=quarantine: Mettere in quarantena in caso di fallimento

D.2 Mediators (Mediatori)​

I mediatori sono sistemi che modificano o reinviano mail nella catena di trasmissione. I mediatori comuni includono mailing list, servizi di inoltro e sistemi di risposta automatica.

D.2.1 Mailing list​

Problema:

Le mailing list tradizionali conservano il MAIL FROM originale:

Originale: MAIL FROM:`&lt;[email protected]&gt;`
Dopo lista: MAIL FROM:`&lt;[email protected]&gt;`
IP mittente: list-server.mailinglist.org

Verifica SPF:

Interrogare il record SPF di example.com
Verificare l'IP di list-server.mailinglist.org
Risultato: fail (IP non è nel record SPF di example.com)

D.2.2 Soluzioni​

Soluzione 1: Riscrivere MAIL FROM (raccomandato)

Riscritto: MAIL FROM:`&lt;[email protected]&gt;`
Reply-To: [email protected]

Vantaggi:

  • La verifica SPF ha successo
  • I rimbalzi tornano al server di lista
  • Il destinatario può identificare correttamente

Svantaggi:

  • Modifica le informazioni del mittente originale
  • Gli utenti devono adattarsi a Reply-To

Esempio di implementazione (Mailman):

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

Soluzione 2: Utilizzare SRS (Sender Rewriting Scheme)

SRS è uno schema di riscrittura più complesso:

Originale: [email protected]
Riscritto in: [email protected]

Formato SRS:

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

Esempio:
[email protected]

Vantaggi:

  • Preserva le informazioni del mittente originale (nel local-part)
  • La verifica SPF ha successo
  • Può essere tracciato e verificato

Svantaggi:

  • Implementazione complessa
  • Necessita di un database SRS
  • Il local-part diventa difficile da leggere

Soluzione 3: Utilizzare DKIM invece di SPF

Configurazione:

1. Il mittente originale utilizza la firma DKIM
2. Il server di lista conserva la firma originale
3. Il server di lista aggiunge la propria firma DKIM
4. Il destinatario verifica DKIM (ignora il fallimento SPF)

Configurazione DMARC:

_dmarc.example.com IN TXT "v=DMARC1; p=none; adkim=r; aspf=r"
  • p=none: Nessuna applicazione (consente il fallimento SPF)
  • adkim=r: Allineamento DKIM rilassato (consente la firma di lista)

D.2.3 Servizi di inoltro posta​

Tipo 1: Inoltro semplice

Configurazione utente: [email protected] → [email protected]
Il servizio di inoltro conserva: MAIL FROM:`&lt;[email protected]&gt;`
Invia dall'IP del server di inoltro

Problema SPF:

Gmail verifica SPF di original.com
L'IP del server di inoltro non è nel record SPF
Risultato: fail

Soluzione A: Riscrittura SRS

Il servizio di inoltro utilizza SRS:
MAIL FROM:&lt;[email protected]>

Soluzione B: Utilizzare ~all invece di -all

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

Le mail inoltrate otterranno softfail invece di fail, più probabilmente accettate.

Tipo 2: File .forward

# ~/.forward
[email protected]

Problema identico all'inoltro semplice.

Migliori pratiche:

1. I servizi di inoltro dovrebbero implementare SRS
2. Il mittente originale dovrebbe utilizzare DKIM
3. I destinatari dovrebbero considerare i risultati DKIM, non solo SPF

D.2.4 Sistemi di risposta automatica e notifica​

Problema:

Mail originale: [email protected] → [email protected]
Risposta automatica: MAIL FROM:`&lt;[email protected]&gt;`
(Inviata dal server company.com)

La verifica SPF fallirà.

Soluzione:

Inviare notifiche con MAIL FROM vuoto:
MAIL FROM:<>
From: Mail Delivery System `&lt;[email protected]&gt;`

Oppure:

Utilizzare un indirizzo locale:
MAIL FROM:`&lt;[email protected]&gt;`
From: Automatic Reply `&lt;[email protected]&gt;`
Reply-To: [email protected]

D.3 Receiving ADMDs (ADMD destinatari)​

L'ADMD destinatario deve gestire le mail provenienti da mediatori e prendere decisioni appropriate.

D.3.1 Identificazione delle mail di mediatori​

Identificatori:

1. Salti intermedi nelle intestazioni Received
2. Intestazioni List-* (mailing list)
3. Precedence: bulk o list
4. MAIL FROM in formato SRS
5. Firma DKIM da servizio di lista noto

Esempio di logica di rilevamento:

def is_mailing_list(message):
# Verificare intestazioni 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

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

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

return False

D.3.2 Raccomandazioni di politica​

Politica 1: Trattamento permissivo delle mail di lista

if is_mailing_list(message):
if spf_result == 'fail':
# Verificare DKIM
if dkim_result == 'pass':
accept_message()
else:
# Verificare la reputazione della lista
if list_is_trusted(list_id):
accept_message()
else:
quarantine_message()

Politica 2: Affidarsi a DMARC

if dmarc_result == 'pass':
accept_message()
elif spf_result == 'fail' and dkim_result == 'fail':
reject_message()
else:
# SPF o DKIM ha successo
if is_mailing_list(message):
accept_message()
else:
apply_content_filtering()

Politica 3: Regole specifiche dell'utente

Gli utenti possono configurare whitelist:
- Mailing list affidabili
- Indirizzi di inoltro noti
- Trattamento permissivo di domini specifici

D.3.3 Raccomandazioni di implementazione​

Configurazione SpamAssassin:

# Trattamento permissivo delle mailing list
header LIST_ID exists:List-Id
score LIST_ID -0.1

# SPF fail ma con intestazione List-Id
meta SPF_FAIL_LIST (SPF_FAIL && LIST_ID)
score SPF_FAIL_LIST 0.5

# SPF fail normale (senza intestazione di lista)
score SPF_FAIL 5.0

Configurazione Postfix:

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

# Il servizio di politica SPF può identificare le mail di lista e adattarsi

Configurazione rspamd:

-- Configurazione modulo SPF
spf {
-- Applicare peso diverso per le mailing list
symbol_fail = "R_SPF_FAIL";
symbol_softfail = "R_SPF_SOFTFAIL";

-- Regole personalizzate
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 Raccomandazioni di interoperabilità​

D.4.1 Standardizzazione​

Utilizzare intestazioni standard:

Le mailing list dovrebbero aggiungere:
- List-Id: &lt;list-name.domain.com>
- List-Post: &lt;mailto:[email protected]>
- List-Unsubscribe: &lt;mailto:[email protected]>
- Precedence: bulk

Firma DKIM:

I server di lista dovrebbero:
1. Conservare la firma DKIM originale (se presente)
2. Aggiungere la propria firma DKIM
3. Non modificare le intestazioni firmate

D.4.2 Comunicazione​

Notifica del mittente:

Il servizio di lista dovrebbe informare gli iscritti:
- Le mail saranno rinviate dal server di lista
- MAIL FROM sarà riscritto
- Raccomandazione di utilizzare Reply-To per rispondere alla lista

Documentazione del destinatario:

Documentare le politiche di ricezione:
- Come vengono trattate le mail di lista
- Meccanismo di whitelist
- Opzioni configurabili dall'utente

D.5 Direzione dello sviluppo futuro​

D.5.1 ARC (Authenticated Received Chain)​

RFC 8617 ha introdotto ARC:

ARC consente ai mediatori di aggiungere informazioni di autenticazione:
- ARC-Seal: Firma del mediatore
- ARC-Message-Signature: Firma del messaggio
- ARC-Authentication-Results: Risultati di autenticazione

Esempio:

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

Vantaggi:

  • Preserva i risultati di autenticazione originali
  • Consente la verifica a catena
  • I destinatari possono fidarsi dei mediatori

D.5.2 Raccomandazioni​

Per le nuove distribuzioni:

  1. Implementare DKIM e SPF
  2. Pubblicare una politica DMARC
  3. Considerare il supporto ARC (se mediatore)
  4. Testare l'interoperabilità con le mailing list comuni

Per i sistemi esistenti:

  1. Esaminare la rigidità delle politiche SPF
  2. Monitorare i rapporti DMARC
  3. Identificare le fonti problematiche (liste, inoltri, ecc.)
  4. Adattare le politiche o implementare SRS

Appendix E. Mail Services (Servizi di posta)​

Questa appendice discute le considerazioni di implementazione SPF per vari scenari di servizi di posta.

E.1 Web-Based Mail Services (Servizi di posta basati sul web)​

E.1.1 Prospettiva del fornitore di servizi​

Scenario: Fornire servizi di webmail (come Gmail, Yahoo Mail, Outlook.com)

Considerazioni SPF:

1. Gli utenti inviano e-mail da più domini
2. Tutte le e-mail vengono inviate tramite i server del fornitore di servizi
3. Record SPF appropriati richiesti

Esempio di configurazione:

# Dominio principale del fornitore di servizi
mailprovider.com IN TXT "v=spf1 ip4:203.0.113.0/24 ip4:198.51.100.0/24 -all"

# Supporto per domini personalizzati
# Gli utenti devono includere il fornitore di servizi nel loro dominio
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 Configurazione dei domini personalizzati​

Requisito dell'utente: Utilizzare un dominio personalizzato per inviare e-mail tramite il servizio di webmail

Passaggi di configurazione:

  1. Verificare la proprietà del dominio
Il fornitore di servizi richiede l'aggiunta di un record di verifica:
_verification.user-domain.com IN TXT "provider-verification-code"
  1. Configurare SPF
user-domain.com IN TXT "v=spf1 include:_spf.mailprovider.com -all"
  1. Configurare DKIM
# Il fornitore di servizi fornisce la chiave pubblica DKIM
selector._domainkey.user-domain.com IN TXT "v=DKIM1; k=rsa; p=MIGfMA0..."
  1. Configurare DMARC
_dmarc.user-domain.com IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"

E.2 Shared Hosting Services (Servizi di hosting condiviso)​

E.2.1 Sfide​

Problema: Più clienti condividono lo stesso indirizzo IP

hosting-provider.com: 203.0.113.10
customer1.com: Ospitato su 203.0.113.10
customer2.com: Ospitato su 203.0.113.10
customer3.com: Ospitato su 203.0.113.10

Requisito SPF: Ogni dominio cliente deve autorizzare l'IP condiviso

E.2.2 Soluzioni​

Soluzione 1: Inclusione SPF unificata

# Il fornitore di hosting fornisce
_spf.hosting-provider.com IN TXT "v=spf1 ip4:203.0.113.0/24 -all"

# Configurazione del cliente
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"

Soluzione 2: Autorizzazione IP diretta

# Ogni cliente configura indipendentemente
customer1.com IN TXT "v=spf1 ip4:203.0.113.10 -all"
customer2.com IN TXT "v=spf1 ip4:203.0.113.10 -all"

Vantaggi: Semplice, nessuna dipendenza Svantaggi: In caso di cambio IP, tutti i clienti devono aggiornare

Soluzione 3: IP dedicato (consigliato per i grandi clienti)

# Assegnare IP dedicato ai clienti importanti
important-customer.com IN TXT "v=spf1 ip4:203.0.113.50 -all"

E.2.3 Best practice​

I fornitori di hosting dovrebbero:

1. Fornire documentazione chiara sulla configurazione SPF
2. Generare automaticamente record SPF (tramite pannello di controllo)
3. Informare i clienti delle modifiche all'indirizzo IP
4. Fornire strumenti di validazione SPF

I clienti dovrebbero:

1. Utilizzare il metodo include per fare riferimento all'SPF del fornitore di hosting
2. Validare regolarmente i record SPF
3. Monitorare la consegnabilità delle e-mail

E.3 Enterprise Mail Systems (Sistemi di posta aziendali)​

E.3.1 Ambiente complesso​

Scenario aziendale tipico:

- Più data center
- Più server di posta in uscita
- Servizi di posta di terze parti (marketing, notifiche, ecc.)
- Server di uffici locali
- Integrazione di servizi cloud

Sfide di configurazione SPF:

1. Limite di query DNS (10 volte)
2. Limite di dimensione del record (512 byte)
3. Più dipartimenti/unità aziendali
4. Frequenti modifiche all'infrastruttura

E.3.2 Architettura SPF aziendale​

Progettazione gerarchica:

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

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

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

# Sottodomini dipartimentali
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"

Gestione degli intervalli IP:

# Data center A
_spf-dc-a.company.com IN TXT "v=spf1 ip4:203.0.113.0/25 -all"

# Data center B
_spf-dc-b.company.com IN TXT "v=spf1 ip4:198.51.100.0/25 -all"

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

E.3.3 Strategia di appiattimento SPF​

Problema: Superamento del limite di 10 query DNS

Soluzione: Appiattimento regolare

# Script di automazione
def flatten_spf_includes():
"""
Interrogare regolarmente tutti gli IP di dominio inclusi
Generare un record SPF appiattito
"""
includes = [
'_spf.salesforce.com',
'sendgrid.net',
'mailchimp.com'
]

ips = []
for domain in includes:
# Analizzare il record SPF ed estrarre gli IP
ips.extend(resolve_spf_ips(domain))

# Generare un nuovo record SPF
spf_record = f"v=spf1 {' '.join([f'ip4:{ip}' for ip in ips])} -all"

# Aggiornare DNS (tramite API)
update_dns_record('_spf-flattened.company.com', spf_record)

# Eseguire settimanalmente

Nota: Dopo l'appiattimento, aggiornare regolarmente poiché gli IP di terze parti possono cambiare

E.4 Email Marketing Services (Servizi di email marketing)​

E.4.1 Configurazione del servizio​

Servizi comuni:

  • SendGrid
  • Mailchimp
  • Amazon SES
  • Mailgun

Esempi di configurazione 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"

Uso combinato:

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

E.4.2 Strategia di sottodominio​

Best practice: Utilizzare un sottodominio dedicato per le e-mail di marketing

# Dominio principale (per e-mail aziendali importanti)
company.com IN TXT "v=spf1 mx -all"

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

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

Vantaggi:

1. Separazione della reputazione (le e-mail di marketing non influenzano il dominio principale)
2. Gestione più facile dei record SPF
3. Migliore monitoraggio e reporting
4. Conforme alle best practice DMARC

E.4.3 Configurazione DKIM​

Combinato con SPF:

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

# DKIM (fornito da 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 (Servizi di e-mail transazionali)​

E.5.1 Scenario​

E-mail transazionali:

  • Conferma di registrazione
  • Reimpostazione password
  • Notifiche ordini
  • Fatture e ricevute

Fornitori di servizi:

  • Amazon SES
  • SendGrid
  • Mailgun
  • Postmark

E.5.2 Configurazione​

Utilizzare un sottodominio dedicato:

# Sottodominio e-mail transazionali
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=..."

Configurazione dell'applicazione:

# Esempio Django
EMAIL_HOST = 'smtp.mailgun.org'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_FROM = '[email protected]'

# Inviare un'e-mail
send_mail(
subject='Password Reset',
message='Click here to reset...',
from_email='[email protected]',
recipient_list=['[email protected]']
)

E.5.3 Monitoraggio​

Metriche chiave:

- Tasso di consegna e-mail
- Tasso di rimbalzo
- Tasso di successo SPF
- Tasso di successo DKIM
- Tasso di allineamento DMARC
- Tasso di reclami

Impostazioni di avviso:

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 (Dispositivi mobili e IoT)​

E.6.1 Sfide​

Dispositivi mobili:

- Indirizzi IP dinamici
- Invio tramite reti degli operatori
- Non possono essere elencati in SPF

Dispositivi IoT:

- Grande numero di dispositivi
- Distribuiti su reti diverse
- Invio di e-mail diretto

E.6.2 Soluzioni​

Soluzione 1: Utilizzare un relay SMTP

Dispositivo → Relay SMTP → Destinatario

Configurazione:
- Il dispositivo si connette al relay tramite autenticazione
- Server relay autorizzato nel record SPF
- Il relay aggiunge una firma DKIM

Configurazione 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"

Soluzione 2: Invio tramite API

I dispositivi inviano e-mail tramite API HTTP:
- Utilizzare un servizio di terze parti (come API SendGrid)
- Coperto dal record SPF del fornitore di servizi
- Nessun invio SMTP diretto dal dispositivo richiesto

E.7 Best Practices Summary (Riepilogo delle best practice)​

E.7.1 Raccomandazioni generali​

1. Utilizzare sottodomini per separare diversi tipi di e-mail
2. Implementare la tripla protezione SPF + DKIM + DMARC
3. Verificare e aggiornare regolarmente i record SPF
4. Monitorare i limiti di query DNS
5. Utilizzare include invece di elencare direttamente tutti gli IP
6. Utilizzare IP dedicati per servizi critici
7. Implementare il monitoraggio dell'autenticazione e-mail
8. Stabilire un processo di risposta agli incidenti

E.7.2 Checklist di configurazione​

Verificare prima della pubblicazione:

□ Sintassi del record SPF corretta
□ Numero di query DNS ≤ 10
□ Dimensione del record &lt; 512 byte
□ Tutti i server di invio autorizzati
□ Utilizzare qualificatori appropriati (-all o ~all)
□ DKIM configurato
□ Politica DMARC pubblicata
□ E-mail di test inviate e verificate

Monitoraggio continuo:

□ Verificare i rapporti DMARC settimanalmente
□ Monitorare la consegnabilità delle e-mail
□ Tracciare gli errori SPF/DKIM
□ Verificare le nuove fonti di invio
□ Aggiornare le modifiche dei servizi di terze parti

Appendix F. Test Suite (Suite di test)​

Questa appendice fornisce una suite di test completa per validare le implementazioni SPF. I test coprono vari scenari per garantire che i verificatori SPF funzionino correttamente.

F.1 Basic Tests (Test di base)​

F.1.1 Test IP4 semplici​

Test 1: Corrispondenza IP4 diretta

Record SPF: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: pass

Test 2: Corrispondenza CIDR IP4

Record SPF: v=spf1 ip4:192.0.2.0/24 -all
IP di test: 192.0.2.128
Risultato atteso: pass

Test 3: Non-corrispondenza IP4

Record SPF: v=spf1 ip4:192.0.2.0/24 -all
IP di test: 192.0.3.1
Risultato atteso: fail

F.1.2 Test IP6 semplici​

Test 4: Corrispondenza IP6 diretta

Record SPF: v=spf1 ip6:2001:db8::1 -all
IP di test: 2001:db8::1
Risultato atteso: pass

Test 5: Corrispondenza CIDR IP6

Record SPF: v=spf1 ip6:2001:db8::/32 -all
IP di test: 2001:db8::dead:beef
Risultato atteso: pass

Test 6: Non-corrispondenza IP6

Record SPF: v=spf1 ip6:2001:db8::/32 -all
IP di test: 2001:db9::1
Risultato atteso: fail

F.2 Mechanism Tests (Test dei meccanismi)​

F.2.1 Test del meccanismo A​

Test 7: Meccanismo A - corrispondenza

Dominio: example.com
Record SPF: v=spf1 a -all
Record DNS A per example.com: 192.0.2.1
IP di test: 192.0.2.1
Risultato atteso: pass

Test 8: Meccanismo A con CIDR

Dominio: example.com
Record SPF: v=spf1 a/24 -all
Record DNS A per example.com: 192.0.2.1
IP di test: 192.0.2.200
Risultato atteso: pass

Test 9: Meccanismo A con specifica di dominio

Dominio: sender.example.com
Record SPF: v=spf1 a:mail.example.com -all
Record DNS A per mail.example.com: 192.0.2.10
IP di test: 192.0.2.10
Risultato atteso: pass

F.2.2 Test del meccanismo MX​

Test 10: Meccanismo MX - corrispondenza

Dominio: example.com
Record SPF: v=spf1 mx -all
Record DNS MX per example.com: 10 mail.example.com
Record DNS A per mail.example.com: 192.0.2.1
IP di test: 192.0.2.1
Risultato atteso: pass

Test 11: Meccanismo MX con più record MX

Dominio: example.com
Record SPF: v=spf1 mx -all
Record DNS MX:
10 mail1.example.com → 192.0.2.1
20 mail2.example.com → 192.0.2.2
IP di test: 192.0.2.2
Risultato atteso: pass

Test 12: Meccanismo MX con CIDR

Dominio: example.com
Record SPF: v=spf1 mx/24 -all
Record DNS MX: 10 mail.example.com
Record DNS A per mail.example.com: 192.0.2.1
IP di test: 192.0.2.200
Risultato atteso: pass

F.2.3 Test del meccanismo PTR (NON USARE)​

Test 13: Meccanismo PTR - corrispondenza

Dominio: example.com
Record SPF: v=spf1 ptr -all
IP di test: 192.0.2.1
Record PTR per 192.0.2.1: mail.example.com
Record A per mail.example.com: 192.0.2.1
Risultato atteso: pass

Nota: Il meccanismo PTR è obsoleto e non dovrebbe essere usato.

F.2.4 Test del meccanismo EXISTS​

Test 14: Meccanismo EXISTS - trovato

Dominio: example.com
Record SPF: v=spf1 exists:%\{i}.whitelist.example.com -all
IP di test: 192.0.2.1
Query DNS A per 192.0.2.1.whitelist.example.com: 127.0.0.2
Risultato atteso: pass

Test 15: Meccanismo EXISTS - non trovato

Dominio: example.com
Record SPF: v=spf1 exists:%\{i}.whitelist.example.com -all
IP di test: 192.0.2.99
Query DNS A per 192.0.2.99.whitelist.example.com: NXDOMAIN
Risultato atteso: fail

F.2.5 Test del meccanismo INCLUDE​

Test 16: INCLUDE - propagazione semplice di pass

Dominio: example.com
Record SPF: v=spf1 include:trusted.example.com -all
Record SPF per trusted.example.com: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: pass

Test 17: INCLUDE - fail non è propagato

Dominio: example.com
Record SPF: v=spf1 include:trusted.example.com -all
Record SPF per trusted.example.com: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.99
Risultato atteso: fail (non da include, ma da -all)

Test 18: INCLUDE - propagazione di TempError

Dominio: example.com
Record SPF: v=spf1 include:trusted.example.com -all
Query DNS per trusted.example.com: server DNS non disponibile
Risultato atteso: temperror

Test 19: INCLUDE - propagazione di PermError

Dominio: example.com
Record SPF: v=spf1 include:trusted.example.com -all
Record SPF per trusted.example.com: v=spf1 ip4:192.0.2.1 ip4:192.0.2.1 -all (invalido)
Risultato atteso: permerror

F.2.6 Test del meccanismo ALL​

Test 20: ALL con diversi qualificatori

+all: pass
-all: fail
~all: softfail
?all: neutral

F.3 Qualifier Tests (Test dei qualificatori)​

Test 21: Qualificatore più (+)

Record SPF: v=spf1 +ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: pass

Test 22: Qualificatore meno (-)

Record SPF: v=spf1 -ip4:192.0.2.1 ~all
IP di test: 192.0.2.1
Risultato atteso: fail

Test 23: Qualificatore tilde (~)

Record SPF: v=spf1 ~ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: softfail

Test 24: Qualificatore punto interrogativo (?)

Record SPF: v=spf1 ?ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: neutral

F.4 Modifier Tests (Test dei modificatori)​

F.4.1 Test del modificatore REDIRECT​

Test 25: REDIRECT - reindirizzamento di base

Dominio: example.com
Record SPF: v=spf1 redirect=_spf.example.com
Record SPF per _spf.example.com: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: pass

Test 26: REDIRECT - ignorato dopo meccanismo

Dominio: example.com
Record SPF: v=spf1 ip4:192.0.2.1 redirect=_spf.example.com
IP di test: 192.0.2.1
Risultato atteso: pass (meccanismo corrisponde, redirect ignorato)

Test 27: REDIRECT - nessuna corrispondenza

Dominio: example.com
Record SPF: v=spf1 redirect=_spf.example.com
Record SPF per _spf.example.com: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.99
Risultato atteso: fail

F.4.2 Test del modificatore EXP​

Test 28: EXP - recupero stringa di spiegazione

Dominio: example.com
Record SPF: v=spf1 ip4:192.0.2.1 -all exp=explain.example.com
Record DNS TXT per explain.example.com: "Mail from %\{i} not allowed"
IP di test: 192.0.2.99
Risultato atteso: fail
Spiegazione attesa: "Mail from 192.0.2.99 not allowed"

F.5 Macro Tests (Test delle macro)​

F.5.1 Espansione macro di base​

Test 29: %{s} - mittente

Dominio: example.com
MAIL FROM: [email protected]
Record SPF: v=spf1 exists:%\{s}.whitelist.example.com -all
Espanso a: exists:[email protected]

Test 30: %{l} - parte locale

Dominio: example.com
MAIL FROM: [email protected]
Record SPF: v=spf1 exists:%\{l}.whitelist.example.com -all
Espanso a: exists:sender.whitelist.example.com

Test 31: %{o} - dominio

Dominio: example.com
MAIL FROM: [email protected]
Record SPF: v=spf1 exists:%\{o}.whitelist.example.com -all
Espanso a: exists:example.com.whitelist.example.com

Test 32: %{d} - dominio corrente

Dominio: mail.example.com
Record SPF: v=spf1 exists:%\{d}.whitelist.example.com -all
Espanso a: exists:mail.example.com.whitelist.example.com

Test 33: %{i} - indirizzo IP

IP di test: 192.0.2.1
Record SPF: v=spf1 exists:%\{i}.whitelist.example.com -all
Espanso a: exists:192.0.2.1.whitelist.example.com

Test 34: %{i} - indirizzo IPv6

IP di test: 2001:db8::1
Record SPF: v=spf1 exists:%\{i}.whitelist.example.com -all
Espanso a: exists:2001.0db8.0000.0000.0000.0000.0000.0001.whitelist.example.com

F.5.2 Trasformatori di macro​

Test 35: Trasformatore di inversione (r)

Dominio: mail.example.com
Macro: %\{d}
Normale: mail.example.com
Con r: %\{dr}
Espanso a: com.example.mail

Test 36: Delimitatore e inversione

MAIL FROM: [email protected]
Macro: %\{or}
Espanso a: com.example.mail

Test 37: Specifica cifre

Dominio: mail.example.com
Macro: %\{d2}
Espanso a: example.com (ultimi 2 componenti)

Test 38: Cifre con inversione

Dominio: mail.example.com
Macro: %\{d2r}
Espanso a: com.example

F.5.3 Codifica URL nelle macro​

Test 39: Caratteri di escape URL

MAIL FROM: "test user"@example.com
Macro: %\{l}
Espanso a: test%20user

F.6 DNS Lookup Limit Tests (Test del limite di query DNS)​

Test 40: Limite di query DNS - esattamente 10

Record SPF: v=spf1 mx a include:d1.example.com include:d2.example.com ...
(totale di 10 meccanismi che richiedono query DNS)
Risultato atteso: elaborato con successo

Test 41: Limite di query DNS - 11 superato

Record SPF: v=spf1 mx a include:d1.example.com ... (11 query)
Risultato atteso: permerror

Test 42: Conteggio query include nidificati

Dominio: example.com
SPF: v=spf1 include:a.example.com -all (1 query)
a.example.com: v=spf1 include:b.example.com -all (1 query)
b.example.com: v=spf1 mx a -all (2 query)
Totale query: 4
Risultato atteso: pass (se l'IP corrisponde)

F.7 Void Lookup Tests (Test di query vuote)​

Test 43: Meccanismo A - nessun record A

Dominio: example.com
Record SPF: v=spf1 a -all
Record DNS A per example.com: (nessuno)
IP di test: 192.0.2.1
Risultato atteso: fail (meccanismo non corrisponde)
Query vuote: 1

Test 44: Meccanismo MX - nessun record MX

Dominio: example.com
Record SPF: v=spf1 mx -all
Record DNS MX per example.com: (nessuno)
IP di test: 192.0.2.1
Risultato atteso: fail
Query vuote: 1

Test 45: Limite di query vuote - superato

Record SPF con 3 meccanismi che restituiscono ciascuno query vuote
Risultato atteso: permerror (se il limite è 2)

F.8 Syntax Error Tests (Test di errori di sintassi)​

Test 46: Versione SPF mancante

Record SPF: ip4:192.0.2.1 -all
Risultato atteso: none (nessun record SPF valido)

Test 47: Indirizzo IP non valido

Record SPF: v=spf1 ip4:999.999.999.999 -all
Risultato atteso: permerror

Test 48: Intervallo CIDR non valido

Record SPF: v=spf1 ip4:192.0.2.0/99 -all
Risultato atteso: permerror

Test 49: Modificatori duplicati

Record SPF: v=spf1 redirect=a.example.com redirect=b.example.com
Risultato atteso: permerror

Test 50: Modificatore sconosciuto (dovrebbe essere ignorato)

Record SPF: v=spf1 ip4:192.0.2.1 unknown=value -all
IP di test: 192.0.2.1
Risultato atteso: pass (modificatore sconosciuto ignorato)

F.9 Integration Tests (Test di integrazione)​

Test 51: Scenario realistico complesso

Dominio: company.com
Record SPF: v=spf1 mx include:_spf.google.com include:sendgrid.net -all

Configurazione:
- Record MX: mail1.company.com (192.0.2.1), mail2.company.com (192.0.2.2)
- L'SPF di Google include più intervalli IP
- L'SPF di SendGrid include più intervalli IP

Casi di test:
1. IP 192.0.2.1: pass (corrispondenza mx)
2. IP dall'intervallo Google: pass (corrispondenza include)
3. IP dall'intervallo SendGrid: pass (corrispondenza include)
4. IP casuale: fail (-all)

Test 52: Gestione sottodomini

Dominio: mail.company.com
Record SPF per company.com: v=spf1 -all
Record SPF per mail.company.com: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: pass (il sottodominio ha il proprio record SPF)

Test 53: Nessun record SPF

Dominio: example.com
Record SPF: (nessuno)
IP di test: 192.0.2.1
Risultato atteso: none

F.10 Edge Cases (Casi limite)​

Test 54: Parte locale vuota

MAIL FROM: <>
HELO: mail.example.com
Record SPF per mail.example.com: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: pass (identità HELO utilizzata)

Test 55: Indirizzo IPv6 mappato IPv4

Record SPF: v=spf1 ip4:192.0.2.1 -all
IP di test: ::ffff:192.0.2.1 (IPv6 mappato IPv4)
Risultato atteso: pass (dovrebbe essere trattato come IPv4)

Test 56: CIDR /32 per IPv4

Record SPF: v=spf1 ip4:192.0.2.1/32 -all
IP di test: 192.0.2.1
Risultato atteso: pass

Test 57: CIDR /128 per IPv6

Record SPF: v=spf1 ip6:2001:db8::1/128 -all
IP di test: 2001:db8::1
Risultato atteso: pass

Test 58: Più record SPF (non valido)

Dominio: example.com
Record SPF:
v=spf1 ip4:192.0.2.1 -all
v=spf1 ip4:192.0.2.2 -all
Risultato atteso: permerror (più record SPF non consentiti)

F.11 Performance Tests (Test di prestazioni)​

Test 59: Profondità massima di query DNS

Include nidificati fino a una profondità di 10
Verificare che tutti siano elaborati correttamente

Test 60: Grandi intervalli CIDR

Record SPF: v=spf1 ip4:192.0.0.0/8 -all
IP di test: 192.255.255.255
Risultato atteso: pass

F.12 Test Result Summary Format (Formato di riepilogo dei risultati del test)​

Per ogni esecuzione di test, le seguenti informazioni dovrebbero essere registrate:

ID test: F.1.1-Test1
Descrizione: Corrispondenza IP4 diretta
Record SPF: v=spf1 ip4:192.0.2.1 -all
IP di test: 192.0.2.1
Risultato atteso: pass
Risultato effettivo: pass
Stato: SUPERATO
Query DNS: 1
Query vuote: 0
Tempo di elaborazione: 45ms

Un'implementazione SPF completa dovrebbe superare tutti i test in questa suite per essere considerata conforme alla RFC 7208.


Appendix G. Acknowledgements (Riconoscimenti)​

Lo sviluppo del Sender Policy Framework (SPF) è stato uno sforzo collaborativo che ha coinvolto molte persone e organizzazioni della comunità Internet.

G.1 Original Contributors (Contributori originali)​

SPF si basa sulle idee di diverse proposte precedenti di autenticazione della posta elettronica:

  • Designated Mailers Protocol (DMP): Proposto da Gordon Fecyk
  • Reverse MX (RMX): Proposto da Hadmut Danisch
  • Sender Permitted From (SPF): Proposto da Meng Weng Wong

Meng Weng Wong ha svolto un ruolo fondamentale nell'unificare questi diversi approcci in un framework coerente e ha guidato lo sviluppo iniziale di SPF.

G.2 RFC 4408 Contributors (Contributori RFC 4408)​

RFC 4408, la specifica SPF originale, è stata scritta da Meng Weng Wong e Mark Lentczner. Molti altri hanno contribuito al suo sviluppo:

Contributori tecnici e revisori:

  • Stuart Cheshire
  • Claus Färber
  • Mark Lentczner
  • Wayne Schlitt
  • Julian Mehnle
  • Scott Kitterman

Partecipanti al gruppo di lavoro: Il gruppo di lavoro IETF MARID (MTA Authorization Records in DNS) ha fornito contributi significativi allo sviluppo e alla discussione iniziali dei concetti SPF.

G.3 RFC 7208 Contributors (Contributori RFC 7208)​

Questa specifica attuale (RFC 7208) è stata scritta da Scott Kitterman e basata su RFC 4408. Le seguenti persone hanno contribuito a questo aggiornamento:

Contributori principali:

  • Scott Kitterman (autore principale)
  • Murray S. Kucherawy (contributore e revisore)

Revisori tecnici e contributori:

  • Alessandro Vesely
  • Barry Leiba
  • Bron Gondwana
  • Franck Martin
  • John Levine
  • Michael Hammer
  • Pete Resnick
  • Steve Atkins
  • Stuart Cheshire

G.4 Community Contributions (Contributi della comunità)​

La comunità SPF ha contribuito attivamente allo sviluppo, all'implementazione e al deployment di SPF:

Implementatori: Numerosi sviluppatori hanno creato librerie e strumenti SPF in vari linguaggi di programmazione, tra cui:

  • Perl
  • Python
  • Java
  • C/C++
  • PHP
  • Ruby
  • Go

Fornitori di servizi: I principali fornitori di servizi di posta elettronica hanno adottato ampiamente SPF e hanno aiutato a perfezionare la specifica basandosi sull'esperienza nel mondo reale:

  • Google (Gmail)
  • Microsoft (Outlook.com, Office 365)
  • Yahoo
  • AOL
  • Altri principali fornitori di posta elettronica

Fornitori DNS: I fornitori di servizi DNS hanno sviluppato strumenti di gestione SPF e creato documentazione per facilitare l'adozione di SPF.

G.5 IETF Working Groups (Gruppi di lavoro IETF)​

Diversi gruppi di lavoro IETF hanno contribuito allo sviluppo di SPF:

Gruppo di lavoro MARID (MTA Authorization Records in DNS):

  • Focalizzato sull'autenticazione della posta elettronica tramite DNS
  • Ha discusso vari approcci alla convalida del mittente
  • Ha fornito un forum per lo sviluppo iniziale di SPF

ASRG (Anti-Spam Research Group):

  • Ha valutato SPF nel contesto delle tecnologie anti-spam
  • Ha fornito feedback su considerazioni di sicurezza e privacy

Gruppo di lavoro DKIM:

  • Ha lavorato su tecnologie di autenticazione della posta elettronica complementari
  • Ha assicurato che SPF e DKIM funzionassero bene insieme

Gruppo di lavoro DMARC:

  • Ha sviluppato DMARC, che integra SPF e DKIM
  • Ha aiutato a definire come i risultati SPF vengono utilizzati nelle politiche di autenticazione della posta elettronica

G.6 Tool and Library Developers (Sviluppatori di strumenti e librerie)​

I seguenti progetti open source e sviluppatori hanno contribuito in modo significativo all'ecosistema SPF:

Librerie SPF:

  • libspf2 (libreria C) dal gruppo di progetto libspf2
  • Mail::SPF (modulo Perl) da Julian Mehnle e altri
  • pyspf (libreria Python) da Stuart Gathman e Terence Way
  • spf4j (libreria Java) da vari contributori

Strumenti di validazione SPF:

  • Verificatori SPF online di vari fornitori
  • Tester SPF da riga di comando
  • Strumenti di analisi DNS

Implementazioni di server di posta:

  • Integrazione SPF Postfix
  • Supporto SPF Exim
  • Integrazione SPF Sendmail
  • Implementazione SPF Microsoft Exchange

G.7 Documentation Contributors (Contributori alla documentazione)​

Molte persone hanno contribuito alla documentazione SPF, tutorial e best practice:

  • OpenSPF.org: Documentazione e risorse SPF mantenute dalla comunità
  • Liste di distribuzione IETF: Discussioni tecniche dettagliate e chiarimenti
  • Autori di blog e scrittori tecnici: Che hanno spiegato SPF a un pubblico più ampio
  • Documentazioni dei fornitori DNS: Che hanno fornito guide pratiche di implementazione SPF

G.8 Testing and Deployment (Test e deployment)​

Organizzazioni e persone che hanno aiutato nei test e nei deployment su larga scala:

Adottanti iniziali:

  • Grandi fornitori di servizi di posta elettronica che hanno testato SPF nelle loro reti
  • Organizzazioni aziendali che hanno implementato la convalida SPF
  • ISP che hanno aggiunto SPF come componente di filtraggio spam

Test di interoperabilità:

  • Sviluppatori che hanno eseguito test tra implementazioni
  • Organizzazioni che hanno ospitato suite di test SPF
  • Contributori che hanno segnalato bug e problemi di interoperabilità

G.9 Special Thanks (Ringraziamenti speciali)​

Ringraziamenti speciali a:

  • Meng Weng Wong: Per la concezione SPF originale e il suo instancabile lavoro nel riunire la comunità per sviluppare lo standard

  • Mark Lentczner: Per la co-redazione della specifica RFC 4408 originale

  • Scott Kitterman: Per aver guidato il processo di aggiornamento da RFC 4408 a RFC 7208 e per la manutenzione attiva continua della comunità SPF

  • Wayne Schlitt: Per i contributi tecnici estesi e l'esperienza di implementazione

  • Julian Mehnle: Per lo sviluppo di librerie SPF chiave e la chiarificazione della specifica

La comunità Internet: A tutti coloro che hanno utilizzato, implementato, discusso e contribuito a migliorare l'autenticazione della posta elettronica.

G.10 Ongoing Work (Lavoro in corso)​

Lo sviluppo di SPF continua attraverso:

  • Chiarimenti delle specifiche: Discussioni in corso per chiarire casi limite
  • Aggiornamenti delle librerie: Manutenzione attiva delle implementazioni SPF
  • Sviluppo di best practice: Guide in evoluzione per il deployment SPF
  • Integrazione con altri standard: Coordinamento con DKIM, DMARC e altre tecnologie di sicurezza della posta elettronica

La comunità SPF rimane attiva e impegnata nel migliorare l'autenticazione e la sicurezza della posta elettronica su Internet.


Nota finale: Questa specifica e il protocollo SPF non sarebbero stati possibili senza gli sforzi di innumerevoli volontari che hanno contribuito con il loro tempo, competenza e risorse per migliorare la sicurezza della posta elettronica per tutti.