API HTTP, server TCP e spamd

API HTTP#

Shell
spamscanner http --port 7832 --token "$SPAMSCANNER_TOKEN"

È in ascolto su 127.0.0.1, salvo diversa indicazione di --host. Con un token, ogni richiesta tranne /health richiede Authorization: Bearer <token>. Mettila dietro un reverse proxy con TLS prima di esporla al di fuori della macchina.

Metodo e percorsoCorpoRisposta
GET /health{"ok": true, "version": "7.0.0"}
POST /scanIl messaggio grezzoIl risultato dell'analisi in JSON
POST /checkIl messaggio grezzoIl messaggio con le intestazioni X-Spam-* aggiunte, come message/rfc822
POST /learn/spamIl messaggio grezzo{"ok": true, "learned": "spam"}; richiede un token
POST /learn/hamIl messaggio grezzo{"ok": true, "learned": "ham"}; richiede un token

I parametri della query descrivono la sessione SMTP:

ParametroSignificato
ipL'indirizzo IP del client
hostnameIl suo nome DNS inverso verificato
heloIl suo nome HELO o EHLO
fromIl mittente dell'envelope
toUn destinatario; ripetilo o separa più destinatari con virgole
verbose=1/scan: restituisce anche l'elenco delle parole e l'oggetto
subjectTag/check: prefisso per l'oggetto dello spam, ad esempio %5BSPAM%5D

/check restituisce anche X-Spam-Flag, X-Spam-Score e X-Spam-Action come intestazioni della risposta, quindi un client può decidere senza analizzare il messaggio.

I messaggi più grandi di 25 MB ricevono 413. Un'analisi che fallisce riceve 500 con {"error": "..."}.

Shell
curl -s -X POST -H "Authorization: Bearer $SPAMSCANNER_TOKEN" \
  --data-binary @message.eml "http://127.0.0.1:7832/scan?ip=203.0.113.5&to=bob@example.org" | jq '.isSpam, .score, .tests'

Con --out model.json, ciò che /learn insegna viene salvato in quel file dopo ogni richiesta. Senza, l'apprendimento dura fino al riavvio del server.

Da Node.js:

JavaScript
const response = await fetch('http://127.0.0.1:7832/scan?ip=203.0.113.5', {
  method: 'POST',
  headers: {authorization: `Bearer ${process.env.SPAMSCANNER_TOKEN}`},
  body: rawMessage,
});
const {isSpam, score, action} = await response.json();

Da Python:

Python
import os, urllib.request

request = urllib.request.Request(
    'http://127.0.0.1:7832/scan',
    data=open('message.eml', 'rb').read(),
    headers={'Authorization': f"Bearer {os.environ['SPAMSCANNER_TOKEN']}"},
    method='POST',
)
print(urllib.request.urlopen(request).read().decode())

Server TCP#

Shell
spamscanner server --port 7830

Invia il messaggio grezzo, chiudi il lato di invio della connessione e leggi una riga di JSON:

Shell
nc -N 127.0.0.1 7830 < message.eml

Con --verbose, la risposta è invece una riga di testo: SPAM 16.3/5.0 BAYES_999,PHISHING_LOOKALIKE_DOMAIN,DECEPTIVE_LINK,FROM_NAME_BRAND o HAM -2.5/5.0 BAYES_00.

spamd#

Shell
spamscanner spamd --port 783

Un server compatibile con SpamAssassin per spamc, Exim, Haraka e altri client SpamAssassin. Configurare Exim e Haraka

ComandoRisposta
CHECKSpam: True ; 16.3 / 5.0
SYMBOLSIl verdetto e i nomi dei test scattati
REPORTIl verdetto e una tabella di test, punti e motivi
REPORT_IFSPAMCome REPORT, con un report vuoto per l'ham
PROCESSIl verdetto e il messaggio con le intestazioni X-Spam-*
HEADERSIl verdetto e il blocco di intestazioni del messaggio con le intestazioni X-Spam-*
PINGPONG
SKIPNiente
TELLImpara spam o ham, con --allow-tell; salva in --out

Le richieste compresse (Compress: zlib) vengono rifiutate.

Modifica questa pagina su GitHub · Markdown ·