La version communautaire score avec les signaux d’authentification, de réseau, d’heuristique et bayésiens. Des étages d’analyse de contenu plus avancés existent en extension commerciale et sont volontairement absents ici : les champs qu’ils rempliraient restent vides plutôt que d’être simulés.
Le pipeline, dans l’ordre
- Contrôle des pairs de confiance (ADR-031). La boucle locale et
[security] trusted_ipssautent SPF, DNSBL et le rejet de politique DMARC, mais jamais l’analyse de contenu : une application locale compromise peut toujours spammer. - Verdicts d’authentification. Les résultats SPF, DKIM, DMARC et ARC (issus de la passe de vérification entrante) alimentent le score. Un échec DMARC
p=rejectest rejeté d’emblée avec550 5.7.26, avant le scoring de contenu : c’est une décision d’authentification, pas un score de spam. - DNSBL. L’IP qui se connecte est vérifiée contre les listes de blocage que vous configurez (
[spam] dnsbl_servers, vide par défaut). Un listage pèse dans le score. - Signaux de contenu. Des heuristiques (chaînes de raccourcisseurs d’URL, falsification d’en-têtes, anomalies structurelles) et un classifieur bayésien entraîné par organisation. Deux garde-fous gardent le Bayes honnête : il s’entraîne exactement sur la représentation qu’il score (pas de dérive entraînement/scoring), et les votes dans sa zone morte statistique sont écartés plutôt que forcés en verdict.
- Disposition (ADR-080). Une fonction partagée unique traduit le verdict final en action :
Rejectvers550;Defervers451;Junkvers le dossier Indésirables ; suspect et en masse vers la boîte de réception, avec un tagX-Spam-Status, jamais aux Indésirables. Seul un verdict confiant écarte du courrier de la vue.
- La liste blanche des réponses. Un correspondant à qui vous avez répondu est en liste blanche, mais elle n’est honorée que si l’enveloppe entrante est authentifiée (alignement SPF/DKIM) : un
From:falsifié d’un contact connu n’y gagne rien. - La capture spamtrap (ADR-077). Le courrier vers un destinataire piège désigné est accepté et classé de force en
$junkcomme vérité terrain pour le corpus, plutôt que rejeté : le piège existe pour collecter exactement ce courrier.
Pas de greylisting
Il n’y a aucune étape de greylisting, et aucun réglage n’en active une. La barrière au moment duRCPT, qui refusait temporairement un triplet (IP, expéditeur, destinataire) inconnu par un 451 en attendant un réessai, a été retirée (ADR-128), parce que l’hypothèse sur laquelle elle reposait a cessé de tenir : les botnets modernes réessaient, les gros expéditeurs légitimes répondent depuis des pools d’adresses qui ne re-présentent jamais le même triplet, et le coût retombait précisément sur les correspondants que vous voulez le plus voir arriver, ceux qui vous écrivent pour la première fois. Cela impliquait aussi d’accepter une écriture en base avant toute authentification.
L’exigence d’authentification et le pipeline scoré portent cette charge à la place. Si vous migrez depuis un serveur où le greylisting faisait un travail visible, les équivalents ici sont la pondération DNSBL, les verdicts d’authentification et le corpus bayésien, pas un interrupteur à réactiver.
Une variante conditionnée au score est spécifiée : ne retarder que dans la bande de score ambiguë, là où un réessai est une preuve plutôt qu’un péage. Elle n’est pas active dans cette version et n’est pas réglable par l’opérateur ; la seule chose qui tourne aujourd’hui est la tâche de ménage qui purge par âge l’ancienne table de triplets. Rien sur cette page n’en dépend.
Entraînement et retour
Le corpus Bayes apprend des actions des utilisateurs : déplacer un message vers les Indésirables l’entraîne comme spam, en repêcher un l’entraîne comme légitime (avec un plafond sur les votes légitimes répétés pour une même classe de message, pour qu’un utilisateur enthousiaste ne fausse pas le modèle). Le corpus est versionné par époque : quand la représentation des jetons change, le modèle est reconstruit depuis le corpus stocké au lieu de mélanger des générations incompatibles :/admin/v1/spam/stats, /spam/test, /spam/feedback/{tenant} et /spam/retrain/{tenant} exposent les mêmes opérations pour l’outillage. POST /spam/retrain/{tenant} lance un vrai réentraînement et renvoie son résultat (précision, échantillons utilisés, version du modèle) ; sans réentraîneur configuré (spam.retrain_enabled vaut false par défaut, aucune box n’embarque de script d’entraînement), la route répond 503 en nommant les deux réglages à changer, jamais un succès pour un travail qui n’a pas eu lieu.
Configuration
Anti-abus : limitation de débit et fail2ban
La protection contre la force brute et les inondations est dans le binaire ; n’installez pas le démon fail2ban à côté d’OxiMail :- Limiteur de débit : seau à jetons par IP (
[rate_limit]), couvrant les surfaces HTTP et SMTP. - Fail2ban : les échecs d’authentification sur tous les protocoles (JMAP, IMAP, SMTP AUTH, DAV, ManageSieve) sont suivis par IP ; franchir
[security] fail2ban_max_attemptsbannit l’IP avec escalade (60 min puis 6 h puis 24 h). Derrière un proxy, la vraie IP cliente est lue depuisX-Forwarded-For(uniquement depuis[server] trusted_proxies) ou le protocole PROXY : les bannissements frappent l’attaquant, pas votre proxy. - Surface opérateur :
oximail unban <ip>,oximail ban list|add, etGET/DELETE /admin/v1/bans: voir Exploitation.
[security] trusted_ips contourne les deux mécanismes pour votre propre infrastructure.
Lire le verdict sur un message
Chaque message scoré porte un en-têteX-Spam-Status avec le verdict et les signaux qui y ont contribué : le premier endroit où regarder quand un utilisateur demande « pourquoi ce message est aux Indésirables » (ou « pourquoi celui-ci n’y est pas »). La décision de remise produite est dans les journaux du serveur avec son contexte complet.