Postfix avec MySQL et identification SASL (SMTP Auth)

Je vais détailler l'installation du serveur mail Postfix couplé à MySQL pour gérer simplement les domaines et les boites mails des utilisateurs. Ensuite, pour éviter que le serveur Mail ne devienne un relais à spam, il est possible d'utiliser une authentification SMTP pour envoyer des mails, ainsi, lorsqu'un utilisateur voudra envoyer un mail il devra être authentifié.

Article modifié le : 28/02/2008.

Installation de Postfix / MySQL

apt-get install postfix postfix-mysql

Utilisation de l'IP Failover

Avant de commencer ce tutoriel, nous allons configurer Postfix pour qu'il utilise la bonne IP. En effet, le RPS possède 2 IP :

  • 1 IP physique
  • 1 IP failover qui sera identique même si vous changez de serveur

Il faut donc que PostFix utilise l'IP de failover car elle possède un reverse DNS ce qui vous évitera d'avoir des mails classés en SPAM avec l'erreur ”said: 421 Refused. You have no reverse DNS entry”.

Lors d'un ipconfig sur mon RPS 1, voila ce que j'obtiens :

eth0      Lien encap:Ethernet  HWaddr 00:19:D1:86:D4:8C
          inet adr:91.121.193.xxx  Bcast:91.121.193.255  Masque:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6029245 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8890768 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:1273621622 (1.1 GiB)  TX bytes:1861274124 (1.7 GiB)
          Interruption:16 Adresse de base:0x2000

eth0:0    Lien encap:Ethernet  HWaddr 00:19:D1:86:D4:8C
          inet adr:91.121.36.xxx  Bcast:91.255.255.255  Masque:255.255.255.255
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interruption:16 Adresse de base:0x2000
  • eth0 est l'IP physique rattaché à mon serveur, d'ailleurs il s'agit des 1ers serveurs livrés caractérisés par une IP qui contient .193.
  • eth0:0 est l'IP failover qui ne changera jamais et sera rattaché à mon compte OVH.

Pour que PostFix utilise l'IP failover il faut modifier le fichier /etc/postfix/main.cf et la variable inet_interfaces qui devra être égale à l'IP Failover :

nano /etc/postfix/main.cf

inet_interfaces = 91.121.36.xxx

Création des tables MySQL

Dans PhpMyAdmin (guide d'installation de PhpMyAdmin), nous allons créer les tables qui vont contenir les boîtes mails, les domaines, les alias :

CREATE TABLE `alias` (
`address` varchar(255) NOT NULL default '',
`goto` text NOT NULL,
`domain` varchar(255) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`modified` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
PRIMARY KEY  (address)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Aliases';

CREATE TABLE `domain` (
`domain` varchar(255) NOT NULL default '',
`description` varchar(255) NOT NULL default '',
`aliases` int(10) NOT NULL default '0',
`mailboxes` int(10) NOT NULL default '0',
`maxquota` int(10) NOT NULL default '0',
`transport` varchar(255) default NULL,
`backupmx` tinyint(1) NOT NULL default '0',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`modified` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
PRIMARY KEY  (domain)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Domains';

CREATE TABLE `mailbox` (
`username` varchar(255) NOT NULL default '',
`password` varchar(255) NOT NULL default '',
`name` varchar(255) NOT NULL default '',
`maildir` varchar(255) NOT NULL default '',
`quota` int(10) NOT NULL default '0',
`domain` varchar(255) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`modified` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
PRIMARY KEY  (`username`)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Mailboxes';

Création d'un utilisateur qui va contenir les boîtes Mails

Création d'un groupe Mail et création des utilisateurs :

groupadd -g 5000 grpmail
useradd -g grpmail -u 5000 usermail -d /usr/local/virtual -m

Les boîtes sont stockées dans /usr/local/virtual et l'utilisateur doit recevoir un email pour activer sa boite.

De plus, il n'a pas besoin d'accès SSH donc :

nano /etc/passwd

usermail:x:5000:5000::/usr/local/virtual:/bin/false

Configuration de Postfix : ajout de la gestion MySQL

Modification du fichier de configuration pour ajouter la gestion MySQL :

	nano /etc/postfix/main.cf

# Support Mysql
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:5000
virtual_mailbox_base = /usr/local/virtual
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_limit = 51200000
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 5000
virtual_transport = virtual
virtual_uid_maps = static:5000
# Support du quota
#virtual_create_maildirsize = yes
#virtual_mailbox_extended = yes
#virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
#virtual_mailbox_limit_override = yes
#virtual_maildir_limit_message = Desole, la boite email de l'utilisateur est pleine, essayez plus tard.
#virtual_overquota_bounce = yes

# Suport du relay
relay_domains = mysql:/etc/postfix/mysql_relay_domains_maps.cf

Fichiers pour l'accès à MySQL

Création des fichiers qui vont se connecter à MySQL :

	nano /etc/postfix/mysql_virtual_alias_maps.cf

user = root
password = mot_de_passe
hosts = 127.0.0.1
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = 1

	nano /etc/postfix/mysql_virtual_domains_maps.cf

user = root
password = mot_de_passe
hosts = 127.0.0.1
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
#query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '0' and active = '1'

	nano /etc/postfix/mysql_virtual_mailbox_maps.cf

user = root
password = mot_de_passe
hosts = 127.0.0.1
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = 1

	nano /etc/postfix/mysql_virtual_mailbox_limit_maps.cf

user = root
password = mot_de_passe
hosts = 127.0.0.1
dbname = postfix
query = SELECT quota FROM mailbox WHERE username='%s'

	nano /etc/postfix/mysql_relay_domains_maps.cf

user = root
password = mot_de_passe
hosts = 127.0.0.1
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1'

Modification des droits pour que Postfix puisse lire les fichiers

Il faut ensuite donner les droits pour que Postfix puisse lire les fichiers de configuration MySQL :

chmod 640 mysql_*
chgrp postfix mysql_*

Déchrooter Postfix

Pour le bon fonctionnement, il faut déchrooter Postfix (avec le SMTP Auth activé, j'avais cette erreur : ” postfix/smtpd[10776]: warning: SASL authentication failure: cannot connect to saslauthd server: No such file or directory”) pour que tout fonctionne.

Il faut mettre ”n” dans la colonne ”chroot” à la ligne ”smtp” :

nano /etc/postfix/master.cf

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd

Sécurisation et suppression des mails non conformes

Postfix va effectuer un 1er tri pour supprimer les mails qui sont mal formatés par les spammeurs ou autres “bots” mal configuré. Pour chaque ligne rajouté, son explication est donnée en commentaire.

nano /etc/postfix/main.cf

# 	définit la liste des adresses valides du domaine
#relay_recipient_maps = hash:/etc/postfix/relay_recipients
relay_domains = $mydomain
smtpd_client_restrictions = permit_mynetworks

# 	adresses d'expédition forgé avec "MAIL FROM:"
# reject_unknown_sender_domain 	-> rejette le mail si aucun enregistrement DNS A ou MX
# warn_if_reject		-> enregistre avertissement au lieu de suppr le mail "reject_warning"
smtpd_sender_restrictions =
        permit_mynetworks,
        reject_unknown_sender_domain

# 	Restriction d'accès - adresses de destination avec "RCPT TO:"
# reject_unauth_destination 		-> fonctionne avec le fichier : relay_recipient_maps et rejette les domaines non valides
# reject_unknown_recipient_domain	-> rejette le mail si aucun enregistrement DNS A ou MX
# reject_non_fqdn_recipient		-> rejette si "RCPT TO:" est non conforme avec la RFC
smtpd_recipient_restrictions = 
	permit_mynetworks, 
	#reject_unauth_destination,
	reject_unknown_recipient_domain

Installation de SASL (SMPT auth)

Cette partie va obliger les utilisateurs à s'authentifier pour envoyer des mails et donc empêcher que le serveur mail devienne “open relay” pour les spammeurs.

Installation des librairies SASL :

apt-get install libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl

Activation de la gestion SASL dans la configuration Postfix

	nano /etc/postfix/main.cf

# Support SASL
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = 
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_non_fqdn_hostname,
  reject_non_fqdn_sender,
  reject_non_fqdn_recipient,  
  reject_unauth_destination,
  reject_unauth_pipelining,   
  reject_invalid_hostname
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous

Par défaut, SASL lit un fichier pour effectuer la vérification du login et mot de passe afin de valider si l'utilisateur a le droit d'envoyer un email. Comme nous utilisons MySQL, nous allons indiquer à SASL d'utiliser MySQL car la base contient déjà le login et mot de passe de l'utilisateur, ainsi, l'utilisateur aura les mêmes identifications, que se soit pour lire sa boîte mail ou pour envoyer des mails.

Configuration du module d'authentification : saslauthd

nano /etc/default/saslauthd

START=yes
MECHANISMS="pam"
OPTIONS="-r"

Configuration du module PAM et MySQL

	nano /etc/pam.d/smtp

auth       required     pam_mysql.so user=root passwd=mot_de_passe host=127.0.0.1 db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1
account    sufficient   pam_mysql.so user=root passwd=mot_de_passe host=127.0.0.1 db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1

	/etc/init.d/saslauthd restart
	# ajout de SASL au groupe POSTFIX
	adduser postfix sasl

Création de la requête utilisée par SASL pour les informations des utilisateurs lors de l'authentification

	nano /etc/postfix/sasl/smtpd.conf

pwcheck_method: saslauthd auxprop
mech_list: plain login
auxprop_plugin: sql
sql_engine: mysql
sql_hostnames: 127.0.0.1
sql_user: root
sql_database: postfix
sql_passwd: mot_de_passe
sql_select: select password from mailbox where username = '%u@%r'

Installation de Courier POP et IMAP

apt-get install courier-authdaemon courier-authlib-mysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl

Configuration du module d'authentification de COURIER

nano /etc/courier/authdaemonrc

authmodulelist="authpam"	->	authmodulelist="authmysql"

	nano /etc/courier/authmysqlrc

MYSQL_SERVER            127.0.0.1
MYSQL_USERNAME          root
MYSQL_PASSWORD          mot_de_passe

#MYSQL_SOCKET           /var/lib/mysql/mysql.sock
MYSQL_PORT              0
MYSQL_OPT               0

MYSQL_DATABASE          postfix
MYSQL_USER_TABLE        mailbox
MYSQL_CRYPT_PWFIELD     password
#DEFAULT_DOMAIN         domain.tld

MYSQL_UID_FIELD         5000
MYSQL_GID_FIELD         5000

MYSQL_LOGIN_FIELD       username
MYSQL_HOME_FIELD        "/usr/local/virtual"
MYSQL_NAME_FIELD        name
MYSQL_MAILDIR_FIELD     maildir

#MYSQL_QUOTA_FIELD      quota
#MYSQL_WHERE_CLAUSE     server='exemple.domain.tld'

Si vous avez des erreurs, il est possible que le démon affiche plus d'information dans les logs, dès lors, il est possible de voir les requètes MySQL exécutées, les logins et mots de passe utilisés pour débuguer:

nano /etc/courier/authdaemonrc
# modification du mode DEBUG
DEBUG_LOGIN=2
# redémarrage du démon pour afficher plus de logs
/etc/init.d/courier-authdaemon restart

Ainsi, avec une fenêtre qui affiche “tail -f /var/log/mail.log” on voit les requêtes SQL générées, avec les mots de passe, etc, c'est exactement ce qu'il nous faut pour débuguer ! Par exemple, “imapd: authentication error: Input/output error”.

Pour revenir par défaut : DEBUG_LOGIN=0.

Sous Thunderbird : “imapd: LOGIN FAILED” dans les logs → bien vérifier la configuration

Redémarrer les démons

/etc/init.d/postfix restart
/etc/init.d/saslauthd restart
/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

SpamAssassin

SpamAssassin va scanner les mails et supprimer le Spam.

apt-get install spamassassin spamc razor

Configuration du démon SpamAssassin pour qu'il se lance au démarrage :

nano /etc/default/spamassassin

ENABLED=1

Configuration de SpamAssassin :

nano /etc/spamassassin/local.cf

rewrite_header Subject ***** SPAM *****
required_score 5.0
# ne place pas le mail considéré comme SPAM en pièce jointe. Pour activer, mettre "1"
report_safe 0
use_bayes 1
bayes_auto_learn 1
use_razor2              1

	/etc/init.d/spamassassin restart

Création d'un utilisateur qui va stocker dans son répertoire HOME les données de Spamassassin. Puisqu'il n'a pas besoin d'une connexion au shell, nous utilisons l'argument -s /sbin/nologin.

useradd -s /sbin/nologin -d /home/spamuser spamuser
mkdir /home/spamuser
chown -R spamuser:spamuser /home/spamuser

Configuration du fichier master.cf pour que Postfix utilise Spamassassin à chaque mail reçu :

nano /etc/postfix/master.cf

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd -o content_filter=spamassassin

A la fin du fichier master.cf, on rajoute la référence à Spamassassin et l'utilisation de l'utilisateur spamuser (pour stocker les préférences, etc.) :

spamassassin
          unix  -       n       n       -       -       pipe
   user=spamuser argv=/usr/bin/spamc -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Pour prendre en compte les modifications nous redémarrons Postfix :

/etc/init.d/postfix restart

Pour vérifier que tout va bien, il suffit d'envoyer un mail dans la boite mail d'un utilisateur :

tail -f /var/log/mail.log

Feb  2 23:40:37 stock spamd[11594]: spamd: connection from localhost.localdomain [127.0.0.1] at port 39160
Feb  2 23:40:37 stock spamd[11594]: spamd: setuid to spamuser succeeded
Feb  2 23:40:37 stock spamd[11594]: spamd: creating default_prefs: /home/spamuser/.spamassassin/user_prefs
Feb  2 23:40:37 stock spamd[11594]: config: created user preferences file: /home/spamuser/.spamassassin/user_prefs

L'utilisateur spamuser a bien stocké les préférences par défaut de Spamassassin dans son dossier home : /home/spamuser donc tout fonctionne !

Il est possible de faire un test pour vérifier que SpamAssassin détecte bien les spams, il suffit d'envoyer un mail vers le serveur mail (par exemple d'un adresse Gmail) avec dans le sujet la chaine : XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

Dans les logs, la détection se fait bien :

Feb  2 23:45:46 stock spamd[11594]: spamd: identified spam (1001.6/5.0) for spamuser:5001 in 4.7 seconds, 3610 bytes.

Une fois que ThunderBird retire le mail de la boite gérée par Postfix, le champ de l'objet reçoit un entête * SPAM *.

 
mail/installation_de_postfix_avec_mysql_et_sasl_smtp_auth.txt · Dernière modification: 2009/04/26 20:35 (édition externe)
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki