Howto Postfix
- Documentation : http://www.postfix.org/documentation.html
- Rôle Ansible : https://gitea.evolix.org/evolix/ansible-roles/src/branch/stable/postfix
Postfix est serveur SMTP libre et populaire sous GNU/Linux et BSD. Il a été développé en 1999 par Wietse Venema comme une alternative plus facile à administrer et plus sécurisée que l’historique Sendmail.
Installation
# apt install postfix
# postconf -d | grep ^mail_version
mail_version = 2.11.3
Configuration
Postfix s’appuie principalement sur le fichier /etc/postfix/master.cf
(configuration des process de Postfix) et le fichier /etc/postfix/main.cf
(configuration des options).
L’utilitaire postconf permet de lister/vérifier les options du main.cf
.
## Vérifier la validité de la configuration (check conf)
# postconf >/dev/null
## Lister les options par défaut
# postconf -d
## Lister les options actuelles
# postconf
## Lister les options modifiées par rapport au défaut
# postconf -n
## Manpage très détaillée sur toutes les options disponibles
# man 5 postconf
Configuration minimale
Pour une configuration minimale, nous conseillons d’avoir le fichier main.cf
suivant en ajustant le paramètre myhostname avec un enregistrement DNS existant pointant vers le serveur concerné :
smtpd_banner = $myhostname ESMTP mail server
biff = no
append_dot_mydomain = no
myhostname = hosting.example.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = $myhostname
mydestination = $myhostname localhost.localdomain localhost localhost.$mydomain
relayhost =
mynetworks = 127.0.0.0/8
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
disable_vrfy_command = yes
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtp_tls_security_level = may
smtp_tls_mandatory_protocols=!SSLv2,!SSLv3
smtp_tls_protocols=!SSLv2,!SSLv3
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_loglevel = 1
Configuration minimale pour serveur web
N.B. : cette configuration complète la configuration minimale donnée plus haut.
Un serveur web va souvent envoyer des emails, et notamment vers des fournisseurs d’accès connus (gmail.com, orange.fr, etc.). On conseille donc d’ajouter les options suivantes dans main.cf
pour gérer le rythme d’envoi :
#delay_warning_time = 4h
minimal_backoff_time = 15m
maximal_backoff_time = 6h
maximal_queue_lifetime = 4d
queue_run_delay = 100s
bounce_queue_lifetime = 1d
initial_destination_concurrency = 5
default_destination_concurrency_limit = 20
slow_destination_rate_delay = 0
slow_destination_concurrency_limit = 1
slow_destination_concurrency_failed_cohort_limit = 100
slow_destination_recipient_limit = 25
transport_maps = hash:$config_directory/transport
et on ajoute la ligne suivante dans master.cf
:
slow unix - - n - - smtp -o syslog_name=postfix-slow
Il faut également créer le fichier /etc/postfix/transport
et indiquer des domaines vers lesquels le rythme d’envoi sera plus lent (à cause de restrictions de leur côté) :
orange.fr slow:
wanadoo.fr slow:
voila.fr slow:
laposte.net slow:
On fera ensuite :
# postmap /etc/postfix/transport
# systemctl restart postfix
On peut ensuite vérifier que la configuration est bien prise en compte en regardant dans les logs de Postfix. On doit pouvoir observer des processus « postfix-slow » pour tous les domaines concernés.
Configuration avancée pour serveur de messagerie
Voir HowtoMail/Postfix
SSL/TLS
http://www.postfix.org/TLS_README.html
Activation SSL/TLS au niveau serveur SMTP (smtpd)
Activer SSL/TLS au niveau serveur SMTP permet la réception d’emails depuis des clients SMTP capables d’envoyer en SSL/TLS.
Il faut générer une clé privée et un certificat, voir HowtoSSL. On peut ensuite activer via le fichier /etc/postfix/main.cf
:
smtpd_tls_security_level = may
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3
smtpd_tls_protocols=!SSLv2,!SSLv3
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_tls_loglevel = 1
smtpd_tls_key_file = /etc/ssl/private/smtp.example.com.key
smtpd_tls_cert_file = /etc/ssl/certs/smtp.example.com.crt
smtpd_tls_CAfile = /etc/ssl/certs/GandiStandardSSLCA2.pem
Note 1 : la désactivation des protocoles SSLv2 et SSLv3 est désormais par défaut, mais on préfère garder cette option
Note 2 : Pour Debian 7 et 8, on conseille d’ajouter également :
smtpd_tls_mandatory_exclude_ciphers = ECDHE-RSA-RC4-SHA, RC4, aNULL smtpd_tls_exclude_ciphers = ECDHE-RSA-RC4-SHA, RC4, aNULL smtpd_tls_mandatory_ciphers = medium
Pour l’envoi d’emails depuis des clients SMTP authentifiés (smtpd_sasl_auth_enable=yes), on active en général le port TCP/587 (appelé SMTP Submission) qui n’accepte que des connexions chiffrées (smtpd_tls_security_level=encrypt) et le port TCP/465 (appelé SMTPS) qui n’accepte que des connexions SMTP over TLS (smtpd_tls_wrappermode=yes). Ces activations se font en décommentant les lignes appropriées dans /etc/postfix/master.cf
.
Dans le cas d’utilisation de Let’s Encrypt voici un exemple de config à utiliser :
smtpd_tls_key_file = /etc/letsencrypt/live/smtp.example.com/privkey.pem
smtpd_tls_cert_file = /etc/letsencrypt/live/smtp.example.com/fullchain.pem
On peut ensuite vérifier l’activation de SSL/TLS au niveau serveur en obtenant le message STARTTLS
dans une session SMTP :
$ telnet bugs.debian.org 25
Trying 209.87.16.39...
Connected to bugs.debian.org.
Escape character is '^]'.
220 buxtehude.debian.org
EHLO example.com
250-buxtehude.debian.org Hello example.com [80.12.63.254]
250-SIZE 104857600
250-8BITMIME
250-STARTTLS
250 HELP
QUIT
221 buxtehude.debian.org closing connection
Connection closed by foreign host.
On peut également utiliser une connexion chiffrée avec un serveur SMTP via la commande :
$ openssl s_client -CApath /etc/ssl/certs -connect smtp.example.com:25 -crlf -starttls smtp
Activation SSL/TLS au niveau client SMTP (smtp)
Activer SSL/TLS au niveau client SMTP permet d’envoyer des emails vers des serveurs SMTP capables de recevoir en SSL/TLS.
On conseille d’activer cela par défaut via le fichier /etc/postfix/main.cf
:
smtp_tls_security_level = may
smtp_tls_mandatory_protocols=!SSLv2,!SSLv3
smtp_tls_protocols=!SSLv2,!SSLv3
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_loglevel = 1
Note : la désactivation des protocoles SSLv2 et SSLv3 est désormais par défaut, mais on préfère garder cette option
Administration
Logs
Postfix envoie une trace de ses actions à Syslog avec la facility LOG_MAIL. On retrouve donc les fichiers de journalisation définis dans le fichier /etc/rsyslog.conf
:
mail.* -/var/log/mail.log
mail.info -/var/log/mail.info
mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
Note : ce sont les adresses email d’enveloppe affichées dans les logs Postfix
L’indication delays=a/b/c/d dans les logs est utile pour avoir des informations sur le temps d’envoi d’un mail :
a=time before queue manager, including message transmission;
b=time in queue manager;
c=connection setup time including DNS, HELO and TLS;
d=message transmission time.
File d’attente
Postfix utilise différentes files d’attente (ou queues). Les files d’attente principales sont incoming, active et deferred :
incoming : première étape pour tous les nouveaux messages (après un passage par cleanup)
active : messages en cours de livraison (provenant principalement d'incoming ou deferred)
deferred : messages non délivrés lors du premier essai
Il existe aussi d’autres files d’attente, qui servent beaucoup moins fréquemment : corrupt (messages invalides) et hold (messages mis de côté).
Ces files d’attente sont des répertoires situés dans /var/spool/postfix
dans lesquels chaque message est stocké dans un fichier (sur une seule ligne), avec une arborescence de 16 répertoires (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F) pour optimiser lorsqu’un grand nombre de messages est dans une file d’attente. On peut gérer ces files d’attente grâce à des commandes d’administration.
Lecture et analyse de la file d’attente
mailq
(ou sendmail -bp
) liste toutes les files d’attente. Cela nous donne pour chaque message :
- Queue ID
- Taille du message
- Date d’arrivée dans la file d’attente
- Expéditeur
- Éventuelle raison de non-livraison (entre parenthèses)
- Destinataires(s)
Voici dans quel ordre sont listés les messages :
- Messages de la queue active (une étoile figure à côté du Queue ID)
- Messages de la queue deferred
- Messages de la queue hold (un point d’exclamation figure à côté du queue ID)
Afficher le contenu d’un message :
# postcat -vq <queue_id>
Afficher seulement les mails IDs (utile pour les scripts) :
# mailq | sed -E -n 's/^([[:alnum:]]+)[[:blank:]].*/\1/gp'
Exemple d’usage :
keyword="blabla"
ids=$(mailq | sed -E -n 's/^([[:alnum:]]+)[[:blank:]].*/\1/gp')
for id in $ids; do
mail_content=$()
if postcat -q $id | grep -q $keyword; then
echo "$id contains $keyword"
# Faire quelque chose (voir la section suivante "Opérations sur la file d'attente")
fi
done
Exclure les mails en cours d’envoi de l’affichage de la file d’attente :
# mailq | sed -E '/v[[:alnum:]]+\*[[:blank:]]/,+2d'
Compter le nombre d’e-mails par adresse expéditrice dans la mailq
:
# mailq | awk '$1 ~ /^[0-9A-F]+$/ { a[$NF]++ } END { for (i in a) printf "%d %s\n", a[i], i }' | sort -n
Obtenir la liste les expéditeurs triés par ordre croissant du nombre d’e-mails en attente d’envoi :
# mailq | awk '/^[0-9A-F]+[*!]? /{a[$NF]++}END{for(i in a)print a[i],i | "sort -n"}'
Note : le BEGIN { RS = "" }
est nécessaire car la sortie de mailq peut être sur plusieurs lignes, et le tr -d '*!'
permet de ne pas prendre les messages en « hold ».
Lister les messages dans la file d’attente deffered :
# qshape deferred
T 5 10 20 40 80 160 320 640 1280 1280+
TOTAL 78 0 0 0 0 1 0 0 0 0 77
gmail.fr 11 0 0 0 0 0 0 0 0 0 11
homail.fr 3 0 0 0 0 0 0 0 0 0 3
yaoo.fr 2 0 0 0 0 0 0 0 0 0 2
yahou.fr 2 0 0 0 0 0 0 0 0 0 2
oange.fr 2 0 0 0 0 0 0 0 0 0 2
hotmai.fr 2 0 0 0 0 0 0 0 0 0 2
wanado.fr 2 0 0 0 0 0 0 0 0 0 2
orangr.fr 1 0 0 0 0 0 0 0 0 0 1
prange.fr 1 0 0 0 0 0 0 0 0 0 1
ornage.fr 1 0 0 0 0 0 0 0 0 0 1
# Affichage par sender
# qshape -s deferred
Opérations sur la file d’attente
Suppressions :
## Supprimer un message (ou tous) des files d'attente :
# postsuper -d <queue_id>
## Supprimer tous les messages de la queue deferred
# postsuper -d ALL deferred
## Supprimer tous les messages des files d'attente :
# postsuper -d ALL
# mailq -q
/!\ Attention, postsuper -d ALL
et mailq -q
réactivent immédiatement l’ensemble des messages en file d’attente, il faut donc les utiliser avec modération, surtout sur les serveurs avec des files d’attentes chargées.
Divers :
## Libérer un message (ou tous) en « hold »
# postsuper -H <queue_id>
# postsuper -H ALL
# Refaire passer un message (ou tous) par les process de livraison
# postsuper -r <queue_id>
# postsuper -r ALL
## Purger des fichiers temporaires (en cas de crash par exemple)
# postsuper -p
## Réparer/vérifier l'arborescence des files d'attente
# postsuper -s
La commande postsuper -r
est pratique dans les cas où l’on a modifié des alias ou des ré-écritures, elle va déposer les messages concerné dans la queue maildrop et lui attribuer un nouveau . Attention, cela ne va pas provoquer un envoi immédiat car le traitement des files d’attente est différé. Si l’on veut un ré-envoi immédiat d’un message :
Hold :
## Placer en « hold » un message (ou tous)
# postsuper -h <queue_id>
# postsuper -h ALL
## Placer en « hold » tous les messages de la queue deferred
# postsuper -h ALL deferred
Traitement par lot via un pré-filtrage avec Awk :
On pourra utiliser ces commandes sur des ensembles de messages via des scripts du type :
# mailq | tail -n +2 | awk 'BEGIN { RS = "" } /user@example\.com/ { print $1 }' | tr -d '*!' | postsuper -h -
# mailq | tail -n +2 | awk 'BEGIN { RS = "" } /example\.com/ { print $1 }' | tr -d '*!' | postsuper -d -
# mailq | awk '/^[0-9A-Z]+/&&/sender@example\.com$/{print $1}' | tr -d '*!' | postsuper -h -
# mailq | awk '/^[0-9A-Z]+/&&/example\.com$/{print $1}' | tr -d '*!' | postsuper -d -
# mailq > mailq.log ; for var in $(grep <from@example.com> mailq.log | cut -b '1-12'); do postsuper -d $var; done
## Supprimer les e-mails envoyés par someone@some.where
# mailq | awk '/^[0-9A-F]+[!*]? /&&/someone@some\.where$/{gsub("[!*]", "", $1); print $1 | "postsuper -d -"}'
## Supprimer les courriels envoyé vers @example.com
# mailq | tail -n +2 | awk 'BEGIN { RS = "" } /@example\.com$/ { r = $1; gsub(/[!*]/, "", r); print r }' | postsuper -d -
Supprimer les mails correspondant à ce type de ligne :
6B28125849 3039 Fri Sep 25 07:27:53 MAILER-DAEMON
(host mx2.foo.com[1.2.3.4] said: 452 Too many incoming emails for this account (in reply to RCPT TO command))
mail.example.com
# mailq | awk '/^[0-9A-F]+/&&/MAILER-DAEMON$/{id=$1} /mail@example.com$/{print id}' | postsuper -d -
Notifications
Postfix envoie des notifications à ajuster avec l’option notify_classes
.
On peut ainsi ajuster cette option ainsi :
notify_classes = resource, software, bounce, 2bounce, delay
delay_notice_recipient = delay
error_notice_recipient = error
bounce_notice_recipient = bounce
2bounce_notice_recipient = 2bounce
Puis ajuster les alias via /etc/alias
:
error: localadmin
bounce: postmaster
2bounce: postmaster
delay: alert0@example.com
/!\ Attention, pour un serveur recevant pas mal de messages, cela peut générer pas mal de notifications. Si nécessaire, ajuster ainsi pour avoir un minimum d’alertes :
notify_classes = resource, software
error_notice_recipient = error
Plomberie
Postfix est découpé en plusieurs processus (qmgr, pickup, smtp, smtpd, bounce, cleanup, error, etc.) contrôlé par un processus nommé master
. Chaque processus est défini dans le fichier de configuration master.cf
.
Sur un serveur inactif, vous verrez au minimum les processus suivants :
|-master,432636 -l -t unix -u
| |-qmgr,5036 -l -t unix -u-u -c
| `-pickup,9162 -l -t unix -u -c
Sur un serveur actif, vous verrez de nombreux processus, par exemple :
|-master,2576
| |-scache,13334 -l -t unix -u
| |-qmgr,22888 -l -t fifo -u
| |-anvil,22891 -l -t unix -u
| |-smtp,25261 -t unix -u
| |-smtp,26204 -t unix -u
| |-trivial-rewrite,26596 -n rewrite -t unix -u
| |-smtp,26629 -t unix -u
| |-pickup,27010 -l -t fifo -u
| |-smtp,27102 -t unix -u
| |-smtp,27976 -t unix -u
| |-proxymap,28383 -t unix -u
| |-smtp,29967 -t unix -u
| |-smtp,29968 -t unix -u
| |-smtp,29969 -t unix -u
| |-bounce,29970 -z -t unix -u
| |-bounce,30351 -z -n defer -t unix -u
| |-bounce,30352 -z -n defer -t unix -u
| |-bounce,30354 -z -n defer -t unix -u
| |-bounce,30355 -z -n defer -t unix -u
| |-cleanup,30364 -z -t unix -u
| |-cleanup,30365 -z -t unix -u
| |-smtpd,30366 -n smtp -t inet -u -o stress= -s 2
| |-error,30367 -n retry -t unix -u
| |-error,30368 -n retry -t unix -u
| |-error,30369 -n retry -t unix -u
| `-smtpd,30374 -n smtp -t inet -u -o stress= -s 2
Voici un schéma qui illustre la communication entre les processus/files d’attente/tables :
- Le processus bounce gère les messages de non-livraison qui sont stockés dans les répertoires
/var/spool/postfix/bounce/*
,/var/spool/postfix/defer/*
ou encore/var/spool/postfix/trace/*
selon les types de message.
Changer les templates de bounce
Par exemple pour mettre un message personnalisé (et en Français) des DSN du type « successful delivery ».
Installer le paquet postfix-doc
, copier le fichier bounce.cf.default
dans /etc/postfix/bounce.cf
, éditer le fichier comme voulu et ajouter la directive bounce_template_file = /etc/postfix/bounce.cf
à postfix.
# apt install postfix-doc
# install -m 644 /usr/share/doc/postfix-doc/examples/bounce.cf.default /etc/postfix/bounce.cf
# vim /etc/postfix/bounce.cf
# echo "bounce_template_file = /etc/postfix/bounce.cf" >> /etc/postfix/main.cf
# systemctl reload postfix
Monitoring
La surveillance régulière des fichiers de journalisation ainsi que des files d’attente s’avère nécessaire, éventuellement à l’aide d’outils permettant de générer des statistiques, des courbes, etc. On peut ainsi citer l’outil mailgraph qui trace des courbes rrdtool à partir du fichier de journalisation, ou encore Munin qui trace des courbes selon l’état des files d’attente.
mailgraph
# apt install mailgraph
mailgraph fait tourner un démon Perl qui analyse /var/log/mail.log
, on peut ensuite visualiser des courbes RRDtool via un script CGI /usr/lib/cgi-bin/mailgraph.cgi
.
Pour diverses raisons, si l’on ne veut pas avoir de module CGI on pourra utiliser un script Shell à placer en crontab :
#!/bin/sh
MAILGRAPH_PATH=/usr/lib/cgi-bin/mailgraph.cgi # Debian
MAILGRAPH_DIR=/var/www/mailgraph
umask 022
mkdir -p $MAILGRAPH_DIR
$MAILGRAPH_PATH | sed '1,2d ; s/mailgraph.cgi?//' > $MAILGRAPH_DIR/index.html
for i in 0-n 0-e 1-n 1-e 2-n 2-e 3-n 3-e; do
QUERY_STRING=$i $MAILGRAPH_PATH | sed '1,3d' > $MAILGRAPH_DIR/$i
done
Munin
Par défaut, on trouve des plugins intéressants, notamment postfix_mailqueue pour l’évolution des files d’attente. Pour activer les plugins Postfix pour Munin :
# cd /etc/munin/plugins
# ln -s /usr/share/munin/plugins/postfix_mailqueue
# ln -s /usr/share/munin/plugins/postfix_mailstats
# ln -s /usr/share/munin/plugins/postfix_mailvolume
Nagios
Voici des checks standards pour vérifier que Postfix répond en SMTP et surveiller sa file d’attente :
$ /usr/lib/nagios/plugins/check_smtp -H localhost
$ /usr/lib/nagios/plugins/check_mailq -M postfix -w 42 -c 1337
log2mail
Pour être alerté en cas d’erreurs graves, voici une config pour log2mail :
file = /var/log/mail.log
pattern = "fatal:"
mailto = alert@example.com
pattern = "panic:"
mailto = alert@example.com
pattern = "No such file or directory"
mailto = alert@example.com
pattern = "table lookup problem"
mailto = alert@example.com
pattern = "warning: connect to Milter service"
mailto = alert@example.com
pattern = "451 4.7.1 Service unavailable - try again later"
mailto = alert@example.com
pflogsumm
C’est un petit outil pour afficher des stats sur les logs mails. Plutôt pratique, il évite de « grepper » à la main mail.log
.
pflogsumm /var/log/mail.log [/var/log/mail.log.1 [...]] >> stats_mail.out
Délivrabilité
La délivrabilité est un concept visant à s’assurer qu’un email envoyé va bien atteindre son destinataire.
Voici un check-up pour s’assurer d’avoir une bonne délivrabilité :
- Reverse DNS configuré vers un enregistrement valide pointant lui-même vers l’adresse IP du serveur mail
- IPv6 correctement configuré (avec reverse DNS) ou desactivé
- Utiliser une adresse de retour valide (expéditeur d’enveloppe ou Return-Path) et traiter les retours régulièrement voire dynamiquement en cas de gros volume
- Configurer SPF
- Configurer DKIM
- Configurer DMARC
- Nettoyer ses entêtes, notamment des informations locales (IP RFC1918, enregistrements DNS locaux, etc.)
- S’enregistrer auprès de http://www.dnswl.org/
- S’enregistrer auprès de http://www.emailreg.org/ (payant, environ 20$/domaine/an)
- Pour Hotmail/Outlook/Microsoft/Office365, faire un ticket support depuis sender.office.com et ce formulaire https://support.microsoft.com/en-us/supportrequestform/8ad563e3-288e-2a61-8122-3ba03d6b8d75 pour autoriser IPv4.
- Payer https://returnpath.com/fr/ pour améliorer sa délivrabilité auprès de Yahoo/Microsoft/etc. (payant en fonction du volume et très cher…)
- Régler son rythme d’envoi, notamment vers Orange, Free, etc.
- Vérifier son contenu via des outils comme SpamAssassin
- Vérifier la réputation via https://www.talosintelligence.com/reputation_center/email_rep
- Vérifier via Postmaster tools de Google en cas de problème de Spam pour Google/Gmail
- Vérifier via https://sendersupport.olc.protection.outlook.com/snds/ en cas de problème de Spam pour Microsoft/Hotmail/Live
SPF
SPF est une norme pour vérifier l’adresse IP expéditrice d’un email. La vérification se fait en utilisant le nom de domaine de l’expéditeur d’enveloppe et en récupérant un enregistrement DNS qui va lister les adresses IP autorisées.
Voici un exemple d’enregistrement DNS autorisant des adresses IP pour une adresse en @example.com
@ IN TXT "v=spf1 a mx ptr ip4:192.0.2.142 ip4:192.0.2.0/24 ip6:2001:db8::/32 ~all"
Voici un exemple d’enregistrement DNS autorisant l’envoi de n’importe où :
@ IN TXT "v=spf1 a mx ptr +all"
On peut utiliser un include:
vers un autre enregistrement TXT, pratique pour la gestion ou éviter d’avoir des enregistrements TXT dépassant 255 caractères. Voici un exemple, les deux chaines de caractères seront concaténées donc il ne faut pas oublier qu’au moins une des deux chaine doit contenir une espace libre :
@ IN TXT "v=spf1 a mx ptr ip4:192.0.2.142 ip4:192.0.2.0/24" " ip6:2001:db8::/32 ~all"
Chez Evolix, on utilise ainsi include:spf.protection.evolix.net
. Si vous utilisez Mailchimp vous devez ajouter include:spf.mandrillapp.com
par exemple.
Vérification SPF
Pour vérifier les enregistrements SPF des emails :
# apt install postfix-policyd-spf-python
# cp /usr/share/doc/postfix-policyd-spf-python/policyd-spf.conf.commented /etc/postfix-policyd-spf-python/policyd-spf.conf
On ajoutera dans /etc/postfix/master.cf
:
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
et /etc/postfix/main.cf
:
smtpd_recipient_restrictions =
...
reject_unauth_destination
check_policy_service unix:private/policyd-spf
...
policyd-spf_time_limit = 3600
Voici les paramètres intéressants pour /etc/postfix-policyd-spf-python/policyd-spf.conf
:
defaultSeedOnly = 0 # Mode simulation, aucun rejet, seulement la description de l'action dans les logs.
Mail_From_reject = Fail # Rejete les mails si le check SPF échoue.
Mail_From_reject = Softfail # Rejete les mails si le check SPF échoue même en « soft » (utilisation de ~all par exemple), non recommandé.
Reject_Not_Pass_Domains = aol.com,hotmail.com # Transoforme un ~all en -all pour des domaines en particuliers.
Cela ajoutera l’entête suivant aux emails :
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.0.2.1; helo=mail.example.com; envelope-from=jdoe@example.com; receiver=<UNKNOWN>
Cet entête pourra notamment être utilisé par des filtres, SpamAssassin, etc.
Note : attention, pour les emails locaux, cela n’ajoutera pas l’entête
Received-SPF
ce qui peut poser des soucis avec les outils s’appuyant dessus, notamment SpamAssassin ou OpenDMARC.
Utilitaire spfquery
Pour vérifier manuellement un enregistremnt SPF vous pouvez utiliser spfquery
fourni par le paquet du même nom. La commande necessite 3 arguments et s’utilise comme suit :
$ spfquery -ip=31.170.8.17 -sender=example@evolix.fr -helo=evolix.fr
pass
spfquery: domain of evolix.fr designates 31.170.8.17 as permitted sender
Received-SPF: pass (spfquery: domain of evolix.fr designates 31.170.8.17 as permitted sender) client-ip=31.170.8.17; envelope-from=example@evolix.fr; helo=evolix.fr;
Utilisaire spf
L’utilitaire spf
permet aussi d’avoir une vision synthétique sur la configuration SPF d’un domaine. Écrit en Perl il est facile à installer et fonctionne presque partout.
$ spf netmeister.org
netmeister.org:
policy:
a -all
valid
pass:
a (1 name):
netmeister.org
a (2 IPs):
166.84.7.99
2001:470:30:84:e276:63ff:fe72:3900
All others: fail
SPF record for domain 'netmeister.org': valid
Total counts:
Total number of DNS lookups : 1
pass:
Total # of a directives : 1
Total # of ip4 addresses : 1
Total # of ip6 addresses : 1
All others: fail
DKIM
DKIM est une norme pour ajouter une signature cryptographique dans les entêtes d’un email envoyé. La signature se fait à partir à de l’expéditeur d’entête (From:
d’un email), des entêtes au choix (sujet, date, etc.) et le corps du message. Cela utilise aussi une clé publique stockée dans un enregistrement DNS TXT.
Voir https://wiki.evolix.org/HowtoOpenDKIM
DMARC
DMARC est une spécification qui vient en complément de DKIM et SPF. Cela permet de spécifier aux serveurs de messagerie comment traiter les emails reçus non conformes aux vérifications SPF et/ou DKIM. Cela permet également de récupérer des informations voire des emails complets si ils ne sont pas conformes. Encore une fois, cela se fait avec un enregistrement DNS TXT.
Voici un exemple d’enregistrement DNS basique :
_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
On pourra spécifier : * p=none
si l’on ne veut pas que les emails non conformes soient rejetés * p=reject
si l’on veut que les emails non conformes soient rejetés * p=quarantine
si l’on veut que les emails non conformes soient mis de côté (dans une sous-boîte Spam en général)
Attention, si vous spécifiez rua=mailto:dmarc@example.com
vous recevrez pas mal de rapports Report domain
de Google, Outlook, etc. vous notifiant des emails non conformes. Les rapports incluent un fichier XML, on peut le lire via des outils comme mxtoolbox ou easydmarc.
Voici un exemple d’un enregistrement DNS plus avancé :
_dmarc IN TXT "v=DMARC1;p=reject;rua=mailto:dmarc+aggr@example.com;ruf=mailto:dmarc+forensic@example.com;fo=1;adkim=r;aspf=r;sp=none;pct=100"
Vérification DMARC
Pour vérifier la politique DMARC des emails :
# apt install opendmarc
# systemctl enable opendmarc
# systemctl start opendmarc
On configure via /etc/opendmarc.conf
:
AuthservID mail.example.com
PidFile /var/run/opendmarc/opendmarc.pid
PublicSuffixList /usr/share/publicsuffix
Socket inet:8892@localhost
#Socket local:/var/run/opendmarc/opendmarc.sock
Syslog true
UMask 0002
UserID opendmarc
IgnoreHosts /etc/opendmarc/ignore.hosts
OpenDMARC s’appuie sur l’entête Received-SPF
, il faut donc avoir installé la vérification DKIM.
Et il faut ajouter un fichier /etc/opendmarc/ignore.hosts
pour ignorer les emails locaux :
127.0.0.0/8
::1/128
localhost
localhost.localdomain
192.168.0.0/16
192.0.2.0/24
Et l’on ajoute un milter :
non_smtpd_milters = inet:127.0.0.1:8892
smtpd_milters = inet:127.0.0.1:8892
in_flow_delay = 0s
Cela ajoutera les entêtes suivants aux emails :
Authentication-Results: mail.smsmode.com; dmarc=pass (p=none dis=none) header.from=...
Authentication-Results: mail.smsmode.com; dkim=pass ...
Cet entête pourra notamment être utilisé par des filtres, SpamAssassin, etc.
Contacts des principaux fournisseurs d’email
En cas de souci de délivrabilité vers un domaine particulier, on est amené à contacter son responsable. En théorie l’adresse email postmaster@
permet cela.
En pratique pour les principaux fournisseurs d’emails, voici comment les contacter :
- Free : http://postmaster.free.fr/
- Orange : http://assistance.orange.fr/la-cellule-abuse-1260.php
- Hotmail/Outlook/Microsoft : https://support.microsoft.com/en-us/getsupport?oaspworkflow=start_1.0.0.0&wfname=capsub&productkey=edfsmsbl3&ccsid=635688189955348624&wa=wsignin1.0
- Yahoo : https://postmaster.yahoo.com/sender-request
- La Poste : https://postmaster.laposte.net/
- GMAIL : http://support.google.com/mail/bin/request.py?contact_type=bulk_send&&hl=en (NE REPONDENT JAMAIS !!!)
Postcreen
Postscreen est un démon léger destiné à faire des tests préliminaires avant de passer un message entrant à Postfix… ou de le rejeter !
Voir https://wiki.evolix.org/HowtoMail/Antispam#postscreen
FAQ
Récupérer expéditeur et destinataire dans mail.log
Pour récupérer à la fois l’adresse expéditeur et destinataire dans les logs :
# grep "blocked using FBLW15" /var/log/mail.log | cut -d " " -f 6 | tr -d ':' \
| while read msgid; do grep $msgid /var/log/mail.log |grep " postfix/" \
| grep -E '(from|to)=<'|awk -F ' ' '{ print $1,$2,$3,$7 }' |tr -d ','; echo; done
Taille maximum d’un message
Par défaut, la taille d’un message est limitée à 10 Mo, cela se modifie avec le paramètre message_size_limit
.
Attention, lorsqu’une pièce jointe est dans un format binaire (exemples : JPG, PDF, etc.), les emails sont traduits en caractères texte (conversion uuencode) ce qui provoque une augmentation de la taille jusqu’à 40%.
Voici par exemple le paramètre que l’on conseille de mettre si l’on veut autoriser les messages jusqu’à 20 Mo :
message_size_limit = 25600000
Attention, la taille par défaut de la mailbox est de 50 Mo (mailbox_size_limit = 51200000
). Si vous définissez message_size_limit
> mailbox_size_limit
(sauf si la taille est illimitée avec mailbox_size_limit = 0
), Postfix bloquera les mails dans la queue (avec un *
).
SMTPUTF8
SMTPUTF8 est une extension pour support l’UTF8 dans les entêtes de messages.
En effet, de façon standard tous les entêtes de messages doivent avoir un encoding spécial pour les caratères non ASCII.
Il peut arriver que cela pose des problèmes, notamment avec des clients SMTP qui gèrent mal cet encoding.
À partir de Debian 9, on peut alors activer l’option smtputf8_enable = yes
dans Postfix.
Et Postfix annoncera qu’il supporte cette extension :
$ nc 127.0.0.1 25
220 smtp.example.com ESMTP mail server
EHLO foo.bar
250-smtp.example.com
250-PIPELINING
250-SIZE 51200000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
Pour plus de détails, lire http://www.postfix.org/SMTPUTF8_README.html
Relai vers Mailjet selon l’expéditeur
Voir leur documentation : https://fr.mailjet.com/docs/code/postfix
.forward
Voir aussi : /HowtoMail/Roundcube#plugin-vacation
De façon similaire aux fichiers .htaccess
pour Apache, un utilisateur UNIX peut créer un fichier .forward
à la racine de son home-directory pour faire passer tous ses emails reçus dans une moulinette : renvoi automatique vers une autre adresse, traitement via Procmail, envoi d’un message d’absence, etc. Attention, cela ne fonctionne que pour Postfix en mode local, cela ne fonctionne pas en mode virtual.
Pour ré-envoyer tous les emails vers une autre adresse jdoe@example.com
on mettra simplement :
$ cat ~/.forward
jdoe@example.com
Pour envoyer tous les emails vers une autre adresse MAIS garder une copie sur sa boîte foo
:
$ whoami
foo
$ cat ~/.forward
\foo,jdoe@example.com
Pour faire traiter tous ses emails reçus par le logiciel Procmail :
$ cat ~/.forward
"| IFS=' ' && exec /usr/bin/procmail -f- || exit 75"
Pour envoyer un message d’absence en gardant une copie sur sa boîte foo
:
$ cat ~/.forward
\foo,"|/usr/bin/vacation foo"
vacation
Voir aussi : /HowtoMail/Roundcube#plugin-vacation
# apt install vacation
Le programme vacation
permet d’envoyer des messages d’absence SANS renvoyer des messages aux adresses déjà prévenues et SANS envoyer de message d’absence quand le mail reçu est une copie cachée.
ATTENTION : vacation n’envoie PAS de message d’absence si la destination n’est pas le compte UNIX. Par exemple si l’on a un compte jdoe
et que l’on reçoit un email sur john.doe@example.com
aucun message d’absence ne sera renvoyé. Il faut alors préciser un alias avec l’option -a
:
/usr/bin/vacation -a john.doe -a jdoe
Le message d’absence en lui-même se trouve dans ~/.vacation.msg
, on conseille notamment de préciser le Content-Type
et d’éviter les accents dans le sujet :
$ cat ~/.vacation.msg
From: John Doe <john.doe@example.com>
Subject: John Doe / Example - Absence
Content-Type: text/plain; charset=UTF-8
Je suis en congé parental, veuillez joindre mon collègue.
On peut lister les adresses qui ont reçu un message d’absence ainsi :
$ vacation -l