Installation Postfix sur Etch

De wikiGite

Installation d'un serveur Postfix sur Debian Etch

Avec comptes virtuels sous MySQL, SASL/TLS, courier, spamassassin, clamav

Install de base Debian dans une VM

Chargement d'une iso Debian

wget ftp://ftp.proxad.net/mirrors/cdimage.debian.org/debian-cd/current/i386/iso-cd/debian-40r5-i386-netinst.iso

Création de la VM en bootant sur l'ISO. Le disque (10G) est partitionné en LVM, avec /home séparé (en prévision d'éventuels quotas disque, sachant que les quotas des BAL seront gérés en virtuel par Postfix).
Install de base, on verra exactement ensuite ce qui est nécessaire.

Première chose à faire : installer et paramétrer ssh

apt-get install openssh-server

pour pouvoir se connecter via un terminal plus convivial que la console vmware.

Postfix sur MySQL

L'idée est d'utiliser une base MySQL pour conserver les infos des comptes mails, plutôt que des fichiers plats.
Install Postfix, mysql et procmail

apt-get install postfix postfix-mysql mysql-server mysql-common mysql-client procmail libsasl2 sasl2-bin libsasl2-modules libdb3-util libpam-mysql openssl

Installer Postfix en "site internet" et donner le nom du serveur.

En vue de la gestion des quotas sur les comptes virtuels, il faut patcher Postfix. On télécharge les sources :

apt-get install build-essential dpkg-dev fakeroot debhelper libgdbm-dev libldap2-dev libpcre3-dev libssl-dev libsasl2-dev postgresql-dev po-debconf dpatch libdb4.3-dev libmysqlclient15-dev lsb-release libcdb-dev
cd /usr/src
apt-get source postfix

Patch Postfix:

wget http://vda.sourceforge.net/VDA/postfix-2.3.8-vda.patch.gz
gunzip postfix-2.3.8-vda.patch.gz
cd postfix-2.3.8
patch -p1 < ../postfix-2.3.8-vda.patch
dpkg-buildpackage

Installation de Postfix patché :

cd /usr/src && dpkg -i postfix_2.3.8-2_i386.deb
cd /usr/src && dpkg -i postfix-mysql_2.3.8-2_i386.deb

Modifier /etc/postfix/main.cf.

  • Les paramètres de base (nom du serveur dans les mails, utilisation de Maildir...)
postconf -e 'myhostname = server1.example.com'
postconf -e 'inet_interfaces = all'
postconf -e 'home_mailbox = Maildir/'
  • Pour le support MySQL :
postconf -e 'relay_domains = proxy:mysql:/etc/postfix/mysql_relay_domains_maps.cf'
postconf -e 'virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf'
postconf -e 'virtual_gid_maps = static:20001'
postconf -e 'virtual_mailbox_base = /home/virtual'
postconf -e 'virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf'
postconf -e 'virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf'
postconf -e 'virtual_minimum_uid = 20001'
postconf -e 'virtual_uid_maps = static:20001'
postconf -e '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 $smtpd_recipient_restrictions $smtpd_sender_login_maps'
  • Pour le support des quotas :
postconf -e 'virtual_create_maildirsize = yes'
postconf -e 'virtual_mailbox_extended = yes'
postconf -e 'virtual_mailbox_limit_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_limit_maps.cf'
postconf -e 'virtual_mailbox_limit_override = yes'
postconf -e 'virtual_maildir_limit_message = "The user you are trying to reach is over quota."'
postconf -e 'virtual_overquota_bounce = yes'

Plutôt que d'utiliser des fichiers plats (hash:) on utilise des requêtes dans la base Mysql (proxy:mysql:). Les fichiers sont créés ainsi :

  • mysql_relay_domains_maps.cf
user = postfix
password = ****
hosts = 127.0.0.1
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1' and active = '1'
  • mysql_virtual_alias_maps.cf
user = postfix
password = ****
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' and active = '1'
  • mysql_virtual_domains_maps.cf
user = postfix
password = ****
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '0' and active = '1'
  • mysql_virtual_mailbox_maps.cf
user = postfix
password = ****
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE email='%s' and active = '1'
  • mysql_virtual_mailbox_limit_maps.cf
user = postfix
password = ****
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE email=’%s’ and active = '1'

Note1 : Postfix doit pouvoir lire ces fichiers. Donc :

chmod 640 mysql_*
chgrp postfix mysql_*

Note2 : Les utilisateurs étant virtuels (créés dans la base mais pas sur le système), il faut tout de même stocker les mails quelque part. Le répertoire qui recevra leurs boites aux lettres est "virtual_mailbox_base = /home/virtual" : s'assurer qu'il existe et appartient à Postfix.

TODO  : comment fonctionne le multi-domaine avec mysql ?

SASL/TLS

Pour l'envoi de mails, si l'utilisateur qui passe par ce serveur pour envoyer ses mails a une adresse IP fixe, il suffit de préciser son adresse dans l'option "mynetworks" du main.cf. S'il est en adressage dynamique, il faut mettre en place une authentification de type SASL, sur TLS (pour le cryptage de la session, indispensable !).
SASL et TLS dans main.cf:

postconf -e 'smtpd_sasl_local_domain ='
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'smtpd_sasl_security_options = noanonymous'
postconf -e 'broken_sasl_auth_clients = yes'
postconf -e 'smtp_use_tls = yes'
postconf -e 'smtpd_use_tls = yes'
postconf -e 'smtpd_tls_auth_only = no'
postconf -e 'smtp_tls_note_starttls_offer = yes'
postconf -e 'smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key'
postconf -e 'smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt'
postconf -e 'smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem'
postconf -e 'smtpd_tls_loglevel = 1'
postconf -e 'smtpd_tls_received_header = yes'
postconf -e 'smtpd_tls_session_cache_timeout = 3600s'
postconf -e 'tls_random_source = dev:/dev/urandom'

Décommenter aussi ces lignes dans master.cf :

submission	  inet	n	-	-	-	-	smtpd 
   -o smtpd_tls_security_level=encrypt
   -o smtpd_sasl_auth_enable=yes
   -o smtpd_etrn_restrictions=reject
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject

Note 1 : "submission" correspond au port 587, vérifier qu'il est bien référencé comme tel dans /etc/services.
Note 2 : l'option smtpd_etrn_restrictions peut manquer, penser à l'ajouter.
Note 3 : Le port 587 n'est pas standard pour certains client mails (exemple : Evolution) car le port par défaut est 465 (mail il est utilisé aujourd'hui par des backdoors et autres trojan, donc considéré comme douteux). Dans le paramétrage du client, pour serveur d'envoi de mail, il faut forcer ce port en l'ajoutant au nom du serveur (sous la forme "nom_serveur.mail:587"), et choisir l'authentification TLS en plain text. Note 4 : Si certaine options sont en double entre main.cf et les "-o" de master.cf, ce n'est pas grave : garder simplement à l'esprit que la valeur paramètre de master.cf écrase celle de main.cf.

Créer également le fichier /etc/postfix/sasl/smtpd.conf, pour qu'il utilise la base mysql (mettre le user et password mysql):

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

ATTENTION : Postfix par défaut est chrooté (ce qui est parfait !), mais pour discuter avec le démon SASL il faut qu'il accède au socket. Pour ça, créer un répertoire dans le chroot :

mkdir -p /var/spool/postfix/var/run/saslauthd

Et indiquer à saslauthd d'y poser son fichier de socket, dans /etc/default/saslauthd, remplacer la ligne OPTION :

OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"

Les autres options doivent être :

START=yes
MECH_OPTIONS=""
MECHANISMS="pam"
THREADS=5

Créer un fichier /etc/pam.d/smtp pour lier pam à mysql (pensez à mettre le bon user et password !):

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

Et sécuriser :

chmod 640 /etc/pam.d/smtp

Tester l'authentification SASL

testsaslauthd -u test -p test -s smtp

Un peu de sécurité sur Postfix

en plus des options propres à sasl :

postconf -e 'message_size_limit = 50240000'
postconf -e 'smtpd_helo_required = yes'
postconf -e 'smtpd_data_restrictions = reject_unauth_pipelining, permit'

Pour restreindre les destinataires (champ RCPT TO) :

postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'

On peut aller jusqu'au rejet des mails dont le champ MAIL FROM ne contient pas de domaine identifiable (enregistrement DNS ou MX) ou des serveur qui envoient un mauvais HELO. Attention, c'est sévère et peut occasionner des faux-positifs (MAIL FROM reformattés venant d'outils d'alerte/monitoring, par exemple)

postconf -e 'smtpd_sender_restrictions = permit_sasl_authenticated,permit_mynetworks,,reject_unauth_destination, reject_unknown_sender_domain, reject_non_fqdn_sender, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname'

Ou alors, au avec des BL

postconf -e 'smtpd_recipient_restrictions =
   reject_invalid_hostname,
   reject_unknown_recipient_domain,
   reject_unauth_pipelining,
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_unauth_destination,
   reject_rbl_client multi.uribl.com,
   reject_rbl_client dsn.rfc-ignorant.org,
   reject_rbl_client dul.dnsbl.sorbs.net,
   reject_rbl_client list.dsbl.org,
   reject_rbl_client sbl-xbl.spamhaus.org,
   reject_rbl_client bl.spamcop.net,
   reject_rbl_client dnsbl.sorbs.net,
   reject_rbl_client cbl.abuseat.org,
   reject_rbl_client ix.dnsbl.manitu.net,
   reject_rbl_client combined.rbl.msrbl.net,
   reject_rbl_client rabl.nuclearelephant.com,
   permit'


Note : A garder à l'esprit, l'utilisation de blacklists directement dans ce champ, en ajoutant

reject_rbl_client zen.spamhaus.org,
reject_rbl_client bl.spamcop.net

Spamhaus est gratuit pour un usage privé et payant pour un usage commercial (et il inclut désormais la liste cbl.abuseat.org), SpamCop est gratuit. ça permet d'éliminer les spams qu'ils listent dès l'arrivée, mais attention à ce que ce ne soit pas trop !
Sur http://www.spamhaus.org/ZEN/ et http://www.spamcop.net/bl.shtml, on peut vérifier si certaines IP sont blacklistées.

On créé les certificats SSL dont TLS va avoir besoin.

mkdir /etc/postfix/ssl
cd /etc/postfix/ssl
openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509
chmod 644 /etc/postfix/smtpd.key

On redémarre tout

/etc/init.d/postfix restart
/etc/init.d/saslauthd restart

Les outils complémentaires

  • Cache DNS: le serveur mail faisant une utilisation abondante des DNS. L'installation de base sous Debian propose un serveur cache, on a donc rien à faire :
apt-get install bind9

Faire pointer le resolv.conf en local

nameserver 127.0.0.1
search systea.net

Puis on teste la résolution

ping www.google.fr
  • Notification des quotas: un récap des quotas utilisateurs avec envoi d'une alerte au compte (normalement, Postfix ne renvoie un message de dépassement qu'aux expéditeurs, pas au propriétaire de la BAL).
    • Copier le fichier quota_notify.pl (Télécharger) sur le serveur, et le planifier toutes les heures (cron.hourly). Editer le fichier et modifier les variables selon la config (nom de l'expéditeur du mail récap, etc...).

Courier

Courier va être le serveur POP et IMAP. Il se charge égalementd de l'authentification via courier-authdaemon, à qui il faut dire qu'on utilise une base Mysql.

apt-get install courier-authdaemon courier-authmysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl

On édite /etc/courier/authdaemonrc pour qu'il utilise Mysql :

authmodulelist="authmysql"

Puis on édite /etc/courier/authmysqlrc, qui doit ressembler à ça (mettre les bons user et password mysql):

MYSQL_SERVER	localhost
MYSQL_USERNAME	postfix
MYSQL_PASSWORD	****
MYSQL_PORT	0
MYSQL_DATABASE	postfix
MYSQL_USER_TABLE	mailbox
MYSQL_CRYPT_PWFIELD	password
#MYSQL_CLEAR_PWFIELD	password
MYSQL_UID_FIELD	5000
MYSQL_GID_FIELD	5000
MYSQL_LOGIN_FIELD	email
MYSQL_HOME_FIELD	"/home/virtual"
#Sous MYSQL_HOME_FIELD, on construit un répertoire unique par compte à partir de l'adresse mail
MYSQL_MAILDIR_FIELD	CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
#MYSQL_NAME_FIELD
MYSQL_QUOTA_FIELD	quota

Note : Attention à ce fichier sensile à la syntaxe, il doit y avoir un TAB entre le champ et sa valeur, et pas d'espace au bout du nom de champ. Puis on sécurise :

chown daemon: authdaemonrc
chmod 660 authdaemonrc
chown daemon: authmysqlrc
chmod 640 authmysqlrc

On redémarre les démons courier :

/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

On teste :

telnet localhost pop3
 +OK Hello there.
quit

MySQL

S'assurer que leur l'hôte local peut s'y connecter. Personne n'a besoin d'y accéder de l'extérieur. Dans /etc/mysql/my.cnf, décommenter :

bind-address            = 127.0.0.1

et redémarrer Mysql

/etc/init.d/mysql restart

On donne un mot de passe au compte administrateur de mysql, et on initialise la base "postfix".

mysqladmin -u root password '*****'
mysqladmin -u root --password='*****' create postfix

Copier le fichier postfix.sql (Télécharger) sur le serveur, et lancer :

sed -i 's/nom_de_domaine.tld/toto.com/g' postfix.sql

en remplaçant évidemment nom_de_domaine.tld par le bon nom de domaine pour ce serveur ! Puis :

mysql -u root -p < postfix.sql

spamassassin et clamav

Installation

apt-get install amavisd-new spamassassin clamav clamav-daemon zoo unzip unarj bzip2

TODO :

Postgrey ou Sqlgrey

Ask

MailInBlack