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é.
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.
Pour les serveurs RPS d’OVH, 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 [[http://www.serveur-rps.fr/manager_ovh/services#reverse|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 serveur, 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
- eth0:0 est l’IP failover
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 *****.