===== Les armes anti-spam de postfix ===== Postfix est un outil particulièrement modulaire, et que l'on peut facilement paramétrer pour mettre en place une politique anti-spam. Depuis la version 2.1 il est de plus doté de la fonctionnalité "policy-server" qui lui permet de prendre une décision rapide dès le début de la connexion, permettant de renvoyer un 4xx ou un 5xx sur des critères comme l'IP, le from et le to. Les versions binaires sont disponibles sur [[http://postfix.wl0.org/en/]]. La version 2.2, très récente, est capable grâce au module anvil de limiter la cadence d'expédition des mails. ==== L'anti-relaying ==== Afin d'éviter l'utilisation par les spammeurs de nos serveurs, des techniques intégrées dans Postfix sont utilisées. On se doit de créer un fichier mynetwork qui contient les adresses IP des réseaux internes. Les protections sont ensuite vérifiées par un telnet relay-test.mail-abuse.org depuis le serveur smtp frontal.\\ Le fichier /etc/postfix/main.cf (pour la partie antispam) de postfix a alors la tête suivante mynetworks = /etc/postfix/network_table mynetworks_style = subnet smtpd_recipient_restrictions = permit_mynetworks reject_unauth_destination permit Le contenu du fichier network_table contient lui quelque chose comme 10.0.0.0/8 192.168.0.0/16 On pourra, avec profit, se reporter à [[http://x.guimard.free.fr/postfix/index.php?page=SMTPD_ACCESS_README.html]] Il est à noter que de très nombreux tests de rejet sont disponibles dans Postfix (voir l'url ci-dessus). Mais ces tests sont parfois trop agressifs. On peut tester quasiment n'importe quoi à n'importe quel moment, y compris avec des RBL, des expressions régulières, des fichiers, des hash, des reverse dns, etc. ==== Le greylisting ==== Le greylisting s'applique grâce à la notion de policy-server. Afin de pallier au problème des domaines incompatibles avec le greylisting, on crée un fichier whitelisted_domains qui les exclus du greylisting. Le fichier /etc/postfix/main.cf (pour la partie antispam) de postfix a alors la tête suivante mynetworks = /etc/postfix/network_table mynetworks_style = subnet smtpd_recipient_restrictions = permit_mynetworks # que l'on remplacera plus bas par une routine plus efficace reject_unauth_destination # pour empêcher le relaying. check_client_access hash:/etc/postfix/whitelisted_domains check_policy_service unix:private/whitelist check_policy_service unix:private/greylist permit De plus pour les installer il faut insérer dans /etc/postfix/master.cf greylist unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/greylist.pl whitelist unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/whitelist.pl Des outils qui permettent de mettre en place le greylisting sont disponibles sur [[http://cri.univ-tlse1.fr/documentations/spam/outils/]] * Les outils sont en Perl * Ils nécessitent les packages suivants : perl -MCPAN -e 'install DB_File' perl -MCPAN -e 'install DB_File::Lock' * créer le répertoire /var/mta et le faire appartenir à l'utilisateur nobody * le script greylist.pl calcule les triplets et les met dans la base de données. * le script whitelist.pl vérifie les triplets par rapport à la base des triplets blanchis * le script clean_policy.pl récupère dans le /var/log/maillog les triplets blanchis de la base "liste_grise" et les insère dans la base "liste_blanche", en "oubliant" les spammeurs, et virus notoires, et enfin efface les triplets blancs de plus de 36 jours. Il doit être lancé par le crontab toutes les nuits. * ATTENTION, les scripts greylist.pl, et whitelist.pl retournent OK_AND_PREPEND, car ils utilisent des fonctions qui seront vues plus bas. On peut remplacer ces return "OK_AND_PREPEND"; par return "OK";. Idem pour la base whitelisted_domains. ==== Les blacklists ==== Le blacklisting est une méthode efficace pour bloquer les spams. Plusieurs listes publiques sont disponibles et permettent de rejeter les mails qui proviennent d'expéditeurs spammeurs. Toujours dans notre optique de limitation des effets, nous avons mis en place un taggage des mails suivant le résultat des blacklists. Mais une simple modification du programme suffit à rendre le programme "énergique". Pour les installer il faut insérer dans /etc/postfix/master.cf rbl unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/rbl.pl greylist unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/greylist.pl whitelist unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/whitelist.pl Mais cela ne suffit pas, car nous souhaitons taguer tout message qui arrive. Pour cela nous créons une classe de restriction SMTP appelée OK_AND_PREPEND qui va nous permettre d'accepter des messages, mais d'ajouter un renseignement complémentaires sur les résultats de divers tests. La liste des RBL utilisées est directement intégrée dans le script. Le fichier /etc/postfix/main.cf (pour la partie antispam) de postfix a alors la tête suivante mynetworks = /etc/postfix/network_table mynetworks_style = subnet smtpd_recipient_restrictions = permit_mynetworks reject_unauth_destination check_policy_service unix:private/whitelist check_policy_service unix:private/greylist permit smtpd_restriction_classes = OK_AND_PREPEND OK_AND_PREPEND = check_policy_service unix:private/rbl permit Pour un exemple de développement : * L'outil est toujours en perl : * le script rbl.pl vérifie un certain nombre de bases de listes noires et crée une chaine compilant les résultats de chacune d'elle. ==== Les tests d'expéditions ==== Ils permettent de vérifier que la machine qui envoie le message est autorisée à le faire avec l'identité qu'elle prétend ( exemple seuls les serveurs hotmail.com sont autorisés à envoyer du @hotmail.com). Plusieurs dispositifs sont connus pour le faire. SPF et DomainsKey. Notre outil ne gère que SPF. Pour le mettre en place il faut insérer dans /etc/postfix/master.cf spf unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/spf.pl rbl unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/rbl.pl greylist unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/greylist.pl whitelist unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/whitelist.pl Nous complétons ensuite la classe OK_AND_PREPEND. Contenu de main.cf mynetworks = /etc/postfix/network_table mynetworks_style = subnet smtpd_recipient_restrictions = permit_mynetworks reject_unauth_destination check_policy_service unix:private/whitelist check_policy_service unix:private/greylist permit # en théorie : il n'est jamais atteint smtpd_restriction_classes = OK_AND_PREPEND OK_AND_PREPEND = check_policy_service unix:private/spf check_policy_service unix:private/rbl permit * L'outil est toujours en perl : * Il nécessite une librairie perl * perl -MCPAN -e 'install Mail::SPF::Query' * le script spf.pl vérifie le résultat SPF pour l'adresse d'expéditeur et place un tag. Il est disponible sur [[http://cri.univ-tlse1.fr/documentations/spam/outils/spf.pl]] ==== Les tests de connexion ==== En plus de la protection anti-spam nous en avons profité pour tester la cadence d'émission des postes locaux à l'aide d'un autre script. Celui -ci va vérifier qu'un poste ne prend pas plus de 5 identités d'expéditeurs par 10 minutes) Pour installer cette protection il faut insérer dans master.cf mynetwork unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/mynetwork.pl spf unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/spf.pl rbl unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/rbl.pl greylist unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/greylist.pl whitelist unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/extra/whitelist.pl Nous ajoutons la classe MYNETWORK. Nouvelle version de main.cf: mynetworks = /etc/postfix/network_table mynetworks_style = subnet smtpd_recipient_restrictions = check_client_access hash:/etc/postfix/mynetwork permit_mynetworks reject_unauth_destination check_policy_service unix:private/whitelist check_policy_service unix:private/greylist permit smtpd_restriction_classes = OK_AND_PREPEND,MYNETWORK OK_AND_PREPEND = check_policy_service unix:private/spf check_policy_service unix:private/rbl permit MYNETWORK = check_policy_service unix:private/mynetwork permit * L'outil est toujours en perl * le script mynetwork.pl conserve dans une base de données le nombre d'expéditeurs pour chaque machine. * Le fichiers utilisés pour choisir quelles ip doivent être traitées est peu ou prou identique à /etc/postfix/network-table, hormis que l'on autorise directement certains serveurs SMTP ou webmail (qui ont plus de 4 expéditeurs par 10 minutes), tout le reste devant passer par la classe MYNETWORK. 127.0.0.1 OK 193.49.48.250 OK 193.49.48.247 OK 194.254.254.31 OK 192.93.172 MYNETWORK 193.49.48 MYNETWORK 193.49.50 MYNETWORK 193.49.51 MYNETWORK 193.49.52 MYNETWORK 193.49.53 MYNETWORK 193.49.54 MYNETWORK 193.49.55 MYNETWORK 193.49.58 MYNETWORK 194.254.254 MYNETWORK 194.254.255 MYNETWORK 195.83.197 MYNETWORK 10 MYNETWORK 192.168 MYNETWORK ==== Les tests sur les annexes ==== Les virus sont parfois trop rapides pour les antivirus : 4 heures pour la mise à disposition d'une signature (et parfois bien plus). C'est pour cela qu'il peut être intéressant de bloquer ou de retarder les annexes connues pour leur utilisation virales. Toujours selon notre politique, nous nous contentons de mettre en quarantaine les mails avec ce type d'annexes, puis nous les ressortons au bout de 6 heures. On commence par modifier le fichier /etc/postfix/header_checks en lui ajoutant la ligne suivante. /^content-(type|disposition):.*name[[:space:]]*=.*\.(com|cpl|scr|vbe|vbs|pif|hta|shs|vxd|wsh|lnk|shm|shb)/ HOLD Attachement Type Not Allowed. Annexe de type non autorise Il faut ensuite utiliser la possibilite de check de PostFix dans /etc/postfix/main.cf header_checks = regexp:/etc/postfix/header_checks Le script release_hold_mail.sh tournant toutes les heures va vérifier les mails en quarantaine et les relancer au bout de 6 heures. #!/bin/sh # # On passe en langue anglaise, car les dates sont en anglais # LANG=us_GB # # On prend le jour, le mois et l'heure il y a 6 heures # date_recherchee=`date --date '6 hours ago' +'%a %b %e %H'` # # On recherche les mails en hold qui (dont le code se termine par # un "!") puis on recherche ceux dont l'heure est égale # à date_recherchée, on enlève le point d'exclamation, et on envoi # le tout à postsuper pour qu'il les "sorte" du HOLD. # /usr/sbin/postqueue -p|egrep '^([0-9A-F]{10}\!)'|grep "$date_recherchee"|awk '{print $1}'|sed 's/!//'|/usr/sbin/postsuper -H - # # On release après un sleep de 30 secondes, les mails de la veille # # sleep 30 # # On prend le jour et le mois il y a 1 jour (en cas de pépin lors du # release normal # date_recherchee=`date --date '1 days ago' +'%a %b %e'` /usr/sbin/postqueue -p|egrep '^([0-9A-F]{10}\!)'|grep "$date_recherchee"|awk '{print $1}'|sed 's/!//'|/usr/sbin/postsuper -H -