Date de publication: le mercredi 16 mai 2007 à 11h10
Dernière modification: par Pascal BOYER le mardi 28 décembre 2010 à 14h43
« Article précédent: Postfix : le fichier smtpd.conf
» Article suivant: Postfix : Analyse des logs
Avant propos
Dans cet article, nous allons voir comment utiliser un annuaire LDAP afin de contrôler les adresses de destination des mails que reçoit le serveur smtpd Postfix.
Les informations contenues dans cet article sont la somme de toutes les recherches que j’ai faites sur le net, de l’aide de Momo (un grand merci à lui ;-) ) et des informations tirées du livre LDAP - Administration système, ed O’REILLY
Pré-requis
La configuration du serveur smtpd Postfix présentée ici est totalement indépendante d’une quelconque configuration préalable, et relative à LDAP, du serveur imapd Cyrus IMAP.
Il en résulte que vous pouvez très bien configurer votre serveur smtpd Postfix comme indiqué dans cet article sans avoir à configurer le serveur imapd Cyrus-IMAP pour LDAP. En d’autres termes, vous pouvez très bien arrêter votre lecture sur la configuration de Cyrus IMAP à l’article 4, passer à la mise en oeuvre du serveur Postfix présentée dans les articles 8, 9, 10, 11 puis enchainer sur celui-ci. Bon, là, je pense avoir été clair.... ;-)
Généralités
La bibliothèque SASL utilise un fichier de configuration distinct pour chaque application avec laquelle elle travaille. Dans le cas de Postfix, il s’agit du fichier smtpd.conf (p157). L’emplacement de ce fichier est /etc/postfix/sasl/ smtpd.conf
Contexte
Le but que nous cherchons à atteindre est le suivant:
Chaque fois que Postfix va recevoir un mail à délivrer localement alors il va contrôler que l’adresse du destinataire existe bien dans l’annuaire.
- si une entrée de l’annuaire LDAP contient cette adresse de destination alors Postfix fait suivre le mail à l’agent de distribution local qui le déposera dans la BàL,
- si aucune entrée de l’annuaire LDAP ne contient cette adresse alors le mail sera rejeté par Postfix.
Ce comportement manichéen de Postfix (mail accepté ou rejetté) est délibéré.
:
Il est possible de configurer Postfix pour qu’il délivre les mails sans destinataire connu dans une BàL prévue à cet effet.
Mais cela n’était pas mon souhait.
1°/ Le fichier main.cf
Puisqu’il faut bien commencer quelque part, ce sera par ce fichier.
Les modifications à apporter ne sont pas importantes et sont indiquées en commentaire dans le fichier /etc/postfix/ main.cf présenté dans l’article
Postfix : le fichier main.cf
.
En effet, le seul changement à effectuer dans ce fichier est relatif à la règle local_recipient_maps. Actuellement, cette règle est ainsi définie:
local_recipient_maps = $alias_maps
Et la variable $alias_maps renvoie à cette règle:
alias_maps = hash:/etc/postfix/aliases
Nous allons donc modifier la règle local_recipient_maps comme ceci:
local_recipient_maps = $alias_maps, ldap:/etc/postfix/ldap_local_recipient.cf
De la sorte, pour chaque mail reçu, Postfix contrôle l’adresse de destination dans la table /etc/postfix/aliases puis dans l’annuaire LDAP en tenant compte des indications que nous allons inclure dans le fichier /etc/postfix/ ldap_local_recipient.cf
:
le nom du fichier ldap_local_recipient.cf est à la libre appréciation de chacun !!!
2°/ Le fichier /usr/lib/sasl2/smtpd.conf
Pour savoir comment configurer correctement ce fichier, qui ne requière que très très peu de modifications, reportez-vous au chapitre 2°/ Le fichier smtpd.conf de l’article
Postfix : le fichier smtpd.conf
Tout est y indiqué.
3°/ La table de recherche /etc/postfix/aliases
Dans les commentaires relatifs à la règle local_recipient_maps du fichier /etc/postfix/ main.cf il est dit ceci:
La table de recherche /etc/postfix/aliases doit contenir au moins tous les utilisateurs ayant une BàL sur le serveur IMAP si et seulement si local_recipient_maps = alias_maps !!!
donc:
- 1°/ si nous conservons intacte cette table de rechercher, le serveur LDAP ne sera pas consulté puisque les adresses de destination sont contenues dans cette table qui est consultée en premier.
- 2°/ nous devons conserver cette table de recherche car elle contient tous les alias relatifs au différents administrateurs logiciel ou système.
Une première solution aux 1°/ et 2°/ consiste bien évidemment à intervertir l’ordre de recherche. On obtient alors:
local_recipient_maps = ldap:/etc/postfix/ldap_local_recipient.cf, $alias_maps
Auquel cas, l’annuaire LDAP étant consulté en premier il ne devient alors point nécessaire de modifier la table de recherche /etc/postfix/aliases. Mais laissons de côté cette solution facile, et éditons la table de recherche /etc/postfix/aliases
vi /etc/postfix/aliases
# /etc/postfix/aliases # ======================== IMPORTANT !!! ========================== # # Après chaque modification de cette base, penser à lancer les commandes: # # ~# newaliases # ~# postfix reload # ============================================================= # CI-DESSOUS, LES ALIAS DES ADMINISTRATEURS SYSTÈME ET LOGICIEL: abuse: pascal@linuxorable.fr ftp: pascal@linuxorable.fr hostmaster: pascal@linuxorable.fr mailer-daemon: pascal@linuxorable.fr news: pascal@linuxorable.fr nobody: pascal@linuxorable.fr noc: pascal@linuxorable.fr pirouette: pascal@linuxorable.fr postmaster: pascal@linuxorable.fr root: pascal@linuxorable.fr security: pascal@linuxorable.fr usenet: pascal@linuxorable.fr webmaster: pascal@linuxorable.fr webmin: pascal@linuxorable.fr www: pascal@linuxorable.fr # CI-DESSOUS, UNE ENTRÉE POUR CHAQUE BàL CRÉÉE SUR LE SERVEUR Cyrus-IMAP SI ON # N'UTILISE PAS LDAP. # SI ON UTILISE LDAP, ALORS IL FAUT COMMENTER LES ENTRÉES CI-DESSOUS. # En LHS il ne doit pas y avoir de nom n'ayant pas de BàL sur le serveur !!! # LHS RHS ma-femme: ma-femme@linuxorable.fr ma-fille: ma-fille@linuxorable.fr ma-soeur: ma-soeur@linuxorable.fr mon-bof: mon-bof@linuxorable.fr mon-frere: mon-frere@linuxorable.fr mon-garçon1: mon-garçon1@linuxorable.fr mon-garçon2: mon-garçon2@linuxorable.fr pascal: pascal@linuxorable.fr
Donc, comme cela est indiqué, pour utiliser l’annuaire LDAP il suffit de commenter toutes les entrées de ce fichier relatives aux personnes ayant une BàL sur le serveur.
Il est également possible, bien sûr, de supprimer ces lignes. Voici alors notre nouvelle table de recherche /etc/postfix/aliases
vi /etc/postfix/aliases
# /etc/postfix/aliases # ======================== IMPORTANT !!! ========================== # # Après chaque modification de cette base, penser à lancer les commandes: # # ~# newaliases # ~# postfix reload # ============================================================= # CI-DESSOUS, LES ALIAS DES ADMINISTRATEURS SYSTÈME ET LOGICIEL: abuse: pascal@linuxorable.fr ftp: pascal@linuxorable.fr hostmaster: pascal@linuxorable.fr mailer-daemon: pascal@linuxorable.fr news: pascal@linuxorable.fr nobody: pascal@linuxorable.fr noc: pascal@linuxorable.fr pirouette: pascal@linuxorable.fr postmaster: pascal@linuxorable.fr root: pascal@linuxorable.fr security: pascal@linuxorable.fr usenet: pascal@linuxorable.fr webmaster: pascal@linuxorable.fr webmin: pascal@linuxorable.fr www: pascal@linuxorable.fr
A partir de maintenant, si vous tapez les deux commandes suivantes:
newaliases
et/ou
postfix reload
alors plus aucun mail ne parviendra dans les BàL et en regardant les logs de /var/log/mail.log vous devriez obtenir des messages du type:
postfix/smtpd[16464]: maps_find: local_recipient_maps: @linuxorable.fr: not found postfix/smtpd[16464]: mail_addr_find: mon-bof@linuxorable.fr -> (not found) postfix/smtpd[16464]: NOQUEUE: reject: RCPT from web26801.mail.ukl.yahoo.com[217.146.176.77]: 550 <mon-bof@linuxorable.fr>: Recipient address rejected: User unknown in local recipient table; from=<lucien@yahoo.fr> to=<mon-bof@linuxorable.fr> proto=SMTP helo=<web26801.mail.ukl.yahoo.com> postfix/smtpd[16464]: > web26801.mail.ukl.yahoo.com[217.146.176.77]: 550 <mon-bof@linuxorable.fr>: Recipient address rejected: User unknown in local recipient table
Explicitons ce qui m’apparaît par ailleurs tout à fait clair:
-
1ère ligne:
aucune adresse en @linuxorable.fr n’a été trouvée dans la table de recherche définie par la règle local_recipient_maps.
-
2ème ligne:
l’adresse mon-bof@linuxorable.fr n’a pas été trouvée.
-
3ème ligne:
- le mail n’a pas été placé dans la file d’attente deferred.
- le mail, en provenance de mail.ukl.yahoo.com[217.146.176.77] a été rejeté définitivement (code erreur 550) parce que le destinataire est inconnu dans la table de recherche ( Recipient address rejected: User unknown in local recipient table;).
-
4ème ligne:
à nouveau on nous donne la raison du rejet du mail.
:
le caractère définitif du rejet, signifié par le code 550, est défini à la fin du fichier /etc/postfix/ main.cf par la règle unknown_address_reject_code = 550. Ce qui ne constitue pas le fonctionnement par défaut de Postfix mais un choix personnel.
Et pendant ce temps, voici le mail que reçoit lucien, l’expéditeur du mail rejeté:
MAILER-DAEMON@ yahoo.com failure notice
qui contient:
Date: 17 Jan 2005 15:55:58 -0000 De: MAILER-DAEMON@yahoo.com Ajouter au carnet d'adressesAjouter au carnet d'adresses À: lucien@yahoo.fr Objet: failure notice Hi. This is the qmail-send program at yahoo.com. I'm afraid I wasn't able to deliver your message to the following addresses. This is a permanent error; I've given up. Sorry it didn't work out. <mon-bof@linuxorable.fr>: 88.xxx.xxx.xxx does not like recipient. Remote host said: 550 <mon-bof@linuxorable.fr>58 Recipient address rejected58 User unknown in local recipient table Giving up on 88.xxx.xxx.xxx. --- Below this line is a copy of the message. [...]
4°/ Le fichier /etc/postfix/ldap_local_recipient.cf
Ce fichier contient toutes les indications nécessaires à Postfix pour effectuer le contrôle de l’adresse du destinataire dans l’annuaire LDAP.
:
Il existe deux manières de déclarer à Postfix les indications de recherche dans l’annuaire LDAP. La première consiste à déclarer ces indications directement dans le fichier /etc/postfix/ main.cf
C’est la solution souvent rencontrée dans les documents trouvés sur le net.
La deuxième, celle que j’ai retenue, consiste à créer un fichier spécifique (en l’occurence le fichier /etc/postfix/ ldap_local_recipient.cf ) externe au fichier /etc/postfix/ main.cf
Si mon choix s’est porté sur la deuxième méthode, c’est tout simplement parce que je suis du genre à aimer que chaque chose soit bien à sa place afin que les vaches soient bien gardées !
D’autre part, je trouve que cela rend l’administration du serveur de mail plus aisée et plus claire.
:
Ce fichier est le seul fichier externe nécessaire à Postfix pour contrôler les adresses de destination auprès du serveur LDAP.
4.1°/ Principe de fonctionnement d’une requête LDAP
Postfix recherche dans l’annuaire LDAP la valeur de l’attribut "mail". Pour chaque entrée consultée dans l’annuaire, Postfix compare l’adresse de destination du mail qu’il vient de recevoir à la valeur de l’attribut "mail" de l’entrée consultée.
- 1°/ si après avoir consulté toutes les entrées, aucune correspondance n’est trouvée, alors le mail est rejeté définitivement avec le code 550.
- 2°/ si une correspondance est trouvée alors le mail est livré à l’agent de livraison locale qui se nomme local.
Voici donc à quoi ressemble le fichier /etc/postfix/ ldap_local_recipient.cf
# Explications des 5 lignes ci-dessous: # *********************************** # Ces 5 lignes veulent dire: # Sur le serveur LDAP dont l'adresse IP est 82.67.66.131 et qui écoute sur le port 389, effectuons une recherche # à partir du contexte "ou=mail accounts,dc=linuxorable,dc=fr". # Le filtre de recherche précise que Postfix recherche la valeur de l'attribut "mail" telle que précisée par # la commande "RCPT TO:" et c'est la valeur de l'attribut "mail" qui devra être retournée comme résultat de la recherche. server_host = 82.67.66.131 server_port = 389 search_base = ou=mail accounts,dc=linuxorable,dc=fr # le %s signifie "adresse du destinataire telle que fournie par la commande "RCPT TO:" query_filter = (mail=%s) result_attribute = mail
Les options possibles de ce fichier (p157-158) sont définies dans la page de man ~# man 5 ldap_table
5°/ Les fichiers .ldif
Pour que les requêtes LDAP soient efficientes il est bien évidemment nécessaire de créer des entrées dans l’annuaire LDAP. Ces entrées devront contenir au minimum l’attribut mail.
Les entrées que je vous propose de créer sont en tous points identiques à celles présentées au paragraphe 5°/ de l’article Cyrus IMAP : authentification LDAP .
Je ne m’étendrai donc pas sur la création de tels fichiers (reportez vous à l’article sus-cité) et vous présente simplement un exemple de leur contenu:
# AJOUT D'UN UTILISATEUR DANS l'ANNUAIRE LDAP dn: cn=mon-bof DURANT,ou=mail accounts,dc=linuxorable,dc=fr cn: mon-bof DURANT cn: mon-bof sn: DURANT mail: mon-bof@linuxorable.fr userPassword: xxxxx objectClass: inetOrgPerson
:
L’ ou spécifié dans le fichier .ldif ( ou=mail accounts) doit être soit identique à celui spécifié comme base de recherche dans le fichier /etc/postfix/ldap_local_recipient.cf soit en être un sous-contexte de nommage.
Bien. Une fois toutes vos entrées créées, il ne vous reste plus qu’à tester que tout fonctionne correctement en vous envoyant un mail à partir du webmail de votre FAI par exemple.
:
Pour tester la validité de vos fichiers /etc/postfix/ ldap_local_recipient.cf et .ldif vous pouvez utiliser la commande suivante:
postmap -q mon-bof@linuxorable.net ldap:/etc/postfix/ldap_local_recipient.cf
Si tout fonctionne bien, alors la sortie de cette commande doit être:
mon-bof@linuxorable.fr
Si tout fonctionne parfaitement, voici ce que vous devez trouver dans les logs de /var/log/mail.log
Voici à quoi ressemble les logs d'une requête qui abouti positivement: postfix/smtpd[16923]: dict_ldap_lookup: In dict_ldap_lookup postfix/smtpd[16923]: dict_ldap_lookup: Using existing connection for LDAP source /etc/postfix/ldap_local_recipient.cf postfix/smtpd[16923]: dict_ldap_lookup: Searching with filter (mail=mon-bof@linuxorable.fr) postfix/smtpd[16923]: dict_ldap_get_values[1]: Search found 1 match(es) postfix/smtpd[16923]: dict_ldap_get_values[1]: search returned 1 value(s) for requested result attribute mail postfix/smtpd[16923]: dict_ldap_get_values[1]: Leaving dict_ldap_get_values postfix/smtpd[16923]: dict_ldap_lookup: Search returned mon-bof@linuxorable.fr postfix/smtpd[16923]: maps_find: local_recipient_maps: ldap:/etc/postfix/ldap_local_recipient.cf(0,100): mon-bof@linuxorable.net = mon-bof@linuxorable.fr postfix/smtpd[16923]: mail_addr_find: mon-bof@linuxorable.fr -> mon-bof@linuxorable.fr postfix/smtpd[16923]: connect to subsystem public/cleanup
Conclusion
Cette serie d’articles consacrés à la mise en oeuvre d’un serveur Postfix prend fin. J’espère qu’à sa lecture vous aurez pris plaisir et appris quelque chose. A nouveau je vous engage vivement à me faire connaître toutes vos remarques en m’écrivant ici .
Les articles consacrés à l’utilisation de LDAP devraient, me semble t-il, être étoffés de plus de précisions et d’exemples. Je pense particulièrement à la création des filtres de recherche.Je ne suis malheureusement pas un expert de l’administration de LDAP.
Cependant, j’enrichirai ces articles à mesures que mes connaissances s’affineront.
Commentaires














