SecuMail » Historique » Version 12
Version 11 (Fabien Dupont, 16/08/2012 20:44) → Version 12/63 (Fabien Dupont, 16/08/2012 21:17)
h1. Sécuriser un serveur de mail
{{>toc}}
h2. Présentation des différents systèmes
h3. Antivirus
Bon...linux, pas de virus, tout ça tout ça...m'enfin, ça ne coûte pas grand chose de filtrer ses propres messages à l'envoi pour s'assurer qu'on ne forwarde pas un PPT plein de chatons qui jouent du piano et de virus. Et puis quitte à filtrer dans un sens, autant filtrer dans l'autre.
Il n'y a pas 50000 antivirus sous linux, ClamAV est l'un des plus complet, mis à jour et performant. Appelé depuis "ClamSMTP":http://thewalter.net/stef/software/clamsmtp/, il s'intègre très bien à postfix.
h3. Spamassassin
Spamassassin est un programme en perl développé par la fondation Apache. Ce programme regroupe plusieurs méthodes de détection de spams telles que :
* DNSBL (DNS BlackList) : blocage d'adresses IP (voir RBL plus loin) par interrogation de DNS.
* SURBL (URL BlackList) : idem mais par interrogation d'URI.
* Hashcash : Système en DoS se basant sur la consommation CPU utilisée par l'émetteur lors de l'envoi de mail.
D'autres sont disponibles via l'installation et l'activation de plug'ins.
De plus, SpamAssassin, propose la détection de spams via l'application de "filtres bayesiens":http://fr.wikipedia.org/wiki/Th%C3%A9or%C3%A8me_de_Bayes permettant de différencier les spams des hams (les « pas spams »).
h3. Greylisting
Le greylisting est un procédé permettant de refuser la réception de spams en provenance de spambots. Ce procédé se base sur le fait que certains spams ne sont pas émis depuis de « vrais » serveurs de mail.
Un « vrai » serveur de mail dispose d'une file de messages dans laquelle il stocke les messages dont l'émission a été refusée par une erreur 4xx (généralement, 450) alors qu'un spambot émets des mails sans se soucier du succès de l'envoi ou pas.
Ainsi, un daemon de greylisting refuse systématiquement les mails en provenance d'un serveur en retournant un code d'erreur 450. Dans le même temps, il mémorise les informations de ce serveur (IP, nom, etc.). Ãtant donné que le code d'erreur n'est pas un refus catégorique (5xx), le serveur émetteur retente un envoi régulièrement, généralement toutes les 5 ou 10 minutes, jusqu'à la fin d'un timeout défini, généralement plusieurs jours. Si le même message a été émis 3 fois d'affilé, le daemon de greylisting l'accepte et place le serveur émetteur dans une « whitelist » temporaire pendant un temps défini.
Un des daemons de greylisting célèbre et fonctionnant bien avec postfix est postgrey.
h3. RBL
Les RBL ou « Realtime Black Lists » sont des listes mises à jour en temps réel d'adresses IP réputées pour être émettrices de spams. L'interrogation de ces listes se fait grâce au protocole DNS.
Par exemple, pour savoir si l'adresse IP 91.224.149.142 est classée comme émettrice de spams, d'abord, retournons là : 142.149.224.91. Puis ajoutons le nom d'une RBL, par exemple sbl-xbl.spamhaus.org. Et regardons si une adresse IP correspond à ce « nom de domaine » :
<pre>
$ host 142.149.224.91.sbl-xbl.spamhaus.org
Host 142.149.224.91.sbl-xbl.spamhaus.org not found: 3(NXDOMAIN)
</pre>
Pas d'adresse IP associée à ce nom de domaine, l'adresse IP 91.224.149.142 est clean !
Même exercice pour l'adresse IP 114.37.70.152 :
<pre>
# host 152.70.37.114.sbl-xbl.spamhaus.org
152.70.37.114.sbl-xbl.spamhaus.org has address 127.0.0.4
</pre>
L'adresse IP 127.0.0.4 est retournée et selon la "documentation de spamhaus.org":http://www.spamhaus.org/zen/, 127.0.0.4 veut dire que cette IP est notée comme étant une machine infectée par un virus émetteur de spam.
L'utilisation de RBL pour bloquer les mails est souvent soumise à controverse car le remplissage et la maintenance de ces listes sont généralement obscurs. Il en existe même qui demande une rémunération pour la suppression d'adresse IP. Bref, libre à chacun d'utiliser ces listes ou pas tant que c'est en tout connaissance de cause.
h3. SPF
SPF ou « Sender Policy Framework », est un système anti « spoofing ». C'est à dire qu'il permet de valider que le serveur émetteur du mail est bien le serveur qui gère ce mail.
Ce système se base sur la mise en place d'un champ TXT (ou SPF) dans le nom de domaine émetteur. Ce champs ne peut être ajouté que par le gestionnaire du domaine et donc sûrement le gestionnaire du serveur de mail émetteur (en tout cas, lui seul peut valider que l'un est associé à l'autre).
Ce champ TXT permet de valider que le nom de domaine de l'adresse mail émettrice, l'adresse IP du serveur émetteur et son reverse sont valides.
Exemple de champs SPF pour le domaine kafe-in.net :
<pre>
$ dig +short spf kafe-in.net
"v=spf1 mx ptr:muscat.kafe-in.net ptr:fdn.le.fai.avec.les.bulles.qui.vont.vers.le.bas.kafe-in.net mx:mail.kafe-in.net mx:mail2.kafe-in.net ip6:2a01:6600:8081:8e00::fab ip6:2001:910:109c:2::25 ip4:91.224.149.142 ip4:80.67.176.156 include:dupont.eu.org -all"
</pre>
h3. DKIM
DKIM, ou « DomainKeys Identified Mail », est une autre méthode pour associer un nom de domaine à un mail. Cette validation se base sur l'ajout d'un header contenant une clé, cette clé permet de signer le mail. Cette signature est validée en interrogeant un champ TXT du nom de domaine émetteur du mail.
Exemple de champs TXT pour le domaine kafe-in.net et de signature :
<pre>
dig +short txt default._domainkey.kafe-in.net
"v=DKIM1\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh2cOuv5Tb+oFElVq3sf837oclBXoiHcMDjlWxpjCfjyYq1fSZNyMxXG/CKqLRx/bqyI/Bcl6n30pR8Okp8ItjBvUXQJwh6fczyKdto69Z2DrGf495ANghUtPxKFOe98PXuEa0OmvhOD45VOKeHU9TW32SgxHy6kxur/WMaJMbDwIDAQAB"
</pre>
<pre>
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=kafe-in.net;
s=default; t=1344852664;
bh=fdkeB/A0FkbVP2k4J4pNPoeWH6vqBm9+b0C3OY87Cw8=;
h=From:Date:To:Subject;
b=DqT32ZzqUgRPm9PGYwfB7nxJiyaTLxT6yoeIPLqPnxwgMJ933nYLxQpMimSsaKZdT
iGo68RBhgFFXe+6zJCWPZbCye8ptW8awCHfwsogYAzvRs0wk9rF/r78CWZXAn6dCeH
cCMomFWcBOzTdbqQ/ZKizBCOdgLsT/aPDVBV00Eo=
</pre>
h2. Enchaînement des différents systèmes
Il existe plusieurs moyens pour postfix de vérifier la validité du mail, ou pas :
* Les content filters : Ce sont des programmes recevant un mail selon le protocole SMTP et le renvoyant, ou pas, à postfix selon le même protocole après ajout de headers. Exemple : ClamSMTP et SpamAssassin.
* Les milters : ce sont des programmes dialoguant avec postfix sur un port TCP donné en suivant un "protocole défini":https://www.milter.org/developers/api/index. Exemple : OpenDKIM.
* Les policy services : Ce sont des programmes au fonctionnement proche des milters. Ils permettent de valider ou non le passage d'un mail selon ses paramètres. Exemple : PostGrey et postfix-policyd-spf-python.
* Les RBL : Voir plus haut, la gestion des RBL est gérée directement par postfix.
Voilà rapidement l'enchaînement des validations faites à l'arrivée d'un mail :
* Ãmetteur : Ouverture d'une connexion sur le port 25 (SMTP).
* Récepteur : Vérification de la validité de l'adresse IP source et consultation des RBL (smtpd_client_restrictions).
* Ãmetteur : HELO sondomaine.tld
* Récepteur : Vérification de la validité du domaine et du reverse (smtpd_helo_restrictions).
* Ãmetteur : MAIL from : "Marvin the paranoid android" <marvin@sondomaine.tld>
* Récepteur : Vérification de la validité de l'adresse émettrice (smtpd_sender_restrictions).
* Ãmetteur : RCPT to : "Fabien Dupont" <fab@mondomaine.tld>
* Récepteur : Vérification de la validité de l'adresse destinataire (smtpd_recipient_restrictions).
** Interrogation du « policy service » postgrey sur le port 10023
** Interrogation du « policy service » python-spf via la socket unix private/policyd-spf
* Récepteur : Envoi du code de retour au serveur émetteur ("RFC3463":http://www.rfc-editor.org/rfc/rfc3463.txt) :
** 3xx : OK pour la suite
** 4xx : Erreur temporaire (exemple: postgrey).
** 5xx : Erreur permanente (Adresse émettrice ou réceptrice non valide).
* Ãmetteur : DATA puis le contenu du mail (headers compris).
* Récepteur : Transfert du mail au « content filters » :
** ClamSMTP reçoit le mail sur le port 10025 et si le mail est valide...
** SpamAssassin reçoit le mail sur le port 10026 et si le mail est valide...
** Postfix récupère le mail validé sur le port 10028
* Récepteur : Validation du mail via le milter OpenDKIM sur le port 10028
* Récepteur : Envoi du code de retour au serveur émetteur ("RFC3463":http://www.rfc-editor.org/rfc/rfc3463.txt) :
** 2xx : OK pour l'envoi
** 4xx : Erreur temporaire (exemple: postgrey).
** 5xx : Erreur permanente (exemple: spam détecté par SpamAssassin, virus par ClamAV, etc.).
* Ãmetteur : Fermeture de la connexion sur le port 25.
h2. Installation et configuration
h3. Postfix
h4. Configuration de base
Ce tutoriel part du principe que postfix est déjà correctement installé et configuré pour l'émission et la réception de mails.
La configuration de postfix sera modifiée au fur et à mesure de l'installation des différents services.
Postfix, s'il est configuré en tant que serveur de mail visible depuis internet, doit être configuré pour autoriser la réception de messages depuis n'importe où et l'émission uniquement depuis le réseau local. Si ce n'est pas le cas, le serveur de mail sera configuré en mode "open relay":http://en.wikipedia.org/wiki/Open_relay. Bien évidemment un tel serveur serait une plateforme d'envoi de spams ou autre saletés. Il serait très vite blacklisté auprès des différentes RBL.
Pour ce tutoriel, le serveur de mail nommé ve-mail hébergera des adresses du domaine kafe-in.net et le réseau local sera composé de 192.168.2.0/24 en IPv4 et 2001:910:109c::/48 en IPv6.
+main.cf :+
<pre>
mydomain = kafe-in.net
mydestination = ve-mail, ve-mail.kafe-in.net, localhost.localdomain, localhost, kafe-in.net
mynetworks = 127.0.0.0/8, [::1]/128, 192.168.2.125/32, [2001:910:109c::]/48
</pre>
h4. Restrictions de base
Dans un premier temps, il faut indiquer à postfix qu'il faut délayer le rejet d'un mail à la fin du dialogue avec dialogue avec le serveur SMTP distant. C'est le paramètre "smtpd_delay_reject":http://www.postfix.org/postconf.5.html#smtpd_delay_reject. Ceci permet "3 choses":http://www.postfix.org/SMTPD_ACCESS_README.html#timing :
* certains serveurs SMTP ne prennent pas en compte les rejets pendant l'émission d'un mail et essaient donc de finir de l'envoyer même s'il a été refusé,
* postfix peut ainsi logger plusieurs informations intéressantes relatives à l'émetteur et au destinataire du mail,
* une adresse émettrice peut être rejetée selon le destinataire du mail (ex: greylisting), il faut donc avoir tous les paramètres du mail avant de prendre une décision.
Le paramètre "smtpd_helo_required":http://www.postfix.org/postconf.5.html#smtpd_helo_required permet de n'autoriser la réception de mail que si le serveur distant s'est présenté (HELO). Cela permet d'introduire des restrictions par rapport à cette commande SMTP (voir plus bas).
Le paramètre "strict_rfc821_envelopes":http://www.postfix.org/postconf.5.html#strict_rfc821_envelopes permet de refuser la réception de mail si le serveur distant ne respecte pas strictement la "rfc821":http://www.faqs.org/rfcs/rfc821.html, celle qui décrit le protocole SMTP.
+main.cf, restrictions de base :+
<pre>
# Basics Restrictions
smtpd_delay_reject = yes
smtpd_helo_required = yes
strict_rfc821_envelopes = yes
</pre>
Postfix applique ensuite des restrictions selon les paramètres du mail, dans l'ordre suivant :
* restrictions sur le client, c'est à dire sur l'adresse IP du serveur émetteur,
* restrictions sur le mot clé *HELO* lors du dialogue avec ce serveur,
* restrictions sur le mot clé *MAIL from*, c'est à dire sur l'adresse mail de l'émetteur,
* restrictions sur le mot clé *RCPT to*, c'est à dire sur l'adresse mail du destinataire,
Une liste de restrictions, dans postfix, est définie avec la syntaxe suivante :
smtpd_*nom*_restrictions = restriction 1, restriction 2, ..., restriction n
Elles sont parcourues dans l'ordre, jusqu'à ce que l'une d'entre elle accepte ou rejette le mail. La dernière restriction est *permit*, ainsi le mail est accepté si rien n'a indiqué explicitement son rejet ou sa validation.
h4. Restrictions sur le client
Ici, notre serveur est public, il doit donc accepter les connexions entrantes depuis n'importe quelle adresse IP.
+main.cf, restrictions sur le client :+
<pre>
# Requirements for the connecting server
smtpd_client_restrictions =
permit
</pre>
h4. Restrictions sur HELO
Comme on n'est pas des sauvages, on ne positionne aucunes restrictions si l'émetteur se situe sur notre réseau local (paramètre *mynetwork*, voir plus haut). Par contre, pour toutes les autres adresses IP source, on vérifie que le paramètre *HELO* correspond à un "FQDN":http://en.wikipedia.org/wiki/FQDN et que celui-ci correspond à un nom d'hôte valide.
+main.cf, restrictions sur le mot clé HELO :+
<pre>
# Requirements for the HELO statement
smtpd_helo_restrictions =
permit_mynetworks,
reject_non_fqdn_hostname,
reject_invalid_hostname,
permit
</pre>
h4. Restrictions sur l'adresse de l'émetteur
De la même façon, il est préférable de refuser des mails ayant un domaine inexistant ou mal formé, sauf pour notre réseau local.
+main.cf, restriction sur l'émetteur (sender) :+
<pre>
# Requirements for the sender address
smtpd_sender_restrictions =
permit_mynetworks,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
permit
</pre>
h4. Restrictions sur l'adresse du destinataire
On autorise notre LAN à envoyer des mails à destination de n'importe quelle adresse. Par contre, pour les autres on refuse les mails à destination d'une adresse mal formée (*reject_non_fqdn_recipient* et *reject_unknown_recipient_domain*) ou bien inconnue du serveur (*reject_unauth_destination*). C'est à dire dont la partie domaine de l'adresse n'est pas listée dans les variables *mydestination* ou *relay_domains*. Le refuser si la boite n'existe pas sera le travail du LDA (Local Delivery Agent), c'est à dire le programme qui délivre le mail dans la boite IMAP ou POP du destinataire.
<pre>
# Requirement for the recipient address
smtpd_recipient_restrictions =
permit_mynetworks,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_unauth_destination,
permit
</pre>
h4. Content filters
Les content filters sont des mini-serveurs SMTP analysant les mails entrants et les renvoyants ou pas sur un autre serveur SMTP. Postfix est donc le serveur source pour les content filters ainsi que le serveur de destination. Si un mail revient des content filters sans encombres, il est valide.
Les content filters peuvent être chaînés. Le premier écoute sur un port (ex: 10025) puis le passe au second sur un autre port (ex: 10026) qui le retransmet au serveur postfix de départ sur un port défini (ex: 10025). En cas de problème sur le second content filter, il retourne une erreur 5xx au premier content filter qui retourne donc cette erreur au serveur postfix de départ. Les refus sont ainsi transmis en cascade et pris en compte par postfix au final.
+main.cf, content filters :+
<pre>
# Content filtering
content_filter = scan:127.0.0.1:10025
receive_override_options = no_address_mappings
</pre>
Le port de destination des contents filters est écouté par un simple smtpd mais avec aucune restrictions ni autre content filters définis. Si ce n'était pas le cas, les mails entrant partirait en boucle dans le serveur de mail et serait refusés au final. Ce port est ouvert uniquement pour localhost (127.0.0.1) pour éviter qu'un serveur distant n'envoie un mail directement par ce biais.
+master.cf, définition du service de réception des content filters :+
<pre> </pre>
# For injecting mail back into postfix from the filter
127.0.0.1:10027 inet n - n - 16 smtpd
-o content_filter=
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks_style=host
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
</pre>
h3. ClamSMTPd
L'interface entre postfix est ClamAV peut être faite de différentes manières. La plus simple à mettre en place est d'utiliser le daemon ClamSMTP.
C'est un simple content filter pour lequel on définit le port d'entrée selon le paramètre *content_filter* de postfix et le port de sortie comme le port du prochain content filter mis en place ou bien celui de postfix si on ne désire pas en mettre en place d'autres.
+Installation de ClamSMTP :+ ClamSMTP+
<pre>
# apt-get install clamsmtp clamav-daemon
</pre>
+/etc/clamsmtpd.conf, fichier de configuration du daemon :+ daemon+
<pre>
# Port et adresse IP sur lesquels le daemon écoute
Listen: 127.0.0.1:10025
# Port et adresse IP sur lesquels le mail sera forwardé
OutAddress: 127.0.0.1:10026
# Chemin vers la socket unix ouverte par le daemon ClamAV
ClamAddress: /var/run/clamav/clamd.ctl
# Header ajouté au mail pour indiquer qu'il a bien été scanné
Header: X-AV-Checked: ClamAV using ClamSMTP
# Répertoire temporaire
TempDirectory: /var/spool/clamsmtp
# Chemin vers le fichier PID
PidFile: /var/run/clamsmtp/clamsmtpd.pid
# Action effectuée en cas de détection de virus :
# * bounce : retour à l'envoyeur (pas génial car l'adresse émettrice est souvent spoofée)
# * drop : le mail est supprimé silencieusement
# * pass : le mail est accepté mais le header X-Virus-Infected est ajouté
Action: drop
# Si 'on', les mails infectés sont stockés dans le répertoire temporaire
Quarantine: on
# Nom d'utilisateur sous lequel le programme tourne (ne pas utiliser root !)
User: clamsmtp
</pre>
h3. SpamPD
SpamPD est un proxy mail (un content filter) codé en perl et utilisant SpamAssassin pour tagger les mails en tant que spam ou ham (non spam).
+ Installation de SpamPD :+ SpamPD+
<pre>
# apt-get install spampd spamassassin
</pre>
+/etc/default/spampd, configuration du daemon :+
<pre>
# Démarrage du daemon au boot
STARTSPAMPD=1
# Chemin vers le fichier PID
PIDFILE=/var/run/spampd.pid
# Port et adresse IP sur lesquels le daemon écoute
LISTENHOST=127.0.0.1
LISTENPORT=10026
# Port et adresse IP sur lesquels le mail sera forwardé
DESTHOST=127.0.0.1
DESTPORT=10027
# Nombre de processus enfants (trop = beaucoup de ressources utilisées, pas assez = traitement des mails lent en cas de gros trafic)
CHILDREN=3
# Nom d'utilisateur et groupe sous lesquels le daemon tourne (pas root !)
USERID=spampd
GRPID=spampd
# Ajoute les headers de SpamAssassin indiquant que le mail a été scanné même s'il n'a pas été identifié comme spam.
TAGALL=1
# Option non utilisée depuis SpamAssassin >= 3.x
AUTOWHITELIST=0
# Désactivation de tous les tests sur l'adresse IP source (ici ce sera toujours 127.0.0.1)
LOCALONLY=1
# Utilisation de syslog via une socket unix (=0) ou une socket IP (=1)
LOGINET=0
# Options additionnelles à passer à SpamAssassin
ADDOPTS=""
</pre>
h3. Postgrey
Postgrey est un policy server (voir plus haut) qui est appelé par postfix si besoin et via un port TCP. Ici le port 10023 a été choisi de façon arbitraire.
+Installation de postgrey :+
<pre>
# apt-get install postgrey
</pre>
+/etc/default/postgrey, configuration du service :+
<pre>
# --inet : Port utilisé pour dialoguer avec postfix
# --delay : Durée en secondes pendant laquelle les mails sont refusés
# --max-age : Période en jour après laquelle le compteur d'émission est remis à zéro si pas de nouvelle réémission d'un mail
POSTGREY_OPTS="--inet=10023 --delay=300 --max-age=35"
# Message renvoyé en plus de l'erreur 4xx au serveur émettant le mail
POSTGREY_TEXT="Good news, everyone ! I taught the mail server to detect spambots."
</pre>
+main.cf, ajout du policy service postgrey aux restrictions sur le destinataire :+
<pre>
# Requirement for the recipient address
smtpd_recipient_restrictions =
permit_mynetworks,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_unauth_destination,
check_policy_service inet:127.0.0.1:10023,
permit
</pre>
{{>toc}}
h2. Présentation des différents systèmes
h3. Antivirus
Bon...linux, pas de virus, tout ça tout ça...m'enfin, ça ne coûte pas grand chose de filtrer ses propres messages à l'envoi pour s'assurer qu'on ne forwarde pas un PPT plein de chatons qui jouent du piano et de virus. Et puis quitte à filtrer dans un sens, autant filtrer dans l'autre.
Il n'y a pas 50000 antivirus sous linux, ClamAV est l'un des plus complet, mis à jour et performant. Appelé depuis "ClamSMTP":http://thewalter.net/stef/software/clamsmtp/, il s'intègre très bien à postfix.
h3. Spamassassin
Spamassassin est un programme en perl développé par la fondation Apache. Ce programme regroupe plusieurs méthodes de détection de spams telles que :
* DNSBL (DNS BlackList) : blocage d'adresses IP (voir RBL plus loin) par interrogation de DNS.
* SURBL (URL BlackList) : idem mais par interrogation d'URI.
* Hashcash : Système en DoS se basant sur la consommation CPU utilisée par l'émetteur lors de l'envoi de mail.
D'autres sont disponibles via l'installation et l'activation de plug'ins.
De plus, SpamAssassin, propose la détection de spams via l'application de "filtres bayesiens":http://fr.wikipedia.org/wiki/Th%C3%A9or%C3%A8me_de_Bayes permettant de différencier les spams des hams (les « pas spams »).
h3. Greylisting
Le greylisting est un procédé permettant de refuser la réception de spams en provenance de spambots. Ce procédé se base sur le fait que certains spams ne sont pas émis depuis de « vrais » serveurs de mail.
Un « vrai » serveur de mail dispose d'une file de messages dans laquelle il stocke les messages dont l'émission a été refusée par une erreur 4xx (généralement, 450) alors qu'un spambot émets des mails sans se soucier du succès de l'envoi ou pas.
Ainsi, un daemon de greylisting refuse systématiquement les mails en provenance d'un serveur en retournant un code d'erreur 450. Dans le même temps, il mémorise les informations de ce serveur (IP, nom, etc.). Ãtant donné que le code d'erreur n'est pas un refus catégorique (5xx), le serveur émetteur retente un envoi régulièrement, généralement toutes les 5 ou 10 minutes, jusqu'à la fin d'un timeout défini, généralement plusieurs jours. Si le même message a été émis 3 fois d'affilé, le daemon de greylisting l'accepte et place le serveur émetteur dans une « whitelist » temporaire pendant un temps défini.
Un des daemons de greylisting célèbre et fonctionnant bien avec postfix est postgrey.
h3. RBL
Les RBL ou « Realtime Black Lists » sont des listes mises à jour en temps réel d'adresses IP réputées pour être émettrices de spams. L'interrogation de ces listes se fait grâce au protocole DNS.
Par exemple, pour savoir si l'adresse IP 91.224.149.142 est classée comme émettrice de spams, d'abord, retournons là : 142.149.224.91. Puis ajoutons le nom d'une RBL, par exemple sbl-xbl.spamhaus.org. Et regardons si une adresse IP correspond à ce « nom de domaine » :
<pre>
$ host 142.149.224.91.sbl-xbl.spamhaus.org
Host 142.149.224.91.sbl-xbl.spamhaus.org not found: 3(NXDOMAIN)
</pre>
Pas d'adresse IP associée à ce nom de domaine, l'adresse IP 91.224.149.142 est clean !
Même exercice pour l'adresse IP 114.37.70.152 :
<pre>
# host 152.70.37.114.sbl-xbl.spamhaus.org
152.70.37.114.sbl-xbl.spamhaus.org has address 127.0.0.4
</pre>
L'adresse IP 127.0.0.4 est retournée et selon la "documentation de spamhaus.org":http://www.spamhaus.org/zen/, 127.0.0.4 veut dire que cette IP est notée comme étant une machine infectée par un virus émetteur de spam.
L'utilisation de RBL pour bloquer les mails est souvent soumise à controverse car le remplissage et la maintenance de ces listes sont généralement obscurs. Il en existe même qui demande une rémunération pour la suppression d'adresse IP. Bref, libre à chacun d'utiliser ces listes ou pas tant que c'est en tout connaissance de cause.
h3. SPF
SPF ou « Sender Policy Framework », est un système anti « spoofing ». C'est à dire qu'il permet de valider que le serveur émetteur du mail est bien le serveur qui gère ce mail.
Ce système se base sur la mise en place d'un champ TXT (ou SPF) dans le nom de domaine émetteur. Ce champs ne peut être ajouté que par le gestionnaire du domaine et donc sûrement le gestionnaire du serveur de mail émetteur (en tout cas, lui seul peut valider que l'un est associé à l'autre).
Ce champ TXT permet de valider que le nom de domaine de l'adresse mail émettrice, l'adresse IP du serveur émetteur et son reverse sont valides.
Exemple de champs SPF pour le domaine kafe-in.net :
<pre>
$ dig +short spf kafe-in.net
"v=spf1 mx ptr:muscat.kafe-in.net ptr:fdn.le.fai.avec.les.bulles.qui.vont.vers.le.bas.kafe-in.net mx:mail.kafe-in.net mx:mail2.kafe-in.net ip6:2a01:6600:8081:8e00::fab ip6:2001:910:109c:2::25 ip4:91.224.149.142 ip4:80.67.176.156 include:dupont.eu.org -all"
</pre>
h3. DKIM
DKIM, ou « DomainKeys Identified Mail », est une autre méthode pour associer un nom de domaine à un mail. Cette validation se base sur l'ajout d'un header contenant une clé, cette clé permet de signer le mail. Cette signature est validée en interrogeant un champ TXT du nom de domaine émetteur du mail.
Exemple de champs TXT pour le domaine kafe-in.net et de signature :
<pre>
dig +short txt default._domainkey.kafe-in.net
"v=DKIM1\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh2cOuv5Tb+oFElVq3sf837oclBXoiHcMDjlWxpjCfjyYq1fSZNyMxXG/CKqLRx/bqyI/Bcl6n30pR8Okp8ItjBvUXQJwh6fczyKdto69Z2DrGf495ANghUtPxKFOe98PXuEa0OmvhOD45VOKeHU9TW32SgxHy6kxur/WMaJMbDwIDAQAB"
</pre>
<pre>
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=kafe-in.net;
s=default; t=1344852664;
bh=fdkeB/A0FkbVP2k4J4pNPoeWH6vqBm9+b0C3OY87Cw8=;
h=From:Date:To:Subject;
b=DqT32ZzqUgRPm9PGYwfB7nxJiyaTLxT6yoeIPLqPnxwgMJ933nYLxQpMimSsaKZdT
iGo68RBhgFFXe+6zJCWPZbCye8ptW8awCHfwsogYAzvRs0wk9rF/r78CWZXAn6dCeH
cCMomFWcBOzTdbqQ/ZKizBCOdgLsT/aPDVBV00Eo=
</pre>
h2. Enchaînement des différents systèmes
Il existe plusieurs moyens pour postfix de vérifier la validité du mail, ou pas :
* Les content filters : Ce sont des programmes recevant un mail selon le protocole SMTP et le renvoyant, ou pas, à postfix selon le même protocole après ajout de headers. Exemple : ClamSMTP et SpamAssassin.
* Les milters : ce sont des programmes dialoguant avec postfix sur un port TCP donné en suivant un "protocole défini":https://www.milter.org/developers/api/index. Exemple : OpenDKIM.
* Les policy services : Ce sont des programmes au fonctionnement proche des milters. Ils permettent de valider ou non le passage d'un mail selon ses paramètres. Exemple : PostGrey et postfix-policyd-spf-python.
* Les RBL : Voir plus haut, la gestion des RBL est gérée directement par postfix.
Voilà rapidement l'enchaînement des validations faites à l'arrivée d'un mail :
* Ãmetteur : Ouverture d'une connexion sur le port 25 (SMTP).
* Récepteur : Vérification de la validité de l'adresse IP source et consultation des RBL (smtpd_client_restrictions).
* Ãmetteur : HELO sondomaine.tld
* Récepteur : Vérification de la validité du domaine et du reverse (smtpd_helo_restrictions).
* Ãmetteur : MAIL from : "Marvin the paranoid android" <marvin@sondomaine.tld>
* Récepteur : Vérification de la validité de l'adresse émettrice (smtpd_sender_restrictions).
* Ãmetteur : RCPT to : "Fabien Dupont" <fab@mondomaine.tld>
* Récepteur : Vérification de la validité de l'adresse destinataire (smtpd_recipient_restrictions).
** Interrogation du « policy service » postgrey sur le port 10023
** Interrogation du « policy service » python-spf via la socket unix private/policyd-spf
* Récepteur : Envoi du code de retour au serveur émetteur ("RFC3463":http://www.rfc-editor.org/rfc/rfc3463.txt) :
** 3xx : OK pour la suite
** 4xx : Erreur temporaire (exemple: postgrey).
** 5xx : Erreur permanente (Adresse émettrice ou réceptrice non valide).
* Ãmetteur : DATA puis le contenu du mail (headers compris).
* Récepteur : Transfert du mail au « content filters » :
** ClamSMTP reçoit le mail sur le port 10025 et si le mail est valide...
** SpamAssassin reçoit le mail sur le port 10026 et si le mail est valide...
** Postfix récupère le mail validé sur le port 10028
* Récepteur : Validation du mail via le milter OpenDKIM sur le port 10028
* Récepteur : Envoi du code de retour au serveur émetteur ("RFC3463":http://www.rfc-editor.org/rfc/rfc3463.txt) :
** 2xx : OK pour l'envoi
** 4xx : Erreur temporaire (exemple: postgrey).
** 5xx : Erreur permanente (exemple: spam détecté par SpamAssassin, virus par ClamAV, etc.).
* Ãmetteur : Fermeture de la connexion sur le port 25.
h2. Installation et configuration
h3. Postfix
h4. Configuration de base
Ce tutoriel part du principe que postfix est déjà correctement installé et configuré pour l'émission et la réception de mails.
La configuration de postfix sera modifiée au fur et à mesure de l'installation des différents services.
Postfix, s'il est configuré en tant que serveur de mail visible depuis internet, doit être configuré pour autoriser la réception de messages depuis n'importe où et l'émission uniquement depuis le réseau local. Si ce n'est pas le cas, le serveur de mail sera configuré en mode "open relay":http://en.wikipedia.org/wiki/Open_relay. Bien évidemment un tel serveur serait une plateforme d'envoi de spams ou autre saletés. Il serait très vite blacklisté auprès des différentes RBL.
Pour ce tutoriel, le serveur de mail nommé ve-mail hébergera des adresses du domaine kafe-in.net et le réseau local sera composé de 192.168.2.0/24 en IPv4 et 2001:910:109c::/48 en IPv6.
+main.cf :+
<pre>
mydomain = kafe-in.net
mydestination = ve-mail, ve-mail.kafe-in.net, localhost.localdomain, localhost, kafe-in.net
mynetworks = 127.0.0.0/8, [::1]/128, 192.168.2.125/32, [2001:910:109c::]/48
</pre>
h4. Restrictions de base
Dans un premier temps, il faut indiquer à postfix qu'il faut délayer le rejet d'un mail à la fin du dialogue avec dialogue avec le serveur SMTP distant. C'est le paramètre "smtpd_delay_reject":http://www.postfix.org/postconf.5.html#smtpd_delay_reject. Ceci permet "3 choses":http://www.postfix.org/SMTPD_ACCESS_README.html#timing :
* certains serveurs SMTP ne prennent pas en compte les rejets pendant l'émission d'un mail et essaient donc de finir de l'envoyer même s'il a été refusé,
* postfix peut ainsi logger plusieurs informations intéressantes relatives à l'émetteur et au destinataire du mail,
* une adresse émettrice peut être rejetée selon le destinataire du mail (ex: greylisting), il faut donc avoir tous les paramètres du mail avant de prendre une décision.
Le paramètre "smtpd_helo_required":http://www.postfix.org/postconf.5.html#smtpd_helo_required permet de n'autoriser la réception de mail que si le serveur distant s'est présenté (HELO). Cela permet d'introduire des restrictions par rapport à cette commande SMTP (voir plus bas).
Le paramètre "strict_rfc821_envelopes":http://www.postfix.org/postconf.5.html#strict_rfc821_envelopes permet de refuser la réception de mail si le serveur distant ne respecte pas strictement la "rfc821":http://www.faqs.org/rfcs/rfc821.html, celle qui décrit le protocole SMTP.
+main.cf, restrictions de base :+
<pre>
# Basics Restrictions
smtpd_delay_reject = yes
smtpd_helo_required = yes
strict_rfc821_envelopes = yes
</pre>
Postfix applique ensuite des restrictions selon les paramètres du mail, dans l'ordre suivant :
* restrictions sur le client, c'est à dire sur l'adresse IP du serveur émetteur,
* restrictions sur le mot clé *HELO* lors du dialogue avec ce serveur,
* restrictions sur le mot clé *MAIL from*, c'est à dire sur l'adresse mail de l'émetteur,
* restrictions sur le mot clé *RCPT to*, c'est à dire sur l'adresse mail du destinataire,
Une liste de restrictions, dans postfix, est définie avec la syntaxe suivante :
smtpd_*nom*_restrictions = restriction 1, restriction 2, ..., restriction n
Elles sont parcourues dans l'ordre, jusqu'à ce que l'une d'entre elle accepte ou rejette le mail. La dernière restriction est *permit*, ainsi le mail est accepté si rien n'a indiqué explicitement son rejet ou sa validation.
h4. Restrictions sur le client
Ici, notre serveur est public, il doit donc accepter les connexions entrantes depuis n'importe quelle adresse IP.
+main.cf, restrictions sur le client :+
<pre>
# Requirements for the connecting server
smtpd_client_restrictions =
permit
</pre>
h4. Restrictions sur HELO
Comme on n'est pas des sauvages, on ne positionne aucunes restrictions si l'émetteur se situe sur notre réseau local (paramètre *mynetwork*, voir plus haut). Par contre, pour toutes les autres adresses IP source, on vérifie que le paramètre *HELO* correspond à un "FQDN":http://en.wikipedia.org/wiki/FQDN et que celui-ci correspond à un nom d'hôte valide.
+main.cf, restrictions sur le mot clé HELO :+
<pre>
# Requirements for the HELO statement
smtpd_helo_restrictions =
permit_mynetworks,
reject_non_fqdn_hostname,
reject_invalid_hostname,
permit
</pre>
h4. Restrictions sur l'adresse de l'émetteur
De la même façon, il est préférable de refuser des mails ayant un domaine inexistant ou mal formé, sauf pour notre réseau local.
+main.cf, restriction sur l'émetteur (sender) :+
<pre>
# Requirements for the sender address
smtpd_sender_restrictions =
permit_mynetworks,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
permit
</pre>
h4. Restrictions sur l'adresse du destinataire
On autorise notre LAN à envoyer des mails à destination de n'importe quelle adresse. Par contre, pour les autres on refuse les mails à destination d'une adresse mal formée (*reject_non_fqdn_recipient* et *reject_unknown_recipient_domain*) ou bien inconnue du serveur (*reject_unauth_destination*). C'est à dire dont la partie domaine de l'adresse n'est pas listée dans les variables *mydestination* ou *relay_domains*. Le refuser si la boite n'existe pas sera le travail du LDA (Local Delivery Agent), c'est à dire le programme qui délivre le mail dans la boite IMAP ou POP du destinataire.
<pre>
# Requirement for the recipient address
smtpd_recipient_restrictions =
permit_mynetworks,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_unauth_destination,
permit
</pre>
h4. Content filters
Les content filters sont des mini-serveurs SMTP analysant les mails entrants et les renvoyants ou pas sur un autre serveur SMTP. Postfix est donc le serveur source pour les content filters ainsi que le serveur de destination. Si un mail revient des content filters sans encombres, il est valide.
Les content filters peuvent être chaînés. Le premier écoute sur un port (ex: 10025) puis le passe au second sur un autre port (ex: 10026) qui le retransmet au serveur postfix de départ sur un port défini (ex: 10025). En cas de problème sur le second content filter, il retourne une erreur 5xx au premier content filter qui retourne donc cette erreur au serveur postfix de départ. Les refus sont ainsi transmis en cascade et pris en compte par postfix au final.
+main.cf, content filters :+
<pre>
# Content filtering
content_filter = scan:127.0.0.1:10025
receive_override_options = no_address_mappings
</pre>
Le port de destination des contents filters est écouté par un simple smtpd mais avec aucune restrictions ni autre content filters définis. Si ce n'était pas le cas, les mails entrant partirait en boucle dans le serveur de mail et serait refusés au final. Ce port est ouvert uniquement pour localhost (127.0.0.1) pour éviter qu'un serveur distant n'envoie un mail directement par ce biais.
+master.cf, définition du service de réception des content filters :+
<pre> </pre>
# For injecting mail back into postfix from the filter
127.0.0.1:10027 inet n - n - 16 smtpd
-o content_filter=
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks_style=host
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
</pre>
h3. ClamSMTPd
L'interface entre postfix est ClamAV peut être faite de différentes manières. La plus simple à mettre en place est d'utiliser le daemon ClamSMTP.
C'est un simple content filter pour lequel on définit le port d'entrée selon le paramètre *content_filter* de postfix et le port de sortie comme le port du prochain content filter mis en place ou bien celui de postfix si on ne désire pas en mettre en place d'autres.
+Installation de ClamSMTP :+ ClamSMTP+
<pre>
# apt-get install clamsmtp clamav-daemon
</pre>
+/etc/clamsmtpd.conf, fichier de configuration du daemon :+ daemon+
<pre>
# Port et adresse IP sur lesquels le daemon écoute
Listen: 127.0.0.1:10025
# Port et adresse IP sur lesquels le mail sera forwardé
OutAddress: 127.0.0.1:10026
# Chemin vers la socket unix ouverte par le daemon ClamAV
ClamAddress: /var/run/clamav/clamd.ctl
# Header ajouté au mail pour indiquer qu'il a bien été scanné
Header: X-AV-Checked: ClamAV using ClamSMTP
# Répertoire temporaire
TempDirectory: /var/spool/clamsmtp
# Chemin vers le fichier PID
PidFile: /var/run/clamsmtp/clamsmtpd.pid
# Action effectuée en cas de détection de virus :
# * bounce : retour à l'envoyeur (pas génial car l'adresse émettrice est souvent spoofée)
# * drop : le mail est supprimé silencieusement
# * pass : le mail est accepté mais le header X-Virus-Infected est ajouté
Action: drop
# Si 'on', les mails infectés sont stockés dans le répertoire temporaire
Quarantine: on
# Nom d'utilisateur sous lequel le programme tourne (ne pas utiliser root !)
User: clamsmtp
</pre>
h3. SpamPD
SpamPD est un proxy mail (un content filter) codé en perl et utilisant SpamAssassin pour tagger les mails en tant que spam ou ham (non spam).
+ Installation de SpamPD :+ SpamPD+
<pre>
# apt-get install spampd spamassassin
</pre>
+/etc/default/spampd, configuration du daemon :+
<pre>
# Démarrage du daemon au boot
STARTSPAMPD=1
# Chemin vers le fichier PID
PIDFILE=/var/run/spampd.pid
# Port et adresse IP sur lesquels le daemon écoute
LISTENHOST=127.0.0.1
LISTENPORT=10026
# Port et adresse IP sur lesquels le mail sera forwardé
DESTHOST=127.0.0.1
DESTPORT=10027
# Nombre de processus enfants (trop = beaucoup de ressources utilisées, pas assez = traitement des mails lent en cas de gros trafic)
CHILDREN=3
# Nom d'utilisateur et groupe sous lesquels le daemon tourne (pas root !)
USERID=spampd
GRPID=spampd
# Ajoute les headers de SpamAssassin indiquant que le mail a été scanné même s'il n'a pas été identifié comme spam.
TAGALL=1
# Option non utilisée depuis SpamAssassin >= 3.x
AUTOWHITELIST=0
# Désactivation de tous les tests sur l'adresse IP source (ici ce sera toujours 127.0.0.1)
LOCALONLY=1
# Utilisation de syslog via une socket unix (=0) ou une socket IP (=1)
LOGINET=0
# Options additionnelles à passer à SpamAssassin
ADDOPTS=""
</pre>
h3. Postgrey
Postgrey est un policy server (voir plus haut) qui est appelé par postfix si besoin et via un port TCP. Ici le port 10023 a été choisi de façon arbitraire.
+Installation de postgrey :+
<pre>
# apt-get install postgrey
</pre>
+/etc/default/postgrey, configuration du service :+
<pre>
# --inet : Port utilisé pour dialoguer avec postfix
# --delay : Durée en secondes pendant laquelle les mails sont refusés
# --max-age : Période en jour après laquelle le compteur d'émission est remis à zéro si pas de nouvelle réémission d'un mail
POSTGREY_OPTS="--inet=10023 --delay=300 --max-age=35"
# Message renvoyé en plus de l'erreur 4xx au serveur émettant le mail
POSTGREY_TEXT="Good news, everyone ! I taught the mail server to detect spambots."
</pre>
+main.cf, ajout du policy service postgrey aux restrictions sur le destinataire :+
<pre>
# Requirement for the recipient address
smtpd_recipient_restrictions =
permit_mynetworks,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_unauth_destination,
check_policy_service inet:127.0.0.1:10023,
permit
</pre>