Classifier le spam sur une boite mail free.fr ou autre
Historiquement, j’utilise une adresse mail en free.fr. Malheureusement celle-ci
était plus que spammée, environ 30 mails de spams par jour. Ce qui est
drôle c’est que Free utilise un anti-spam mais ne fait pas l’effort de l’utiliser
pour classifier automatiquement les mails afin d’avoir une boite propre et des clients heureux.
J’ai donc utilisé les informations retournées par l’anti-spam dans chaque email pour les classifier.
Pour ça il y a le super outil imapfilter, le tout packagé
dans un container Docker et vous pouvez de nouveau utiliser votre email en free.fr
.
Le projet complet est disponible sur mon gitlab1.
La classification du SPAM chez free.fr
En ouvrant le source de chaque mail de votre boite Free il y a un header qui catégorise le mail.
Une petite recherche sur le net avec X-ProXaD-SC
et vous trouverez des infos diverses
sur les valeurs que peut prendre ce champ. Commençons par analyser le format de ce header,
il est définit ainsi state=<state>:<category> score=<score>.
Après observation sur un échantillon de mail voici comment Free fait varier les champs de ce header.
state | category | score |
---|---|---|
HAM | CommercialEmailGeneric, CommercialEmailKnown, SocialNetwork | 0 .. n |
SPAM | 0 .. n |
Ci-dessous des exemples, la catégorie n’est pas forcément ajoutée. Plus la valeur du score est importante
moins le mail à d’importance. Un mail de type HAM
avec un score à 0 est un mail légitime.
X-ProXaD-SC: state=HAM score=0
X-ProXaD-SC: state=HAM:CommercialEmailKnown score=7
X-ProXaD-SC: state=HAM:CommercialEmailGeneric score=17
X-ProXaD-SC: state=HAM:SocialNetwork score=10
X-ProXaD-SC: state=HAM score=99
Classifer vos mails avec imapfilter
Dans mon cas j’ai effectué mon filtre avec imapfilter
mais vous pouvez très bien
utiliser les règles de filtrage depuis un webmail ou client mail. J’utilise imapfilter pour être sûr que
mes mails seront classifiés vu que j’utilise un client mail lourd comme Thunderbird.
Pour faire simple je redirige tous les emails commerciaux
dans le répertoire Junk
, les mails des réseaux sociaux dans un répertoire que j’ai créé Social
et tous les mails considérés comme SPAM
ou HAM
avec un score supérieur à 75 directement
dans la poubelle aka Trash
.
Avec imapfilter
vous pouvez donc définir les règles de filtrage dans un fichier de config en
Lua. L’ensemble des primitives pour filtrer sont disponibles sur
le manuel d’imapfilter_config
. Ci-dessous un extrait du code Lua pour classifier votre spam après avoir
décoder le header. A savoir c’est mon premier script Lua il est certainement pas optimal
mais pour le moment il tourne depuis plus de 6 mois sans accrocs.
spam = Set {}
social = Set {}
commercial = Set {}
results = account.INBOX:is_unseen()
for _, msg in ipairs(results) do
mbox, uid = table.unpack(msg)
spamcause = mbox[uid]:fetch_field("X-ProXaD-SC")
print(os.date("%c") .. " headers >> " .. spamcause)
fullstate, score = string.match(spamcause, "state=([a-zA-Z0-9 :]+) score=(%d+)")
score = tonumber(score) or 0
state, category = get_state(fullstate)
print(os.date("%c") .. " state(" .. state .. ") category(" .. category .. ") score(" .. score .. ")")
if state == "HAM" and (category == "CommercialEmailGeneric" or category == "CommercialEmailKnown") then
table.insert(commercial, msg)
elseif state == "HAM" and category == "SocialNetwork" then
table.insert(social, msg)
elseif (state == "SPAM" or state == "HAM") and score > 75 then
table.insert(spam, msg)
end
end
commercial:move_messages(account.Junk)
social:move_messages(account.Social)
spam:move_messages(account.Trash)
Lancer l’ensemble dans un container Docker
Une fois le script de filtrage fait il faut le déployer quelque part. Pour m’assurer
que ça marche partout sur mon laptop ou serveur j’ai packagé ça avec Docker. La version
d’imapfilter
est donc figée et le certificat SSL de Free est également ajouté. L’image
de base est de type alpine, après build l’image Docker fait à peine 8MB. L’image est
construite avec une étape intermédiaire de pre-build pour ne pas embarquer les dépendances
de build dans l’image de production.
FROM alpine as builder
ARG version=v2.6.12
ARG archive=$version.tar.gz
ADD https://github.com/lefcha/imapfilter/archive/$archive /ws/
RUN apk add build-base openssl-dev lua-dev pcre-dev \
&& tar xvf /ws/$archive -C /ws/ \
&& cd /ws/imapfilter-${version#v} \
&& make install DESTDIR=/install
FROM alpine
COPY --from=builder /install /
RUN apk add pcre lua openssl \
&& addgroup -S imapfilter \
&& adduser -S imapfilter -G imapfilter
USER imapfilter
COPY --chown=imapfilter:imapfilter config.lua /home/imapfilter/.imapfilter/
RUN openssl s_client -connect free.fr:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > /home/imapfilter/.imapfilter/certificates
ENTRYPOINT ["imapfilter"]
Une fois l’image dispo il suffit d’exécuter le container avec les 2 variantes qui nous intéresses, à savoir le login de votre boite et son mot de passe.
docker run --rm -it -e FREE_USERNAME=$FREE_USERNAME -e FREE_PASSWORD=$FREE_PASSWORD imapfilter-free.fr
Fetched field "X-ProXaD-SC" of username@imap.free.fr/INBOX[80732].
Thu Oct 10 05:32:41 2019 headers >> X-ProXaD-SC: state=HAM:CommercialEmailGeneric score=17
Thu Oct 10 05:32:41 2019 state(HAM) category(CommercialEmailGeneric) score(17)
1 messages moved from username@imap.free.fr/INBOX to username@imap.free.fr/Junk.
Fetched field "X-ProXaD-SC" of username@imap.free.fr/INBOX[80734].
Thu Oct 10 07:12:42 2019 headers >> X-ProXaD-SC: state=HAM:CommercialEmailGeneric score=17
Thu Oct 10 07:12:42 2019 state(HAM) category(CommercialEmailGeneric) score(17)
1 messages moved from username@imap.free.fr/INBOX to username@imap.free.fr/Junk.
Conclusion
Évidemment il n’y a plus beaucoup de monde qui utilise une boite Free, mais si vous voulez
effectuer des post-traitements sur une boite mail que vous n’hébergez pas imapfilter
est
une solution. Ça a donné une seconde vie à ma boite Free, ce qui implique que je ne m’en suis toujours
pas débarrassé !