SPF est un enregistrement DNS spécialement construit, qui permet de dire quelles adresses IPs ont le droit d'envoyer des mails pour un domaine.
Pour le domaine “tjaouen.fr
” par exemple, c'est mail.eez.fr
.
Postfix peut alors rejeter ou marquer comme SPAM, des mails d'origines douteuses.
~~READMORE~~
A l'origine, SPF est un enregistrement DNS de type SPF
.
Mais en pratique, comme expliqué là, c'est simplement un enregistrement DNS de type TXT
.
Un petit rappel: Pour connaitre qu'elles sont les serveurs devant traiter les mails a destination d'un domaine:
$ dig -t MX le-domaine-en-question.com
Exemple, pour les mails @gmail.com
:
$ dig +short -t MX gmail.com 10 alt1.gmail-smtp-in.l.google.com. 20 alt2.gmail-smtp-in.l.google.com. 30 alt3.gmail-smtp-in.l.google.com. 40 alt4.gmail-smtp-in.l.google.com. 5 gmail-smtp-in.l.google.com.
Maintenant, pour savoir qu'elles sont les serveurs pouvant émettre des mails pour un domaine:
$ dig +short -t TXT le-domaine-en-question.com | grep "v=spf1"
Encore une fois, en théorie, -t SPF
devrait aussi fonctionner, mais c'est rarement le cas.
Le marquage “v=spf1”
fait partie du protocole: http://www.openspf.org/SPF_Record_Syntax
Exemple:
$ dig +short -t TXT gmail.com | grep "v=spf1" "v=spf1 redirect=_spf.google.com"
Comme @gmail.com
a une configuration a peu complexe, on doit suivre le redirect
:
$ dig +short -t TXT _spf.google.com | grep "v=spf1" "v=spf1 include:_netblocks.google.com include:_netblocks6.google.com ?all"
et encore:
$ dig +short -t TXT _netblocks.google.com | grep "v=spf1" "v=spf1 ip4:216.239.32.0/19 ip4:64.233.160.0/19 ip4:66.249.80.0/20 ip4:72.14.192.0/18 ip4:209.85.128.0/17 ip4:66.102.0.0/20 ip4:74.125.0.0/16 ip4:64.18.0.0/20 ip4:207.126.144.0/20 ip4:173.194.0.0/16 ?all"
Des scripts font ça très bien automatiquement. Comme par exemple spfquery
.
# aptitude update # aptitude install spfquery
Par exemple, testons “gmail.com” dans une mauvaise condition, parce l'IP donné n'est pas autorisé:
$ spfquery -ip=11.22.33.44 -sender=toto@gmail.com neutral Please see http://www.openspf.org/Why?id=toto%40gmail.com&ip=11.22.33.44&receiver=spfquery : Reason: mechanism spfquery: 11.22.33.44 is neither permitted nor denied by domain of gmail.com Received-SPF: neutral (spfquery: 11.22.33.44 is neither permitted nor denied by domain of gmail.com) client-ip=11.22.33.44; envelope-from=toto@gmail.com;
La même chose avec une IP autorisée (parce qu'on la vu dans la requête “dig” précédement) :
$ spfquery -ip=216.239.32.1 -sender=toto@gmail.com pass ...
ce n'est pas une obligation ! mais juste un conseil. |
Pour faire bref:
Créer un enregistrement DNS de type TXT
qui dit: “autoriser mes serveurs, et interdire les autres”.
Pour mon cas, dans le DNS ( bind
) :
tjaouen.fr. 3600 IN TXT "v=spf1 a:mail.eez.fr -all"
Voila: le seul serveur autorisé est “mail.eez.fr
”.
Pour terminer, je crois que ce n'est pas à négliger, il faut bien s'assurer que le HELO
envoyé par le serveur est un domaine autorisé par le protocole SPF
.
Par exemple, dans ma conf Postfix
, j'ai ça dans le fichier /etc/postfix/main.cf
:
myhostname = mail.eez.fr
PS: parce que je crois qu'il y a 2 tests avec le SPF
: sur l'IP et sur le HELO
.
UPDATE : La version “python” est meilleure: postfix_pypolicyd-spf |
Ce filtre va simplement rejeter les mails dont la source est explicitement douteuse, et ajouter un “header” spécifique pour les autres, expliquant le status du mails par rapport aux protocoles SPF.
SpamAssassin
est , par défaut, déjà prêt pour tagguer les entêtes SPF.
Plugin là: /usr/share/perl5/Mail/SpamAssassin/Plugin/SPF.pm
Et ce plugin est chargé comme on le voit là:
$ grep SPF /etc/spamassassin/* /etc/spamassassin/init.pre:# SPF - perform SPF verification. /etc/spamassassin/init.pre:loadplugin Mail::SpamAssassin::Plugin::SPF
Ce qui manque, c'est le bon filtre “SPF” qui va ajouter les “header” (entête!) .
UPDATE Nov.2014 :
En fait, le script “SPF.pm” de “spamassassin
” fonctionnera totalement si les entêtes du mail contiennent l'enveloppe du “sender” via l'entete “Return-Path”. ( source: https://wiki.apache.org/spamassassin/IntegratedSpamdInPostfix )
Donc: dans le fichier “master.cf
” , ne pas oublier “flags=Rq
” avec la mise en place de “spamassassin
”.
Donc:
# aptitude update # aptitude install postfix-policyd-spf-perl
Il suffit de suivre la doc:
$ man postfix-policyd-spf-perl
C'est à dire:
Dans le fichier /etc/postfix/master.cf
, ajouter:
spfcheck unix - n n - 0 spawn user=policyd-spf argv=/usr/sbin/postfix-policyd-spf-perl
Dans /etc/postfix/main.cf
, ajouter quelque part, aprés reject_unauth_destination
:
smtpd_recipient_restrictions = ... reject_unauth_destination check_policy_service unix:private/spfcheck ...
Et aussi dans main.cf
:
spfcheck_time_limit = 3600
… sinon, on aura plein de message (pas grave) du genre:
Oct 3 23:31:23 mail postfix/spawn[6517]: warning: /usr/sbin/postfix-policyd-spf-perl: process id 8239: command time limit exceeded
Redemarrer postfix:
# /etc/init.d/postfix restart
ou simplement postfix reload
?
Normalement, on doit voir dans les logs des choses en relation avec SPF:
Oct 3 19:58:11 mail postfix/policy-spf[2638]: : SPF pass (Mechanism 'a:mail.eez.fr' matched): Envelope-from: noboby@tjaouen.fr Oct 3 19:58:11 mail postfix/policy-spf[2638]: handler sender_policy_framework: is decisive. Oct 3 19:58:11 mail postfix/policy-spf[2638]: : Policy action=PREPEND Received-SPF: pass (tjaouen.fr ... eez.fr: 88.190.21.130 is authorized to use 'noboby@tjaouen.fr' in 'mfrom' identity (mechanism 'a:mail.eez.fr' matched)) receiver=mail.local.eez.fr; identity=mailfrom; envelope-from="noboby@tjaouen.fr"; helo=mail.eez.fr; client-ip=88.190.21.130
Il y aura surement des IPs ou des plages d'IPs qu'il faudra ne surtout pas tester: c'est a dire des “relay” qui transfèrent des mails sans ré-ecrire l'adresse de l'emetteur et pour lesquels le test SPF echoue inexorablement (voir SRS
et Forwarding
dans un autre article).
Dans la doc, il est dit :
" you can add them to relay_addresses on line 78 "
Cette ligne est dans le fichier (perl) /usr/sbin/postfix-policyd-spf-perl
,
… et ce présente comme cela (extrait) :
use constant relay_addresses => map( NetAddr::IP->new($_), qw( ) ); # add addresses to qw ( ) above separated by spaces using CIDR notation.
Donc, ajouter par exemple:
qw( 1.2.3.4 5.6.7.0/24 )
: un petit patch pour une conf externe et local serait génial ! |
tumgreyspf
est un système de greylist
et un testeur de protocole SPF
.
PS: pour bien tester, j'ai d'abord desactivé tout autres logiciels filtrant via SPF
(comme par exemple: postfix-policyd-spf-perl
)
# aptitude update # aptitude install tumgreyspf ... Created user tumgreyspf ...
D'aprés la doc, il serait indispensable d'avoir un scripte qui fait le ménage dans la base de données (qui est en fait un ensemble de fichiers et de sous répertoire dans /var/lib/tumgreyspf/data/
)
Ce scripte est déjà installé par défaut , et il est là:
/etc/cron.daily/tumgreyspf
A priori, il fait le même boulot que tumgreyspf-clean
, 1 fois par jour. (A confirmer)
Dans master.cf
:
# tumgreyspf tumgreyspf unix - n n - - spawn user=tumgreyspf argv=/usr/bin/tumgreyspf
Dans main.cf
:
smtpd_recipient_restrictions = ... reject_unauth_destination check_policy_service unix:private/tumgreyspf
tumgreyspf_time_limit = 3600
Mettre la politique “tumgreyspf” toujours quelque part après reject_unauth_destination |
Redemarrer.
# postfix reload
Dec 9 07:45:03 mail tumgreyspf[1837]: Pending greylisting: REMOTEIP="212.27.42.9" HELO="smtpfb1-g21.free.fr" SENDER="nobodynobody@free.fr" RECIPIENT="nobody@tjaouen.fr" QUEUEID=""
J'en vois 2 selons moi:
tumgreyspf
est d'abord un ordinaire système de “greylist”, a la manière de postgrey
.
Il n'y a pas de rapport entre le protocole SPF
et la mise en greylist
.
L'entête Received-SPF
n'est jamais renseigné !
C'est pourtant interessant pour savoir comment a été traité le mail et eventuellement pourquoi il a été marqué, ou non, comme SPAM !
Si vous avez besoin de “greylist”, préférer “postgrey”.
Si vous avez besoin de rejeter ou marquer des mails selon le protocole SPF
, alors préferer postfix-policyd-spf-perl
Et aussi là: http://www.openspf.org/Tools
Il suffit d'envoyer un simple mail à “spf-test@openspf.net” et une erreur revient contenant “none” ou “pass” ou “fail”.
Ça peut dépanner temporairement…