Configuration d'un serveur de courriers

Cette page est en cours de réécriture.

Description d’une méthode d’installation d’un serveur de courriel Postfix, sur une distribution Linux Debian (Buster) possédant déjà une configuration avec un serveur DNS (BIND) et une base de données MySQL (MariaDB), avec les éléments suivants :

phpMyAdmin

Postfix

Postfix-policyd-spf-python

Dovecot

Postgrey

Amavisd-new

Clamav

Spamassassin

OpenDKIM

OpenDMARC

Monit

Installation de paquets

Il est conseillé d’avoir installé et configuré rkhunter.

apt update && apt-get upgrade
apt purge exim4 exim4-base exim4-config exim4-daemon-light
apt install postfix postfix-mysql postfix-policyd-spf-python postgrey dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql dovecot-sieve dovecot-antispam opendkim opendkim-tools amavisd-new clamav-daemon monit opendmarc spamassassin spamc mailutils

Pendant l'installation de Postfix, il faudra choisir “internet site”, entrer comme nom du système FQDN de courrier la valeur de la commande hostname -f ou si elle renvoie juste le nom du serveur entrer la valeur complète avec le nom de domaine, cela ressemblera à hostname.domaine.tld ou à domaine.tld.

Sous Debian 10 (Buster), Monit n'est plus disponible dans les dépôts,voir Install monit in Debian 10 (buster) et cette page pour l'installation des backports.

Définition du "hostname"

La machine doit avoir un nom de machine et de domaine complet, cela est à définir dans le fichier /etc/hosts :

127.0.0.1 localhost 127.0.1.1 hostname.domaine.eu hostname

Pour tester la configuration :

root@hostname:~# hostname -s hostname root@hostname:~# hostname -d domaine.eu root@hostname:~# hostname -f hostname.domaine.eu

Mais aussi la zone PTR de recherche inversée doit être configurée, la commande dig -x doit renvoyer la valeur de hostname -f.

Configuration additionnelle

Les ports TCP 25, 465, 587 et 993 du firewall doivent être ouvert.

Installation et configuration de phpMyAdmin

Pour Debian et Ubuntu il existe un paquet dans les dépôts, cependant, au moment où j'écris cette page, il existe un bug dans l'installation. J’ai donc choisi d'installer la dernière version à partir des sources.

Vérifier les sources

Pour vérifier l’intégrité des fichiers (somme de contrôle et signature GPG), le détail est expliqué ici.

Création d’un serveur virtuel Apache2

VirtualHost sur le port 80

Je crée un VirtualHost sur le port 80, j'ajouterai ensuite une redirection sur le port 443, mais avant de décommenter RewriteRule il me faudra générer un certificat SSL.

<VirtualHost *:80> # The ServerName directive sets the request scheme, hostname and port that # the server uses to identify itself. This is used when creating # redirection URLs. In the context of virtual hosts, the ServerName # specifies what hostname must appear in the request's Host: header to # match this virtual host. For the default virtual host (this file) this # value is not decisive as it is used as a last resort host regardless. # However, you must set it for any further virtual host explicitly. #ServerName www.example.com ServerName pma.hostname.domaine.eu ServerAlias pma.hostname.domaine.eu ServerAdmin webmaster@domaine.eu DocumentRoot /var/www/pma RewriteEngine On #RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301] # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, # error, crit, alert, emerg. # It is also possible to configure the loglevel for particular # modules, e.g. #LogLevel info ssl:warn ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>

Création d’un certificat avec Let’s Encrypt

certbot certonly --webroot -w /var/www/pma -d pma.hostname.domaine.eu --email webmaster@domaine.eu --rsa-key-size 4096

VirtualHost sur le port 443

La directive RewriteRule peut maintenant être décommentée, ensuite il faut créer un VirtualHost afin d'utiliser SSL. J'utilise ici une configuration restrictive, il faudra peut-être une configuration plus souple (voir Server Side TLS ) si de nombreux clients doivent se connecter.

<IfModule mod_ssl.c> <VirtualHost *:443> ServerName pma.hostname.domaine.eu ServerAlias pma.hostname.domaine.eu ServerAdmin webmaster@domaine.eu DocumentRoot /var/www/pma <Directory /> Options SymLinksIfOwnerMatch AllowOverride None Require all denied </Directory> <Directory /var/www/pma/> Options -Indexes -FollowSymLinks +MultiViews AllowOverride All # restreindre l'accés à certaines adresses IP Require ip 0.0.0.1 0.0.0.2 </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Require all denied </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews FollowSymLinks AllowOverride None Require ip 127.0.0.0/255.0.0.0 ::1/128 </Directory> # enable HTTP/2, if available Protocols h2 http/1.1 # SSL Engine Switch: # Enable/Disable SSL for this virtual host. SSLEngine on # The CRIME attack uses SSL Compression, we need to disable that SSLCompression off SSLProtocol +TLSv1.3 -TLSv1.2 -TLSv1.1 -TLSv1 -SSLv3 -SSLv2 SSLCipherSuite TLSv1.3 TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 SSLHonorCipherOrder on SSLSessionTickets off SSLUseStapling On # SSLStaplingCache must be exist in /etc/apache2/mods-available/ssl.conf, # see https://itigloo.com/security/how-to-configure-ocsp-stapling-on-apache-http-server/ # SSLOpenSSLConfCmd is supported by version 2.5 and later # SSLOpenSSLConfCmd DHParameters /etc/ssl/private/dh4096.pem SSLCertificateFile /etc/letsencrypt/live/pma.hostname.domaine.eu/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/pma.hostname.domaine.eu/privkey.pem <IfModule mod_headers.c> Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "DENY" Header always set X-XSS-Protection "1; mode=block" Header set Content-Security-Policy-Report-Only "default-src 'self'" </IfModule> # Certificate Authority (CA): # Set the CA certificate verification path where to find CA # certificates for client authentication or alternatively one # huge file containing all of them (file must be PEM encoded) # Note: Inside SSLCACertificatePath you need hash symlinks # to point to the certificate files. Use the provided # Makefile to update the hash symlinks after changes. #SSLCACertificatePath /etc/ssl/certs/ SSLCACertificateFile /etc/letsencrypt/live/pma.hostname.domaine.eu/fullchain.pem </VirtualHost> </IfModule>

Configuration

La configuration se fait via le fichier config.inc.php, voir cette page. Pour configurer $cfg['blowfish_secret'], voir la documentation. Pour générer le secret, la commande suivante peut-être utilisée ou tout autre générateur de code, 32 caractères est un minimum.

openssl rand -base64 64

Authentification à deux facteurs

Pour activer le double facteur, voir la page sur le double-facteur puis suivre les instructions de la documentation pour installer les tables de stockage.

mysqldump -u root --events --routines --triggers --lock-tables --all-databases > /srv/backups/mysqldump/MySQLDatap-`date +"%Y%m%d"`.sql
cd /var/www/pma/sql
mysql < create_tables.sql -u root

Et pour toute version de MariaDB :

mysql -u root
root@localhost [(none)]> CREATE USER 'pma'@'localhost' IDENTIFIED VIA mysql_native_password USING 'pmapass';
root@localhost [(none)]> GRANT SELECT, INSERT, UPDATE, DELETE ON `<pma_db>`.* TO 'pma'@'localhost';

En cas d’erreur :

root@localhost [(none)]> CREATE USER 'pma'@'localhost' ;
root@localhost [(none)]> SET PASSWORD FOR 'pma'@'localhost' = PASSWORD('00000000');
root@localhost [(none)]> GRANT SELECT, INSERT, UPDATE, DELETE ON `<pma_db>`.* TO 'pma'@'localhost';

Mise à jour

Ne jamais extraire une nouvelle version de phpMyAdmin par-dessus une version déjà existante. Toujours supprimer d’abord les anciens fichiers en ne conservant que la configuration. De cette manière, vous ne laisserez pas de fichiers vieux ou périmés dans le répertoire, ce qui peut avoir de sérieuses implications de sécurité et provoquer divers dysfonctionnements, voir https://docs.phpmyadmin.net/fr/latest/setup.html#upgrading-from-an-older-version.

Configuration de la base de données

Pour un meilleur prompt MySQL il faut ajouter dans le fichier .profile la variable suivante :

# Display username, hostname and current database name in the mysql prompt export MYSQL_PS1="\u@\h [\d]> "

Mais surtout il faut exécuter ces commandes pour la création de la base de données :

mysql -u root -p
CREATE DATABASE db_mail;
CREATE USER "nom_utilisateur"@"localhost";
SET PASSWORD FOR 'nom_utilisateur'@'localhost' = PASSWORD('00000000');
GRANT ALL PRIVILEGES ON db_mail.* TO 'nom_utilisateur'@'localhost' IDENTIFIED BY '00000000';
FLUSH PRIVILEGES;
use db_mail;

Pour ensuite créer les tables avec la commande :

mysql -h localhost -u root -p db_mail < db-mail.sql

Le premier tableau contiendra les domaines que nous utiliserons avec le serveur de messagerie, ensuite le concont contiendra les utilisateurs et leur mot de passe, enfin la dernière table contiendra les alias de messagerie :

USE db_mail; CREATE TABLE `domain` ( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) NOT NULL ) ENGINE = InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `user` ( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, domain_id INT UNSIGNED NOT NULL, `user` VARCHAR(64) NOT NULL, password VARCHAR(128) NOT NULL, CONSTRAINT UNIQUE_EMAIL UNIQUE (domain_id,USER), FOREIGN KEY (domain_id) REFERENCES DOMAIN(id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `alias` ( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, domain_id INT UNSIGNED NOT NULL, SOURCE VARCHAR(64) NOT NULL, destination VARCHAR(128) NOT NULL, FOREIGN KEY (domain_id) REFERENCES DOMAIN(id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET=utf8;

Postfix doit savoir comment accéder à cette base, créons les fichiers de configuration dans le dossier /etc/postfix/mysql

mkdir /etc/postfix/mysql

Pour que Postfix puisse connaître les adresses emails existantes, nous créons email2email.cf

hosts = 127.0.0.1 dbname = db_mail user = nom_utilisateur password = xxxxxxxx query = SELECT CONCAT(user.user, '@', domain.name) AS email FROM domain,user WHERE user.domain_id=domain.id AND CONCAT(user.user, '@', domain.name)='%s'

Et pour que Postfix puisse connaître les alias (redirections emails) virtual-alias-maps.cf

hosts = 127.0.0.1 dbname = db_mail user = nom_utilisateur password = xxxxxxxx query = SELECT destination FROM alias, domain WHERE alias.domain_id=domain.id AND CONCAT(alias.source, '@', domain.name)='%s'

Puis pour que Postfix puisse connaître les domaines gérés virtual-mailbox-domains.cf

hosts = 127.0.0.1 dbname = db_mail user = nom_utilisateur password = xxxxxxxx query = SELECT 1 FROM domain WHERE name='%s'

Enfin pour vérifier si une adresse email est bien gérée par le serveur virtual-mailbox-maps.cf

hosts = 127.0.0.1 dbname = db_mail user = nom_utilisateur password = xxxxxxxx query = SELECT 1 FROM user,domain WHERE user.domain_id=domain.id AND CONCAT(user.user, '@', domain.name)='%s'

Notons que nous ne pouvons pas utiliser “localhost”, car Postfix tourne dans un contexte restreint, il n'a pas le droit d'accéder au socket mysql. Le fait de forcer l'hôte à 127.0.0.1 impôse à Postfix de passer par une connexion TCP. Ensuite assurons-nous que root et postfix soient les seuls à pouvoir accéder à ces fichiers de configuration (ils contiennent des identifiants pour MySQL) :

chgrp -R postfix /etc/postfix/mysql
chmod 750 /etc/postfix/mysql
chmod 640 /etc/postfix/mysql/*.cf

Domaines, utilisateurs et alias

Avec phpMyAdmin, nous nous connectons à la base de données du serveur de courrier db_mail avec notre compte postmaster, puis nous créons notre domaine dans la table domaine (s’il n'existe pas), ensuite dans la table user nous ajoutons un utilisateur en indiquant l’identifiant du domaine et le hash de son mot de passe. Pour obtenir le hash, nous utiliserons la commande :

doveadm pw -s SHA512-CRYPT

Il faut utiliser le retour de cette commande sans la partie {SHA512-CRYPT}, à partir de $6$.

La commande postmap permet de vérifier le fonctionnement :

postmap -q domaine.eu mysql:/etc/postfix/mysql/virtual-mailbox-domains.cf
postmap -q example@domaine.eu mysql:/etc/postfix/mysql/virtual-mailbox-maps.cf
postmap -q alias@domaine.eu mysql:/etc/postfix/mysql/virtual-alias-maps.cf

Configuration de Postfix

Faisons une sauvegarde des fichiers d’origine.

cp /etc/postfix/main.cf /etc/postfix/main.cf.original.bak
cp /etc/postfix/master.cf /etc/postfix/master.cf.original.bak

Création d’un utilisateur et d’un groupe

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail -m -s /bin/false

Création d’un certificat avec Let’s Encrypt

Configurons Postfix pour utiliser TLS avec un certificat Let’s Encrypt :

apt install python3-pip python3-dnslib
pip3 install certbot-dns-standalone
systemctl stop postfix
certbot --non-interactive --agree-tos --email webmaster@domaine.eu certonly \
--preferred-challenges dns --authenticator certbot-dns-standalone:dns-standalone \
--certbot-dns-standalone:dns-standalone-address=0.0.0.0 \
--certbot-dns-standalone:dns-standalone-ipv6-address=:: \
--certbot-dns-standalone:dns-standalone-port=53 \
-d mail.domaine.eu --email webmaster@domaine.eu --rsa-key-size 4096
systemctl start postfix

Pour comprendre cette commande, vous pouvez regarder la documentation de Cerbot.

Les fichiers générés se trouvent dans le répertoire /etc/letsencrypt/live/mail.domaine.eu/.

Création des fichiers pour les paramètres DH (Diffie-Helmann)

Ces fichiers s’utilisent dans les paramètres DH (Diffie-Helmann) que le serveur SMTP doit utiliser avec le chiffrement EDH. Ces paramêtres sont smtpd_tls_dh1024_param_file et smtpd_tls_dh1024_param_file, ils se trouvent dans le fichier main.cd de Postfix. Il est possible de générer des paramètres avec des valeurs supérieures à celles par défaut afin d’améliorer la sécurité contre les attaques et pour assurer la compatibilité avec les clients SMTP Exim sous Debian qui nécessitent une longueur de ≥ 2048 bits.

openssl dhparam -outform PEM -out dh2048.pem -rand /dev/urandom 2048
openssl dhparam -outform PEM -out dh512.pem -rand /dev/urandom 512

Attention, les serveurs possèdent souvent une entropie faible, il est préférable de générer ces fichiers sur une machine en possédant. Il faut ensuite donner des droits d'accés faibles à ces fichiers.

chmod 644 dh512.pem dh2048.pem

Configuration du fichier master.cf

Dans le fichier master.cf, il faut décommenter la ligne de smtps et vérifier la présence des options suivantes :

# ========================================================================== # service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (no) (never) (100) # ========================================================================== smtp inet n - y - - smtpd #smtp inet n - y - 1 postscreen #smtpd pass - - y - - smtpd #dnsblog unix - - y - 0 dnsblog #tlsproxy unix - - y - 0 tlsproxy #submission inet n - y - - smtpd # -o syslog_name=postfix/submission # -o smtpd_tls_security_level=encrypt # -o smtpd_sasl_auth_enable=yes # -o smtpd_tls_auth_only=yes # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions # -o smtpd_recipient_restrictions= # -o smtpd_relay_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING smtps inet n - y - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions # -o smtpd_recipient_restrictions= # -o smtpd_relay_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING

puis ajouter ces lignes à la fin de ce fichier afin de permettre à Postfix de communiquer avec Dovecot :

dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/bin/sudo /usr/lib/dovecot/deliver -d ${recipient}

Pour fonctionner, ces éléments doivent exécuter des commandes avec les droits root, mais comme pour des raisons de sécurité ils ne doivent pas connaître le mot de passe de ce super-utilisateur nous créons le fichier /etc/sudoers.d/mail. Si le dossier n’existe pas il faudra installer sudo.

apt install sudo
vi /etc/sudoers.d/mail

Defaults:postfix !syslog postfix ALL=NOPASSWD:/usr/lib/dovecot/deliver Defaults:clamav !syslog clamav ALL=NOPASSWD:/usr/lib/dovecot/deliver Defaults:dovecot !syslog dovecot ALL=NOPASSWD:/usr/lib/dovecot/deliver Defaults:dspam !syslog dspam ALL=NOPASSWD:/usr/lib/dovecot/deliver Defaults:vmail !syslog vmail ALL=NOPASSWD:/usr/lib/dovecot/deliver

Nous devons appliquer des droits à ce fichier :

chmod 0440 /etc/sudoers.d/mail

Configuration main.cf

Le fichier main.cf de configuration Postfix doit contenir ces valeurs :

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) biff = no config_directory = /etc/postfix disable_vrfy_command = yes smtpd_helo_required = yes queue_directory = /var/spool/postfix # appending .domain is the MUA's job. append_dot_mydomain = no # Uncomment the next line to generate "delayed mail" warnings #delay_warning_time = 4h readme_directory = no # See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on # fresh installs. compatibility_level = 2 # TLS parameters smtpd_use_tls=yes smtpd_tls_auth_only = yes smtpd_tls_cert_file=/etc/letsencrypt/live/mail.streetdispatch.org/fullchain.pem smtpd_tls_key_file=/etc/letsencrypt/live/mail.streetdispatch.org/privkey.pem smtpd_tls_CAfile=/etc/letsencrypt/live/mail.streetdispatch.org/chain.pem smtpd_tls_CApath=/etc/ssl/certs smtpd_tls_mandatory_protocols=!SSLv2, !SSLv3, !TLSv1, !TLSv1.1 smtpd_tls_mandatory_exclude_ciphers = eNULL, aNULL, LOW, EXP, MEDIUM, ADH, AECDH, MD5, DSS, ECDSA, CAMELLIA128, CAMELLIA256, 3DES smtpd_tls_mandatory_ciphers=high smtpd_tls_protocols=!SSLv2,!SSLv3, !TLSv1, !TLSv1.1 smtpd_tls_exclude_ciphers = eNULL, aNULL, LOW, EXP, MEDIUM, ADH, AECDH, MD5, DSS, ECDSA, CAMELLIA128, CAMELLIA256, 3DES smtpd_tls_ciphers = high smtpd_tls_security_level = may smtpd_tls_dh1024_param_file = /etc/postfix/dh_4096.pem smtpd_tls_dh512_param_file = /etc/postfix/dh_4096.pem smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtpd_tls_eecdh_grade = ultra tls_eecdh_strong_curve = prime256v1 tls_eecdh_ultra_curve = secp384r1 tls_high_cipherlist=EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!MEDIUM:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA tls_ssl_options = no_ticket, no_compression, no_renegotiation tls_preempt_cipherlist = yes tls_random_source = dev:/dev/urandom smtpd_data_restrictions = reject_unauth_pipelining, permit smtpd_helo_required = yes smtp_use_tls = yes smtp_tls_cert_file=$smtpd_tls_cert_file smtp_tls_key_file=$smtpd_tls_key_file smtp_tls_CAfile=$smtpd_tls_CAfile smtp_tls_CApath=/etc/ssl/certs smtp_tls_mandatory_protocols=!SSLv2, !SSLv3, !TLSv1, !TLSv1.1 smtp_tls_mandatory_exclude_ciphers = MD5, SRP, PSK, aDSS, kECDH, kDH, SEED, IDEA, RC2, RC5, RC4 smtp_tls_mandatory_ciphers = high smtp_tls_protocols=!SSLv2,!SSLv3, !TLSv1, !TLSv1.1 smtp_tls_exclude_ciphers = MD5, SRP, PSK, aDSS, kECDH, kDH, SEED, IDEA, RC2, RC5, RC4 smtp_tls_ciphers = high smtp_tls_security_level = may smtp_tls_loglevel = 1 smtp_tls_note_starttls_offer = yes smtp_tls_session_cache_timeout = 3600s smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache # See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for # information on enabling SSL in the smtp client. smtpd_milters = non_smtpd_milters = $smtpd_milters milter_protocol = 6 milter_default_action = accept smtpd_recipient_restrictions = reject_rbl_client xbl.spamhaus.org, reject_rbl_client pbl.spamhaus.org, reject_rbl_client sbl.spamhaus.org, reject_rbl_client multi.uribl.com, reject_rbl_client rbl-plus.mail-abuse.org, reject_rbl_client dialups.mail-abuse.org, reject_invalid_hostname, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, permit_mynetworks, permit_sasl_authenticated, permit_auth_destination, reject_unauth_destination, reject_unverified_recipient, permit smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination smtpd_sasl_auth_enable = yes smtpd_sasl_local_domain = $myhostname smtpd_sasl_security_options = noanonymous smtpd_sasl_tls_security_options = $smtpd_sasl_security_options smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth broken_sasl_auth_clients = yes #limit incoming or receiving email rate smtpd_error_sleep_time = 1s smtpd_soft_error_limit = 10 smtpd_hard_error_limit = 20 myhostname = host.domaine.eu mydomain = domaine.eu #myorigin = /etc/mailname myorigin = $mydomain mydestination = $myhostname, localhost.$mydomain, mail.$mydomain, lists.$mydomain, host, localhost mynetworks = 127.0.0.0/8 [:: ffff:127.0.0.0]/104 [::1]/128 relayhost = relay_domains = lists.domaine.eu alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases mailbox_size_limit = 51200000 message_size_limit = 25600000 recipient_delimiter = + inet_interfaces = all inet_protocols = ipv4 maximal_queue_lifetime = 3d bounce_queue_lifetime = 3d virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_mailbox_domains = mysql:/etc/postfix/mysql/virtual-mailbox-domains.cf virtual_mailbox_maps = mysql:/etc/postfix/mysql/virtual-mailbox-maps.cf virtual_alias_maps = mysql:/etc/postfix/mysql/virtual-alias-maps.cf,mysql:/etc/postfix/mysql/email2email.cf virtual_transport = dovecot dovecot_destination_recipient_limit = 1

La variable myhostname doit être définie avec un nom de domaine pleinement qualifié FQDN et le fichier /etc/mailname doit avoir cette même valeur.

Relancer Postfix

systemctl restart postfix

Tester la sécurité des échanges

Pour tester la sécurité de Postfix, il est possible de vérifier avec des outils comme starttls.info

Attention désactiver certains ciphers risquent de provoquer des fallbacks et le passage en clair des données : Disabling Anonymous Diffie Hellman

Configuration de Dovecot

Configuration principale

Depuis la mise à jour vers la version 2.3 plusieurs paramètres sont devenus obsolètes, voir Upgrading Dovecot v2.2 to v2.3

Par défaut sous Debian, Dovecot utilise plusieurs fichiers de configuration dans /etc/dovecot/conf.d. Sauvegardons les fichiers d’origine :

cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.original.bak
cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.original.bak
cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.original.bak
cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext.original.bak
cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.original.bak
cp /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.original.bak
cp /etc/dovecot/conf.d/10-logging.conf /etc/dovecot/conf.d/10-logging.conf.original.bak
cp /etc/dovecot/conf.d/15-mailboxes.conf /etc/dovecot/conf.d/15-mailboxes.conf.original.bak
cp /etc/dovecot/conf.d/15-lda.conf /etc/dovecot/conf.d/15-lda.conf.original.bak
cp /etc/dovecot/conf.d/20-imap.conf /etc/dovecot/conf.d/20-imap.conf.original.bak
cp /etc/dovecot/conf.d/20-lmtp.conf /etc/dovecot/conf.d/20-lmtp.conf.original.bak
cp /etc/dovecot/conf.d/90-sieve.conf /etc/dovecot/conf.d/90-sieve.conf.original.bak
cp /etc/dovecot/conf.d/auth-static.conf.ext /etc/dovecot/conf.d/auth-static.conf.ext.original.bak
cp /etc/dovecot/conf.d/auth-sql.conf.ext /etc/dovecot/conf.d/auth-sql.conf.ext.original.bak

Éditons le fichier :

vi /etc/dovecot/dovecot.conf

et vérifions que cette ligne soit bien décommenter :

!include conf.d/*.conf

ainsi que pour cette ligne :

!include_try /usr/share/dovecot/protocols.d/*.protocol

puis nous paramétrons les fichiers suivant du répertoire /etc/dovecot/conf.d :

mail_home = /var/mail/%d/%n mail_location = maildir:/var/mail/%d/%n mail_privileged_group = vmail mail_plugin_dir = /usr/lib/dovecot/modules mail_plugins =
disable_plaintext_auth = yes auth_mechanisms = plain login #!include auth-deny.conf.ext #!include auth-master.conf.ext #!include auth-system.conf.ext !include auth-sql.conf.ext #!include auth-ldap.conf.ext #!include auth-passwdfile.conf.ext #!include auth-checkpassword.conf.ext #!include auth-vpopmail.conf.ext !include auth-static.conf.ext
service imap-login { inet_listener imap { port = 0 } inet_listener imaps { #port = 993 #ssl = yes } } service pop3-login { inet_listener pop3 { port = 0 } inet_listener pop3s { port = 0 } } service auth { unix_listener auth-userdb { mode = 0600 user = vmail } # Postfix smtp-auth unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix } # Auth process is run as this user. user = $default_internal_user } service imap { } service pop3 { }

Dovecot utilisera les mêmes certificats que Postfix

ssl = required ssl_cert = </etc/letsencrypt/live/mail.domaine.eu/fullchain.pem ssl_key = </etc/letsencrypt/live/mail.domaine.eu/privkey.pem ssl_ca = </etc/letsencrypt/live/mail.doamin.eu/chain.pem ssl_dh=</etc/dovecot/private/dh.pem ssl_min_protocol = TLSv1.2 ssl_cipher_list = EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!aNULL; ssl_prefer_server_ciphers = yes

Pour générer le fichier du paramètre Diffie-Hellman j'ai utilisé, sur un ordinateur avec une forte entropie, la commande suivante :

openssl dhparam -outform PEM -out dh4096.pem -rand /dev/urandom 4096
log_path = syslog syslog_facility = mail auth_verbose = yes
namespace inbox { inbox = yes type = private mailbox Drafts { auto = subscribe special_use = \Drafts } mailbox Junk { auto = subscribe special_use = \Junk } mailbox Sent { auto = subscribe special_use = \Sent } mailbox Trash { auto = subscribe special_use = \Trash } }
postmaster_address =postmaster@domaine.eu
protocol lmtp { postmaster_address = postmaster@domaine.eu mail_plugins = $mail_plugins sieve auth_socket_path = /var/run/dovecot/auth-master }
plugin { sieve = /var/mail/sieve/users/%u.sieve sieve_after = /var/mail/sieve/after sieve_before = /var/mail/sieve/before # After Dovecot v2.3 these settings are deprecated in newer versions # https://wiki2.dovecot.org/Pigeonhole/Sieve/Configuration # sieve_global_dir = /var/lib/dovecot/sieve/ # sieve_dir = ~/sieve # use sieve_global instead sieve_global_dir # sieve_global = /var/lib/dovecot/sieve/ }
userdb { driver = static args = uid=5000 gid=5000 home=/home/vmail/%d/%n allow_all_users=yes }

Avec cette configuration, les utilisateurs virtuels utiliseront le répertoire /var/mail/$domain/$user/ et l'utilisateur vmail sera le propriétaire. Pour que cela fonctionne, il faudra créer les dossiers des domaines hébergés, mais Dovecot créera ceux des utilisateurs virtuels.

mkdir -p /var/mail/domaine.eu
chown vmail:vmail /var/mail/domaine.eu && chmod 770 /var/mail/domaine.eu

Paramètre MySQL pour Dovecot

Les paramètres de connexion à la base de données se configure dans dovecot-sql.conf.ext :

driver = mysql connect = host=127.0.0.1 dbname=db_mail user=postmaster password=xxxxxxxx default_pass_scheme = SHA512-CRYPT user_query = SELECT ('5000') as 'uid',('5000') as 'gid' password_query = SELECT CONCAT(user.user, '@', domain.name) AS user,user.password FROM user,domain WHERE user.domain_id=domain.id AND CONCAT(user.user, '@', domain.name)='%u'

Pour protéger le fichier :

chown root:root /etc/dovecot/dovecot-sql.conf.ext && chmod 400 /etc/dovecot/dovecot-sql.conf.ext

Configuration de Sieve

Création des dossiers nécessaires au fonctionnement :

mkdir -p /var/mail/sieve/before
mkdir /var/mail/sieve/after
mkdir /var/mail/sieve/users
chown -R vmail:vmail /var/mail/sieve && chmod -R 770 /var/mail/sieve

Si vous voulez avoir des règles spécifiques pour un utilisateur, il faut créer un fichier $user@$domain.sieve dans le dossier de l'utilisateur (example@domaine.eu dans notre cas). Tous les fichiers .sieve dans le dossier before seront utilisés pour tous les utilisateurs virtuels et avant leur configuration individuelle, par contre les fichiers .sieve dans le dossier after seront utilisées après. Créons un fichier spam.sieve dans le répertoire /var/mail/sieve/before avec le contenu suivant qui déplacera tous les messages avec drapeau SPAM dans le dossier Junk :

vi /var/mail/sieve/before/spam.sieve

require ["envelope", "fileinto", "imap4flags", "regex"]; if not header :regex "message-id" ".*@.*\." { fileinto "Junk"; } if header :contains "X-Spam-Level" "*****" { fileinto "Junk"; }

puis changeons les permissions sur ce fichier :

chown vmail:vmail /var/mail/sieve/before/spam.sieve && chmod 660 /var/mail/sieve/before/spam.sieve
==== Lancement du service ====
Nous pouvons maintenant lancer ce service avec la commande
<code>
systemctl restart dovecot

mais avant il est préférable de lancer dans un autre terminal l'affichage des logs pour voir les éventuelles erreurs de configuration.

tail -f /var/log/syslog

Tester la configuration

En gardant un œil ouvert sur syslog nous effectuons quelques tests

echo "test" | mail -s "Test" root@domaine.eu

Si tout est bien configuré, un email arrive dans la boite et aucune apparaît dans les logs.

Maintenant ouvrons avec Telnet une connexion sur notre serveur SMTP et essayons d'envoyer un courrier sur une adresse qui n'est pas de notre réseau et donc le domaine n'est pas indiqué en paramètre de la variable mydestination du fichier de configuration de Postfix /etc/postfix/main.cf afin de voir si le serveur refuse bien de relayer le courrier comme il doit le faire (rien de pire qu'un SMTP ouvert) pour les domaines non autorisés.

telnet host.domaine.eu 25
Trying xxx.xxx.xxx.xxx...
Connected to host.domaine.eu.
Escape character is '^]'.
220 domaine.eu ESMTP Postfix (Debian/GNU)
EHLO gmail.com
250-domaine.eu
250-PIPELINING
250-SIZE 20480000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
MAIL FROM: <user@gmail.com>
250 2.1.0 Ok
RCPT TO: <mail@yahoo.com>
554 5.7.1 <mail@yahoo.com>: Relay access denied

Essayons maintenant d'envoyer un courrier depuis une de nos adresses configurées sur le serveur vers un domaine non configuré dans Postfix. Nous devons obtenir un refus puisque la configuration autorise l'envoi de courrier que depuis des utilisateurs authentifiés.

telnet host.domaine.eu 25
Trying xxx.xxx.xxx.xxx...
Connected to host.domaine.eu.
Escape character is '^]'.
220 domaine.eu ESMTP Postfix (Debian/GNU)
EHLO domaine.eu
250-domaine.eu
250-PIPELINING
250-SIZE 20480000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
MAIL FROM: <postmaster@domaine.eu>
250 2.1.0 Ok
RCPT TO: <mail@yahoo.com>
554 5.7.1 <mail@yahoo.com>: Relay access denied

Et pour les couches sécurisées, elles peuvent être testées avec ces commandes :

openssl s_client -servername mail.domaine.eu -connect mail.domaine.eu:smtps
openssl s_client -servername mail.domaine.eu -connect mail.domaine.eu:imaps

Configuration de Postgrey

Après l’installation du paquet, nous devons éditer le fichier de configuration /etc/postfix/main.cf afin de modifier la variable smtpd_recipient_restrictions.

smtpd_recipient_restrictions = reject_rbl_client xbl.spamhaus.org, reject_rbl_client pbl.spamhaus.org, reject_rbl_client sbl.spamhaus.org, reject_rbl_client multi.uribl.com, reject_rbl_client rbl-plus.mail-abuse.org, reject_rbl_client dialups.mail-abuse.org, reject_invalid_hostname, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, permit_mynetworks, permit_sasl_authenticated, permit_auth_destination, reject_unauth_destination, reject_unverified_recipient, check_policy_service inet:127.0.0.1:10023, permit

Puis il faut relancer Postfix en surveillant les logs :

systemctl restart postfix

Configuration de Clamav

Ce sera Amavis-new qui fera le pont entre Postfix et Clamav. Le fichier de configuration /etc/amavis/conf.d/15-av_scanners d’Amavis permet d’utiliser d'autres programmes anti-virus.

La configuration par défaut de ClamAV nous conviendra ; son fichier est /etc/clamav, vous y trouverez plus d’options.

Il faut ajouter l’utilisateur clamav au groupe amavis afin qu’Amavisd-new ait des droits sur les fichiers de ClamAV et inversement :

adduser clamav amavis adduser amavis clamav

Configuration d’Amavis-new

Amavis servira pour le passage des messages entrants à des filtres comme Clamav et Spamassassin. Il faut ajouter les sections suivantes dans le fichier de configuration /etc/postfix/master.cf :

amavis unix - - - - 2 smtp -o smtp_data_done_timeout=1200 -o smtp_send_xforward_command=yes -o disable_dns_lookups=yes -o max_use=20 127.0.0.1:10025 inet n - - - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_restriction_classes= -o smtpd_delay_reject=no -o smtpd_client_restrictions=permit_mynetworks,reject -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o smtpd_data_restrictions=reject_unauth_pipelining -o smtpd_end_of_data_restrictions= -o mynetworks=127.0.0.0/8 -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000 -o smtpd_client_connection_count_limit=0 -o smtpd_client_connection_rate_limit=0 -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

Ces deux paragraphes permettront la création des points d’accrochage entre le module smtpd de Postfix et le daemon amavisd.

Les options -o indiquées surchargeront éventuellement celles qui seraient données dans main.cf pour les services en question, c'est à dire d'une part smtp-amavis et d'autre part le service smtpd attaché à amavis sur le port 10025.

Ajoutez aussi les deux lignes suivantes immédiatement en dessous du service de transport “pickup” :

pickup unix n - y 60 1 pickup -o content_filter= -o receive_override_options=no_header_body_checks

Ceci empêchera la classification en tant que pourriel des messages de rapport de pourriels.

De plus, il faut modifier le fichier main.cf pour indiquer à Postfix que smtpd doit se connecter à Amavis, mais il y a juste une ligne à ajouter :

content_filter=smtp-amavis:[127.0.0.1]:10024

Les fichiers de configuration d’Amavis sont dans le répertoire /etc/amavis/conf.d.

Pour activer la détection de spam et de virus; il faut ensuite décommenter les lignes utiles dans le fichier /etc/amavis/conf.d/15-content_filter_mode :

use strict; # You can modify this file to re-enable SPAM checking through spamassassin # and to re-enable antivirus checking. # # Default antivirus checking mode # Please note, that anti-virus checking is DISABLED by # default. # If You wish to enable it, please uncomment the following lines: #@bypass_virus_checks_maps = ( # \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re); # # Default SPAM checking mode # Please note, that anti-spam checking is DISABLED by # default. # If You wish to enable it, please uncomment the following lines: #@bypass_spam_checks_maps = ( # \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); 1; # ensure a defined return

Cependant, il est préférable de copier ces lignes dans le fichier 50-user comme pour toutes modifications des variables de la configuration. Le fichier /etc/amavis/conf.d/20-debian_defaults a son importance, car il contient bon nombre de paramètres de configuration d' Amavis. Dans les grandes lignes, mieux vaut garder cette configuration, sauf que :

si vous désirez que les tags posés par spamassassin soient systématiquement ajoutés dans les en-têtes de messages, ça n'ira pas ;

si vous voulez que les spams ne soient jamais éliminés, mais simplement marqués comme tels, ça n'ira pas non plus ;

si par la suite, vous souhaitez, comme nous le ferons dans le chapitre suivant, utiliser des domaines « virtuels » vos tags risquent de ne jamais apparaître.

En effet, Amavisd-new ne retranscrit les tags de spamassassin que pour les messages à destination des domaines référencés dans la variable (liste) @local_domains_acl.

De plus, la variable $sa_kill_level_deflt définit le score à partir duquel nous sommes surs qu'un message est un spam, et la variable $final_spam_destiny indique quoi faire de ce message dans ce cas.

Dans la configuration par défaut, vous constaterez que si un message obtient un score >= 100, il est « D_BOUNCE » ce qui veut dire qu'il est mis en quarantaine locale et que le destinataire ne reçoit rien. Certes, un score de 100 est assez significatif, mais tout de même, peut-être souhaiterez-vous vous montrer plus libéral.

En cas de refus de tags de la part d'Amavis, de vérifier que le problème ne vient pas de la variable @local_domains_acl. Passer celle-ci avec la valeur @local_domains_acl = ( “.” ); permet d’effectuer le marquage des tags anti-spam quel que soit le domaine de destination.

Enfin, les variables $sa_tag_level_deflt et $sa_tag2_level_deflt influent sur le marquage du message, de même que la variable $sa_spam_subject_tag a un effet direct sur l’esthétique du message délivré.

Voilà à quoi pourrait ressembler le fichier /etc/amavis/conf.d/50-user :

use strict; # # Place your configuration directives here. They will override those in # earlier files. # # See /usr/share/doc/amavisd-new/ for documentation and examples of # the directives you can use in this file # @local_domains_acl = ( "." ); @bypass_virus_checks_maps = ( \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re); @bypass_spam_checks_maps = ( \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); $sa_tag_level_deflt = -9999; # note minimale pour ajouter les tags X-Spam... à l'en-tête des emails # ici, nous sommes à peu près surs que le tag sera toujours présent $sa_tag2_level_deflt = 5.0; # note minimale pour ajouter le tag X-Spam-Flag: YES # et modifier l'objet $sa_kill_level_deflt = 100; # note à partir de laquelle les mails sont traités comme définis # par la variable $final_spam_destiny (ici ils sont acceptés) $sa_spam_subject_tag = '[SPAM]'; # chaine ajoutée à l'objet de l'email $final_spam_destiny = D_PASS; # Pour ne pas en dire trop sur les armes employées $X_HEADER_LINE = "spam & virus filtering at $mydomain"; #------------ Do not modify anything below this line ------------- 1; # ensure a defined return

Vérifier la configuration

Pour cela, il faut commencer par relancer les services en observant les logs afin de trouver les éventuelles erreurs :

systemctl restart postfix systemctl restart amavis

Et de vérifier que les programmes Postfix et Amaivs soit bien à l'écoute :

netstat -tap | grep LISTEN tcp 0 0 0.0.0.0:submissions 0.0.0.0:* LISTEN 27299/master tcp 0 0 0.0.0.0:smtp 0.0.0.0:* LISTEN 27299/master tcp 0 0 0.0.0.0:imaps 0.0.0.0:* LISTEN 597/dovecot tcp 0 0 localhost:10023 0.0.0.0:* LISTEN 13838/postgrey --pi tcp 0 0 localhost:10024 0.0.0.0:* LISTEN 28665/amavisd-new ( tcp 0 0 localhost:10025 0.0.0.0:* LISTEN 27299/master

Installation des paquets suggérés

Afin de lire certains formats de fichiers, Amavis suggère l'installation de paquets supplémentaires.

apt install arj cabextract cpio lhasa lzop nomarch p7zip rpm unrar-free unzip zip

Configuration de Spamassasin

Les alternatives

DSPAM n’est plus maintenu et le paquet est enlevé des dépôts depuis Debian Jessie ;

Rspamd est un projet intéressant ;

Bogofilter est un filtre antispam efficace, comme alternative ou comme complément à Spamassassin.

Paquets facultatifs

Il existe des paquets facultatifs qui s’intègrent avec Spamassassin pour une meilleure détection des spams :

apt install pyzor razor

Puis :

user@host:~# su - amavis -s /bin/bash $ razor-admin -create $ razor-admin -register

Activation du service

Dans le fichier de configuration est /etc/default/spamassassin :

CRON=1

puis :

systemctl start spamassassin

Configuration

Sauvegardons le fichier original de la configuration local.cf avant de modifier les paramètres :

cp /etc/spamassassin/local.cf /etc/spamassassin/local.cf.original.bak

rewrite_header Subject [SPAM] report_safe 1 required_score 5.0 use_bayes 1 bayes_auto_learn 1

Nous pouvons redémarrer les services SpamAssassin et Postfix :

systemctl restart postfix
systemctl restart amavis
systemctl restart spamassassin

Vérifier le fonctionnement

Pour vérifier si cela fonctionne, envoyez-vous un e-mail d’un autre fournisseur et vous devriez voir des en-têtes plus ou moins semblables aux suivantes :

X-Virus-Scanned: Debian amavisd-new at host.domaine.eu
X-Spam-Flag: NO
X-Spam-Score: 0.001
X-Spam-Level:
X-Spam-Status: No, score=0.001 tagged_above=-9999 required=5
tests=[HTML_MESSAGE=0.001] autolearn=ham autolearn_force=no

Configurer SPF

Permettre à votre serveur d’envoyer pour votre domaine

SPF (Sender Policy Framework) est un mécanisme qui confirme que l’IP de votre serveur est autorisé à envoyer des e-mails pour votre domaine. Techniquement, il est un enregistrement DNS TXT qui ressemble à ceci :

domaine.eu. IN TXT "v=spf1 mx ip4:0.0.0.1 ~all"

Cet enregistrement DNS permet aux autres serveurs de messagerie de savoir que les serveurs qui possèdent un enregistrement MX pour mon domaine sont également autorisés à envoyer des e-mails. Pour plus d’informations sur la syntaxe SPF, vous pouvez consulter la documentation officielle. Sans un enregistrement SPF correctement configuré, les autres serveurs de messagerie pourraient considérer vos courriers comme un SPAM ou carrément les laisser tomber.

SPF Record pour les courriers entrants

Maintenant que nous avons mis en place notre propre enregistrement SPF, nous allons configurer Postfix pour vérifier que d’autres serveurs de messagerie puissent communiquer avec nous comme nous avons fait. Avant tout, nous allons ajouter les deux lignes suivantes à la fin de /etc/postfix-policyd-spf-python/policyd-spf.conf :

Header_Type = AR Authserv_Id = hostname.domaine.eu

Pour connaître les différentes options, il existe la commande :

man policyd-spf.conf

Puis nous éditons le fichier master.cf :

policy-spf unix - n n - - spawn user=nobody argv=/usr/bin/policyd-spf

Ensuite nous modifions dans le fichier /etc/postfix/main.cf la section smtpd_recipient_restrictions pour ajouter la ligne de check_policy_service comme nous le voyons ci-dessous ainsi qu’un paramètre policy-spf_time_limit :

smtpd_recipient_restrictions = reject_rbl_client xbl.spamhaus.org, reject_rbl_client pbl.spamhaus.org, reject_rbl_client sbl.spamhaus.org, reject_rbl_client multi.uribl.com, reject_rbl_client rbl-plus.mail-abuse.org, reject_rbl_client dialups.mail-abuse.org, reject_invalid_hostname, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, permit_mynetworks, permit_sasl_authenticated, permit_auth_destination, reject_unauth_destination, reject_unverified_recipient, check_policy_service unix:private/policy-spf, check_policy_service inet:127.0.0.1:10023, permit policy-spf_time_limit = 3600s

Placez le service de politique après reject_unauth_destination afin d’éviter que des réponses inattendues du service de politique ne fassent de votre système un relais ouvert (ceci est recommandé pour tous les services de politique). En outre, placez le service de politique après avoir autorisé les expéditeurs locaux. Vous souhaitez que le SPF ne vérifie que le courrier entrant provenant d’Internet, et non le courrier sortant de vos utilisateurs.

Nous pouvons maintenant relancer le service :

systemctl restart postfix

Notre serveur peut maintenant vérifier les enregistrements SPF d’un autre serveur de messagerie. Pour vous assurer que cela fonctionne, envoyez-vous un e-mail depuis un autre fournisseur et vous devriez voir l’en-tête suivant :

Authentication-Results: myserver.domaine.eu; spf=pass (sender SPF authorized)
[...] receiver=example@domaine.eu)

OpenDKIM

DKIM (DomainKeys Identified Mail) est un mécanisme qui valide l'identité du nom de domaine d'un email par une authentification cryptographique. Bien que non obligatoire, la mise en place DKIM améliore les chances que les courriers envoyés à partir de votre serveur ne sont pas marqués comme SPAM par d'autres fournisseurs. Avec cette configuration, OpenDKIM vérifiera également la clé pour les e-mails entrants.

Configuration

Sauvegardons le fichier original de configuration :

cp /etc/opendkim.conf /etc/opendkim.conf.original.bak

Puis nous configurons /etc/opendkim.conf :

AutoRestart Yes AutoRestartRate 10/1h UMask 0002 Syslog yes SyslogSuccess Yes LogWhy Yes OversignHeaders From AlwaysAddARHeader yes Canonicalization relaxed/simple ExternalIgnoreList refile:/etc/postfix/dkim/TrustedHosts InternalHosts refile:/etc/postfix/dkim/TrustedHosts KeyTable refile:/etc/postfix/dkim/KeyTable SigningTable refile:/etc/postfix/dkim/SigningTable Mode sv PidFile /var/run/opendkim/opendkim.pid SignatureAlgorithm rsa-sha256 UserID opendkim:opendkim Socket local:/var/spool/postfix/opendkim/opendkim.sock

Puis nous devons créer les dossiers nécessaires :

mkdir -p /etc/postfix/dkim/keys/domaine.eu/

Nous créons maintenant /etc/postfix/dkim/TrustedHosts, ce fichier contiendra les hôtes et les domaines pour lesquels OpenDKIM devra signer les emails :

localhost 127.0.0.1 ::1 domaine.eu

Nous créons ensuite /etc/postfix/dkim/KeyTable, ce fichier indiquera à OpenDKIM la clé qu'il devra utiliser pour chaque sélecteur.

mail._domainkey.domaine.eu domaine.eu:mail:/etc/postfix/dkim/keys/domaine.eu/mail.private

Et enfin le fichier /etc/postfix/dkim/SigningTable, ce fichier indiquera à OpenDKIM quel sélecteur il devra utiliser pour chaque domaine.

*@domaine.eu mail._domainkey.domaine.eu

Nous générons ensuite une paire de clefs (publique/privé) pour notre domain :

cd /etc/postfix/dkim/keys/domaine.eu/
opendkim-genkey -s mail -d domaine.eu

Parmi les deux fichiers créés mail.private contient la clef privée et mail.txt contient la clef publique, changeons les permissions :

chown -R opendkim: /etc/postfix/dkim/keys
chmod -R 700 /etc/postfix/dkim/keys
chmod 400 /etc/postfix/dkim/keys/domaine.eu/*

Intégration Postfix

La dernière chose que nous avons à faire est de configurer Postfix pour qu'il puisse communiquer avec OpenDKIM. Nous créons ce dossier

mkdir /var/spool/postfix/opendkim
chown opendkim: /var/spool/postfix/opendkim
adduser postfix opendkim

Puis nous éditons le fichier /etc/postfix/main.cf pour ajouter :

smtpd_milters = unix:/opendkim/opendkim.sock

Nous pouvons relancer ces services :

systemctl restart opendkim
systemctl restart postfix

Intégration DNS

Pour que DKIM fonctionne, nous devons configurer un enregistrement TXT DNS dans la zone du domaine. Ce record a été générée automatiquement par OpenDKIM dans le fichier mail.txt mentionné précédemment :

mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkJq0CW3tl2XHZ1CN5XdbqRDU7KfXOJ70nlwI09bHmDU63/Yz3J5rl863S0t2ncVHfIudZANj0OaiJe5HRR7WCsjuNIhQFfPFGIWLNClpxqdQVQURI38sAGeyn7Ed/Cor1AiWABzFWzel0kvXILw8K/NTzxaAPeSa9ttwQEgSmowIDAQAB" ; ----- DKIM key mail for domaine.eu

Tout ce que vous devons faire est de copier et de coller cet enregistrement dans notre fichier de zone DNS. Pour vous assurer que OpenDKIM fonctionne, vous pouvez envoyer un email vide à check-auth@verifier.port25.com et vous devriez recevoir une réponse avec le contenu suivant:

==========================================================
Summary of Results
==========================================================
SPF check: pass
DomainKeys check: neutral
DKIM check: pass
Sender-ID check: pass
SpamAssassin check: ham

L'utilisation de mail-tester.com vous aidera aussi à vérifier la configuration SPF et DKIM.

OpenDMARC

DMARC (Domain-based Message Authentication, Reporting & Conformance) standardisation des mécanismes d'authentification SPF et DKIM. Il permet au propriétaire d'un nom de domaine d'indiquer que son email est protégée par SPF et/ou DKIM et ce que les autres fournisseurs doivent faire avec les e-mails qui ne passent pas ces contrôles.

Configuration

Sauvegardons le fichier de la configuration d'origine :

cp /etc/opendmarc.conf /etc/opendmarc.conf.original.bak
rm /etc/opendmarc.conf
gunzip /usr/share/doc/opendmarc/opendmarc.conf.sample.gz
cp /usr/share/doc/opendmarc/opendmarc.conf.sample /etc/opendmarc.conf

AutoRestart true AutoRestartRate 10/1h UMask 0002 Syslog true AuthservID hostname.domaine.eu TrustedAuthservIDs hostname.domaine.eu IgnoreHosts /etc/postfix/dkim/TrustedHosts RejectFailures false UserID opendmarc:opendmarc PidFile /var/run/opendmarc.pid Socket local:/var/spool/postfix/opendmarc/opendmarc.sock

Intégration avec Postfix

Créons ce dossier :

mkdir /var/spool/postfix/opendmarc
chown opendmarc: /var/spool/postfix/opendmarc
adduser postfix opendmarc

Puis modifions le fichier de configuration /etc/postfix/main.cf de Postfix :

smtpd_milters = unix:/opendkim/opendkim.sock, unix:/opendmarc/opendmarc.sock

Nous pouvons en relancer ces services (toujours en regardant les logs) :

systemctl restart opendmarc
systemctl restart postfix

Pour vérifier le fonctionnement, vous devriez voir dans les en têtes de vos messages entrants :

Authentication-Results: host.domaine.eu; dmarc=pass header.from=gmail.com

Intégration DNS

DMARC, comme SPF et DKIM, est basé sur les enregistrements DNS TXT.

_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:postmaster@domanaine.eu; ruf=mailto:postmaster@domanaine.eu"

Cela indique à d'autres fournisseurs de ne pas rejeter ou mettre vos emails en quarantaine en cas d'échec de la vérification FPS ou DKIM échouer mais d'envoyer un rapport quotidien de ces vérifications au postmaster@domanaine.eu. Pour plus d'informations sur la syntaxe DMARC, voici un article de Google.

Monit

Monit est un daemon qui surveille d'autres daemons et vérifie qu'ils soient lancés, en cas de crash il les redémarre automatiquement. Il n'est pas lié à un serveur de messagerie et il est assez facile à mettre en place. Sauvegardons le fichier de la configuration d'origine :

cp /etc/monit/monitrc /etc/monit/monitrc.original.bak

Puis éditions la configuration pour adapter ces valeurs et décommenter ces paramètres, les autres valeurs par défauts et actives peuvent être laissées comme telles :

set daemon 30 set logfile syslog facility log_daemon set httpd port 2812 and use address localhost allow localhost set mailserver localhost with timeout 30 seconds using hostname myserver.domaine.eu set mail-format { from: monit@domaine.eu } set alert root@domaine.eu include /etc/monit/conf.d/*

Puis nous créons le fichier /etc/monit/conf.d/mail avec le contenu suivant :

check process postfix with pidfile "/var/spool/postfix/pid/master.pid" start program = "/bin/systemctl start postfix" stop program = "/bin/systemctl stop postfix" alert monit@domaine.eu group mail check process dovecot with pidfile "/run/dovecot/master.pid" start program = "/bin/systemctl start dovecot" stop program = "/bin/systemctl stop dovecot" alert monit@domaine.eu group mail depends on postfix check process spamassassin with pidfile "/run/spamassassin.pid" start program = "/bin/systemctl start spamassassin" stop program = "/bin/systemctl stop spamassassin" alert monit@domaine.eu group mail depends on postfix, dovecot check process opendkim with pidfile "/run/opendkim/opendkim.pid" start program = "/bin/systemctl start opendkim" stop program = "/bin/systemctl stop opendkim" alert monit@domaine.eu group mail depends on postfix, dovecot check process opendmarc with pidfile "/run/opendmarc/opendmarc.pid" start program = "/bin/systemctl start opendmarc" stop program = "/bin/systemctl stop opendmarc" alert monit@domaine.eu group mail depends on postfix, dovecot

Donnons de bonne permissions à ce nouveau fichier :

chown root: /etc/monit/conf.d/mail && chmod 600 /etc/monit/conf.d/mail

Nous pouvons maintenant relancer ce service :

monit reload

Avec la commande monit summary nous vérifions le fonctionnement et obtenons un rapport semblable

The Monit daemon 5.9 uptime: 0m
Process 'postfix' Running
Process 'dovecot' Running
Process 'spamassassin' Running
Process 'opendkim' Running
Process 'opendmarc' Running

Mailman

Pour gérer des listes de diffusion avec cette configuration, vous pouvez installer Mailman.

Conclusion

Nous avons maintenant un serveur de messagerie correctement configuré. Il pourrait être encore amélioré par la mise en place de détection de greylisting et de virus.

Réferences

Les tutoriaux et les pages d’aide qui furent utilisés pour construire cette page :

Setting up a mail server de Captainark

Installation d'un serveur mail complet

NSA-proof your e-mail in 2 hours

help.ubuntu.com/Postfix/SPF

Installation d'une politique de sécurité des emails avec OpenDKIM et SPF

Postfix before-queue Milter support

Postfix limit incoming or receiving email rate

Kimsufi, votre reverse DNS ne correspond pas avec votre domaine d'envoi.

Configuration pour avoir une bonne sécurité du SSL

Greylisting to avoid spam

Filtrer avec Amavis

Filtrage du courrier éléctronique