Forward Email

O Spam Scanner foi desenvolvido pelo Forward Email, o serviço de e-mail de código aberto focado em privacidade, para os seus próprios servidores de e-mail. O Forward Email não guarda registros do conteúdo das mensagens, então nenhum serviço de filtragem externo serviria: o filtro precisava rodar nos seus próprios servidores e explicar cada decisão sem que uma pessoa lesse o e-mail.

Esta página mostra como um servidor de e-mail como o do Forward Email o usa e o que mudou para o código escrito para o Spam Scanner 5 ou 6.

Em um servidor de recebimento de e-mails#

O Forward Email recebe e-mails com o smtp-server. O padrão, para qualquer servidor construído com ele:

JavaScript
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();
}

O scanner.scan() aceita o stream SMTP diretamente. Se você já tem os resultados do mailauth, pule o authentication e passe apenas o endereço IP.

Uma resposta 421 ou 451 faz o servidor de envio colocar a mensagem na fila e tentar de novo mais tarde. Novas regras de rejeição podem começar com um código temporário e passar para 550 depois que os seus resultados forem conferidos, sem perder e-mails nesse meio-tempo.

Atualizando a partir da versão 5 ou 6#

A versão 7 é uma reescrita. O construtor, o scan() e os campos do resultado que o código das versões 5 e 6 lê continuam funcionando; o classificador, o modelo e as verificações opcionais com TensorFlow mudaram.

Continua igual#

  • new SpamScanner(options) e await scanner.scan(source).
  • require('spamscanner') retorna a classe, e import SpamScanner from 'spamscanner' funciona.
  • result.isSpam, result.message e result.results.classification, .phishing, .executables, .arbitrary, .viruses, .macros e .idnHomographAttack.
  • Cada item de results.phishing, .executables, .arbitrary e .viruses é convertido no mesmo tipo de string de mensagem de antes (String(item), template literals, message.includes('adult-related content')). Agora eles são objetos com type, message e detalhes.
  • getTokensAndMailFromSource(), getClassification() e getTokens().
  • Estas opções correspondem aos novos nomes: clamscan para clamav, enableMacroDetection: false para macros: false, enableArbitraryDetection: false para arbitrary: false, enableAuthentication com authOptions para authentication e session, enableReputation com reputationOptions.apiUrl para reputation, strictIDNDetection para phishing.homograph.strictMode, e allowlist e denylist. logger e memoize são aceitas e ignoradas.

Mudou#

AntesAgora
scan('path/to/file.eml') lia o arquivoUma string é texto de mensagem. Use scanFile(path) ou passe um Buffer
Um modelo naive Bayes de palavras (classifier.json), que não pode mais ser carregadoUm novo classificador e um novo formato de modelo; treine de novo com spamscanner train (treinamento)
As verificações de toxicidade e NSFW carregavam modelos TensorFlow da rede no primeiro usoTraga o seu próprio modelo: toxicity: {model} e nsfw: {model} aceitam qualquer objeto com um método classify(), por exemplo do @tensorflow-models/toxicity e do nsfwjs
results.arbitrary listava todos os padrões que casavamEle lista as regras fortes o bastante para marcar spam sozinhas; todas as regras estão em result.tests
Uma resposta sim ou nãoresult.score, result.action (accept, tag ou reject) e result.tests, cada um com pontos e um motivo
isSpam decidido pelo classificador ou por qualquer verificação isoladaisSpam é uma pontuação de 5 ou mais; os limites e os pontos podem ser alterados
Verificações de reputação contra um endpoint do Forward EmailUm serviço de reputação genérico, desligado a menos que reputation.apiUrl seja definido

Novidades#

  • Modelos de linguagem para os casos duvidosos, locais ou hospedados.
  • SPFSender Policy Framework: um registro DNS que lista os servidores autorizados a enviar e-mails por um domínio., DKIMDomainKeys Identified Mail: uma assinatura sobre a mensagem, verificada com uma chave pública publicada no DNS do remetente., DMARCUma política no DNS que diz aos destinatários o que fazer quando um e-mail que alega vir de um domínio falha no alinhamento de SPF e DKIM. e ARCAuthenticated Received Chain: assinaturas que levam os resultados de autenticação através de servidores de encaminhamento.; listas de bloqueio no DNS; os resolvedores com filtragem da Cloudflare.
  • Verificações de anexos pelo conteúdo: executáveis disfarçados, arquivos compactados, macros, PDFs ativos.
  • Um milter, uma API HTTP, um servidor TCP e um servidor spamd, e uma linha de comando.
  • Treinamento, avaliação e aprendizado a partir de denúncias, pela linha de comando ou pela API.

Editar esta página no GitHub · Markdown ·