Voici une page sur comment configurer son serveur mail, en passant par le smtpd (postfix ici) facilement & rapidement, en ayant directement les quelques bonnes options qui permettent que ça tombe un peu magiquement en marche. Plus tard il aura la configuration DNS qui va bien (SPF, DKIM), et éventuellement du dovecot pour l’IMAP en terminant (peut-être) par la configuration mutt et webmail avec roundcube. Il y a du chemin à faire !

Postfix

Tout d’abord : il faut se créer un certificat (on va l’auto-signer, il n’y aura qu’une seule étape à changer si on veut le faire signer par une autorité comme CACert).

Après avoir installé openssl, on génère une clé :

génération d’une clé RSA

openssl genpkey -algorithm RSA -out example.com.key \
            -pkeyopt rsa_keygen_bits:4096

On génère le « Certificate Signing Request » qui nous servira à créer notre certificat auto-signé ou le certificat signé par une entité quelconque (non vu ici) :

requête de signature de certificat

openssl req -new -key example.com.key -out example.com.csr

certificat final

openssl x509 -req -days 365 -in example.com.csr \
            -signkey example.com.key -out example.com.cert

J’ai mis ces fichiers dans /etc/postfix/tls/, faites comme bon vous semble. Ensuite il faut générer une clé Diffie Hellman, qui permet de négocier une connexion (échange de clés).

clé Diffie-Hellman

openssl genpkey -genparam -outform PEM -algorithm DH \
            -out dh_1024.pem -pkeyopt dh_paramgen_prime_len:2048

une seconde clé Diffie-Hellman, plus petite

openssl genpkey -genparam -outform PEM -algorithm DH \
            -out dh_512.pem -pkeyopt dh_paramgen_prime_len:512

On revient à la configuration de Postfix, et pour pas faire une longue liste d’explications inutiles, je préfère directement poster la configuration de mon vrai serveur @home.

root@frite /etc/postfix # cat main.cf
# http://www.postfix.org/postconf.5.html#smtpd_banner
# un petit texte affiché en début de connexion ($mail_name vaut par défaut Postfix, $mail_version je vous laisse deviner)
smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)

# http://www.postfix.org/postconf.5.html#biff
# pour avertir les utilisateurs quand on reçoit un nouvel e-mail, faut pas l'activer si on a beaucoup d'utilisateurs
biff = no

# http://www.postfix.org/postconf.5.html#append_dot_mydomain
append_dot_mydomain = no

# http://www.postfix.org/postconf.5.html#delay_warning_time
# après ce délai, l'émetteur reçoit une copie de l'entête des messages qui sont toujours en attente d'être traités
delay_warning_time = 4h

# http://www.postfix.org/postconf.5.html#disable_vrfy_command 
disable_vrfy_command = yes

# http://www.postfix.org/postconf.5.html#mydomain
# mon domaine
mydomain = karchnu.fr

# http://www.postfix.org/postconf.5.html#myhostname
# le fqdn de mon serveur de mails
myhostname = mail.karchnu.fr

# http://www.postfix.org/postconf.5.html#masquerade_domains
# sert à modifier les entêtes des mails à l'envoi, exemple :
# masquerade_domains = foo.example.com example.com
# change "user@any.thing.foo.example.com" en "user@foo.example.com", mais change "user@any.thing.else.example.com" en "user@example.com". 
masquerade_domains = $mydomain

# http://www.postfix.org/postconf.5.html#home_mailbox
# le format de boîte que j'utilise (Maildir et non mbox)
home_mailbox = Maildir/

# http://www.postfix.org/postconf.5.html#alias_maps
alias_maps = hash:/etc/postfix/aliases
# http://www.postfix.org/postconf.5.html#alias_database
alias_database = hash:/etc/postfix/aliases

# http://www.postfix.org/postconf.5.html#myorigin
# c'est à partir de cette adresse qu'est envoyé le courier et c'est pour cette adresse qu'on reçoit le courier
myorigin = karchnu.fr
mydestination = mail.$mydomain, $mydomain, localhost

# http://www.postfix.org/postconf.5.html#mailbox_size_limit
mailbox_size_limit = 1073741824

# http://www.postfix.org/postconf.5.html#message_size_limit
message_size_limit = 15728640

# http://www.postfix.org/postconf.5.html#recipient_delimiter
recipient_delimiter = +

# http://www.postfix.org/postconf.5.html#smtpd_sasl_auth_enable
smtpd_sasl_auth_enable = yes

# http://www.postfix.org/postconf.5.html#smtpd_sasl_security_options
smtpd_sasl_security_options = noanonymous

# http://www.postfix.org/postconf.5.html#smtpd_sasl_local_domain
smtpd_sasl_local_domain     = $mydomain

# http://www.postfix.org/postconf.5.html#broken_sasl_auth_clients
broken_sasl_auth_clients    = no

# http://www.postfix.org/postconf.5.html#smtpd_sender_login_maps
smtpd_sender_login_maps = hash:/etc/postfix/sender_login

# http://www.postfix.org/postconf.5.html#smtpd_sender_restrictions
smtpd_sender_restrictions =
        reject_unknown_sender_domain, 
        reject_non_fqdn_sender, 
        reject_authenticated_sender_login_mismatch

# http://www.postfix.org/postconf.5.html#smtpd_recipient_restrictions
smtpd_recipient_restrictions = 
        permit_sasl_authenticated,
        reject_unknown_recipient_domain, 
        reject_non_fqdn_recipient, 
        reject_unauth_destination

# http://www.postfix.org/postconf.5.html#mailbox_command
# permet de récupérer les e-mails et de les placer où on le souhaite
# par l'intermédiaire d'un programme externe
mailbox_command = /usr/bin/procmail -f- -a $USER

# http://www.postfix.org/postconf.5.html#smtpd_helo_required
smtpd_helo_required = yes

# *********************************************
# *                    TLS                    *
# *********************************************

# http://www.postfix.org/postconf.5.html#smtp_use_tls
smtp_use_tls = yes

# http://www.postfix.org/postconf.5.html#smtpd_use_tls
smtpd_use_tls = yes 

# http://www.postfix.org/postconf.5.html#smtp_tls_security_level
smtp_tls_security_level = may

# http://www.postfix.org/postconf.5.html#tls_export_cipherlist
# pour interdire les chiffrements de merde
tls_export_cipherlist = !aNULL:!eNULL:!EXPORT:!MD5:!DES:!LOW:kEDH:HIGH:!MEDIUM

smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3
smtp_tls_mandatory_protocols=!SSLv2,!SSLv3
smtpd_tls_protocols=!SSLv2,!SSLv3
smtp_tls_protocols=!SSLv2,!SSLv3

# http://www.postfix.org/postconf.5.html#smtpd_tls_auth_only
# http://www.postfix.org/postconf.5.html#smtpd_tls_security_level
# forcer l'utilisation de TLS avant d'envoyer l'identification
smtpd_tls_auth_only = yes
smtpd_tls_security_level = may

# http://www.postfix.org/postconf.5.html#smtpd_tls_auth_only
# http://www.postfix.org/postconf.5.html#smtpd_tls_key_file
# http://www.postfix.org/postconf.5.html#smtpd_tls_cert_file
# http://www.postfix.org/postconf.5.html#smtpd_tls_loglevel
# http://www.postfix.org/postconf.5.html#smtpd_tls_received_header
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/tls/mail.karchnu.fr.key
smtpd_tls_cert_file = /etc/postfix/tls/mail.karchnu.fr.cert
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes

# http://www.postfix.org/postconf.5.html#smtpd_tls_dh1024_param_file
# http://www.postfix.org/postconf.5.html#smtpd_tls_dh512_param_file
# http://www.postfix.org/postconf.5.html#smtpd_tls_eecdh_grade
# Diffie-Hellman
smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem
smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
smtpd_tls_eecdh_grade = strong

vérifier un certificat

openssl verify -purpose sslclient votre_certificat.cert

Sender Policy Framework (SPF)

Le principe derrière SPF est d’indiquer dans notre zone DNS quel serveur a le droit d’envoyer des emails. Cela se résume à simplement une entrée dans votre zone DNS (un Resource Record) de type TXT. Des explications simples sur la syntaxe se trouvent sur cette page.

entrée SPF

@ IN TXT   "v=spf1 a mx a:the.karchnu.fr a:karchnu.fr ?all"

Ceci indique que les serveurs mail de la zone karchnu.fr ainsi que les serveurs the.karchnu.fr et karchnu.fr peuvent envoyer des e-mails. Le ?all indique que si c’est un autre, on peut éventuellement lui faire confiance (on reste neutre à leur égard).

DomainKey Identified Mail (DKIM) – TODO

Le principe derrière DKIM est d’indiquer dans notre zone DNS une clé publique de chiffrement (par exemple RSA) qui permettra de chiffrer ou signer une partie de l’e-mail (principalement les entêtes non visibles de l’utilisateur final) pour prouver que l’émetteur possédait la clé privée de chiffrement (ce qui revient à dire que c’était le bon émetteur). Ceci permet d’éviter les usurpations d’identité.

Partie manquante. Revenez plus tard ! /

Le serveur IMAP (Dovecot)

Il nous faut un serveur IMAP pour discuter avec RoundCube, donc l’installation du serveur IMAP dovecot avec la configuration par défaut va nous suffire, je rajoute simplement l’option mail_location = maildir:~/Maildir pour être sûr qu’il va chercher les mails au format Maildir. La configuration suivante est donc non sécurisée par TLS, donc c’est uniquement pour discuter en local avec RoundCube et pas pour être utilisée sur le net. Je mettrai à jour ce tuto pour y inclure la connexion sécurisée via TLS.

Au cas où, voici la configuration que j’obtiens une fois que j’ai effectué un dovecot -n 2>&1 > /etc/dovecot/dovecot.conf (plus l’option citée au dessus) :

# 2.2.13: /etc/dovecot/dovecot.conf
# OS: Linux 3.16.0-4-amd64 x86_64 Debian 8.1 
#mail_location = mbox:~/mail:INBOX=/var/mail/%u
mail_location = maildir:~/Maildir

namespace inbox {
  inbox = yes
  location = 
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox Junk {
    special_use = \Junk
  }
  mailbox Sent {
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
  mailbox Trash {
    special_use = \Trash
  }
  prefix = 
}

passdb {
  driver = pam
}

protocols = " imap"
ssl = no
userdb {
  driver = passwd
}

Le webmail (RoundCube)

Avoir un serveur de mail c’est pratique, mais on voudrait aussi pouvoir accéder de puis n’importe-où à ses emails, via une interface web. Pour ça il y a pas mal de webmail disponibles, et celui que j’ai choisi est RoundCube parce qu’il est assez répandu et donc il y a une petite communauté autour.

Première étape de l’installation, il faut télécharger l’archive sur le site de RoundCube. Ensuite il faut installer plein de choses, tout est décrit sur la page d’installation. J’ai mis à jour le script d’installation disponible sur la page, qui a plus de commentaires que l’original dans la documentation, fonctionne avec apache2 et Debian Jessie, permet d’installer la dernière version de roundcube, et indique un peu plus ce qu’il fait durant l’exécution. Cette nouvelle version est disponible dans les fichiers attachés dans la page. On commence par installer le minimum, puis le reste sera géré automatiquement par le script :

apt-get install php5 apache2 mysql-server

Le script met un fichier dans /var/www/roundcube/, mais on peut le remplacer par :

<?php

/* Local configuration for Roundcube Webmail */

// ----------------------------------
// SQL DATABASE
// ----------------------------------
// Database connection string (DSN) for read+write operations
// Format (compatible with PEAR MDB2): db_provider://user:password@host/database
// Currently supported db_providers: mysql, pgsql, sqlite, mssql or sqlsrv
// For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
// NOTE: for SQLite use absolute path: 'sqlite:////full/path/to/sqlite.db?mode=0646'
$config['db_dsnw'] = 'mysql://user:password@host/dbname';

// ----------------------------------
// IMAP
// ----------------------------------
// The mail host chosen to perform the log-in.
// Leave blank to show a textbox at login, give a list of hosts
// to display a pulldown menu or set one host as string.
// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
// Supported replacement variables:
// %n - hostname ($_SERVER['SERVER_NAME'])
// %t - hostname without the first part
// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
// %s - domain name after the '@' from e-mail address provided at login screen
// For example %n = mail.domain.tld, %t = domain.tld
// WARNING: After hostname change update of mail_host column in users table is
//          required to match old user data records with the new host.
$config['default_host'] = 'localhost';
$config['mail_domain'] = '%d';
$config['support_url'] = '';

// this key is used to encrypt the users imap password which is stored
// in the session record (and the client cookie if remember password is enabled).
// please provide a string of exactly 24 chars.
$config['des_key'] = 'chaîne-de-24-caractères!';

// ----------------------------------
// PLUGINS
// ----------------------------------
// List of active plugins (in plugins/ directory)
$config['plugins'] = array();

// Set the spell checking engine. Possible values:
// - 'pspell'  - requires the PHP Pspell module and aspell installed
// - 'enchant' - requires the PHP Enchant module
// - 'atd'     - install your own After the Deadline server or check with the people at http://www.afterthedeadline.com before using their API
$config['enable_spellcheck'] = false;

$config['log_driver'] = 'syslog';

Documentation

Quelques tutos glannés sur le net:

Si vous avez des améliorations à apporter, n’hésitez pas à me contacter par e-mail (karchnu CHEZ karchnu POINT fr).