[Postfix](http://www.postfix.org/) est serveur [SMTP](HowtoSMTP) libre et populaire sous GNU/Linux et BSD. Il a été développé en 1999 par [Wietse Venema](http://www.porcupine.org/wietse/) comme une alternative plus facile à administrer et plus sécurisée que l'historique _Sendmail_.
Un serveur SMTP, appelé aussi MTA (Mail Transport Agent), est l'élément principal d'un serveur d'emails. Tout email transite forcément par un serveur SMTP dont il existe de nombreuses implémentations libres (Postfix, Exim, Sendmail, Qmail etc.) ou propriétaires (Microsoft Exchange, Sun Java System Messaging Server, IBM Lotus Domino, etc.).
Postfix n'est pas monolithique : le processus `master` tourne en permanence et gère le démarrage d'autres processus qui ont des tâches dédiées (cleanup, smtpd, pickup, etc.) notamment la transition entre les différentes files d'attente de Postfix (incoming, active, deferred, corrupt, hold).
La configuration de ces processus se trouve dans le fichier `/etc/postfix/master.cf`.
Et le fichier `/etc/postfix/main.cf` gère les nombreuses options de configuration.
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é :
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 :
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é) :
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.
# Attendre la commande 'RCPT TO' avant d'evaluer les restrictions ?
# (peut poser pb avec certains clients et permet d'avoir renseignements suppl)
#par defaut, = yes
#smtpd_delay_reject =
# Definition des plages IP appartenant a mynetworks
#par defaut, toutes les plages d'adresses IPv4 (et IPv6) des interfaces
mynetworks = 127.0.0.0/8,[::1]/128,10.0.0.0/16
# Exiger la commande HELO/EHLO
#par defaut, = no
smtpd_helo_required = yes
# Exiger syntaxe conforme dans les commandes MAIL FROM ou RCPT TO
#par defaut, = no
#strict_rfc821_envelopes =
# Rejeter le courrier provenant d'une adresse inexistante ?
#par defaut, = no
#smtpd_reject_unlisted_sender =
# Rejeter le courrier a destination d'une adresse inexistante ?
#par defaut, = yes
#smtpd_reject_unlisted_recipient =
~~~
#### Utilisation avec un annuaire LDAP
Les bases de données d'utilisateurs et de leurs paramètres peuvent être stockés dans une base de données externe. On peut ainsi utiliser une base de donnée ou un annuaire LDAP. Dans le cas de Postfix, on peut l'utiliser avec MySQL ou OpenLDAP.
Dans le fichier main.cf de Postfix, on utilisera une configuration type :
~~~
alias_maps = [autres bases] ldap:blabla
blabla_server_host = [serveur ldap]
blabla_search_base = [dn de base]
blabla_result_attribute = [type de champs à chercher]
~~~
Dans l'annuaire LDAP on a notamment des champs ressemblant à :
~~~
dn: uid=nnom,[dn de base]
objectClass: inetOrgPerson
objectClass: inetLocalMailRecipient
objectClass: posixAccount
sn: Nom
givenName: Prenom
cn: Nom Prenom
displayName: Nom Prenom
mailLocalAddress: pnom@example.com
uid: nnom
userPassword: ****
uidNumber: 1006
gidNumber: 1006
homeDirectory: /chemin_boite/
~~~
Prenons un exemple d'une configuration de comptes virtuels. La configuration de Postfix peut être :
Il est désormais fortement conseiller d'activer le chiffrement SSL/TLS entre les serveurs SMTP pour éviter de faire circuler en clair les informations (identifiants, contenu des messages) et s'assurer que l'on s'adresse au bon serveur.
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` :
Cette solution est décrite dans la RFC 2554 : SMTP Service Extension for Authentication. Il faut néanmoins prendre garde, car cette possibilité fait baisser le niveau de sécurité de votre service. En effet, tout repose désormais sur les paramètres d'authentification et, outre des moyens sociaux, il faut veiller à ce que ces paramètres ne soient pas interceptés, c'est-à-dire ne circulent pas en clair sur des canaux non sécurisés. Il sera donc prudent de rajouter une couche de chiffrement, ou alors d'exclure certains types d'authentification comme les types PLAIN ou LOGIN.
Un mécanisme d'authentification souvent utilisé est SASL (Simple Authentication and Security Layer), librairie développée par le projet Cyrus. La lecture du document Cyrus SASL for System Administrators donnera des élements pour installer et configurer conrrectement une authentification basée sur la librairie Cyrus. L'installation se fera à partir des sources ou de paquets (sasl2-bin libsasl2 libsasl2-modules). Certains modules sont optionnels et permettent d'utiliser diverses méthodes d'authentification (libsasl2-modules-gssapi-heimdal libsasl2-modules-kerberos-heimdal). Sous Debian Sarge, on installera le paqut postfix-tls qui contient notamment les extensions SASL pour Postfix.
Plusieurs bases d'authentification sont possibles selon les configurations :
* *shadow* : authentification basée sur le fichier _/etc/shadow_
* *pam* utilise directement les librairies PAM (on peut donc par exemple utiliser LDAP ou RADIUS)
* *pwcheck* : authentification basée sur le deamon pwcheck utilisant aussi le fichier /etc/shadow (précision pour Debian Sarge : saslauthd est dans le paquet cyrus-common)
* *saslauthd* : authentification basée sur le deamon saslauthd qui est plus flexible que pwcheck et peut utiliser PAM (mais aussi shadow, ldap, kerberos, etc,.) (précision pour Debian Sarge : saslauthd est dans le paquet sasl2-bin)
La configuration s'effectue dans dans _/etc/default/saslauthd_ :
Et ajouter l'utilisateur `postfix` au groupe `sasl`.
On vérifie la validité des utilisateurs par :
~~~
$ testsaslauthd -u username -p password
~~~
Note : attention, sous Debian Sarge, _testsaslauth_ ne tient apparemment pas compte du mécanisme passé en paramètre de saslauthd, c'est OK depuis Etch
saslauthd utilise le fichier pam.d/smtp (ou pam.d/other) dans ce cas (quelques modifications sont nécessaires si Postfix est chrooté, voir section CHROOT)
* *auxprop* (ou sasldb pour SASL version 1) : utilisation de /etc/sasldb(2)
C'est l'authentification utilisée par défaut par Postfix (si aucun paramètre pwcheck_method n'est précisé dans le smtpd.conf)
Commandes : sasldblistusers(2), saslpasswd(2)
Note : possibilité d'utiliser une base de données avec l'option auxprop_plugin: sql (quelques modifications sont nécessaires si Postfix est chrooté, voir section CHROOT)
Si vous utilisez une authentification non disponible, vous obtiendrez probablement :
Un fichier _smtpd.conf_ contiendra la méthode d'authentification et les types disponibles :
~~~
pwcheck_method: [choix_methode]
mech_list: [choix_type]
~~~
Note concernant Debian Sarge : le paquet authsasld ne permet que les types PLAIN et LOGIN. Si l'on autorise un autre type, il cherchera le fichier /etc/sasldb2 (a priori, le paquet n'a pas été compilé avec les options --enable-cram --enable-digest).
Postfix, lorsqu'il communique avec d'autres serveurs en tant que client, peut avoir besoin de s'authentifier. On peut donc lui passer des paramètres d'authentifications pour certains serveurs :
On peut choisir des options pour le mode compte, par exemple les types d'authentification autorisés :
~~~
smtp_sasl_security_options = noplaintext
~~~
### Gestion du chroot de Postfix
Enfermer Postfix dans un chroot permet de restreindre les accès à d'autres applications en cas de faille de sécurité. Cette protection s'indique au fichier master.cf. Par défaut, cette protection est activée sous Debian. Le répertoire de chroot se situe dans _/var/spool/postfix_
L'utilisation de chroot impose quelques modifications, notamment si l'on utilise l'authentification SMTP :
* saslauthd
Pour SASL avec la méthode saslauthd, il faut préciser la directive suivante dans le fichier _/etc/default/saslauthd_ :
Ne pas oublier de mettre des droits de lecture sur les répertoires _/var/spool/postfix/var/_ et _/var/spool/postfix/var/run/_ afin d'autoriser l'utilisateur _postfix_.
L'utilisateur _postfix_ sera ajouté au groupe _sasl_ si nécessaire (si le répertoire saslauthd appartient à _root:sasl_). Sans ces changements, on obtiendra un message :
Le fichier _/etc/resolv.conf_ est copié dans _/var/spool/postfix/etc/resolv.conf_. Il faut le tenir synchronisé en cas de modification (notamment en cas d'installation sur un réseau différent du réseau final).
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` :
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.
*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_ :**
/!\\ 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.
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 <queue_id>. 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 :
/!\\ 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 :
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 :
* 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.
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.
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](http://mailgraph.schweikert.ch/) 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 :
* 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
* Pour Hotmail/Outlook/Microsoft/Office365, faire un ticket support depuis [sender.office.com](https://sender.office.com/) et ce formulaire <https://support.microsoft.com/en-us/supportrequestform/8ad563e3-288e-2a61-8122-3ba03d6b8d75> pour autoriser IPv4.
[SPF](https://fr.wikipedia.org/wiki/Sender_Policy_Framework) 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ù :
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](https://kb.isc.org/docs/aa-00356). 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](https://mailchimp.com/developer/transactional/docs/authentication-delivery/) vous devez ajouter `include:spf.mandrillapp.com` par exemple.
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.
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 :
L'utilitaire [`spf`](https://github.com/jschauma/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.
*`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](https://mxtoolbox.com/DmarcReportAnalyzer.aspx) ou [easydmarc](https://easydmarc.com/tools/dmarc-aggregated-reports).
Voici un exemple d'un enregistrement DNS plus avancé :
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](https://fr.wikipedia.org/wiki/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 :
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 `*`).
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 :