Aller au contenu

Bonnes pratiques

Haute disponibilité

Enregistrements MX multiples

La première ligne de defense contre les pannes est la redundance DNS avec plusieurs enregistrements MX :

company.io.  300  IN  MX  10  mail-1.company.io.
company.io.  300  IN  MX  10  mail-2.company.io.
company.io.  300  IN  MX  20  mail-backup.company.io.
Configuration Comportement
MX priorité 10 x2 Load balancing entre mail-1 et mail-2 (même priorité)
MX priorité 20 Backup — utilise uniquement si les deux MX 10 sont down

Priorité identique = load balancing

Quand deux enregistrements MX ont la même priorité, les serveurs expéditeurs repartissent la charge aleatoirement entre les deux. C'est le mécanisme de HA le plus simple pour la messagerie.

Clustering Stalwart

Stalwart supporte le clustering actif-actif avec un backend de stockage partage :

graph TD
    S1["Stalwart 1<br/>10.20.1.30"] --> PG["PostgreSQL<br/>(stockage partage)"]
    S2["Stalwart 2<br/>10.20.1.31"] --> PG
    PG --> MinIO["MinIO (S3)<br/>(blobs)"]

Configuration du clustering :

# Instance 1
[cluster]
node-id = 1
bind-addr = "10.20.1.30:1179"
seed-nodes = ["10.20.1.31:1179"]

# Instance 2
[cluster]
node-id = 2
bind-addr = "10.20.1.31:1179"
seed-nodes = ["10.20.1.30:1179"]

DNS failover

Le DNS est le mécanisme de failover natif du protocole email. Configurer des TTL courts pour un basculement rapide :

Enregistrement TTL recommande Justification
MX 300 s (5 min) Basculement rapide entre serveurs
A (mail) 300 s Mise à jour rapide en cas de migration
SPF, DKIM 3600 s (1 h) Changent rarement
DMARC 3600 s Changent rarement

Stratégie de sauvegarde

Sauvegarde des boites aux lettres

Méthode Outil Fréquence RPO
Export Stalwart API /api/store/export Quotidien 24 h
Snapshot PostgreSQL pg_dump / pg_basebackup Quotidien 24 h
Snapshot S3 Réplication MinIO Continu ~0 (sync)
IMAP sync imapsync, offlineimap Quotidien 24 h

Script de sauvegarde

#!/bin/bash
# backup-stalwart.sh — Sauvegarde quotidienne

BACKUP_DIR="/backup/stalwart"
DATE=$(date +%Y%m%d)
RETENTION_DAYS=30

# 1. Export des donnees Stalwart
curl -s -X GET "http://localhost:8080/api/store/export" \
  -H "Authorization: Bearer ${STALWART_ADMIN_TOKEN}" \
  -o "${BACKUP_DIR}/stalwart-${DATE}.tar"

# 2. Chiffrer la sauvegarde
age -r "${BACKUP_PUBLIC_KEY}" \
  -o "${BACKUP_DIR}/stalwart-${DATE}.tar.age" \
  "${BACKUP_DIR}/stalwart-${DATE}.tar"
rm "${BACKUP_DIR}/stalwart-${DATE}.tar"

# 3. Supprimer les anciennes sauvegardes
find "${BACKUP_DIR}" -name "*.age" -mtime +${RETENTION_DAYS} -delete

# 4. Verifier la taille (alerte si trop petite = sauvegarde incomplete)
SIZE=$(stat -f%z "${BACKUP_DIR}/stalwart-${DATE}.tar.age" 2>/dev/null \
  || stat --format=%s "${BACKUP_DIR}/stalwart-${DATE}.tar.age")
if [ "$SIZE" -lt 1048576 ]; then
    echo "ALERTE: Sauvegarde anormalement petite (${SIZE} octets)" >&2
    exit 1
fi

echo "Sauvegarde terminee: stalwart-${DATE}.tar.age (${SIZE} octets)"

Test de restauration

# Restaurer sur une instance de test (jamais en production directement)
podman run -d --name stalwart-restore \
  -v /tmp/restore-data:/opt/stalwart-mail/data:Z \
  -p 18080:8080 \
  docker.io/stalwartlabs/stalwart-mail:latest

# Importer la sauvegarde
age -d -i /path/to/private-key \
  -o /tmp/stalwart-restore.tar \
  /backup/stalwart/stalwart-20260416.tar.age

curl -X POST "http://localhost:18080/api/store/import" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -F "file=@/tmp/stalwart-restore.tar"

# Verifier que les boites sont accessibles
curl -s http://localhost:18080/api/principal | jq '.items | length'

Tester la restauration mensuellement

Une sauvegarde qui n'a jamais ete testée n'est pas une sauvegarde. Planifier un test de restauration mensuel sur une instance isolee.

Deliverabilite

Reputation IP

La deliverabilite depend en grande partie de la reputation de l'adresse IP du serveur mail :

Facteur Impact Action
IP neuve Aucune reputation → mefiante Warm-up progressif
IP blacklistee Emails rejetes Delister, identifier la cause
Reverse DNS absent Emails rejetes par beaucoup Configurer le PTR record
Volume irregulier Pics suspects Lisser le volume d'envoi
Taux de rebond > 5% = penalise Nettoyer les listes, vérifier adresses

Warm-up d'une IP neuve

Quand vous déployer un nouveau serveur mail sur une IP sans historique, les grands fournisseurs (Gmail, Microsoft) limitent le volume accepte :

Semaine Volume quotidien max Actions
1 50 emails Envoyer a des destinataires engages
2 200 emails Augmenter progressivement
3 500 emails Monitorer le taux de delivery
4 1 000 emails Vérifier les postmaster tools
5-8 +1 000/semaine Montee progressive
8+ Volume normal Reputation etablie

Feedback loops

S'enregistrer aux programmes de feedback des grands fournisseurs pour recevoir les signalements de spam :

Fournisseur Programme URL d'inscription
Google Gmail Postmaster Tools https://postmaster.google.com/
Microsoft SNDS + JMRP https://sendersupport.olc.protection.outlook.com/
Yahoo Complaint Feedback Loop https://senders.yahooinc.com/

Monitoring des blacklists

# Verifier si l'IP est blacklistee
# Utiliser MX Toolbox ou un script de verification
for rbl in \
    zen.spamhaus.org \
    bl.spamcop.net \
    b.barracudacentral.org \
    dnsbl.sorbs.net; do
    result=$(dig +short "10.113.0.203.${rbl}" 2>/dev/null)
    if [ -n "$result" ]; then
        echo "BLACKLISTE sur ${rbl}: ${result}"
    else
        echo "OK: ${rbl}"
    fi
done

Reglage anti-spam

Faux positifs

Les faux positifs (emails legitimes marques comme spam) sont le problème operationnel numero un de la messagerie :

Cause fréquente Solution
Score trop agressif Augmenter le seuil de spam (5.0 → 6.0)
DNSBL trop large Retirer les RBL agressives
Domaine partenaire penalise Ajouter en allowlist
Signature DKIM cassee (forwarding) Vérifier la chaîne ARC
Contenu marketing legitime Entraîner le filtre bayesien (ham)

Entrainement du filtre bayesien

# Apprendre un email comme ham (non-spam)
curl -X POST "http://localhost:8080/api/spam/train" \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{"class": "ham", "message": "<raw-email-base64>"}'

# Apprendre un email comme spam
curl -X POST "http://localhost:8080/api/spam/train" \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{"class": "spam", "message": "<raw-email-base64>"}'

Allowlists et blocklists operationnelles

# Domaines de confiance (jamais filtres)
[spam.list.allowlist]
domains = [
    "partenaire-officiel.fr",
    "service-public.gouv.fr",
    "banque-entreprise.fr"
]

# Adresses specifiques en allowlist
addresses = [
    "important-contact@external.com"
]

Migration depuis Exchange/Gmail ou Postfix

Outils de migration IMAP

Outil Langage Fonctionnalité Recommandation
imapsync Perl Sync IMAP → IMAP, incremental, fiable Référence pour la migration
offlineimap Python Sync IMAP ↔ Maildir Alternative open source
larch Ruby Sync IMAP → IMAP, simple Petites migrations

Processus de migration

# 1. Migration incrementale (pendant la coexistence)
imapsync \
  --host1 old-server.company.io --user1 alice --password1 "old-pwd" \
  --host2 mail.company.io --user2 alice@company.io --password2 "new-pwd" \
  --ssl1 --ssl2 \
  --syncinternaldates \
  --exclude "Spam|Trash"

# 2. Migration finale (apres basculement DNS)
imapsync \
  --host1 old-server.company.io --user1 alice --password1 "old-pwd" \
  --host2 mail.company.io --user2 alice@company.io --password2 "new-pwd" \
  --ssl1 --ssl2 \
  --syncinternaldates \
  --delete2duplicates

Plan de migration type

Étape Action Duree
1 Déployer Stalwart, configurer DNS (sans changer MX) 1 semaine
2 Tester avec un groupe pilote (10 utilisateurs) 2 semaines
3 Migration incrementale des boites (imapsync) 1 semaine
4 Basculer le MX vers Stalwart 1 jour
5 Migration finale (derniers emails) 1 jour
6 Decommissionner l'ancien serveur (apres 30 jours)

Coexistence avec l'ancien serveur

Pendant la migration, les deux serveurs coexistent. L'ancien serveur reste le MX primaire jusqu'a l'étape 4. Les utilisateurs migres accedent a Stalwart, les autres restent sur l'ancien. Cela minimise le risque.

Troubleshooting

Echecs de livraison

Symptome Cause probable Diagnostic
550 5.1.1 User unknown Destinataire inexistant Vérifier l'adresse
550 5.7.1 Rejected by SPF IP non autorisee dans SPF dig company.io TXT \| grep spf
421 Too many connections Rate limiting du destinataire Reduire le débit sortant
451 Temporary failure Erreur transitoire (DNS, stockage) Vérifier DNS et stockage, reessayer
554 5.7.1 Rejected by DMARC Alignement DKIM/SPF échoue Vérifier la config DKIM et le From:
Email en spam chez Gmail Reputation IP / SPF/DKIM incomplet Gmail Postmaster Tools

Problèmes TLS

# Tester la connexion TLS SMTP
openssl s_client -connect mail.company.io:465 -quiet

# Tester STARTTLS SMTP
openssl s_client -connect mail.company.io:25 -starttls smtp -quiet

# Tester IMAPS
openssl s_client -connect mail.company.io:993 -quiet

# Verifier le certificat
echo | openssl s_client -connect mail.company.io:465 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer

Alignement DKIM

# Verifier que DKIM signe correctement
# Envoyer un email de test et examiner les en-tetes
swaks --to test@gmail.com \
      --from alice@company.io \
      --server mail.company.io:587 \
      --auth LOGIN --tls

# Dans les en-tetes du mail recu, verifier :
# Authentication-Results: ...
#   dkim=pass header.d=company.io header.s=default
#   spf=pass
#   dmarc=pass

Queue bloquee

# Lister les emails en queue
curl -s http://localhost:8080/api/queue/list \
  -H "Authorization: Bearer <admin-token>" | jq '.items | length'

# Voir les details d'un message en queue
curl -s http://localhost:8080/api/queue/list \
  -H "Authorization: Bearer <admin-token>" | jq '.items[0]'

# Forcer la relivraison
curl -X POST http://localhost:8080/api/queue/retry \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["<message-id>"]}'

# Purger les messages bloques depuis plus de 7 jours
curl -X DELETE "http://localhost:8080/api/queue/purge?older-than=7d" \
  -H "Authorization: Bearer <admin-token>"

Autoconfig qui ne fonctionne pas

Symptome Cause probable Solution
Thunderbird ne détecte pas le serveur DNS CNAME autoconfig manquant Ajouter l'enregistrement DNS
Outlook ne détecte pas le serveur SRV _autodiscover._tcp manquant Ajouter l'enregistrement DNS
Autoconfig retourne une erreur 404 Reverse proxy ne route pas vers Stalwart Vérifier la config du reverse proxy
Certificat invalide CNAME pointe vers un autre domaine Vérifier que le certificat couvre le CNAME

Commandes de diagnostic

# Test complet de la configuration email d'un domaine
# MX, SPF, DKIM, DMARC, reverse DNS, TLS, blacklists
dig company.io MX +short
dig company.io TXT +short
dig default._domainkey.company.io TXT +short
dig _dmarc.company.io TXT +short
dig -x $(dig mail.company.io A +short) +short

# Tester l'envoi SMTP avec details verbeux
swaks --to test@example.com \
      --from alice@company.io \
      --server mail.company.io:587 \
      --auth LOGIN --tls \
      --auth-user alice@company.io \
      -tlsc -tls-verify \
      --header "Subject: Test diagnostique"

# Verifier les logs Stalwart pour les erreurs recentes
podman logs --since 1h stalwart-mail 2>&1 | grep -iE "error|warn|fail"

Checklist operationnelle

Fréquence Action Outil
Quotidien Vérifier la taille de la queue Grafana dashboard
Quotidien Vérifier les echecs de livraison Alertes Prometheus
Hebdo Analyser les rapports DMARC DMARC Analyzer
Hebdo Vérifier les blacklists IP MX Toolbox / script
Mensuel Tester la restauration de sauvegarde Script de restauration
Mensuel Revoir les regles anti-spam (faux positifs) Retours utilisateurs
Trimestriel Rotation des cles DKIM API Stalwart + DNS
Trimestriel Mise à jour de Stalwart Podman pull + restart
Annuel Revoir la politique de retention DPO + juridique
Annuel Audit de sécurité de la configuration Checklist + pentest

Synthese

Opérer une messagerie auto-hebergee demande de la rigueur sur trois axes : la deliverabilite (reputation IP, SPF/DKIM/DMARC, monitoring des blacklists), la fiabilité (HA via MX multiples et clustering, sauvegardes testées) et la sécurité (TLS, anti-spam, audit). Le warm-up de l'IP et le déploiement progressif de DMARC sont les deux étapes les plus critiques lors d'un nouveau déploiement. La migration depuis un système existant se fait de manière incrementale avec imapsync et un basculement DNS maîtrise.