postfix : utilisateurs « virtuels » MySQL ; accès POP3[S], IMAP[S], SASL et TLS ; quota (bingo, j’ai tout mis dans le titre)
Introduction
Hop,
Après ma doc d’initiation Debian, où un rapide chapitre est consacré au montage d’un serveur postfix, spamassassin, greylisting etc, dans une configuration simple,
Après cet article sur le montage complet cette fois, en incluant amavisd-new, anti-virus etc,
=> Voici le complément idéal, par exemple en PME (et même plus gros) :
- Gestion d’utilisateurs virtuels, entendez par là « utilisateurs définis en base de données et non pas utilisateurs réels de l’OS ».
- Mise en place de tout ce qu’il faut pour lire les mails (POP3, POP3S, IMAP, IMAPS) via les outils « courier-* »
- Authentification via SASL
- Mise en place d’authentification sécurisée plus forte pour l’envoi (TLS).
Pour le webmail, j’en ai parlé déjà quelques fois sur mon blog et dernièrement, la version 0.3 de roundcubemail a fait de gros progrès par rapport à la 0.1. Ca s’installe en 3 clics. Si j’ai le temps je ferai un article, mais c’est mal barré.
Situation de départ
Avoir un serveur postfix correctement monté, avec (ou pas) amavis, spamassassin, un anti-virus, du greylisting, un nom correct etc. Bref, un serveur qui fonctionne et qui accepte les mails correspondant à des Maildir d’utilisateur de l’OS. En gros, ce qui est expliqué là .
Je ne parlerai pas d’ouverture de ports réseaux etc, mais ça tombe sous le sens. Ni du fait qu’il vous faudra une base MySQL en état de marche.
Je n’ai pas trouvé de doc officielle sur le sujet. En gros, on a postfix-mysql
qui permet de faire le lien entre le serveur de mails et la base, mais rien dans un gros fichier README qu’on a habituellement avec ce genre de paquet. Ou alors je l’ai loupé.
Le « postfix mysql howto » est juste résumé à ça : http://www.postfix.org/MYSQL_README.html et ça : http://www.postfix.org/mysql_table.5.html. Et pour le coup, ce n’est pas très sexy.
J’ai donc compilé tout un tas de différents articles le sujet, parfois incomplet, parfois des articles décrivant des méthodes à grand coup de compilation-c-est-pénible-et-stupide-pour-suivre-les-mises-à -jour etc. Parfois sans gestion de quota, parfois avec. Et en général, en expliquant rien du tout. Donc dans mon cas, je tâche d’expliquer ce qu’on fait.
Alors, comme à mon habitude, je laisserai trainer 2/3 bugs que j’ai pu rencontrer (de ma faute), ça peut permettre d’aider si vous faites les mêmes erreurs. Et on y apprend l’existence de quelques outils pour tester en ligne de commande.
Remarque pour la partie quota qui ne fonctionne pas nativement dans postfix, je la passe sous silence volontairement au début et y consacre un chapitre à la fin. En effet, c’est relativement dissocié de tout le reste et ça implique de recompiler postfix (ou d’utiliser un .deb fourni par je ne sais qui, mais vous êtes dépendant de lui pour les mises à jour). Comme certains se moqueront des quotas, je le traite à la fin. Beaucoup de guides de mise en place mélangent tout et prévoient des fonctions qu’ils n’exploitent pas. J’essaye pour ma part de faire des briques dissociables.
J’ai aussi tout installé sur un unique serveur. Ce n’est pas une nécessité, sur une grosse installation par exemple.
Autres documentations
A ce propos, j’ai lu à peu près tout ce qui suit (et plein d’autres) pour monter le serveur, notamment les 2 premiers lien. J’ai même en gros simplement repompé, traduit et expliqué :
- http://library.linode.com/email-guides/postfix/postfix-courier-mysql-debian-5-lenny
- http://www.howtoforge.com/virtual-users-domains-postfix-courier-mysql-squirrelmail-debian-lenny
- Quelques survols de docs ici : http://www.postfix.org/docs.html
- Un psycho de la recompilation : http://www.phparchitecture.com/howto_show.php?id=2, mais y’a 2/3 trucs à prendre
Grandes étapes de la procédure
En gros, on va :
- 1) Installer les applicatifs,
- Créer la structure en base,
- Décrire cette structure à postfix pour qu’il sache l’interroger
- 2) Créer ce qu’il faut pour stocker les boites virtuelles
- Faire quelques tests de livraison de mails pour valider la partie « utilisateurs définis en base »
- 3) Paramétrer les outils pour récupérer les mails (courier-POP, IMAP et versions sécurisées par SSL)
- Tester ces protocoles pour la récupération des mails
- Voir l’analyse de quelques erreurs sur la partie « courier »
- 4) Paramétrer les mécanismes d’authentification pour l’envoi (SASL, TLS)
- Tester l’envoi, en TLS ou pas
- Voir l’analyse de quelques erreurs sur la partie authentification pour l’envoi
- 5) Optionnel : activer les quotas
- Et enfin, voir ce que je n’ai pas traité
Installation des paquets
Pour une fois, tout ne descend pas par dépendance, car les différents modules d’authentification (identification via une base MySQL) ne sont pas obligatoires, donc pas de dépendance. Donc pour une fois il faut absolument tout copier-coller. Pour illustrer, installer courier-authlib
n’amène pas forcément courier-authlib-mysql
.
On a donc :
aptitude install postfix-mysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl postfix-tls libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl courier-authdaemon courier-authlib-mysql
Vous pouvez à la limite zapper certains, comme le POP, si vous ne comptez pas l’utiliser. Notez que les webmails tapent en IMAP, si vous ne le saviez pas.
Connexion postfix <-> MySQL
Création de la base de données
J’ai vu des définitions de base hyper complète, pour désactiver le POP (ou je ne sais quoi d’autre) par utilisateur. Sachez qu’il sera toujours temps d’ajouter une colonne à une table, de mettre des valeurs par défaut et d’ajouter une règle dans postfix pour prendre en compte une nouvelle fonctionnalité (c’est d’ailleurs ce qu’on fera pour les quotas de boîtes mails). Donc faisons simple au début.
On crée une base et un utilisateur dédié, avec des droits pas trop larges. Une fois connecté en root dans votre base (exemple : mysql -u root -p
), on crée la base et donne des droits à cet utilisateur qu’on crée au passage :
mysql> create database postfix; Query OK, 1 row affected (0.00 sec) mysql> grant select,insert,update,delete on postfix.* TO 'mail_adm'@'localhost' identified by 'monpassadmin'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)
ATTENTION : dans toute la suite, le nom de la base, le nom des tables, les identifiants etc sont à modifier pour refléter votre installation. Attention à ne pas copier-coller trop vite.
Ensuite, dans la base « postfix », on crée quelques tables :
use postfix; CREATE TABLE domains ( domain varchar(50) NOT NULL, PRIMARY KEY (domain) ); CREATE TABLE forwardings ( source varchar(80) NOT NULL, destination TEXT NOT NULL, PRIMARY KEY (source) ); CREATE TABLE users ( email varchar(80) NOT NULL, password varchar(20) NOT NULL, PRIMARY KEY (email) ); CREATE TABLE transport ( domain varchar(128) NOT NULL default '', transport varchar(128) NOT NULL default '', UNIQUE KEY domain (domain) );
Ces 4 tables permettront, dans l’ordre, de :
- définir la liste des domaines qu’on gère
- créer des alias (renvoyer toto@domaine.fr vers tata@blabla.com + titi@blibli.com)
- définir nos comptes et leurs propriétés
- définir une table de transport, au besoin
Création des requêtes pour savoir comment interroger ces tables
Le principe est le suivant : on a créé des tables avec des noms de colonnes et de tables libres (on aurait pu tout changer), on doit donc indiquer à postfix comment vérifier un mot de passe, voir s’il y a un forward etc. Pour chaque action, on a une directive dans /etc/postfix/main.cf
et un fichier de conf décrivant la base et la requête.
Le truc énorme, c’est qu’on pourrait ajouter n’importe quelle colonne (attribut) pour ajouter un test. Exemple stupide : le password est OK entre 8h et 20h, sinon impossible de relever ses mails.
On ajouterait une colonne et une clause supplémentaire dans le WHERE, tenant compte de l’heure et d’horaires autorisés pour tel utilisateur.
Voici les 4 fichiers de conf pour les 4 tables précédement créées :
Fichier /etc/postfix/mysql-virtual_domains.cf
:
user = mail_adm password = monpassadmin dbname = postfix query = SELECT domain AS virtual FROM domains WHERE domain='%s' hosts = 127.0.0.1
Fichier /etc/postfix/mysql-virtual_forwardings.cf
:
user = mail_adm password = monpassadmin dbname = postfix query = SELECT destination FROM forwardings WHERE source='%s' hosts = 127.0.0.1
Fichier /etc/postfix/mysql-virtual_mailboxes.cf
:
user = mail_adm password = monpassadmin dbname = postfix query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM users WHERE email='%s' hosts = 127.0.0.1
Fichier /etc/postfix/mysql-virtual_transports.cf
:
user = mail_adm password = monpassadmin dbname = postfix query = SELECT transport FROM transport WHERE domain='%s' hosts = 127.0.0.1
Ensuite on sécurise ces fichiers qui contiennent des infos sensibles sur la base d’authentification de mails :
chown root:postfix /etc/postfix/mysql*cf chmod 640 /etc/postfix/mysql*cf
Création de la structure de stockage des boîtes
Le principe est le suivant : on indique un répertoire racine, avec un utilisateur dédié sous lequel tout est stocké.
On aura une belle arborescence de ce type :
/ma/racine/des/maildirs/ - /mon.domaine.fr/ - user1 - cur - new - tmp + .autre.sous.rep.de.maildir.genre.Sent + user2 - /autre.domaine.a.moi.fr/ + userX
Donc, disons que que le répertoire racine de stockage des boîtes mails sera /vmailboxes
. On crée l’utilisateur avec un ID arbitraire :
groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /vmailboxes -m
Attention, vous allez aussi recopier le contenu de /etc/skel dans /vmailboxes, le home de « vmail ». Ce n’est pas forcément utile. Adaptez au besoin.
On indique tout ça à postfix
Dans un premier temps, je n’ajoute pas toute la conf dans /etc/postfix/main.cf
. On va y aller progressivement vu ce qu’on vient d’installer. On ajoute donc :
virtual_alias_domains = virtual_alias_maps = hash:/etc/postfix/virtual,proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf virtual_mailbox_base = /vmailboxes virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_create_maildirsize = yes virtual_maildir_extended = yes transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps \ $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains \ $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps \ $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks
Les fichiers de conf MySQL en « mode proxy » (si on peut dire) permettent d’optimiser les accès en conservant en mémoire le contenu. Pratique pour éviter une tonne d’accès disque inutile.
N’oubliez pas de générer le fichier virtual.db, la « version base de données » associée au fichier « virtual ». Il vous sert à faire suivre par exemple certains comptes locaux vers d’autres adresses e-mails. Pour centraliser vos remontées de serveur autre part.
Rechargez postfix, ça devrait bien se passer. Allez voir dans /var/log/mail.info
ou syslog
sinon.
On va pouvoir tester.
Quelques tests de livraison de mails
Pour créer une boîte, il faudra au minimum :
- Avoir déclaré le domaine qu’on gère
- Avoir déclaré le compte
- Avoir envoyé un mail de bienvenue, localement, pour forcer la création de boîte (arborescence
-
Eventuellement avoir ajouté des sous-répertoires pour que le webmail (si vous en mettez un) soit content : Sent, Trash, Drafts, Junk.
Ajout d’un domaine
Tout comme en postfix « normal », on indique dans « mydestination » la liste des noms de domaines gérés, il faut ici les indiquer dans la base. Et les supprimer de « mydestination » si vous les gériez localement jusqu’alors. On crée simplement un enregistrement en base :
INSERT INTO domains (domain) VALUES ('mxtest.mondomaine.fr');
(Je suppose que mxtest.mondomaine.fr
existe et que l’enregistrement MX existe aussi et pointe vers notre serveur.
Création d’un utilisateur
Simplissime, dans la base aussi :
INSERT INTO users (email, password) VALUES ('jacques@mxtest.mondomaine.fr', ENCRYPT('mon_pass_en_clair'));
Initialisation de sa boîte mail
Connecté localement, par exemple, sur la machine, envoyez un mail en ligne de commande, avec mailx, mutt. Ce que vous voulez.
Là , ô magie, vous devriez voir l’arborescence /vmailboxes se peupler, par exemple avec /vmailboxes/mxtest.mondomaine.fr/jacques/
C’est une arborescence « Maildir » classique, avec cur
, new
, tmp
.
Si le mail est arrivé, on peut pour l’instant le lire en ligne de commande en allant dans le répertoire, tout bêtement.
Création des autres sous-répertoires
Dans cette procédure de création d’un compte, je suggère d’ajouter, pour le webmail, la création des répertoires habituels d’un compte en IMAP. Si vous ne comptez livrer que des boîtes récupérables en POP, ne vous cassez pas la tête, c’est inutile.
Sinon :
su - vmail cd /vmailboxes/mxtest.mondomaine.fr/jacques for i in Sent Trash Drafts Junk do maildirmake .$i #le . est important done
Vous devriez voir les sous-répertoires .Sent, .Junk etc avec à chaque fois le cur/tmp/new et des permissions restreintes à l’utilisateur vmail.
Voilà , la boîte sait recevoir et postfix sait gérer nos comptes virtuels, pour livrer le courier dans les boîtes virtuelles.
Abonnement aux répertoires IMAP ; pour le webmail ou la consultation IMAP
Si besoin, pensez à inclure la création du fichier suivant dans votre procédure de création de boîte mail :
mxtest:/vmailboxes/mxtest.mondomaine.fr/jacques# cat courierimapsubscribed INBOX INBOX.Sent INBOX.Drafts INBOX.Trash INBOX.Junk
Annexe : création d’un alias
Dans la table forwardings, à base de :
INSERT INTO forwardings VALUES ('mon_alias@bla.fr', 'dest1@toto.fr', 'dest2@tata.fr');
Actif immédiatement. Pas plus compliqué que ça .
Partie lecture des mails, via « courier-* » utilisant MySQL pour l’authentification
Ici, on voit créer les services POP, IMAP et leurs versions sécurisées. Le tout sur fond d’authentification des utilisateurs définis en base MySQL.
Indiquer au « daemon » courier d’utiliser MySQL
Simplement, dans /etc/courier/authdaemonrc
, changer la liste des modules utilisés pour l’authentification :
#authmodulelist="authpam" authmodulelist="authmysql"
Dans /etc/courier/authmysqlrc
, il faut positionner les variables suivantes :
MYSQL_SERVER localhost
MYSQL_USERNAME mail_adm
MYSQL_PASSWORD monpassadmin
MYSQL_PORT 0
MYSQL_DATABASE postfix
MYSQL_USER_TABLE users
MYSQL_CRYPT_PWFIELD password
MYSQL_UID_FIELD 5000
MYSQL_GID_FIELD 5000
MYSQL_LOGIN_FIELD email
MYSQL_HOME_FIELD « /vmailboxes »
MYSQL_MAILDIR_FIELD CONCAT(SUBSTRING_INDEX(email,'@',-1),’/',SUBSTRING_INDEX(email,'@',1),’/')
#MYSQL_NAME_FIELD name # NE PAS LAISSER CETTE VARIABLE, voir plus bas, cas d’erreur pour moi
Ici, bien évidemment, les valeurs indiquées reflètent les noms choisis en base.
Générer les certificats pour le POP3S et IMAPS
Cette partie est optionnelle, si vous ne voulez pas du POP3S et IMAPS. Dans ce cas vous pouvez aussi désinstaller courier-*-ssl
.
On modifie les fichiers de conf de génération des certificats des daemon POP et IMAP sécurisés :
mxtest:/etc/courier# cat pop3d.cnf RANDFILE = /usr/lib/courier/pop3d.rand [ req ] default_bits = 1024 encrypt_key = yes distinguished_name = req_dn x509_extensions = cert_type prompt = no [ req_dn ] C=FR ST=France L=PARIS O=Courier Mail Server OU=Automatically-generated POP3 SSL key CN=mondomaine.fr emailAddress=certif@mondomaine.fr [ cert_type ] nsCertType = server
Et pour, l’IMAP :
mxtest:/etc/courier# cat imapd.cnf RANDFILE = /usr/lib/courier/imapd.rand [ req ] default_bits = 1024 encrypt_key = yes distinguished_name = req_dn x509_extensions = cert_type prompt = no [ req_dn ] C=FR ST=France L=PARIS O=Courier Mail Server OU=Automatically-generated IMAP SSL key CN=mondomaine.fr emailAddress=certif@mondomaine.fr [ cert_type ] nsCertType = server
Et on génère les certificats à partir de ces modèles. Ca ne fait que connaître à l’avance certains paramètres :
mxtest:/etc/courier# mkimapdcert cp: not writing through dangling symlink `/usr/lib/courier/imapd.pem' chmod: cannot operate on dangling symlink `/usr/lib/courier/imapd.pem' chown: ne peut effectuer une déférence sur `/usr/lib/courier/imapd.pem': Aucun fichier ou répertoire de ce type Generating a 1024 bit RSA private key ................++++++ ....++++++ writing new private key to '/usr/lib/courier/imapd.pem' ----- 1024 semi-random bytes loaded Generating DH parameters, 512 bit long safe prime, generator 2 This is going to take a long time ..............+.....................................................................................+..+..................... .........+.............................+....+...+........+................................................................... .............+..........+...........+..+...+..............................+....................+......................+...... ........................+.....+.+......+..........................................................+.......................... .........................................................+...........+.........+.......................+..................... ..+..........++*++*++*++*++*++* subject= /C=FR/ST=France/L=PARIS/O=Courier Mail Server/OU=Automatically-generated IMAP SSL key/CN=mondomaine.fr/emailAddress=certif@mondomaine.fr notBefore=Oct 7 15:17:54 2009 GMT notAfter=Oct 7 15:17:54 2010 GMT SHA1 Fingerprint=9D:62:E6:CF:B7:39:80:C8:4E:F9:09:9C:61:36:14:8F:0B:EF:3C:6E
Et :
mxtest:/etc/courier# mkpop3dcert cp: not writing through dangling symlink `/usr/lib/courier/pop3d.pem' chmod: cannot operate on dangling symlink `/usr/lib/courier/pop3d.pem' chown: ne peut effectuer une déférence sur `/usr/lib/courier/pop3d.pem': Aucun fichier ou répertoire de ce type Generating a 1024 bit RSA private key ..++++++ ..................++++++ writing new private key to '/usr/lib/courier/pop3d.pem' ----- 1024 semi-random bytes loaded Generating DH parameters, 512 bit long safe prime, generator 2 This is going to take a long time ...............+..........................++*++*++*++*++*++* subject= /C=FR/ST=France/L=PARIS/O=Courier Mail Server/OU=Automatically-generated POP3 SSL key/CN=mondomaine.fr/emailAddress=certif@mondomaine.fr notBefore=Oct 7 15:18:10 2009 GMT notAfter=Oct 7 15:18:10 2010 GMT SHA1 Fingerprint=DD:8D:7C:0D:87:9D:19:9D:62:BE:5B:9A:B2:D8:43:80:CF:47:E2:14
Redémarrer tout ce bazar
Ayé, tout est prêt, les certificats sont générés, on redémarre tout ce monde :
/etc/init.d/courier-authdaemon restart /etc/init.d/courier-imap restart /etc/init.d/courier-imap-ssl restart /etc/init.d/courier-pop restart /etc/init.d/courier-pop-ssl restart
Tests pour l’envoi, quelques erreurs analysées
Déjà , faites un telnet sur chaque port, 143, 993, 110, 995 pour voir si ça répond bien.
Ensuite, testez chaque protocole. Par exemple avec Thunderbird. Sur un poste Windows, pensez à la version « portable » qui n’interfèrera pas avec votre actuel Thunderbird. Sous Linux, vous pouvez jouer avec vos ~/.mozilla-thunderbird (j’ai plus le nom précis en tête) pour ne pas abîmer votre conf actuelle.
Erreurs rencontrées
Ces erreurs m’ont permis de découvrir la commande authtest pour faire des tests d’aut
Oubli de package
J’ai commencé par tester l’authentification IMAP en local (depuis un webmail, roundcube, installé sur la même machine). Ca ne passait pas. J’ai testé depuis Thunderbird, pareil (pas étonnant), mais cette fois ça a généré un message dans les logs, genre syslog
ou mail.info
je ne sais plus :
Oct 8 16:10:32 ns305192 authdaemond: libauthmysql.so: cannot open shared object file: No such file or directory
Oops, il manquait le package courier-authlib-mysql
.
Heureusement, ce ne sera pas votre cas, c’est bien écrit dans le aptitude install
du début.
Erreur sur MYSQL_NAME_FIELD
Ensuite, j’ai eu le droit à une vraie erreur :
Oct 8 16:53:56 serveur imapd: authentication error: Input/output error
C’est l’occasion de mentionner la commande authtest
(faites man authtest
. Ca peut aider :
authtest ducon@lajoie.fr monpasswd Authentication FAILED: Input/output error
Activez le debug dans /etc/courier/authdaemonrc
avec DEBUG_LOGIN=1, redémarrez le service et allez voir les logs. Ca m’a permis de voir les erreurs SQL :
Oct 8 18:39:21 ns305192 authdaemond: mysql_query failed, reconnecting: Unknown column 'name' in 'field list'
En cherchant un peu, j’ai vu qu’il restait le champ MYSQL_NAME_FIELD dans /etc/courier/authdaemonrc
. Une fois modifié, ça passe :
mxtest:/etc/courier# !auth authtest bla@bla.fr monpassword Authentication succeeded. Authenticated: bla@bla.fr (uid 5000, gid 5000) Home Directory: /vmailboxes Maildir: mondomaine.fr/jacques/ Quota: (none) Encrypted Password: OXXXXgfT0lXjI Cleartext Password: monpassword Options: (none)
A ce moment là, tout marche pour la récupération, webmail aussi (puisque IMAP aussi).
Partie authentification des utilisateurs, pour l’envoi
Pour bien comprendre, on va activer 2 modes : SASL et TLS – encore que le mode TLS reste optionnel. Vous pourriez dans ce cas désinstaller les paquets concernés.
Le premier (SASL) pour avoir un mécanisme d’authentification pour le SMTP « normal », port 25.
Le deuxième (TLS) pour avoir un mécanisme plus sécurisé, avec certificat etc, en TLS (anciennement SMTPS, ou SMTP avec SSL). C’est aussi sur le port 25 (pas 465), et, de ce que j’en ai compris, ça tend à remplacer le SMTPS, sur port 465. C’est expliqué là et j’ai peut-être un peu abrégé l’explication violemment.
Paramétrage de toute la chaîne postfix/sasl/pam/mysql
Pour ne pas se perdre, il faut comprendre que postfix va déléguer l’authentification à une couche d’abstraction, SASL. On va dire à SASL de se baser sur le mécanisme PAM (Pluggable Authentication Module) et on va dire à PAM de contrôler les logins/passwords dans une base MySQL, en lui décrivant cette base. Pigé ?
Dire à SASL d’utiliser PAM pour l’authentification
SASL est chrooté (je ne me souviens plus bien, mais c’est le boxon, j’ai dû en parler dans des posts précédents)
On crée son environnement de « chroot » :
mkdir --parents /var/spool/postfix/var/run/saslauthd
Ensuite, on paramètre le daemon SASL correctement :
Positionner START=yes
dans /etc/default/saslauthd
et modifier la fin du fichier comme suite :
#OPTIONS="-c -m /var/run/saslauthd" OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"
Le reste du fichier par défaut doit être bon (DESC= »SASL Authentication Daemon », NAME= »saslauthd », MECHANISMS= »pam », MECH_OPTIONS= »", THREADS=5).
Vous pourrez voir au passage qu’on indique (via le paramètre MECHANISMS) à SASL d’utiliser PAM.
Maintenant, on va dire à PAM d’utiliser MySQL.
Demander à PAM d’utiliser MySQL en décrivant notre structure
Dans /etc/pam.d/smtp
(à créer je crois), on indique qu’on va utiliser le module MySQL pour PAM :
mxtest:/etc/pam.d# cat smtp auth required pam_mysql.so user=mail_adm passwd=monpassadmin host=127.0.0.1 db=postfix table=users usercolumn=email passwdcolumn=password crypt=1 account sufficient pam_mysql.so user=mail_adm passwd=monpassadmin host=127.0.0.1 db=postfix table=users usercolumn=email passwdcolumn=password crypt=1
Ensuite, dire à postfix de faire confiance à SASL pour l’authentification
Maintenant que SASL sait faire le boulot en base de données, on configure postfix pour authentifier les utilisateurs via SASL/PAM/MYSQL.
Dans /etc/postfix/sasl/
, s’assurer du contenu de smtpd.conf
:
pwcheck_method: saslauthd mech_list: plain login allow_plaintext: true auxprop_plugin: mysql sql_hostnames: 127.0.0.1 sql_user: mail_adm sql_passwd: monpassadmin sql_database: postfix sql_select: select password from users where email = '%u'
Ajoutez l’utilisateur postfix au groupe sasl :
adduser postfix sasl
Enfin, expliquer à postfix de bien vouloir relayer les envois d’utilisateurs authentifiés via SASL. Ce qui donne par exemple dans /etc/postfix/main.cf
:
smtpd_sender_restrictions = permit_sasl_authenticated reject_unauth_pipelining permit_mynetworks reject_unauth_destination reject_unknown_sender_domain reject_non_fqdn_sender check_policy_service inet:127.0.0.1:60000
C’est surtout le « permit_sasl_authenticated » qui nous intéresse là.
Voilà, postfix sait maintenant contrôler les expéditeurs avec l’aide de SASL. Ils doivent se signer et exister dans la base.
Maintenant on met en place le TLS, si vous voulez utiliser du vrai cryptage SSL pour l’authentification.
TLS : certificat et configuration
Dans /etc/postfix/
,on crée les clefs de cryptage :
mxtest:/etc/postfix# openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509 Generating a 2048 bit RSA private key ................................................+++ ................................................+++ writing new private key to 'smtpd.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:FR State or Province Name (full name) [Some-State]:France Locality Name (eg, city) []:PARIS Organization Name (eg, company) [Internet Widgits Pty Ltd]:MASOCIETE Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:mondomaine.fr Email Address []:certif@mondomaine.fr
IMPORTANT : le « Common Name » doit correspondonre à votre /etc/mailname
Protégez la clef privée : chmod 640 smtpd.key
J’ai mis 10 ans, on aurait pu mettre plus ou moins, c’est le paramètre 3650 dans la ligne de commande.
On ajoute pour finir la conf suivante pour activer le TLS et indiquer le certificat à utiliser. Dans /etc/postfix/main.cf
toujours :
smtpd_tls_cert_file=/etc/postfix/smtpd.cert smtpd_tls_key_file=/etc/postfix/smtpd.key smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes # à voir, ça peut interdire certains outlook buggés, je crois, de tête. smtpd_sasl_authenticated_header = yes
C’est fini, on relance tout ça
Redémarrez postfix et saslauthd via les /etc/init.d/saslauthd restart
et /etc/init.d/postfix restart
qui vont bien.
Tests pour l’envoi, quelques erreurs analysées
Après un rapide telnet sur le port 25 (quand même), testez avec un « ehlo mailhost » puor voir si le TLS est activé :
250-STARTTLS
Ensuite, comme pour la réception des mails, testez avec un client mail correct, en mode SMTP normal et avec TLS.
Erreurs rencontrées
Fausse manip dans /etc/pam.d/smtp
Tous les tests SMTP, avec et sans TLS étaient KO. Dans les logs, simplement ça :
Oct 14 13:52:39 ns305192 postfix/smtpd[6759]: connect from bla.fr[81.Y.67.X] Oct 14 13:52:41 ns305192 postfix/smtpd[6759]: warning: SASL authentication failure: Password verification failed Oct 14 13:52:41 ns305192 postfix/smtpd[6759]: warning: bla.fr[81.Y.67.X]: SASL PLAIN authentication failed: authentication failure Oct 14 13:52:41 ns305192 postfix/smtpd[6759]: warning: bla.fr[81.Y.67.X]: SASL LOGIN authentication failed: authentication failure Oct 14 13:52:43 ns305192 postfix/smtpd[6759]: disconnect from bla.fr[81.Y.67.X]
Je me souviens avoir utilisé saslfinger
pour tester et debugger. Essayez-le.
Au final, je m’étais simplement trompé dans le mot de passe MySQL du fichier /etc/pam.d/smtp
Quotas
Sujet totalement optionnel. J’ai besoin dans mon cas de pouvoir affecter des quotas par utilisateur.
Postfix ne gère pas les quotas nativement, il faut appliquer un patch. Donc recompiler. Ou trouver une source, mais au niveau mise à jour de sécurité, vous dépendez alors du type qui maintient le dépôt.
J’ai préféré appliquer moi-même le patch.
Le patch est donné par ce projet : http://vda.sourceforge.net. Il est disponible pour toutes les versions postfix, notamment la 2.5.5, actuellement celle de Debian/Lenny. 32 ou 64 bits.
Ajout du dépôt de sources
D’abord, dans mon cas, j’ajoute un dépôt de sources, via la ligne suivante dans /etc/apt/sources.list
:
deb-src ftp://ftp2.fr.debian.org/debian/ lenny main
Après un aptitude update
, on va télécharger les sources et tout le bazar pour compiler.
Récupération des sources
serv:/etc/postfix# apt-get build-dep postfix Lecture des listes de paquets... Fait Construction de l'arbre des dépendances Lecture des informations d'état... Fait Les NOUVEAUX paquets suivants seront installés : build-essential comerr-dev debhelper dpkg-dev g++ g++-4.3 gettext hardening-wrapper html2text intltool-debian libcdb-dev libcdb1 libdb-dev libdb4.6-dev libfile-remove-perl libkadm55 libkrb5-dev libldap2-dev libmail-box-perl libmail-sendmail-perl libmime-types-perl libmysqlclient15-dev libobject-realize-later-perl libpcre3-dev libpcrecpp0 libpq-dev libsasl2-dev libssl-dev libstdc++6-4.3-dev libuser-identity-perl lsb-release po-debconf tinycdb zlib1g-dev 0 mis à jour, 34 nouvellement installés, 0 à enlever et 0 non mis à jour. Il est nécessaire de prendre 22,7Mo dans les archives. Après cette opération, 69,1Mo d'espace disque supplémentaires seront utilisés. Souhaitez-vous continuer [O/n] ?
Ensuite, on récupère les sources de postfix :
serv:/etc/postfix# cd /usr/src serv:/usr/src# apt-get source postfix
Ca download et décompresse (et gueule car je n’ai pas mis la clef GPG blablabla pour vérifier la signature du paquet, tout ça).
Récupération du patch, compilation
On récupère le patch qui va bien pour notre version postfix et on génère les .deb
cd /usr/src wget http://vda.sourceforge.net/VDA/postfix-2.5.5-vda-ng.patch.gz gunzip postfix-2.5.5-vda-ng.patch.gz cd postfix-2.5.5 patch -p1 < ../postfix-2.5.5-vda-ng.patch dpkg-buildpackage
Remplacement du postfix officiel
Une fois placé dans /usr/src, un simple dpkg -i postfix_2.5.5-1.1_i386.deb postfix-mysql_2.5.5-1.1_i386.deb
suffit à remplacer postfix et son extension mysql. Ca ne flingue même pas la conf actuelle. Bref, nickel.
On ajoute le champ quota, on indique à postfix et courierauth
Dans la base de données, on ajoute la colonne. J'ai choisi 20 Mo par défaut.
mysql> alter table users add quota bigint (20) default '20971520' after password; Query OK, 1 row affected (0.10 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> desc users; +----------+-------------+------+-----+----------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+----------+-------+ | email | varchar(80) | NO | PRI | NULL | | | password | varchar(20) | NO | | NULL | | | quota | bigint(20) | YES | | 20971520 | | +----------+-------------+------+-----+----------+-------+ 3 rows in set (0.00 sec)
Le alter s'est occupé de mettre la valeur par défaut sur les comptes existants
On crée alors la requête qui vérifie les quotas :
mxtest:~# cat /etc/postfix/mysql-virtual_mailbox_limit_maps.cf user = mail_adm password = monpassadmin dbname = postfix query = SELECT quota FROM users WHERE email='%s' hosts = 127.0.0.1
Pensez à priver l'accès à ce fichier.
Et on ajoute cette notion de limite dans notre postfix-qui-sait-gérer-les-quotas, dans /etc/postfix/main.fr
:
virtual_mailbox_limit_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_limit_maps.cf virtual_mailbox_limit_override = yes virtual_maildir_limit_message = "The user you are trying to reach is over quota - L'utilisateur que vous cherchez a contacter a depasse son quota de mails" virtual_overquota_bounce = yes
Sans oublier d'ajouter "$virtual_mailbox_limit_maps
" dans la variable "proxy_read_maps
".
Indication des quotas à "courier"
On précise à courier qu'il y a des quotas en créant ou décommentant la variable suivante :
mxtest:~# grep quota /etc/courier/authmysqlrc MYSQL_QUOTA_FIELD quota
On recharge le tout, on teste, on se congratule. Youpi, c'est fini.
Ce que je n'ai pas traité
j'ai pas joué avec les transports
Pas besoin dans mon cas.
Avoir un procmailrc par utilisateur ?
Aucune idée, je verrai plus tard.
En effet, où doit-on stocker le .procmailrc ??? ou alors faire un /etc/procmailrc général qui éventuellement trie par destinataire... lourd.
Désactivation de protocole par utilisateur
Exemple, besoin de désactiver le webmail ou le POP pour un utilisateur ? A priori, avec les "critères supplémentaires" que l'on peut passer dans les fichiers .cf de description de requêtes, ça doit être jouable. Je n'ai pas cherché car pas encore eu besoin.
Evidemment, il faudra ajouter une/des colonne dans la table, sûrement un booléen indiquant si le protocole est accepté pour l'utilisateur X.
Alerte sur les dépassements de quota
Pas eu encore le temps, mais il faudra y penser pour détecter les boulets qui ont des boîtes pleines et ne comprennent pas pourquoi ils ne reçoivent rien.
Je n'ai pas encore regardé : chapitre 11 dans cette page.
Voilà, j'espère que ça roulera pour votre installation et que vous aurez ainsi une belle plateforme de mails.