Forward Email
Spam Scanner zbudował Forward Email, otwartoźródłowa usługa poczty e-mail nastawiona na prywatność, na potrzeby własnych serwerów pocztowych. Forward Email nie przechowuje logów z treścią wiadomości, więc żadna zewnętrzna usługa filtrująca nie wchodziła w grę: filtr musiał działać na jego własnych serwerach i wyjaśniać każdą decyzję bez czytania poczty przez człowieka.
Ta strona pokazuje, jak korzysta z niego serwer pocztowy taki jak serwery Forward Email, i co się zmieniło dla kodu napisanego pod Spam Scanner 5 lub 6.
Na serwerze poczty przychodzącej#
Forward Email odbiera pocztę za pomocą smtp-server. Wzorzec dla każdego serwera zbudowanego na tej bibliotece:
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() przyjmuje bezpośrednio strumień SMTP. Jeśli wyniki z mailauth są już dostępne, pomiń authentication i przekaż tylko adres IP.
Odpowiedź 421 lub 451 sprawia, że serwer wysyłający umieszcza wiadomość w kolejce i ponawia próbę później. Nowe reguły odrzucania mogą zaczynać od kodu tymczasowego i przejść na 550, gdy ich wyniki zostaną sprawdzone, bez utraty poczty w międzyczasie.
Aktualizacja z wersji 5 lub 6#
Wersja 7 została napisana od nowa. Konstruktor, scan() i pola wyniku, które czyta kod z wersji 5 i 6, nadal działają; zmieniły się klasyfikator, model i opcjonalne kontrole TensorFlow.
Bez zmian#
new SpamScanner(options)iawait scanner.scan(source).require('spamscanner')zwraca klasę, aimport SpamScanner from 'spamscanner'działa.result.isSpam,result.messageorazresult.results.classification,.phishing,.executables,.arbitrary,.viruses,.macrosi.idnHomographAttack.- Każdy element w
results.phishing,.executables,.arbitraryi.virusesdaje się zamienić na taki sam komunikat tekstowy jak wcześniej (String(item), literały szablonowe,message.includes('adult-related content')). Teraz są to obiekty ztype,messagei szczegółami. getTokensAndMailFromSource(),getClassification()igetTokens().- Te opcje odpowiadają nowym nazwom:
clamscantoclamav,enableMacroDetection: falsetomacros: false,enableArbitraryDetection: falsetoarbitrary: false,enableAuthenticationzauthOptionstoauthenticationisession,enableReputationzreputationOptions.apiUrltoreputation,strictIDNDetectiontophishing.homograph.strictMode, a takżeallowlistidenylist.loggerimemoizesą akceptowane i ignorowane.
Zmiany#
| Wcześniej | Teraz |
|---|---|
scan('path/to/file.eml') czytało plik | Ciąg znaków to tekst wiadomości. Użyj scanFile(path) lub przekaż Buffer |
Naiwny model Bayesa dla słów (classifier.json), którego nie da się teraz wczytać | Nowy klasyfikator i format modelu; wytrenuj ponownie przez spamscanner train (trenowanie) |
| Kontrole toksyczności i NSFW przy pierwszym użyciu pobierały modele TensorFlow z sieci | Własny model: toxicity: {model} i nsfw: {model} przyjmują dowolny obiekt z metodą classify(), na przykład z @tensorflow-models/toxicity i nsfwjs |
results.arbitrary wymieniało każdy dopasowany wzorzec | Wymienia reguły na tyle silne, by same oznaczyć spam; wszystkie reguły są w result.tests |
| Odpowiedź tak albo nie | result.score, result.action (accept, tag lub reject) i result.tests, każdy z punktami i powodem |
O isSpam decydował klasyfikator lub dowolna pojedyncza kontrola | isSpam oznacza wynik 5 lub więcej; progi i punkty można zmienić |
| Kontrole reputacji w punkcie końcowym Forward Email | Ogólna usługa reputacji, wyłączona, dopóki nie ustawisz reputation.apiUrl |
Nowości#
- Modele językowe do trudnych przypadków, lokalne lub hostowane.
- SPFSender Policy Framework: rekord DNS z listą serwerów, które mogą wysyłać pocztę w imieniu domeny., DKIMDomainKeys Identified Mail: podpis wiadomości sprawdzany kluczem publicznym opublikowanym w DNS nadawcy., DMARCPolityka w DNS, która mówi odbiorcom, co zrobić z pocztą podającą się za domenę, gdy nie przechodzi ona dopasowania SPF i DKIM. i ARCAuthenticated Received Chain: podpisy, które przenoszą wyniki uwierzytelnienia przez serwery przekazujące pocztę.; czarne listy DNS; filtrujące resolvery Cloudflare.
- Kontrole załączników według zawartości: zamaskowane pliki wykonywalne, archiwa, makra, aktywne pliki PDF.
- Milter, HTTP API, serwer TCP i serwer spamd oraz wiersz poleceń.
- Trenowanie, ewaluacja i nauka ze zgłoszeń, z wiersza poleceń lub przez API.