Aller au contenu

Postfix: Guide de survie pour débutant

Table des matières

Postfix, c’est vaste. Très vaste. La documentation est longue comme un jour sans café, les problèmes ne sont pas forcément simples à détecter, ni à régler. Alors cet article permettra d’y voir un peu plus clair pour les mainteneurs débutants d’un tel service. Il n’abordera pas tout, loin de là, mais quelques bases qui peuvent aider quand on travaille avec Postfix et plus généralement avec du mail. C’est orienté débutant et nous allons parler de vocabulaire, de test d’un serveur SMTP, de code d’erreur, de fichier de log, bref, des trucs sympas !

MTA, MDA, MUA, LDA… Qu’est-ce que ?

Dans le monde de Postfix, ces acronymes sont légions, si vous voulez vous en sortir, il est quand même bon de connaître leur signification.

MTA

Pour Mail Transfer Agent (ou Message Transfer Agent) c’est le logiciel qui est responsable de l’envoi et de la réception des messages ENTRE les systèmes. Ils ne font que deux choses: envoyer et recevoir, ils ne font rien d’autre. La plupart du temps ils causent en (E)SMTP ((Extended) Simple Mail Transfer Protocol couche 7 (application) du modèle OSI) historiquement sur le port 25. On y reviendra par la suite, c’est un protocole très simple (et vieillissant).

MDA

Pour Mail Delivery Agent, il s’occupe de la dernière étape lors de la transmission d’un mail: le déposer dans la bonne boîte aux lettres du bon utilisateur. On peut y coupler un système de filtre, Procmail fait ça très bien. Le MTA cause avec le MDA via l’intermédiaire du protocole LMTP (Local Mail Transfert Protocol). Notez que Dovecot comprend un MDA, on retrouve Courier, Cyrus ainsi que dbmail. Le MDA est sensé signaler toute erreur dans la distribution du courrier au MTA (dique full, quota dépassé, boite inexistante, etc…).

MUA:

Pour Mail User Agent. Inutile de faire compliqué, c’est un simple client de messagerie, comme Claws-Mail, Mutt, Thunderbird ou Outlook (oui, faut que ça parle à tout le monde), donc le logiciel qui va contacter le serveur pour récupérer ses mails via différents protocoles: le vieillissant POP3 ou le plus actuel IMAP qui dispose de plus de fonctionnalités.

Maintenant, on va se pencher sur les porcs. Euh, les ports, pardon.

De port en port

Rien à voir avec des cochons, hein. Pour que tout ce monde puisse causer dans la paix et le respect de l’autre, on a différents protocoles, certains sécurisés, d’autres pas. Ces protocoles utilisent des ports spécifiques pour communiquer. Voyons voir tout ça:

  • POP3: Post Office Protocol sur le 110
  • POP3S: Post Office Protocol over SSL sur le 995
  • IMAP4: Internet Message Access Protocol (v4) sur le 143
  • IMAPS: Internet Message Access Protocol over SSL sur le 993
  • SMTP: Simple Mail Transfert Protocol sur le 25
  • SMTPS: Simple Mail Transfert Protocol over SSL sur le 465 (587 pour le port de soumission).
  • D’autres existent, mais c’est déjà largement suffisant.

On sait qui fait quoi et où passe l’information. Maintenant, on va essayer de tester un serveur SMTP via une bonne vieille connexion Telnet.

Tester un serveur SMTP via Telnet

Attention ! Telnet passe en clair sur le réseau, prenez vos précautions !

On lance une connexion telnet sur le SMTP que nous souhaitons tester via le port 25 (port par défaut du SMTP):

telnet smtp.domain.tld 25

Si c’est OK, il nous répond quelque chose du genre:

Trying IP
Connected to domain.tld.
Escape character is '^]'.
220 mailtest ESMTP Postfix (Debian/GNU)

On est gentil, on dit bonjour au monsieur, en sachant qu’on reviendra sur cette notion un peu plus loin dans cet article:

ehlo domain.tld

On a été gentil, donc il l’est lui aussi, en nous disant ce qu’il propose comme fonctionnalités:

250-xx-xx-xx
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

Super, maintenant, on envoie un mail:

mail from:<moi@domain.tld>

Il nous répond que tout est OK:

250 2.1.0 Ok

Nous lui indiquons le destinataire (en anglais recipient c’est pas «récipient» hein, c’est «destinataire»)

rcpt to:<truc@domain.tld>

Il nous répond que, oui, tout va bien:

250 2.1.5 Ok

Nous sommes prêts, nous l’indiquons à Postfix via une commande data qui nous permettra de mettre du contenu dans le mail:

data

Comme à l’habitude, Postfix est très courtois et nous gratifie de quelques conseils:

354 End data with .

On tape notre mail:

Coucou,

Des bisous.
.

Et Postfix nous indique qu’il l’a correctement reçu, qu’il l’a mis en file d’attente en nous indiquant l’ID:

250 2.0.0 Ok: queued as U3F78240B7

On peut quitter, via la commande quit.

Les logs sont nos amis

Pour confirmer que le petit brin de causette avec notre ami Postfix n’était pas qu’une suite de mensonges, on regarde les logs. Toujours regarder les logs. C’est important et surtout ça vous indique tout. Vraiment TOUT.

Pour les logs, il existe les less / more / cat le tout avec des grep ou même des regexp. Le mieux à mon goût, c’est lancer un tail sur le fichier de log avant de faire les tests et d’observer tout ça en direct (attention, sur un serveur en production, ça peut être très verbeux, même avec peu d’utilisateurs).

Donc, on tail le fichier de log en question, généralement /var/log/mail.log via la commande:

tail -f /var/log/mail.log

La commande tail sous GNU/Linux affiche la dernière partie d’un fichier. On y indique l’option -f pour lui dire boucle à l’infini, comme ça ça nous fait un semblant de défilement en temps réel. Si vous voulez en voir un peu plus au début, passez l’option -n X avec X en guise de nombre de lignes voulues.

Donc afficher les 50 dernières lignes du fichier /var/log/mail.log et avoir un défilement en temps réel (pas vraiment, mais c’est l’idée) pour l’apparition des prochaines lignes, c’est cette commande:

tail -f -n 50 /var/log/mail.log

Pour sortir, un Ctrl + C fait le travail.

La sortie du fichier de log ressemblera à ça:

postfix/smtpd[...]: connect from xx[IP]
postfix/smtpd[...]: 5FF712A6: client=xx[IP]
postfix/cleanup[...]: 5FF712A6: message-id=<...>
postfix/qmgr[...]: 5FF712A6: from=<moi@domain.tld>, size=364, nrcpt=1 (queue active)
postfix/pipe[...]: 5FF712A6: to=<truc@domain.tld>, relay=dovecot, ..., status=sent (delivered via dovecot service)
postfix/qmgr[...]: 5FF712A6: removed
postfix/smtpd[...]: disconnect from xx[IP]

Dans le cas présent, Postfix a passé le relais à Dovecot. Il se chargera lui même de la livraison et informera Postfix du bon déroulement de la chose.

En cas de problème

Postfix enregistre absolument tout ce qu’il se passe, aussi bien les erreurs que les succès ! Plutôt que d’attendre bêtement devant un tail qu’un problème se pose (ce qui handicapera grandement votre vie sociale), on va les traquer à l’aide d’une regexp et le fabuleux egrep.

Notre regexp triera le résultat par ordre d’importance du problème d’un fichier de log entier. Le début de la sortie de notre commande contiendra donc les problèmes les plus intéressants / urgents / graves.

Postfix dispose de 4 niveaux de gravité d’un problème:

  1. panic: Vous le rencontrerez peu, étant donné qu’il émane forcément d’un soucis DANS le logiciel, or la version présente dans les dépôts est normalement correctement testée et éprouvée.
  2. fatal: Celui ci est embêtant car la cause peut venir de plusieurs choses, notamment un fichier manquant, des droits incorrects, des paramètres erronés dans un fichier de configuration.
  3. error: Il vous indique une erreur fatale ou non.
  4. warning: Il vous indique une erreur qui n’empêche pas le fonctionnement. Ça peut être un soucis de configuration minime, un soucis extérieur à votre configuration (un soucis DNS par exemple).

Panic, fatal et error empêche le fonctionnement de Postfix. Tant que les erreurs rencontrées ne sont pas réglées, Postfix ne fonctionnera pas (il refusera de démarrer).

Notre regexp, c’est donc celle ci, on lui passe le fichier de log ainsi qu’un more pour l’affichage:

egrep '(warning|error|fatal|panic):' /chemin/du/log | more

Postfix dispose de 3 fichiers de log (généralement, au moins sous Debian 5-6-7):

  • /var/log/mail.log
  • /var/log/mail.err
  • /var/log/mail.warn

Les codes d’erreur ou de retour SMTP

Précédemment, on a testé un serveur SMTP avec une simple connexion Telnet et Postfix nous répondait des choses comme:

250 2.1.0 Ok

Certes, il est sympathique de nous répondre, mais c’est pas très clair tout ça.

Sachez que le protocole SMTP répond à des règles précises et établies (comme tous les protocoles). Si vous voyez un code de retour commençant par 2, ça va, tout roule. Si ça commence par un 4, posez vous des questions, regardez les logs, ça commence un peu à puer. Si il commence par un 5, adieu veaux, vaches, cochons, fixez le problème et recommencez.

Si le deuxième numéro est un 1, c’est un problème d’adresse (de syntaxe ou de validité) concernant l’expéditeur ou le destinataire.

Si le deuxième numéro est un 2, c’est un soucis de boite aux lettres.

Bon on ne va pas tous les faire, car ça serait vraiment trop long. Pour toutes ces explications, je vous conseille de lire la RFC 1893 qui pose et explique tous ces codes. C’est passionnant, mais un peu long. La recherche est aisée car c’est de la forme suivante:

X.1.4 Destination mailbox address ambiguous

The mailbox address as specified matches one or more recipients on the destination system. This may result if a heuristic address mapping algorithm is used to map the specified address to a local mailbox name.

Et ceci pour tous les numéros !

Tant qu’on y est, prenez connaissance de la RFC 2821 qui contient les spécifications basiques du protocole SMTP ainsi que la RFC 1123 qui, elle, contient des informations supplémentaires à la page 48 (Ctrl + F «SMTP» vous aidera).

Oui, je dis «une» RFC, visiblement, peu importe si c’est «un» ou «une» selon Stéphane Bortzmeyer.

EHLO ou HELO ?

Sur notre test du serveur SMTP, on a utilisé la commande ehlo en guise de greeting command . Sachez qu’il existe aussi la commande helo. Un point d’histoire s’impose…

A l’origine, la RFC 821 (Août 1982) définissait la commande HELO en guise d’identification entre le client et le serveur (identification grossière hein, point de certificat ou de vérification, c’est juste histoire de savoir si la liaison entre le client et le serveur était correcte). La RFC en question donne cet exemple:

In the HELO command the host sending the command identifies itself; the command may be interpreted as saying «Hello, I am <domain>».


Example of Connection Opening

R: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready S: HELO USC-ISIF.ARPA R: 250 BBN-UNIX.ARPA

Au début, les serveurs SMTP ne proposaient pas d’authentification, de chiffrement ou quoique ce soit, ils faisaient un simple travail de relais. Puis est venu le temps des spammeurs et de l’essor d’Internet. Il a donc fallu retravailler tout ça, avec la RFC 2821 qui définit le nouveau SMTP comme le ESMTP (pour Extended SMTP) qui dispose de choses en plus (AUTH, STARTTLS, etc…). Et par conséquent, ils ont fait un EHLO (pour Extended HELO) qui retourne les options disponibles sur le serveur en question.

Testez par vous même, un HELO retourne uniquement le domaine, comme le dit la RFC 821:

helo coucou
250 srv.domaine.fr

Alors qu’un EHLO renverra le HELO ainsi que les fonctionnalités disponibles:

ehlo coucou
250-srv.domaine.fr
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

Notez qu’aujourd’hui, la quasi-totalité des serveurs répondent aussi bien aux helo qu’aux ehlo.

Cependant, Postfix implémente quelques restrictions par défaut qui s’appliquent à tous les messages SMTP, l’une d’entre elle étant l’obligation, pour le client, d’utiliser la commande helo ou ehlo avant la commande mail from. Certains scripts ou logiciels peu sérieux ne tiennent pas compte de cette obligation, c’est bien pour ça que Postfix intègre dans sa configuration par défaut la ligne suivante, qui permet d’éviter ce comportement:

smtpd_helo_required = no

Fin

Fin de ce premier article concernant Postfix pour savoir comment se sortir de situations problématiques. Le deuxième article sur ce sujet est dédié au traitement des files d’attente de Postfix !