Installation postfix & dovecot

Il y a plein de tutos divers et variés sur l'install d'un postfix + pop + imap avec filtrage, mais je n'en ai pas trouvé qui m'allait (quasi tous avec mysql et amavis), je met donc ici ma conf postfix (MTA) + dovecot (pop/imap/MDA) + spamassassin, sans rien de plus.

Ce qui suit est très inspiré de http://docs.origamix.org/archimail/, mais aussi de http://workaround.org/articles/ispmail-etch/ et http://www.vogelweith.com/debian_server/07_postfix.php

Pour avoir la liste détaillée des options de conf de postfix, mais aussi mieux comprendre comment il fonctionne (organisation des processus), voir http://cjovet.free.fr/cours/postfix.htm, et la doc http://x.guimard.free.fr/postfix/ (version originale).

Tout ce qui suit est livré sans aucune garantie, à vous de savoir ce que vous faites.

C'est d'ailleurs à l'heure actuelle un BROUILLON en cours d'élaboration.

On suppose que le host est myhost.example.com et qu'il gère les mails de example.com et example2.com. Les boites mails au format maildir sont dans /home/mail (puis domaine et user), avec uid:gid 5000:5000 (mailboxes:mailboxes). La conf des domaines et comptes virtuels dans /etc/postfix/virtual/, avec les mots de passe pop/imap dans /etc/postfix/dovecot/users.conf (c'est arbitraire, vous préfèrerez peut être le ranger dans /etc/postfix/virtual/ ou /etc/dovecot).

Rq : pour utiliser une ip particulière (surtout pour sortir par l'ip déclaré dans les MX si vous avez plusieurs ip), modifier le inet_interfaces du main.cf. (cf http://advosys.ca/papers/postfix-instance.html et pour relayer certains domaines vers un autre host http://linuxfr.org/forums)/10/24567.html)

postfix

configuration de base

# install de base
aptitude install postfix postfix-tls mailx
# on choisi "Internet site"
# /etc/aliases => rien, on verra à la main
# Mail name : myhost.example.com
# Other destinations to accept mail for : myhost.example.com localhost
# Force synchronous updates on mail queue : No
# Local networks : 127.0.0.0/8
# Use procmail for local delivery : No
# Mailbox size limit : Ce que vous voulez, en octets (0 = nolimit)
# Local addre Internet protocols to use
# Internet protocols to use : au choix (dans le doute mettez all, si vous n'avez pas d'ipv6, ça mettra juste un warning dans le log au démarrage et continuera comme si vous aviez mis ipv4)
# on teste avec
echo "un test de puis la console"|mail -s "test from tty" root
# et on vérifie que ça marche via syslog ou mail.log et le résultat dans /var/mail/root
# On génère un certificat autosigné
openssl req -new -outform PEM -out /etc/ssl/certs/myhost.pem -newkey rsa:2048 -nodes -keyout /etc/ssl/private/myhost.key -keyform PEM -days 3650 -x509

On va faire qq modif manuelles dans /etc/postfix/main.cf

smtpd_banner = $myhostname ESMTP
delay_warning_time = 4h
myorigin = $myhostname
smtpd_tls_cert_file=/etc/ssl/certs/myhost.pem 
smtpd_tls_key_file=/etc/ssl/private/myhost.key

Ajout des domaines virtuels

Dans /etc/postfix/main.cf, on ajoute

# les users
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

# chemin de base des boites
virtual_mailbox_base = /home/mail
# les domaines virtuels (donc pas dans mydestination), on pourrait les lister sur la ligne ci-dessous séparé par une espace plutôt qu'un par ligne dans un fichier externe
# Si l'on utilise dovecot deliver comme lda, ce qui suit ne sera pas utilisé pour livrer le courrier
# mais postfix va l'utiliser pour refuser le courrier vers un utilisateur inexistant (dès la connexion SMTP)
# cf http://postfix.traduc.org/index.php/postconf.5.html#smtpd_reject_unlisted_recipient
virtual_mailbox_domains = /etc/postfix/virtual/domains
# liste des boites et leur emplacement (relatif à virtual_mailbox_base)
virtual_mailbox_maps = hash:/etc/postfix/virtual/user_mailboxes_path
# et tous les alias d'adresse mail
virtual_alias_maps = hash:/etc/postfix/virtual/user_aliases

On ajoute nos domaines dans /etc/postfix/virtual/domains, les boites dans /etc/postfix/virtual/user_mailboxes_path et les aliases dans /etc/postfix/virtual/user_aliases, puis on oublie pas de recompiler les db à partir de ces fichiers textes (ceux qui sont précédés par hash: dans le fichier de conf, pas la liste des domaines).

# les domaines
echo -e "example.com\nexample2.com\n" > /etc/postfix/virtual/domains
# les boites, avec / à la fin pour le format maildir (mailbox sinon)
echo "user1@example.com example.com/user1/" > /etc/postfix/virtual/user_mailboxes_path
echo "user2@example2.com example2.com/user2/" >> /etc/postfix/virtual/user_mailboxes_path
# et un alias
echo "user3@example2.com user1@example.com" > /etc/postfix/virtual/user_aliases
# on ajoute un alias sur ces domaines virtuels à root (pour que le courrier de root aille dans ces bal et plus dans /var/mail/root)
echo "root: user1@example.com" >> /etc/aliases
# on génère les db
postmap /etc/postfix/virtual/user_mailboxes_path
postmap /etc/postfix/virtual/user_aliases
# et les alias locaux
newaliases # idem "postalias /etc/aliases"
# on créé user & groupe
groupadd -g 5000 mailboxes
useradd -d /home/mail -c "user facteur pour délivrer le courrier dans les mailboxes" -u 5000 -g 5000 -s /dev/null mailboxes
# on fixe les droits
chmod -R 750 /home/mail/
chown -R 5000:5000 /home/mail/
# on recharge la conf
/etc/init.d/postfix reload
# et on vérifie
echo "un 2e test"|mail -s "test2root" root
# si le mx de example.com pointe bien sur myhost.example.com, ça doit arriver dans /home/mail/example.com/user1/new/, noter au passage que postfix a bien créé les répertoires manquants
echo "un 3e test"|mail -s "test2user1" user1@example.com
# si le MX est OK, vous pouvez aussi faire un essai d'envoi via votre FAI, ça doit arriver au même endroit.

Jusque là, tout va bien ;-)

Un peu de restrictions

On ajoute au main.conf

# restrictions smtp  cf http://postfix.traduc.org/index.php/SMTPD_ACCESS_README.html
smtpd_client_restrictions = permit_mynetworks,
  permit_sasl_authenticated,
  reject_unknown_client_hostname,
  reject_unknown_reverse_client_hostname

smtpd_recipient_restrictions = permit_mynetworks,
  permit_sasl_authenticated,
  reject_unauth_destination,
  reject_unknown_recipient_domain,
  reject_non_fqdn_recipient,
 warn_if_reject reject_unverified_recipient

smtpd_sender_restrictions = reject_non_fqdn_sender,
  reject_unknown_sender_domain,
 warn_if_reject reject_unverified_sender
smtpd_helo_restrictions = warn_if_reject reject_invalid_helo_hostname,
 warn_if_reject reject_non_fqdn_helo_hostname,
 warn_if_reject reject_unknown_helo_hostname

# restriction mailbox
# 500Mo max par boite locale
mailbox_size_limit = 512000000
# idem boites virtuelles
virtual_mailbox_limit = 512000000

# restriction sur mails reçus
# 50Mo par mail max
message_size_limit = 50000000
# 50 cc par mail max
smtpd_recipient_limit = 50

cf http://blog.taragana.com/index.php/archive/6-simple-safe-postfix-changes-for-over-95-spam-reduction/fr/ et http://cjovet.free.fr/cours/postfix.htm#IV pour la signification de chacune des restrictions

dovecot

Recevoir du courrier c'est bien, pouvoir le lire c'est mieux.

On va installer dovecot, qui va servir de serveur pop3(s) imap(s) pour que l'on puisse relever ses boîtes aux lettres de l'extérieur.

On utilisera aussi dovecot pour l'authentification SASL puis ensuite on remplacera le lda (Local Delivery Agent) de postfix par celui de dovecot pour bénéficier des règles de filtrage de sieve (plugin inclus dans le paquet dovecot de debian).

aptitude install dovecot-common dovecot-imapd dovecot-pop3d

pop / imap

On commence par modifier /etc/dovecot/dovecot.conf avec

base_dir = /var/run/dovecot/
# les protocoles acceptés
protocols = imap imaps pop3 pop3s

disable_plaintext_auth = no
log_timestamp = "%Y-%m-%d %H:%M:%S "
syslog_facility = mail
mail_location = maildir:/home/mail/%d/%n

auth default {
  mechanisms = plain login digest-md5 cram-md5
  # le lookup de deliver
  userdb static {
    # on met allow_all_users=yes pour éviter le lookup de deliver pour chaque user
    # (postfix a déjà vérifié qu'il pouvait prendre le courrier, donc autant 
    # le distribuer même si ce user n'a pas de compte dovecot)
    args = uid=5000 gid=5000 home=/home/mail/%d/%n/ allow_all_users=yes
  }
  # liste des passwds pour authentification pop/imap
  passdb passwd-file {
    args = /etc/postfix/dovecot/users.conf
  }
}

reste à créer un user/pass et à relancer dovecot

echo "user1@example.com:`dovecotpw -p lemotdepasse`" >> /etc/postfix/dovecot/users.conf
/etc/init.d/dovecot restart

(ou bien utiliser le script addDovecotUserPass) et on peut se logger en pop / imap / pops / imaps et récupérer ses mails (avec authentification sécurisée si on veut)… reste à pouvoir les envoyer en utilisant le smtp avec tls

SASL

Dans /etc/postfix/main.cf (cf Création d'un certificat autosigné pour la creation des certificats)

# Pour authentification smtp
smtpd_sasl_auth_enable = yes  
broken_sasl_auth_clients = yes   
smtpd_sasl_type = dovecot     
# chemin relatif au chroot postfix
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
# permit_sasl_authenticated est déjà dans la liste des smtpd_recipient_restrictions
smtpd_use_tls=yes
smtpd_tls_security_level = may # pour forcer tls mettre encrypt à la place de may
smtpd_tls_cert_file=/etc/ssl/certs/myhost.example.com.crt
smtpd_tls_key_file=/etc/ssl/private/myhost.example.com.key
smtpd_tls_session_cache_database = btree:${queue_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${queue_directory}/smtp_scache  

et dans /etc/dovecot/dovecot.conf on ajoute, dans la section auth default

  socket listen {
    # on exporte une socket dans le chroot de postfix, 
    # pour que postfix puisse utiliser dovecot-sasl pour les authentifications smtp
    client listen {
      path = /var/spool/postfix/private/auth
      mode = 0660
      user = postfix
      group = postfix
    }
  } 

et on relance dovecot et postfix, on peut désormais utiliser notre myhost.example.com comme smtp avec tls.

LDA

On utilise aussi dovecot comme LDA pour profiter de sieve :

  • dans main.cf
# dovecot comme LDA
virtual_transport = dovecot 
dovecot_destination_recipient_limit = 1
  • master.cf
dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=mailboxes:mail argv=/usr/lib/dovecot/deliver -d $(recipient)

(pour les flags, cf. la doc postfix) et dans /etc/dovecot/dovecot.conf

protocol lda {
  postmaster_address = postmaster@example.com
  hostname = myhost.example.com
  mail_plugins = cmusieve
  # les scripts sieve de filtrage communs à tous
  global_script_path = /home/mail/globalsieverc
  # un log pour suivre les mails délivrés
  log_path = /var/log/dovecot/deliver.log
  # et la socket que lda utilise pour vérifier user & emplacement (exportée plus bas par soket listen / master)
  auth_socket_path = /var/run/dovecot/auth-master
}
auth default {
  ...
  socket listen {
     master {
        path = /var/run/dovecot/auth-master
        mode = 0660
        user = mailboxes
    }
    client listen {
       ...
    }
  }
}
chown dovecot:dovecot /var/run/dovecot/
chmod 644 /etc/dovecot/dovecot.conf
mkdir /var/log/dovecot/
chown 5000:5000 /var/log/dovecot/
# on redemarre
/etc/init.d/postfix restart
/etc/init.d/dovecot restart
# on teste
echo "test"|mail -s "test dovecot deliver" user1@example.com
# et on vérifie que tout marche bien dans les logs

spamassassin

aptitude install spamassassin spamc libnet-dns-perl
groupadd spamd
useradd -g spamd -s /bin/false -d /var/log/spamassassin spamd
mkdir /var/log/spamassassin
chown spamd:spamd /var/log/spamassassin

Pour indiquer à postfix de donner le courrier à spamassassin pour filtrage, il faut ajouter dans master.cf

# on remplace la ligne smtp par
smtp      inet  n       -       -       -       3       smtpd     -o content_filter=spamassassin -o receive_override_options=no_address_mappings
# et à la fin on ajoute l'entrée
spamassassin unix -     n       n       -       -       pipe
  user=spamd argv=/usr/bin/spamc -f -e
  /usr/sbin/sendmail -oi -f ${sender} ${recipient}

(merci à Julien Wadim pour la 2e option "-o receive_override_options=no_address_mappings", pour éviter la duplication de mail, cf http://blog.julienwadin.be/45/postfix-mails-en-double-lors-de-la-livraison-vers-une-boite-avec-copie-vers-une-autre/ pour l'explication).

On edite /etc/default/spamassassin

ENABLED=1
SAHOME="/var/lib/spamassassin/"
OPTIONS="--create-prefs --max-children 3 --username spamd --helper-home-dir ${SAHOME} -s /var/log/spamassassin/spamd.log"
PIDFILE="/var/run/spamd.pid"
NICE="--nicelevel 15"

Dans /etc/spamassassin/local.cf

report_safe 0
use_bayes 1
bayes_auto_learn 1

et on relance tout ça

/etc/init.d/postfix restart
/etc/init.d/spamassassin start
sa-update
# et on teste
spamassassin < /usr/share/doc/spamassassin/examples/sample-spam.txt

Sieve

Il reste à filtrer les mail taggés spam par sieve, on met donc dans /home/mail/globalsieverc

# import
require "fileinto"; 

# spamassassin a taggé le mail niveau 7, on le détruit donc directement
if header :contains ["X-Spam-Level"] ["*******"] {
  discard;
  # c'est fini pour lui (poubelle), on ne cherche pas à exécuter plus loin...  
  stop;
}
if exists "X-Spam-Flag" { 
  fileinto "Junk"; 
  stop;
}

cf http://workaround.org/articles/ispmail-etch/#sieve-filtering-out-spam, http://wiki.dovecot.org/LDA/Sieve, http://www.howtoforge.com/dovecot_mail_server_sieve_virtual_users, le langage http://www.howtoforge.com/sieve_mail_filtering

webmail roundcube

http://www.roundcube.net/

# recup de l'appli sur puis
tar xvzf roundcubemail-0.1-rc2.tar.gz
cd roundcubemail-0.1-rc2
# on créé user & db puis on injecte
mysql -u[roundcubeUser] -p [roundcubeDb] < SQL/mysql5.initial.sql
# on créé nos fichiers de conf
cp config/db.inc.php.dist config/db.inc.php
cp config/main.inc.php.dist config/main.inc.php

On va modifier config/* pour changer

# dans config/db.inc.php
$rcmail_config['db_dsnw'] = 'mysql://roundcubeUser:roundcubeUserPass@localhost/roundcubeDb';
# et dans config/main.inc.php
$rcmail_config['default_host'] = 'localhost';
$rcmail_config['smtp_user'] = '%u';
$rcmail_config['smtp_pass'] = '%p';
$rcmail_config['locale_string'] = 'fr';
$rcmail_config['date_long'] = 'd/m/Y H:i';
$rcmail_config['enable_spellcheck'] = FALSE;
$rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Junk.Spam-detecte-a-tord', 'Junk.Spam-non-detecte', 'Trash');

regarder http://blog.julienwadin.be/index.php/2007/05/26/72-modification-du-password-email-dans-roundcube pour la modif du passwd depuis l'interface.

Autres webmail :

"Apprentissage" spamassassin

Il reste à créer les dossiers Spam-ok et Spam-KO (par exemple) dans chaque compte pour que les utilisateurs imap puissent y mettre les faux-positifs et faux negatifs, et mettre un cron pour sa-learn.

Un script d'exemple sur checkspam

Mailman

Pour installer mailman comme gestionnaire de liste de diffusion sur un domaine dédié listes.domaine.tld (listes.domaine.tld est donc dans la conf bind de domaine.tld avec A et MX)

aptitude install mailman
# choisir fr, mais ça sert à rien, car avec le paquet de etch il indique quand même :
Installing site language en ............................................ done.

Ajouter un vhost apache basé sur /etc/mailman/apache.conf

# on prend la fin du fichier qui commence par un commentaire
sed -ne '/^#<VirtualHost \*>/,$ s/^#//p' < /etc/mailman/apache.conf > /etc/apache2/sites-available/listes.domaine.tld
# on va modifier qq trucs à la main (logs & co)
joe /etc/apache2/sites-available/listes.domaine.tld
# on active le vhost
a2ensite listes.domaine.tld
/etc/init.d/apache2 reload

Dans /etc/mailman/mm_cfg.py, on ajoute

DEFAULT_EMAIL_HOST = 'listes.domaine.tld'
DEFAULT_URL_HOST = 'listes.domaine.tld'
DEFAULT_URL_PATTERN = 'http://%s/'
DEFAULT_SERVER_LANGUAGE = 'fr'
# on peut relancer l'install en fr
dpkg-reconfigure -p low mailman
# et ça va mieux
Installing site language fr ............................................ done.

# Dans /etc/postfix/main.cf:
# ce domaine ne doit pas figurer ailleurs
relay_domains = ... listes.domaine.tld
transport_maps = hash:/etc/postfix/transport
mailman_destination_recipient_limit = 1

# Dans /etc/postfix/master.cf
mailman unix  -       n       n       -       -       pipe
     flags=FR user=list 
     argv=/var/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${mailbox}

# et dans /etc/postfix/transport
listes.domaine.tld   mailman:

# on oublie pas le 
postmap /etc/postfix/transport
/etc/init.d/postfix reload

# Reste à créer la "site list" mailman "liste par défaut du domaine qui permet d'accéder à l'interface d'admin) avec
newlist mailman

# comme on y est invité,  dans /etc/aliases on ajoute
# mailman mailing list
mailman:              "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:        "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:      "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:      "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:         "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:        "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:        "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:      "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:    "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:  "|/var/lib/mailman/mail/mailman unsubscribe mailman"

# puis
newaliases
/etc/init.d/postfix reload

# y'a plus qu'à démarrer mailman
/etc/init.d/mailman start

reste à vérifier que tout va bien sur http://listes.domaine.tld/admin

Liens

Voir aussi

Et

Bonus

lire les mails du secondaire

Dans le cas où vous avez un MX secondaire qui prend les mails d'un primaire en rade, et que vous avez besoin d'en lire un

  • postqueue -p : pour lister les mails en attente
  • postcat path/2/deferred/file : pour en lire un en console (un à vous !)

Par exemple, (attention, à ne pas faire s'il y a beaucoup de mails !)

find /var/spool/postfix/deferred/ -type f -mmin -5|xargs postcat|sed -ne '/Content-Disposition: attachment/,$ d;
     /^\*\*\* MESSAGE CONTENTS/,/^\*\*\* HEADER EXTRACTED/ p;'

postmap_all

#!/bin/bash
# script qui cherche les fichiers de hash et fait un postmap dessus
 
sed -ne '/^[ \t]*#/ d; s/.*hash:\(.*\)/\1/p' < /etc/postfix/main.cf |while read map
do
  echo $map
  [ "$map" = '/etc/aliases' ] && newaliases || postmap $map
done
echo "à priori, il ne devrait rester à faire que le :"
echo "/etc/init.d/postfix reload"

Réécriture des users locaux

Pour que le courrier envoyé par les users locaux (au hasard www-data) le soit d'une adresse plus parlante, on peut ajouter dans le main.cf

smtp_generic_maps = hash:/etc/postfix/smtp_generic_maps.hash

et dans smtp_generic_maps.hash

www-data webmaster@example.com

Et si l'on en a plein, on peut perfectionner le truc avec

# id du group des users concernés, le UID avec cet ID sera pris même s'il n'appartient pas au groupe
# (sinon faut modifier la règle sed pour prendre le 4e champ délimité par :)
GID=XXX
DOM=monhost.example.com
USER=webmaster@example.com
sed -ne '/'$GID'/ s/^\([^:]\+\):.*/\1@'$DOM' '$USER'/p' < /etc/passwd > /etc/postfix/smtp_generic_maps.hash

Pour que les bounces soient aussi renvoyés à la bonne adresse, il faut ajouter dans /etc/aliases

www-data: webmaster@example.com
 
linux/howto/postfix.txt · Dernière modification: 28/08/2010 17:15 par daniel