La revision a commence par un balayage par motifs — chemins morts, cibles make absentes, comptes derives. Il a trouve une trentaine d ecarts et rate presque tout le reste : un motif ne voit que ce qui s exprime en motif. make hote-planifier en est l exemple. La cible EXISTE, donc le controle passait au vert. C est une cible depreciee qui refuse et sort en 2, recommandee par AGENTS.md, et qui contredit la REGLE D OR du meme fichier trois ecrans plus haut. Il fallait lire pour la voir. 74 documents lus un par un. 66 corriges, 8 exacts. CE QUI ETAIT FRANCHEMENT FAUX AGENTS.md, la source d autorite, annoncait la flotte pas encore executee contre des VM reelles. Elle a ete rasee et remontee depuis zero trois fois. ecosysteme-chezlepro.md, le document montre a un client, portait la meme phrase : il se sous-vendait gravement. courriel-conception.md s ouvrait sur aucun role n est encore ecrit, au-dessus de son propre paragraphe 1 qui les nomme. autorisation.md se terminait sur rien n est construit alors qu il rapporte des mesures datees du role en fonctionnement. hebergeur-exploitation.md disait rien n est fait d un depot qui existe. filiation-emancipation.md se contredisait a deux ecrans de distance. DES MODELES DECRITS D APRES UN MONDE ANTERIEUR Le resolveur : cinq documents decrivaient un Unbound par VM en opt-in, trois le donnaient en exemple d integration FACULTATIVE — il est universel depuis le 2026-08-24. L adressage de nomenclature-vm.md : reseau unique, VLAN 11-15, VMID a cinq chiffres. Le nommage SDN de sdn-evpn.md contre le code : c est le wiki qui avait raison. CE QUI CASSE AU PREMIER ESSAI Le nom du gabarit dore etait faux a quatre endroits, dont la procedure qui le FABRIQUE et le critere R2 de l epreuve d operateur independant. preparer-un-site-hebergeur.md avertissait qu une VM faite a la main serait detruite : raser derive du plan, il ne la detruira jamais — le risque est l inverse. Un mot de passe d essai en clair dans un depot public. DEUX PREUVES ETENDUES, ET UNE QUI SE TROMPAIT ELLE-MEME P57 couvre les groupes : elle a signale aussitot 29 groupes annonces au-dessus d un tableau qui en cite 40. P29 confronte le tableau de authentification.md aux declarations reelles : 12 annonces, 21 reels. Et P57 imposait un chiffre faux — 56 preuves alors que le depot en porte 57, la conditionnelle vivant hors de tout comptage. Un garde-fou qui fait respecter une erreur ajoute l assurance a l erreur. CE QUI RESTE, ET QU AUCUNE PREUVE NE TIENT Deux comptes trouves a la main. Et une lacune reelle : rien ne garde les meta/acces.yml — ni qu un service web-sso en porte un, ni que le groupe qu il nomme existe. P29 tient les positions d authentification, personne ne tient les habilitations. make prouver : CONFORME, 56 OK, 0 echec, 1 saute. 0 lien mort. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
13 KiB
Conception — Service de courriel souverain (Chezlepro)
Pour qui : le mainteneur du service de courriel.
Statut, revu le 2026-09-06 — l'Étape A est LIVRÉE, l'Étape B reste du cadrage. Ce document annonçait « aucun rôle n'est encore écrit » : les trois rôles (
serveur_postfix,serveur_dovecot,serveur_rspamd) existent, sont déployés, et le flux interne est prouvé de bout en bout — SMTP → validation LDAP → LMTP chiffré → boîte → lecture IMAP, avec antispam et signature DKIM. Ce qui n'est pas livré, c'est l'Étape B (§11) : la face publique — Let's Encrypt, reprise du MX.53, enregistrements chez Namespro, tests de délivrabilité. Lire ce document ainsi : les décisions du §1 sont arrêtées et appliquées ; la feuille de route du §11 est ouverte.
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. |
| Stack | Postfix (MTA) + Dovecot (IMAP/LMTP) + rspamd (antispam/DKIM) — la stack libre mature, éprouvée depuis 20+ ans, entièrement configurable par fichiers. Trois rôles Set-OPS (serveur_postfix, serveur_dovecot, serveur_rspamd), comme on configure nginx/powerdns. |
| Identité | Boîtes/utilisateurs dans l'OpenLDAP existant (Postfix + Dovecot → 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. |
| Démarche | Deux étapes (voir §11) : (A) fonctionnement INTERNE d'abord (step_ca, LDAP, SMTP/IMAP internes, zéro dépendance publique) ; (B) fonctionnement EXTERNE ensuite (Namespro, Let's Encrypt, reprise du MX .53). |
Le courrier de notification système des nœuds (cron, alertes) est relayé vers le MTA
serveur_postfix (edge-mta) via client_smtp/msmtp. C'est distinct de ce service de boîtes
et ne le remplace pas. (Note : l'ancien rôle serveur_sendmail a été retiré — supersédé par
Postfix.)
Historique — pivot depuis Stalwart (2026-07-02). On avait d'abord choisi Stalwart (binaire unique, moderne). Le prototypage a révélé un projet jeune et volatil : modèle de config cassé entre 0.15 et 0.16, outil IaC
stalwart config applyannoncé mais non livré dans le binaire, API REST supprimée au profit de JMAP, backlog d'issues/PR important. Pour un pilier critique souverain censé durer, c'est trop précaire. On pivote vers la stack mature Postfix/Dovecot/rspamd, qui a en prime l'avantage d'être 100 % déclarable par fichiers — donc parfaitement alignée avec le modèle Set-OPS (déclaratif, idempotent, exploitable sans IA). La Phase 1 Stalwart (rôleserveur_stalwart) est retirée ; git en garde la trace. Stalwart à réévaluer dans ~2 ans, une fois mûri et sonconfig applylivré.
2. Prérequis IP publique — VÉRIFIÉ (recon DNS, 2026-07-02)
Le full self-host sortant exige un PTR propre, forward-confirmed, hors blocklist. C'est déjà en place pour le MX primaire de Chezlepro :
mx.chezlepro.ca = 69.70.26.53; PTR→ mx.chezlepro.ca; FCrDNS aller-retour OK.- Bloc
69.70.26.x(Videotron statique) contrôlé par Chezlepro ; PTR custom obtenable (déjà fait pour.53).
→ La condition dure de délivrabilité est levée pour le primaire. Le full self-host n'est
pas un pari : c'est reprendre .53 en préservant sa réputation.
Réserves :
laposte-01 = 69.70.26.55(MX secours) a encore le PTR Videotron par défaut (modemcable055…), paslaposte-01.chezlepro.ca— à corriger s'il doit émettre.- DKIM : le sélecteur
default._domainkeyest vide publiquement — à (re)poser.
État de la prod Chezlepro (recon)
| Élément | Réalité |
|---|---|
| DNS public | Namespro (htns1/2/3.namespro.ca) — pas PowerDNS. PowerDNS = interne uniquement. |
| Bloc IP | 69.70.26.x (Videotron statique) : .51 apex, .53 mx, .55 laposte-01, .59 git. |
| Mail existant | MX mx → .53 déjà en service ; SPF -all correct ; DMARC quarantine correct. |
| Vue interne | split-horizon (NS delaviorne.net, IP 10.10.x/192.168.14.x) — ne pas confondre avec le public. |
Conséquence : le service mail n'est pas greenfield. Il reprend/modernise l'existant (MX
.53), il ne le recrée pas.
3. Topologie (2-3 nœuds)
INTERNET
│
DNS public chezlepro.ca : MX 10 → mail1 , MX 20 → mail2
│
┌───────────────┴───────────────┐
▼ ▼
┌────────────────────┐ ┌───────────────────┐
│ mail-01 (PRIMAIRE) │ │ mail-02 (MX secours)│
│ Postfix (MTA) │◄──relais──│ Postfix (relais) │
│ SMTP 25 / 587 / 465│ quand │ SMTP 25 seulement │
│ Dovecot (IMAP 993 │ mail-01 │ file d'attente puis │
│ + LMTP + Sieve) │ est down │ transfert à mail-01 │
│ rspamd (spam + DKIM)│ └───────────────────┘
│ BOÎTES stockées │
└─────────┬──────────┘
│ (réseau interne, mTLS step_ca)
┌───────┼─────────────┬──────────────┐
▼ ▼ ▼ ▼
OpenLDAP step_ca PowerDNS PostgreSQL
(identité)(certs int.)(DNS interne)(métadonnées, option)
Topologie révisée (2026-07-02) — MTA dédié en périphérie, boîtes à l'intérieur. Le schéma ci-dessus (tout-en-un) est remplacé par le modèle ci-dessous.
Internet ─▶ edge-mta : Postfix + rspamd (EXPOSÉ, aucune boîte)
│ LMTP (remise) + SASL (auth) — réseau, mTLS step_ca
▼
mail-store : Dovecot IMAP + boîtes (INTERNE, non exposé)
│
OpenLDAP · step_ca · PowerDNS
- edge-mta (primaire) — Postfix (
:25, soumission:587/:465) + rspamd (anti-spam, DKIM, greylisting). Exposé à Internet ; ne stocke aucune boîte. Auth des soumissions déléguée à Dovecot (SASL réseau) ; remise via LMTP réseau versmail-store. - mail-store (interne) — Dovecot : IMAP
:993, boîtes (Maildir), Sieve, auth LDAP. Non exposé au public ; ne parle qu'àedge-mta(LMTP + SASL) et aux clients IMAP internes. Expose LMTP + auth sur le réseau, chiffré par step_ca. - mta2 (MX de secours) — Postfix relais,
:25seulement ; file puis transfert quandedge-mtaest down ; idéalement sur un lien/IP indépendant.
Séparation clé : le MTA (surface la plus exposée) est isolé des boîtes (données sensibles) ; le lien Postfix→Dovecot passe en réseau chiffré par step_ca — réutilise le mTLS.
Décisions ouvertes : emplacement du MX secours ; edge-mta co-localisé avec l'edge web ou non.
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)
Gérés chez Namespro (registrar/DNS public), PAS dans PowerDNS (qui ne sert que l'interne). Un MX (
mx → .53), un SPF (-all, correct) et un DMARC (quarantine) existent déjà — à reprendre/ajuster, pas à recréer. Le DKIM (default._domainkeyvide) est à (re)poser.
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 (config 100 % par fichiers, comme nginx/powerdns) :
serveur_postfix— MTA :main.cf/master.cf, TLS step_ca, cartes LDAP (domaines, boîtes, alias), remise LMTP vers Dovecot, soumission:587/:465, milter rspamd.serveur_dovecot— IMAP:993+ LMTP + Sieve, stockage des boîtes, auth SASL (pour la soumission Postfix), backend LDAP, TLS step_ca.serveur_rspamd— anti-spam, signature DKIM, greylisting ; branché à Postfix par milter.serveur_postfixen mode relais (paramètre) pour le MX de secours.
- Intégrations des nœuds mail :
client_pki(certs internes),client_backup,client_metrique/client_journal(observabilité). L'annuaire est résolu parresoudre_annuaire(côté rôle), pas une intégration OS. - Secrets (voûte) : bind LDAP, clé privée DKIM, éventuel secret ACME (Étape B) —
via
vault_*, câblés aux rôles.
10. Décisions
- ✅ IP publique + PTR — TRANCHÉ :
.53FCrDNS OK, bloc Videotron contrôlé (§2). - ⬜ Emplacement du MX de secours (
.55existe ; lien/PTR à cadrer) (§3). - ⬜ Stockage : embarqué v1 vs PostgreSQL dès le départ (§4).
- ⬜ Domaine(s) desservi(s) :
chezlepro.caseul, ou multi-domaines (tenants) ? - ⬜ Reprise du MX existant : bascule directe de
.53vers la nouvelle stack, ou cohabitation transitoire ?
11. Démarche en deux étapes
Étape A — Fonctionnement INTERNE (d'abord, sans risque)
But : prouver toute la pile en interne, en code de prod, dans le bac à sable. Aucune dépendance au public.
- Pilier identité :
serveur_openldap(TLS step_ca) — ✅ déployé et prouvé. serveur_postfix+serveur_rspamdsuredge-mta-01,serveur_dovecotsurinfra-mail-01: TLS step_ca, annuaire/auth LDAP, DKIM, nftables mail — ✅ déployés.- Prouver : réception → boîte → accès IMAP → envoi intra-écosystème, le tout en
TLS interne, auth LDAP — ✅ prouvé de bout en bout, et rejoué à la demande par
make courriel-plan, file d'attente comprise.
(Ce paragraphe disait « Étape actuelle : identité OK ; on démarre serveur_postfix » et
plaçait toute la pile sur un mail-01 unique. La topologie retenue est celle du §3 révisé —
le MTA en périphérie, les boîtes à l'intérieur — et l'Étape A est close.)
Étape B — Fonctionnement EXTERNE (transition prod, plus tard)
But : brancher sur le monde en reprenant l'existant (voir §2).
- Basculer le TLS des faces publiques sur Let's Encrypt (ACME).
- Reprendre
mx.chezlepro.ca(.53) — préserve PTR/réputation déjà acquis. - Mettre à jour les enregistrements chez Namespro : MX, DKIM (nouveau sélecteur), vérifier SPF/DMARC.
- MX secours
.55: PTR custom Videotron s'il doit émettre ; sinon réception/queue seulement. - Tests bout en bout : 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. L'Étape A qu'il décrit est livrée et prouvée ; la séquence ci-dessus, qui est l'Étape B, ne l'est pas.