Décisions : vrai service (boîtes/IMAP), full self-host, suite Stalwart enveloppée par un rôle mince, identité via LDAP, PKI Let's Encrypt (public) + step_ca (interne). Topologie MX primaire + MX secours, enregistrements DNS publics, prérequis bloquant IP/PTR, décisions ouvertes et phasage. Conception seulement. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7.8 KiB
Conception — Service de courriel souverain (Chezlepro)
Statut : CONCEPTION (cadrage). Aucun rôle n'est encore écrit. Ce document fixe les décisions, les prérequis et la topologie avant toute implémentation.
1. Décisions arrêtées
| Sujet | Décision |
|---|---|
| Périmètre | Vrai service de courriel (boîtes utilisateurs, réception publique, IMAP) — pas un simple relais sortant. |
| Modèle | Full self-host : MX entrant et sortant chez Chezlepro, réputation d'IP propre. |
| Suite | Stalwart Mail Server (binaire unique Rust, AGPL ; SMTP/IMAP/JMAP/POP3 + anti-spam + DKIM intégrés). Adoptée et enveloppée par un rôle Set-OPS mince — pas de réimplémentation. |
| Identité | Boîtes/utilisateurs dans l'OpenLDAP existant (annuaire Stalwart → LDAP). Pas de comptes en double. |
| DNS | Enregistrements publics dans la zone chezlepro.ca ; noms internes dans PowerDNS. |
| PKI | Deux CA distinctes (voir §6) : Let's Encrypt pour les faces publiques, step_ca pour l'interne. |
Le rôle existant serveur_sendmail (relais sortant Postfix, sans boîtes) reste pour le
courrier de notification système (via client_smtp/msmtp). Il ne fait pas partie de ce
service et ne le remplace pas.
2. Prérequis BLOQUANT — l'IP publique
Le full self-host sortant est viable seulement si :
- IP publique fixe avec un PTR (reverse DNS) contrôlé pointant vers
mail1.chezlepro.ca; - IP absente des listes noires (Spamhaus, etc.) ;
- ports
25 / 465 / 587 / 993 / 443 / 80routables vers les nœuds mail ; - SPF/DKIM/DMARC en place + réchauffement de réputation.
⚠️ Si l'IP de sortie ne peut pas avoir un PTR propre ou est sur une blocklist grand public, l'envoi vers Gmail/Outlook échouera — quelle que soit la suite. À vérifier AVANT toute implémentation.
Décision ouverte : quelle IP / quel hébergement portera le mail de prod ? (non tranché)
3. Topologie (2-3 nœuds)
INTERNET
│
DNS public chezlepro.ca : MX 10 → mail1 , MX 20 → mail2
│
┌───────────────┴───────────────┐
▼ ▼
┌───────────────────┐ ┌───────────────────┐
│ mail-01 (PRIMAIRE) │ │ mail-02 (MX secours)│
│ Stalwart complet │◄──relais──│ Stalwart mode relais│
│ SMTP 25 / 587 / 465│ quand │ SMTP 25 seulement │
│ IMAP 993 / JMAP 443│ mail-01 │ file d'attente puis │
│ antispam + DKIM │ est down │ transfert à mail-01 │
│ BOÎTES stockées │ └───────────────────┘
└─────────┬──────────┘
│ (réseau interne, mTLS step_ca)
┌───────┼─────────────┬──────────────┐
▼ ▼ ▼ ▼
OpenLDAP step_ca PowerDNS PostgreSQL
(identité)(certs int.)(DNS interne)(métadonnées, option HA)
- mail-01 (primaire) — Stalwart complet : réception
:25, soumission authentifiée:587/:465, accès client IMAP:993+ JMAP/web:443, anti-spam, signature DKIM, hébergement des boîtes. - mail-02 (MX de secours) — Stalwart en mode relais, écoute seulement
:25. Quand mail-01 est indisponible, accepte + met en file l'entrant, puis retransmet au rétablissement → zéro perte à l'entrée. À placer idéalement sur un lien/IP indépendant (autre site ou VPS), sinon la résilience est illusoire.
Décision ouverte : emplacement du MX secours (même cluster ? VPS ? autre site ?).
4. Stockage
- v1 : stockage embarqué (RocksDB) sur mail-01 + sauvegardes rigoureuses. Simple et souverain. Le MX secours protège l'entrée, pas les boîtes → la résilience des données repose sur les sauvegardes.
- HA ultérieure : métadonnées dans PostgreSQL (pilier existant) + blobs sur stockage partagé, pour un primaire plus stateless.
5. Flux
- Entrant : expéditeur → MX DNS → mail-01
:25(ou mail-02 si down) → contrôles SPF/DKIM/DMARC + anti-spam → livraison à la boîte (utilisateur résolu via LDAP). - Sortant : client authentifié (LDAP) → soumission
:587→ signature DKIM → remise directe MX vers le serveur destinataire:25(← PTR + réputation décisifs). - Accès client : client mail → IMAP
:993/ JMAP:443→ auth LDAP → boîte.
6. TLS — deux CA distinctes (à ne pas confondre)
| Face | CA | Pourquoi |
|---|---|---|
Publique (25/465/587/993/443 vers le monde) |
Let's Encrypt (ACME intégré à Stalwart) | Les serveurs et clients distants valident contre les racines publiques ; ils ne connaissent pas l'AC interne. |
| Interne (mail ↔ LDAP, ↔ PostgreSQL, ↔ MX secours) | step_ca | Le mTLS souverain déjà en place pour les liaisons internes. |
7. Pare-feu (nftables)
Le socle installe nftables désactivé. Les nœuds mail sont un des endroits où on l'active avec des règles adaptées au rôle :
- Ouvert au monde :
25,465,587,993,443,80(ACME). - Interne seulement : LDAP, PostgreSQL, interface d'admin Stalwart.
8. Enregistrements DNS publics (chezlepro.ca)
mail1 A <IP publique mail-01>
mail2 A <IP publique mail-02>
@ MX 10 mail1.chezlepro.ca.
@ MX 20 mail2.chezlepro.ca.
@ TXT "v=spf1 mx -all"
default._domainkey TXT "v=DKIM1; k=rsa; p=<clé publique DKIM Stalwart>"
_dmarc TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@chezlepro.ca"
- PTR (reverse) :
<IP mail-01>→mail1.chezlepro.ca(chez le propriétaire de l'IP). - MTA-STS / TLS-RPT : optionnels, recommandés.
9. Traduction Set-OPS
- Nomenclature : 2 fonctions, p. ex.
comm-mail(primaire) +comm-mx2(secours) ; VMID / IP / VLAN dérivés comme le reste. - Rôles :
serveur_stalwart— mince : installe le binaire Stalwart, dépose la config (annuaire LDAP, ACME public, DKIM, certs internes step_ca), unité systemd, règles nftables mail.- variante « relais » (ou paramètre du même rôle) pour le MX de secours.
- Intégrations des nœuds mail :
client_ldap(auth),client_pki(certs internes),client_dns. - Secrets (voûte) : clé/mots de passe d'admin Stalwart, éventuel secret ACME, clé
privée DKIM — via
vault_*, câblés au rôle (comme les autres secrets).
10. Décisions ouvertes (à trancher avant l'implémentation)
- IP publique + PTR de prod — le make-or-break (§2).
- Emplacement du MX de secours (§3).
- Stockage : embarqué v1 vs PostgreSQL dès le départ (§4).
- Domaine(s) desservi(s) :
chezlepro.caseul, ou multi-domaines (tenants) ?
11. Phasage proposé
- Vérifier l'IP/PTR (prérequis bloquant). Sans ça, rien.
- Écrire
serveur_stalwart+ le déployer sur mail-01 dans le bac à sable (interne d'abord, ACME en mode staging/interne). - Brancher LDAP (auth), step_ca (interne), DKIM.
- Ajouter mail-02 (MX secours).
- Poser les enregistrements DNS publics + basculer l'ACME en production.
- Tests de bout en bout : réception, envoi vers Gmail/Outlook, SPF/DKIM/DMARC verts, bascule MX secours.
Ce document est un cadrage vivant : il évolue à mesure que les décisions ouvertes se tranchent. Il ne décrit pas encore de code livré.