Forward Email
Spam Scanner è stato sviluppato da Forward Email, il servizio email open source attento alla privacy, per i propri server di posta. Forward Email non conserva log del contenuto dei messaggi, quindi nessun servizio di filtraggio esterno era adatto: il filtro doveva girare sui suoi server e doveva spiegare ogni decisione senza che una persona leggesse la posta.
Questa pagina mostra come lo usa un server di posta come quello di Forward Email, e cosa è cambiato per il codice scritto per Spam Scanner 5 o 6.
Su un server di posta in entrata#
Forward Email riceve la posta con smtp-server. Lo schema, per qualsiasi server basato su di esso:
const SpamScanner = require('spamscanner');
const scanner = new SpamScanner({
clamav: true, // clamd on its default socket
authentication: true, // SPF, DKIM, DMARC, ARC
dnsbl: {ip: ['zen.spamhaus.org'], domain: ['dbl.spamhaus.org']},
dns: {servers: ['127.0.0.1']}, // a local caching resolver
});
async function onData(stream, session, callback) {
const scan = await scanner.scan(stream, {
session: {
remoteAddress: session.remoteAddress,
resolvedClientHostname: session.clientHostname,
helo: session.hostNameAppearsAs,
envelope: session.envelope,
},
});
if (scan.results.viruses.length > 0) {
return callback(Object.assign(new Error(`Message contains a virus: ${scan.results.viruses[0]}`), {responseCode: 554}));
}
if (scan.action === 'reject') {
// A temporary error: the sender retries, and a wrong decision can be undone.
return callback(Object.assign(new Error(`Message rejected as spam: ${scan.message}`), {responseCode: 421}));
}
// scan.isSpam: deliver to the Junk folder, or add scan's headers (spamHeaders) and forward.
callback();
}scanner.scan() accetta direttamente lo stream SMTP. Se hai già a disposizione i risultati di mailauth, tralascia authentication e passa solo l'indirizzo IP.
Una risposta 421 o 451 fa sì che il server mittente metta in coda il messaggio e riprovi più tardi. Le nuove regole di rifiuto possono iniziare con un codice temporaneo e passare a 550 dopo aver verificato i risultati, senza perdere posta nel frattempo.
Aggiornamento dalla versione 5 o 6#
La versione 7 è una riscrittura. Il costruttore, scan() e i campi del risultato letti dal codice delle versioni 5 e 6 funzionano ancora; sono cambiati il classificatore, il modello e i controlli facoltativi basati su TensorFlow.
Cosa resta uguale#
new SpamScanner(options)eawait scanner.scan(source).require('spamscanner')restituisce la classe, eimport SpamScanner from 'spamscanner'funziona.result.isSpam,result.messageeresult.results.classification,.phishing,.executables,.arbitrary,.viruses,.macrose.idnHomographAttack.- Ogni elemento di
results.phishing,.executables,.arbitrarye.virusessi converte nello stesso tipo di stringa di messaggio di prima (String(item), template literal,message.includes('adult-related content')). Ora sono oggetti contype,messagee dettagli. getTokensAndMailFromSource(),getClassification()egetTokens().- Queste opzioni corrispondono ai loro nuovi nomi:
clamscanaclamav,enableMacroDetection: falseamacros: false,enableArbitraryDetection: falseaarbitrary: false,enableAuthenticationconauthOptionsaauthenticationesession,enableReputationconreputationOptions.apiUrlareputation,strictIDNDetectionaphishing.homograph.strictMode, eallowlistedenylist.loggerememoizevengono accettate e ignorate.
Cosa è cambiato#
| Prima | Ora |
|---|---|
scan('path/to/file.eml') leggeva il file | Una stringa è testo del messaggio. Usa scanFile(path) o passa un Buffer |
Un modello naive Bayes di parole (classifier.json), ora non caricabile | Un nuovo classificatore e un nuovo formato del modello; riaddestra con spamscanner train (addestramento) |
| I controlli di tossicità e NSFW caricavano modelli TensorFlow dalla rete al primo utilizzo | Porta il tuo modello: toxicity: {model} e nsfw: {model} accettano qualsiasi oggetto con un metodo classify(), ad esempio da @tensorflow-models/toxicity e nsfwjs |
results.arbitrary elencava ogni schema corrispondente | Elenca le regole abbastanza forti da segnare lo spam da sole; tutte le regole sono in result.tests |
| Una risposta sì o no | result.score, result.action (accept, tag o reject) e result.tests, ciascuno con punti e motivo |
isSpam deciso dal classificatore o da un singolo controllo | isSpam è un punteggio di 5 o più; soglie e punti si possono modificare |
| Controlli di reputazione su un endpoint di Forward Email | Un servizio di reputazione generico, disattivato se reputation.apiUrl non è impostato |
Novità#
- Modelli linguistici per i casi dubbi, locali o in hosting.
- SPFSender Policy Framework: un record DNS che elenca i server autorizzati a inviare posta per un dominio., DKIMDomainKeys Identified Mail: una firma su un messaggio, verificata con una chiave pubblica pubblicata nel DNS del mittente., DMARCUna policy DNS che indica ai destinatari cosa fare quando la posta che dichiara un dominio non supera l'allineamento SPF e DKIM. e ARCAuthenticated Received Chain: firme che trasportano i risultati dell'autenticazione attraverso i server di inoltro.; DNS blocklist; i resolver con filtraggio di Cloudflare.
- Controlli sugli allegati in base al contenuto: eseguibili camuffati, archivi, macro, PDF attivi.
- Un milter, un'API HTTP, un server TCP e un server spamd, e una riga di comando.
- Addestramento, valutazione e apprendimento dalle segnalazioni, dalla riga di comando o dall'API.