Postfix Dovecot MySQL sur Ubuntu 22.04

Introduction

Ce guide vous accompagnera pas à pas dans la configuration d’un serveur de messagerie complet et sûr, en utilisant Postfix (SMTP), Dovecot (IMAP/POP3), MariaDB (base de données des utilisateurs) et Rspamd (antispam). Le serveur utilisera exclusivement des connexions chiffrées avec des certificats Let’s Encrypt.

À la fin, vous disposerez d’un serveur de messagerie professionnel avec :

  • Domaines et utilisateurs virtuels gérés via base de données
  • Chiffrement TLS obligatoire pour toutes les connexions
  • Filtres antispam avancés
  • Protection contre les attaques par force brute
  • Prise en charge des filtres Sieve côté serveur

1. Prérequis et préparation du système

Exigences de base

Pour ce guide, vous aurez besoin de :

  • Un VPS avec IP statique (je conseille Hetzner pour la fiabilité et les prix)
  • Ubuntu 22.04 LTS installé
  • Un domaine enregistré avec accès à la configuration DNS
  • Au moins 2 Go de RAM (4 Go conseillés)

Configuration DNS

Avant de commencer, configurez correctement les enregistrements DNS de votre domaine :

# Enregistrement A pour le serveur mail
mail.exemple.com    A    [IP_VPS]

# Enregistrement MX pour le domaine
exemple.com         MX   10 mail.exemple.com

# Enregistrement PTR (reverse DNS) — à configurer dans le panneau du fournisseur VPS
[IP_VPS]           PTR  mail.exemple.com

# Enregistrement SPF pour autoriser le serveur à envoyer du courrier
exemple.com         TXT  "v=spf1 mx -all"

Important : l’enregistrement PTR doit correspondre au nom d’hôte du serveur. Vérifiez avec :

hostname -f
# Doit retourner : mail.exemple.com

Installation des paquets

Mettons à jour le système et installons tous les composants nécessaires :

apt update && apt upgrade -y

apt install -y \
  mariadb-server \
  postfix postfix-pcre postfix-mysql \
  dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd \
  dovecot-mysql dovecot-sieve dovecot-managesieved \
  rspamd redis-server \
  certbot \
  pwgen \
  fail2ban \
  ufw

Pendant l’installation de Postfix, sélectionnez « Internet Site » et saisissez votre domaine (exemple.com).

2. Certificats SSL/TLS avec Let’s Encrypt

Générons tout de suite les certificats SSL qui protégeront toutes les communications :

# On arrête temporairement les services qui utilisent le port 80
systemctl stop apache2 nginx

# On génère le certificat avec une clé RSA 4096 bits
certbot certonly --standalone --rsa-key-size 4096 -d mail.exemple.com

# On configure le renouvellement automatique avec redémarrage des services
cat > /etc/letsencrypt/cli.ini << EOF
post-hook = systemctl restart postfix dovecot
EOF

3. Configuration de la base de données MariaDB

Sécurisation de la base

Tout d’abord, sécurisons MariaDB :

mysql_secure_installation

# Répondez :
# - Set root password? [Y]
# - Remove anonymous users? [Y]
# - Disallow root login remotely? [Y]
# - Remove test database? [Y]
# - Reload privilege tables? [Y]

Création de la base et de l’utilisateur

Générons un mot de passe sécurisé pour l’utilisateur de la base :

# Génère un mot de passe de 30 caractères
pwgen -s1 30
# Exemple de sortie : rEfsoI2KSejLEHmDNvAYnVEHr8o1ig

Créons maintenant la base et les tables :

mysql -u root -p

-- Création base et utilisateur
CREATE DATABASE mailserver;
CREATE USER 'mailuser'@'localhost' IDENTIFIED BY 'rEfsoI2KSejLEHmDNvAYnVEHr8o1ig';
GRANT ALL PRIVILEGES ON mailserver.* TO 'mailuser'@'localhost';
FLUSH PRIVILEGES;

USE mailserver;

-- Table domaines
CREATE TABLE IF NOT EXISTS `virtual_domains` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Table utilisateurs
CREATE TABLE IF NOT EXISTS `virtual_users` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `email` varchar(100) NOT NULL,
  `password` varchar(150) NOT NULL,
  `quota` bigint(20) NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Table alias
CREATE TABLE IF NOT EXISTS `virtual_aliases` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `source` varchar(100) NOT NULL,
  `destination` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

EXIT;

Ajout de domaines et d’utilisateurs

Pour ajouter un domaine et un utilisateur, générons d’abord un mot de passe chiffré :

# Génère le mot de passe utilisateur
pwgen -s1 20
# Exemple : xK9mNp2Lq8Rt5Yw3Zb7

# Chiffre le mot de passe en SHA256
doveadm pw -s SHA256-CRYPT
# Saisissez le mot de passe quand demandé
# Exemple de sortie : {SHA256-CRYPT}$5$xvxyx8xOf5MSGsK.$zEBRszEg...

Ajoutons maintenant le domaine et l’utilisateur à la base :

mysql -u root -p mailserver

-- Ajoute le domaine
INSERT INTO virtual_domains (name) VALUES ('exemple.com');

-- Ajoute l’utilisateur (utilise le hash généré ci-dessus)
INSERT INTO virtual_users (domain_id, email, password)
VALUES (1, 'info@exemple.com', '{SHA256-CRYPT}$5$xvxyx8xOf5MSGsK.$zEBRszEg...');

-- Ajoute un alias
INSERT INTO virtual_aliases (domain_id, source, destination)
VALUES (1, 'postmaster@exemple.com', 'info@exemple.com');

EXIT;

4. Configuration de Postfix

Fichiers de mapping MySQL

Créons les fichiers qui permettent à Postfix d’interroger la base :

# Fichier : /etc/postfix/mysql-virtual-mailbox-domains.cf
cat > /etc/postfix/mysql-virtual-mailbox-domains.cf << EOF
user = mailuser
password = rEfsoI2KSejLEHmDNvAYnVEHr8o1ig
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
EOF

# Fichier : /etc/postfix/mysql-virtual-mailbox-maps.cf
cat > /etc/postfix/mysql-virtual-mailbox-maps.cf << EOF
user = mailuser
password = rEfsoI2KSejLEHmDNvAYnVEHr8o1ig
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
EOF

# Fichier : /etc/postfix/mysql-virtual-alias-maps.cf
cat > /etc/postfix/mysql-virtual-alias-maps.cf << EOF
user = mailuser
password = rEfsoI2KSejLEHmDNvAYnVEHr8o1ig
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
EOF

# On met les bonnes permissions
chmod 640 /etc/postfix/mysql-*.cf
chown root:postfix /etc/postfix/mysql-*.cf

Configuration main.cf

Configurons Postfix en modifiant le fichier principal :

# Sauvegarde du fichier d’origine
cp /etc/postfix/main.cf /etc/postfix/main.cf.backup

# Configuration de base
postconf -e "myhostname = mail.exemple.com"
postconf -e "mydomain = exemple.com"
postconf -e "myorigin = \$mydomain"
postconf -e "mydestination = localhost"
postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"

# Domaines et boîtes virtuelles
postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
postconf -e "virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf"
postconf -e "virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf"
postconf -e "virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf"

# Authentification SASL via Dovecot
postconf -e "smtpd_sasl_type = dovecot"
postconf -e "smtpd_sasl_path = private/auth"
postconf -e "smtpd_sasl_auth_enable = yes"
postconf -e "broken_sasl_auth_clients = yes"

# TLS/SSL
postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/mail.exemple.com/fullchain.pem"
postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/mail.exemple.com/privkey.pem"
postconf -e "smtpd_tls_security_level = may"
postconf -e "smtpd_tls_auth_only = yes"
postconf -e "smtp_tls_security_level = may"
postconf -e "smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1"
postconf -e "smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1"
postconf -e "smtpd_tls_mandatory_ciphers = high"
postconf -e "tls_high_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305"

# Restrictions
postconf -e "smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination"
postconf -e "smtpd_relay_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination"

# Limites
postconf -e "message_size_limit = 52428800"
postconf -e "mailbox_size_limit = 0"

Configuration master.cf

Activons le port submission (587) pour l’envoi authentifié :

# On modifie /etc/postfix/master.cf
# On décommente et modifie les lignes suivantes :

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=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

5. Configuration de Dovecot

Création de l’utilisateur et du répertoire mail

# Création utilisateur et groupe pour les boîtes virtuelles
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/vmail -m
chown -R vmail:vmail /var/vmail

Configuration de l’authentification

Modifions /etc/dovecot/conf.d/10-auth.conf :

# Mécanismes d’authentification
auth_mechanisms = plain login

# Désactive l’authentification en clair sans TLS
disable_plaintext_auth = yes

# Commenter la ligne auth-system et décommenter auth-sql
#!include auth-system.conf.ext
!include auth-sql.conf.ext

Configuration SQL

Créons /etc/dovecot/dovecot-sql.conf.ext :

driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=rEfsoI2KSejLEHmDNvAYnVEHr8o1ig

default_pass_scheme = SHA256-CRYPT

password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'

user_query = SELECT email as user,
  'vmail' as uid, 'vmail' as gid,
  '/var/vmail/%d/%n' as home,
  '*:storage=1G' as quota_rule
  FROM virtual_users WHERE email='%u'

iterate_query = SELECT email AS user FROM virtual_users

Configuration Mail Location

Modifions /etc/dovecot/conf.d/10-mail.conf :

mail_location = maildir:~/Maildir
mail_uid = vmail
mail_gid = vmail
first_valid_uid = 5000
last_valid_uid = 5000

Configuration SSL

Modifions /etc/dovecot/conf.d/10-ssl.conf :

ssl = required
ssl_cert = </etc/letsencrypt/live/mail.exemple.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.exemple.com/privkey.pem

Configuration Master Services

Modifions /etc/dovecot/conf.d/10-master.conf :

service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }
}

service pop3-login {
  inet_listener pop3 {
    port = 0  # Désactivé
  }
  inet_listener pop3s {
    port = 0  # Désactivé
  }
}

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}

service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
  }
}

service auth-worker {
  user = vmail
}

Activation de Sieve

Modifions /etc/dovecot/conf.d/20-lmtp.conf :

protocol lmtp {
  mail_plugins = $mail_plugins sieve
}

Et /etc/dovecot/conf.d/90-sieve.conf :

plugin {
  sieve = file:~/sieve;active=~/.dovecot.sieve
  sieve_global_path = /var/vmail/sieve/default.sieve
  sieve_dir = ~/sieve
  sieve_max_script_size = 1M
}

6. Configuration de Rspamd (antispam)

Rspamd est un système antispam avancé qui protégera le serveur contre le spam et les malwares.

Configuration de base

# On configure rspamd pour qu’il s’intègre à Postfix
cat > /etc/rspamd/local.d/worker-controller.inc << EOF
password = "\$2\$zy8npwwgqbpgo5ujnug6of3zy3rgpbmj\$k6mmm9xe3jugxr1bii4o5gxjfhqjjh4pg3iyhka4rq3479bjqzny";
enable_password = "\$2\$zy8npwwgqbpgo5ujnug6of3zy3rgpbmj\$k6mmm9xe3jugxr1bii4o5gxjfhqjjh4pg3iyhka4rq3479bjqzny";
EOF

# Configuration milter
cat > /etc/rspamd/local.d/worker-proxy.inc << EOF
bind_socket = "127.0.0.1:11332";
milter = yes;
timeout = 120s;
upstream "local" {
  default = yes;
  self_scan = yes;
}
EOF

# On ajoute rspamd à Postfix
postconf -e "smtpd_milters = inet:127.0.0.1:11332"
postconf -e "non_smtpd_milters = inet:127.0.0.1:11332"
postconf -e "milter_default_action = accept"

# On redémarre rspamd
systemctl restart rspamd

Signature DKIM

# On génère la clé DKIM
mkdir -p /var/lib/rspamd/dkim/
rspamadm dkim_keygen -b 2048 -s mail -k /var/lib/rspamd/dkim/mail.key > /var/lib/rspamd/dkim/mail.txt
chown -R _rspamd:_rspamd /var/lib/rspamd/dkim

# On configure DKIM
cat > /etc/rspamd/local.d/dkim_signing.conf << EOF
selector = "mail";
path = "/var/lib/rspamd/dkim/\$selector.key";
allow_username_mismatch = true;
EOF

# L’enregistrement DNS DKIM à ajouter se trouve dans :
cat /var/lib/rspamd/dkim/mail.txt

7. Configuration de Fail2ban

Protégeons le serveur contre les attaques par force brute :

# Création d’un jail pour Postfix
cat > /etc/fail2ban/jail.d/postfix.conf << EOF
[postfix-sasl]
enabled = true
filter = postfix-sasl
action = iptables-multiport[name=postfix-sasl, port="25,587,465", protocol=tcp]
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600
EOF

# Jail pour Dovecot
cat > /etc/fail2ban/jail.d/dovecot.conf << EOF
[dovecot]
enabled = true
filter = dovecot
action = iptables-multiport[name=dovecot, port="143,993,110,995", protocol=tcp]
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600
EOF

# Redémarrage de fail2ban
systemctl restart fail2ban

8. Configuration du pare-feu

# Configuration d’UFW
ufw allow 22/tcp    # SSH
ufw allow 25/tcp    # SMTP
ufw allow 587/tcp   # Submission
ufw allow 143/tcp   # IMAP
ufw allow 993/tcp   # IMAPS
ufw allow 80/tcp    # HTTP (pour Let’s Encrypt)
ufw allow 443/tcp   # HTTPS

# Activation du pare-feu
ufw enable

9. Tests et vérification

Test de la base

# Test de mapping Postfix
postmap -q exemple.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
# Sortie attendue : 1

postmap -q info@exemple.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
# Sortie attendue : 1

postmap -q postmaster@exemple.com mysql:/etc/postfix/mysql-virtual-alias-maps.cf
# Sortie attendue : info@exemple.com

Test des services

# Vérification configuration Postfix
postfix check

# Vérification configuration Dovecot
dovecot -n

# Test connexion SMTP
telnet localhost 25
EHLO test
# Doit afficher STARTTLS et AUTH

# Test IMAP
telnet localhost 143
a1 LOGIN info@exemple.com password
# Doit s’authentifier correctement

Test SSL/TLS

# Test certificat SMTP
openssl s_client -connect mail.exemple.com:587 -starttls smtp

# Test certificat IMAP
openssl s_client -connect mail.exemple.com:993

10. Configuration des clients de messagerie

Pour configurer un client mail (Thunderbird, Outlook, etc.), utilisez ces paramètres :

  • Serveur IMAP : mail.exemple.com, Port 993, SSL/TLS
  • Serveur SMTP : mail.exemple.com, Port 587, STARTTLS
  • Nom d’utilisateur : adresse email complète (info@exemple.com)
  • Mot de passe : le mot de passe de l’utilisateur
  • Authentification : Mot de passe normal

11. Maintenance et monitoring

Fichiers de logs

Les logs principaux à surveiller :

# Log mail général
tail -f /var/log/mail.log

# Log d’erreurs
tail -f /var/log/mail.err

# Log rspamd
tail -f /var/log/rspamd/rspamd.log

# Statistiques rspamd
rspamc stat

Sauvegarde

# Script de sauvegarde de la base
#!/bin/bash
mysqldump mailserver > /backup/mailserver-$(date +%Y%m%d).sql

# Sauvegarde des boîtes
rsync -av /var/vmail/ /backup/vmail/

# Sauvegarde des configurations
tar czf /backup/mail-config-$(date +%Y%m%d).tar.gz \
  /etc/postfix /etc/dovecot /etc/rspamd

Mises à jour

# Mise à jour sûre du système
apt update
apt upgrade -y
systemctl restart postfix dovecot rspamd

Résolution des problèmes courants

Erreur « Relay access denied »

Vérifiez que l’utilisateur est bien authentifié et que le domaine est correctement configuré dans la base.

Certificats qui ne fonctionnent pas

Vérifiez les permissions et les chemins des certificats. Dovecot nécessite le caractère < avant le chemin.

Mail classé en spam

Assurez-vous d’avoir correctement configuré SPF, DKIM et DMARC. Vérifiez aussi l’enregistrement PTR.

Conclusion

Vous disposez maintenant d’un serveur mail complet et sûr. N’oubliez pas de :

  • Surveiller régulièrement les logs
  • Maintenir le système à jour
  • Faire des sauvegardes régulières
  • Tester périodiquement la délivrabilité
  • Renouveler les certificats SSL avant leur expiration

Pour une sécurité supplémentaire, envisagez la mise en place complète des enregistrements DNS SPF, DKIM et DMARC pour améliorer la réputation de votre serveur.