Postfix version 2.3 introduit le support des applications Milter (mail filter) de Sendmail 8. Ces applications fonctionnent en dehors du MTA pour inspecter les événements SMTP (CONNECT, HELO, MAIL FROM, etc.) et le contenu du message. Une application Milter peut ordonner au MTA d'accepter, rejeter, mettre en attente ou en quarantaine une connexion, une commande ou le contenu d'un message ; d'effacer ou d'ajouter un destinataire ou en en-tête de message ; et de remplacer un en-tête de message ou son contenu entier. Tout ceci se passe avant la mise en file d'attente.
Le support de Milter a été ajouté à Postfix car il existe une grande collection d'applications, pas seulement pour bloquer les messages non souhaités, mais également pour vérifier l'authenticité (exemples: SenderID+SPF et Domain keys) ou pour signer les messages (example: Domain keys). Inventer un autre dispositif pour tous ces logiciels serait un piètre usage des ressources humaines et système.
Postfix 2.3 implemente toutes les requêtes du protocole Milter de Sendmail 8 jusqu'à la version 4, à l'exception d'une : le remplacement du contenu d'un message. Reportez-vous à ce propos au paragraphe, limites à la fin de ce document.
Ce document aborde les sujets suivants :
Bien que les applications Milter peuvent être écrites en C, JAVA or Perl, ce texte ne parle que des applications écrites en C. Pour celles-ci, vous avez besoin d'une librairie qui implemente the protocol Milter. Postfix ne fournit pas actuellement une telle librarie mais Sendmail la fournit.
Sur certaines distributions Linux et *BSD, la librairie libmilter de Sendmail est installée par défaut. Avec celles-ci, les applications telles dk-milter et sid-milter sont compilées ainsi sans nécessiter aucun bricolage :
$ gzcat dk-milter-x.y.z.tar.gz | tar xf - $ cd dk-milter-x.y.z $ make [...nombreuses lignes affichées...]
Sur les autres platformes, vous avez deux options :
Installer la librairie objet libmilter de Sendmail et les fichiers "include" correspondants. Sur les systèmes Linux, libmilter peut être fournie par le package sendmail-devel. Après avoir installé libmilter, compilez les applications Milter comme indiqué au paragraphe précédent.
Ne pas installer les librairies libmilter de Sendmail, mais compilez les librairies depuis le code source de Sendmail :
$ gzcat sendmail-x.y.z.tar.gz | tar xf - $ cd sendmail-x.y.z $ make [...nombreuses lignes affichées...]
Après avoir compilé votre propre libmilter, suivez les instructions d'installation incluses dans les sources de l'application Milter pour indiquer l'emplacement des fichiers "include" et de la librairie libmilter. Généralement, ces paramètres se configurent dans un fichier nommé sid-filter/Makefile.m4 ou équivalent :
dnl APPENDDEF(`confINCDIRS', `-I/some/where/sendmail-x.y.z/include') dnl APPENDDEF(`confLIBDIRS', `-L/some/where/sendmail-x.y.z/obj.systemtype/libmilter')
Compilez ensuite l'application Milter.
Pour lancer une application Milter, reportez-vous à la documentation sur les filtres pour les options. Une ligne de commande typique ressemble à :
$ /chemin/vers/dk-filter -p inet:numeroDePort@localhost ...autres options...
Comme Sendmail, Postfix dispose de nombreuses options de configuration qui contrôlent son diqlogue avec les applications Milter. Avec l'implémentation initiale du protocole Milter dans Postfix, de nombreuses options sont globales, c'est à dire qu'elles s'appliquent à toutes les applications Milter. Les versions futures de Postfix pourront supporter des timeouts, contrôles d'erreurs, etc. différentiés par Milter.
Contenu de ce paragraphe :
Le protocole Milter a été initialement développé pour filtrer les messages indésirables arrivant du réseau. Depuis, il est également utilisé pour signer les messages, ainsi les autres systèmes peuvent détecter le spam, le phishing, etc.
Pour les messages arrivant via le serveur smtpd(8), Postfix utilise les applications Milter listée dans le paramètre smtpd_milters (le cas des messages non SMTP est abordé dans le prochain paragraphe). Vous devez indiquer les applications Milter par le nom de leur socket en écoute ; les autres options Milter sont présentées dans les derniers paragrapes. Postfix vous autorise à indiquer plusieurs applications Milter. Elles seront appliquées dans l'ordre indiqué et la première qui rejetera une commande prendra le pas sur les autres.
/etc/postfix/main.cf: # Milters pour le courrier qui arrive via le serveur smtpd(8). # Voir ci-après pour la syntaxe des adresses de socket. smtpd_milters = inet:localhost:numéroDePort ...autres filtres...
La syntaxe générale pour les sockets en écoute est :
- unix:chemin
Se connect au serveur dans le domaine UNIX indiqué par le chemin. Si les processus smtpd(8) ou cleanup(8) fonctionnent en cage chroot, les chemins absolus seront interprétés relativement au répertoire des files d'attentes de Postfix.
- inet:machine:port
Se connect au port TCP indiqué sur la machine indiquée (locale ou distante). Les machines et ports peuvent être indiqués sous la forme chiffrée ou symbolique.
Note : La syntaxe de Postfix diffère de la syntaxe Milter qui à la forme inet:port@host.
Ce paragraphe décrit comment configurer les applications Milter pour les messages soumis via la commande sendmail(1) de Postfix et pour les messages qui arrivent via le serveur qmqpd(8). Ces applications Milter sont généralement utilisées pour signer les messages, ainsi les autres systèmes peuvent détecter le spam, le phishing, etc. Elles peuvent également être utilisées pour filtrer le courrier, mais celà présente quelques limites dont nous parlerons à la fin de ce paragraphe.
Pour les messages qui n'arrivent pas via le serveur smtpd(8), Postfix utilise les applications Milter qui sont listées avec le paramètre cleanup_milters. On y utilise la même syntaxe que pour le paramètre smtpd_milters ; reportez-vous aux autres paragraphes pour plus de détails. Comme dans le cas des messages SMTP, vous pouvez indiquer plus d'une application ; elles seront appliquées dans l'ordre indiqué et la première application qui rejetera une commande prendra le pas sur les autres.
/etc/postfix/main.cf: # Milters pour les messages non-SMTP. # Voir plus bas pour la syntaxe des adresses de sockets. cleanup_milters = inet:localhost:numéroDePort ...autres filtres...
Une petite complication apparaît lorsqu'on filtre des messages non SMTP avec des applications Milter : le protocole Milter a été conçu pour les messages SMTP. Pour conserver le bon fonctionnement des applications Milter avec les messages non SMTP, le serveur cleanup(8) doit simuler les événements de connexion et de déconnexion du client et les commandes SMTP EHLO, MAIL FROM, RCPT TO et DATA.
Lorsque le message est reçu via la commande sendmail(1), le serveur cleanup(8) prétend que le message arrive par ESMTP depuis "localhost" et avec l'adresse IP "127.0.0.1". Le résultat est très similaire avec ce qui arrive avec les soumissions en ligne de commande de Sendmail versions 8.12 et supérieures, bien que Sendmail utilise un mécanisme très différent.
Lorsque le message est reçu via le serveur qmqpd(8), le serveur cleanup(8) prétend que le message arrive par ESMTP et utilise les nom de machine et adresse IP du client QMQPD.
Ces événements SMTP simulés fonctione comme prévu avec seulement une exception : il est impossible de rejeter les commandes simulées RCPT TO. Lorsqu'une application cleanup_milters rejette un destinataire non SMTP, Postfix rapporte une erreur de configuration et le message reste en file d'attente.
Le paramètre milter_default_action indique la façon dont Postfix interprète les erreurs des applications Milter. Par défaut, il répond avec un statut d'erreur temporaire, ainsi le client réessaiera plus tard. Indiquez "accept" si vous voulez recevoir le courrier comme si le filtre n'existait pas, et "reject" pour rejeter le courrier avec un statut d'erreur permanent.
# Que faire en cas d'erreur ? Indiquez accept, reject, ou tempfail. milter_default_action = tempfail
Comme Postfix n'est pas compilé avec la librairie libmilter de Sendmail, vous devez également indiquer la version du protocole Milter que Postfix doit utiliser. La version par défaut est la n°2.
milter_protocol = 2
Si le paramètre milter_protocol requiert une version trop basse, la librairie libmilter produira un message d'erreur du type :
application name: st_optionneg[xxxxx]: 0xyy does not fulfill action requirements 0xzz
Le remède est d'augmenter le numéro de version milter_protocol. Reportez-vous toutefois au paragraphe limitations ci-dessous pour les fonctionnalités non supportées par Postfix.
Si la paramètre milter_protocol requiert une version trop élevée, la librairie libmilter se déconnecte simplement, et vous verrez un message d'erreur Postfix du type :
postfix/smtpd[21045]: warning: milter inet:host:port: can't read packet header: Unknown error : 0
Le remède est d'abaisser le numéro de version milter_protocol.
Postfix utilise différentes limites de temps aux différentes étapes du protocole Milter. La table présentée ci-dessous montre quels délais limites sont utilisés et quand (FDET = fin des en-têtes; FDM = fin du message).
Paramètre Délai limite Étape du protocole milter_connect_timeout 30s CONNECT milter_command_timeout 30s HELO, MAIL, RCPT, DATA, UNKNOWN milter_content_timeout 300s HEADER, FDET, BODY, FDM
Attention : 30s est un délai court pour les applications qui effectuent plusieurs interrogations DNS. Toutefois, si vous augmentez trop les délais ci-dessus, les clients SMTP distants peuvent se déconnecter et le message peut être livré plusieurs fois. C'est un problème inhérent au filtrage avant mise en file d'attente.
Postfix émule un nombre limité de macros Sendmail, comme indiqué dans le tableau ci-dessous. Différentes macros sont disponibles aux différentes étapes du protocole (FDM = fin-du-message) ; leur disponibilité n'est pas toujours la même que dans Sendmail. Reportez-vous au paragraphe "contournement des problèmes" ci-dessous pour les solutions.
Nom Disponibilité Description i DATA, FDM Identifiant de queue j Toujours valeur de myhostname {auth_authen} MAIL, DATA, FDM nom de login SASL {auth_author} MAIL, DATA, FDM expéditeur SASL {auth_type} MAIL, DATA, FDM méthode de login SASL {client_addr} Toujours Adresse IP du client {client_connections} CONNECT Nombre de connexions concurrentes pour ce client {client_name} Toujours Nom de machine du client, "unknown" lorsque la consultation ou la vérification échoue {client_ptr} CONNECT, HELO, MAIL, DATA Nom du client issu de la consultation DNS inverse, "unknown" lorsque la consultation échoue {cert_issuer} HELO, MAIL, DATA, FDM Fournisseur du certificat TLS client {cert_subject} HELO, MAIL, DATA, FDM "Subject" du certificat TLS client {cipher_bits} HELO, MAIL, DATA, FDM Taille de la clef de session TLS {cipher} HELO, MAIL, DATA, FDM chiffrement TLS {daemon_name} Toujours valeur de milter_daemon_name {mail_addr} Adresse d'expédition {rcpt_addr} RCPT Adresse de destination {tls_version} HELO, MAIL, DATA, FDM Version du protocole TLS
Postfix envoie des ensembles spécifiques de macros aux différentes étapes du protocole. Les ensembles sont configurés par les paramètres présentés dans le tableau ci-dessous.
Nom du paramètre Version de protocole Protocol stage milter_connect_macros 2 ou plus CONNECT milter_helo_macros 2 ou plus HELO/EHLO milter_mail_macros 2 ou plus MAIL FROM milter_rcpt_macros 2 ou plus RCPT TO milter_data_macros 4 or higher DATA milter_end_of_data_macros 2 ou plus FDM milter_unknown_command_macros 3 ou plus commande inconnue
Les applications Milter Sendmail ont été initialement développées pour la version 8 du MTA Sendmail, dont l'architecture est différente de celle de Postfix. En conséquence, certaines applications Milter font des suppositions qui ne sont pas vraie dans l'environnement Postfix.
Certaines applications Milter enregistrent un avertissement du type :
sid-filter[36540]: WARNING: sendmail symbol 'i' not available
et elles peuvent insérer un en-tête de message avec un "unknown-msgid" :
X-SenderID: Sendmail Sender-ID Filter vx.y.z machine.com <unknown-msgid>
Ceci arrive car les application Milter supposent que l'identifiant (queue ID) est connu avant que le MTA n'accepte la commande MAIL FROM (expéditeur). Postfix, d'autre part, ne crée pas de fichier en file d'attente tant que Postfix n'a pas accepté la première commande RCPT TO (destinataire). Le nom de ce fichier doit être globalement unique dans tous les répertoires de files d'attente donc il ne peut être choisi avant que le fichier ne soit effectivement créé.
Pour éviter cet en-tête de message des applications Milter, nous ajoutons un petit bout de code aux sources du Milter pour rechercher l'identifiant de file d'attente après que Postfix n'ait reçu la fin du message.
Editez le fichier source du filter (généralement nommé dk-filter/dk-filter.c ou équivalent).
Cherchez la fonction mlfi_eom() et ajoutez le code en gras ci-dessous vers le début du code de la fonction tel qu'indiqué ci-dessous :
cc = (connctx) smfi_getpriv(ctx); assert(cc != NULL); /* ** Determine the job ID for logging. */ if (sic->ctx_jobid == 0 || strcmp(sic->ctx_jobid, MSGIDUNKNOWN) == 0) { char *jobid = smfi_getsymval(ctx, "i"); if (jobid != 0) sic->ctx_jobid = jobid; }
Ceci ne supprime toutefois pas le message d'avertissement (WARNING).
Avec certaines applications Milters on peut régler l'avertissement et le "unknown-msgid" en repoussant l'appel de mlfi_eoh() (ou d'une autre routine générant l'avertissement) à la fin du message.
Éditez le fichier source du filtre (généralement nommé sid-filter/sid-filter.c ou équivalent).
Cherchez le tableau smfilter et remplacez mlfi_eoh (ou tout autre routine générant l'avertissement) par NULL.
Cherchez la fonction mlfi_eom() et ajoutez le code en gras présenté ci-dessous au début du code avant l'appel à mlfi_eoh() :
assert(ctx != NULL); #endif /* !DEBUG */ ret = mlfi_eoh(ctx); if (ret != SMFIS_CONTINUE) return ret;
Ceci fonctionne avec sid-milter-0.2.10. D'autres applications Milters planteront si vous le faites.
Ce paragraphe liste les limites de l'implementation Milter de Postfix. Certaines de ces limites seront corrigées au fur et à mesure que le support progresse. Bien sûr, les habituelles limitations du filtrage avant mise en file d'attente resteront vraies. Reportez-vous à la page Inspection du contenu pour plus de détails.
Postfix ne supporte actuellement que les applications qui utilisent les versions 2 à 4 du protocole Milter de Sendmail 8. Le support pour les versions pourra être ajouté plus tard.
Pour les applications écrites en C, vous devez utiliser la librairie libmilter de Sendmail. Une librairie Postfix pourra être fournie en remplacement dans le futur.
Lorsque le message n'arrive pas via le serveur smtpd(8), le serveur cleanup(8) doit simuler les événements SMTP de connexion et de déconnexion, et les commandes SMTP HELO, MAIL FROM, RCPT TO, et DATA. Ceci fonctionne parfaitement à une exception près : les applications Milters ne doivent pas rejeter ces événements RCPT TO simulés. Dans le cas contraire, Postfix rapportera une erreur de configuration et le message restera en file d'attente.
Postfix n'applique pas actuellement le filtrage de contenu aux messages qui sont transférés par alias ou autre, ou générés en interne tels les notifications de rejet. Ceci peut poser problème lorsque vous souhaitez utiliser un Milter pour signer de tels messages.
Lorsque vous utilisez un filtre avant mise enfile d'attente pour le courrier entrant par SMTP (voir SMTPD_PROXY_README), les applications Milters n'ont accès qu'aux informations issues des commandes SMTP ; elles n'ont pas accès aux en-têtes ou au contenu du message, et ne peuvent faire de modifications au message ou à l'enveloppe.
Postfix 2.3 ne supporte pas les requêtes Milter remplaçant le corps du message. Les applications Milters qui le resuierent enregistreront un avertissement dans les journaux du type :
application name: st_optionneg[134563840]: 0x3d does not fulfill action requirements 0x1e
La seule solution est d'utiliser (d'attendre) une version de Postfix qui supporte cette fonctionnalité manquante.
La plupart des options de configuration Mister sont globales. Les versions futures de Postfix pourront proposer des timeouts, des contrôles d'erreurs, etc. par Milter.
traduction par Xavier Guimard - Retour au menu