« Alias » et « forward » avec Postfix + LDAP

mail_forwardEn me basant sur l’architecture présentée dans le billet : Installation d’un serveur mail brique par brique… (OpenLDAP, Postfix, Cyrus-imap, TLS, SASL, Spamassassin, Amavis, etc…), je vais chercher, au travers de cet article, à améliorer la distribution des mails entrants. Ce que je souhaite mettre en place est assez simple d’un point de vue fonctionnel :

  1. Chaque utilisateur doit pouvoir disposer de plusieurs adresses email pour une même boîte, sans que l’on ait besoin de le créer plusieurs fois dans l’annuaire (notion d’alias) ,
  2. Les messages entrants doivent pouvoir être stockés sur le serveur Imap Local, transférés vers d’autres adresses (notion de forward) ou, soyons fous, les deux.

Le serveur Imap utilisé est Cyrus, mais ceci n’a pas vraiment d’importance, n’importe quel gestionnaire Imap fera l’affaire. Il en va de même pour le serveur OpenLDAP qui peut être remplacé par un autre annuaire, pourvu qu’il respecte les standards. Vous l’aurez compris, c’est bel et bien Postfix qui va permettre ces petites galipettes.

Pour l’exemple, je vais une fois de plus solliciter mon utilisateur préféré : Monsieur Dupont (Jean pour les intimes) . Ce Monsieur souhaite recevoir tous les mails adressés à :

Il dispose bien entendu d’une boîte Imap sur le serveur, mais souhaite qu’une copie de ses messages soient transférés sur son compte gmail jean.dupont@gmail.com.  C’est pas très très joli pour la sécurité de l’entreprise, mais pour l’exemple (et pour Jean), je vais fermer les yeux !

postfix_maildrop

Le serveur  IMAP :

Je vous l’ai dit, sur le serveur IMAP, rien de particulier. Il faut juste s’assurer qu’il est fonctionnel et que l’utilisateur Jean y est bien présent. Dans le cas contraire, je vous invite à consulter l’article précédent pour l’installation et la configuration d’un serveur Cyrus-Imap.

# cyradm –user cyrus localhost
Password:
localhost> lm
user.jean (HasNoChildren) user.jojo (HasNoChildren)
user.joel (HasNoChildren)
localhost> quit

L’annuaire :

Dans l’annuaire, j’ai légèrement modifié le schéma pour y insérer un deuxième attribut « Mail« , nommé « maildrop ». J’ai emprunté cet attribut à la classe CourierMailAlias (fournie par courier-Imap), mais en fait, n’importe quel attribut texte peut faire l’affaire.

L’idée est d’utiliser l’attribut « Mail » pour enregistrer les adresses pour lesquelles la réception de courrier est autorisée pour l’utilisateur :

Et l’attribut « MailDrop«  pour les adresses auxquelles le courrier va être effectivement distribué. Il faut noter que cet attribut doit correspondre à des boîtes réellement existantes. Dans sa configuration initiale, Cyrus cherche à stocker les messages dans des boîtes identifiées par le préfixe de l’adresse du destinataire (ce qui est avant le @).

Dans cet exemple, tout message adressé  à l’une ou l’autre  des 3 adresses définies par l’attribut « Mail » devra  être distribué aux 2 adresses définies par l’attribut « MailDrop« .

Côté ldiff, ça donne ça :

 
# utilisateurs.ldif
dn: uid=jean,dc=linet,dc=jopa,dc=fr
objectClass: top
objectClass: inetOrgPerson
objectClass: CourierMailAlias
uid: jean
cn: Jean DUPONT
sn: Jean
mail: jean@linet.jopa.fr
mail: dupont@linet.jopa.fr
mail: jean.dupont@linet.jopa.fr
maildrop: jean@linet.jopa.fr
maildrop: jean.dupont@gmail.com
userPassword: toto

Pour utiliser l’attribut « Maildrop » de la classe CourierMailAlias, il est nécessaire de récupérer le schéma décrivant la classe et de l’intégrer à l’annuaire. Le fichier s’appelle authldap.schema et vient avec la doc de Courier-Imap. (/usr/share/doc)… Vous pouvez également le récupérer ici :

authldap.schema

Le fichier doit être copié dans le répertoire contenant les schémas ( /etc/ldap/schema logiquement) et intégré à la structure de l’annuaire dans le fichier /etc/ldap/slapd.conf

/etc/ldap/slapd.conf

# This is the main slapd configuration file. See slapd.conf(5) for more
# info on the configuration options.
 
#######################################################################
# Global Directives:
 
# Features to permit
allow bind_v2
 
# Schema and objectClass definitions
include         /etc/ldap/schema/core.schema
include         /etc/ldap/schema/cosine.schema
include         /etc/ldap/schema/nis.schema
include         /etc/ldap/schema/inetorgperson.schema
include         /etc/ldap/schema/authldap.schema
...
...

Postfix :

Le but ici, est de définir Cyrus comme agent de transport local (et virtuel) et de paramétrer les recherches dans l’annuaire LDAP. Cette recherche sera définie dans deux fichiers de configuration externes : ldap-accounts.cf pour la validation des destinataires et ldap-aliases.cf pour la gestion des alias.

/etc/postfix.main.cf

# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
myorigin = /etc/mailname
...
...
# PARAMETRES LDAP
# Utilisateurs :
virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf
# Alias :
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf
...
...
# Agent de transport local : CYRUS
local_transport = cyrus
virtual_transport = cyrus
mailbox_transport = cyrus
...
...
...

/etc/postfix/ldap-accounts.cf

Ce fichier configure la recherche dans l’annuaire pour l’identification et la validation des destinataires. Il spécifie l’adresse email comme critère de recherche et  cas de succès, précise que c’est  l’uid de l’utilisateur qui doit être retourné.

server_host = localhost
server_port = 389
search_base = dc=linet, dc=jopa, dc=fr
query_filter = (& (objectClass=InetOrgPerson)(mail=%s))
result_attribute = uid
bind = yes
bind_dn = cn=admin,dc=linet,dc=jopa,dc=fr
bind_pw = ******************
version = 3

/etc/postfix/ldap-aliases.cf

Ce fichier permet, quant à lui, de gérer les Alias. Il définit lui aussi une recherche sur l‘adresse email (champ mail) mais cette fois, c’est l’attribut « Maildrop » que sera retourné.

server_host = localhost
server_port = 389
search_base = dc=linet, dc=jopa, dc=fr
query_filter = (& (objectClass=InetOrgPerson)(mail=%s))
result_attribute = maildrop
bind = yes
bind_dn = cn=admin,dc=linet,dc=jopa,dc=fr
bind_pw = ******************
version = 3

En résumé, encore une démonstration de la puissance du duo Postfix/Ldap, pour une fonctionnalité très pratique et relativement simple à mettre en oeuvre.

Laissez votre message après le bip...Biiiiip

Commentaires

Bon howto !

Juste pour info, si les attributs mail et maildrop sont lisibles sur le LDAP de façon annonyme, il n’est pas nécessaire de binder postfix en admin sur le LDAP (il se bindera en anonyme par défaut). Cela évite de laisser trainer le mot de passe en clair dans des fichiers…

Très judicieuse remarque eon ! Et si la lecture anonyme est gênante, j’aurais au moins pu utiliser un utilisateur ayant juste un accès en lecture…

Sans rapport direct avec ce billet, je voulais dire que je viens de rajouter à mon Google Reader l’un des meilleurs blogs que je n’ai jamais lu.
J’ai parcourue une dizaine d’articles et tout simplement : J’adore. Quel style simple, ludique et amusant. Tout paraît simple.

MERCI. 🙂

Merci à toi Khalid et merci à tous pour vos messages sympathiques !
C’est agréable et encourageant de voir que mon blog est visité, et même si ça me fait rougir derrière mon clavier, ça me file un patate dingue !

@+

Effectivement merci beaucoup pour ces très bons articles!

Je viens de finir l’installation complète de l’artillerie imap/ldap en suivant vos deux articles, sans trop de douleurs alors que ç’eut été une toute autre paire de manche sans cette aide précieuse.. et en français!

De mon côté j’avais un dernier petit souci avec Cyrus lors de l’envoi de mails à plusieurs destinataires (ou alias, ..) : bien que le message arrive à tous les destinataires, un message d’erreur était délivré à l’expéditeur, avec une erreur de ce style dans mail.log :

postfix/pipe[4377]: 1CC348008B: to=, orig_to=, relay=cyrus, delay=0.71, delays=0.63/0.01/0/0.06, dsn=5.6.0, status=bounced (data format error. Command output: : Mailbox does not exist )

Quelques suées plus tard j’ai finalement fini par trouver une réponse ( http://www.webservertalk.com/message1116814.html ), il suffit donc d’ajouter
« cyrus_destination_recipient_limit = 1 » à la configuration postfix, si jamais ça peut servir à quelqu’un.

Merci encore pour vos publications!

Superbe !

Juste une petite question d’un jeune padawan au grand Maître Jedi.

J’ai un serveur fetchmail – postfix – dovecot – spamassassin – etc… qui fonctionne très bien.
Et dans un coin, openldap qui contient deux « ou », annuaire et groupes.
« Annuaire » contient les coordonnées de mes contacts et « groupe » contient des groupes de contacts réalisés avec « groupOfNames ».

Ma question, est-il possible d’envoyer un mail à un groupe et que postfix traduise l’adresse pour l’envoyer à tous les membre de ce groupe ?

Merci d’avance

Laisser un commentaire

(requis)

(requis)