Set-OPS-Public/docs/courriel-conception.md
Daniel Allaire e006dee693 Retirer 3 rôles legacy (serveur_sendmail, client_dns, client_ldap) + nettoyage
Supprimés (supersédés / hors-conception) : serveur_sendmail (→ Postfix),
client_dns (→ plancher + client_unbound), client_ldap (login LDAP OS, hors
design). Rôles + playbooks de groupe retirés.

Nettoyage des références :
- dependances-groupes.yml : entrées client_dns/client_ldap retirées + entrées
  mortes des scaffoldings (nextcloud/collabora/client_supervision) ; deps
  périmées corrigées (client_smtp → serveur_postfix ; serveur_keycloak →
  serveur_postgresql, la raison parlait à tort de Nextcloud).
- 6 modèles d'exemple : app mail serveur_sendmail → serveur_postfix.
- README, AGENTS : listes/glossaire nettoyés.
- catalogue-services : listes, tables, roadmap ; note « rôles retirés ».
- nomenclature-vm : infra-mail-01 → serveur_dovecot (était faux).
- courriel-conception, dns-interne (re-ciblé client_unbound), pouvoirs,
  intrants, READMEs (client_smtp/forgejo/openldap/unbound).

ansible-lint : 0 échec (366 fichiers). instancier OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 12:14:04 -04:00

12 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.
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 apply annoncé 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ôle serveur_stalwart) est retirée ; git en garde la trace. Stalwart à réévaluer dans ~2 ans, une fois mûri et son config apply livré.

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…), pas laposte-01.chezlepro.ca — à corriger s'il doit émettre.
  • DKIM : le sélecteur default._domainkey est 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 vers mail-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, :25 seulement ; file puis transfert quand edge-mta est 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 :587signature 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._domainkey vide) 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_postfix en 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 par resoudre_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É : .53 FCrDNS OK, bloc Videotron contrôlé (§2).
  • Emplacement du MX de secours (.55 existe ; lien/PTR à cadrer) (§3).
  • Stockage : embarqué v1 vs PostgreSQL dès le départ (§4).
  • Domaine(s) desservi(s) : chezlepro.ca seul, ou multi-domaines (tenants) ?
  • Reprise du MX existant : bascule directe de .53 vers 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.

  1. Pilier identité : serveur_openldap (TLS step_ca) — déployé et prouvé en bac à sable.
  2. serveur_postfix + serveur_dovecot + serveur_rspamd sur mail-01 : TLS step_ca, annuaire/auth LDAP, DKIM interne, nftables mail.
  3. Prouver : réception → boîte → accès IMAP → envoi intra-écosystème, le tout en TLS interne, auth LDAP.

(Étape actuelle : identité OK ; on démarre serveur_postfix.)

Étape B — Fonctionnement EXTERNE (transition prod, plus tard)

But : brancher sur le monde en reprenant l'existant (voir §2).

  1. Basculer le TLS des faces publiques sur Let's Encrypt (ACME).
  2. Reprendre mx.chezlepro.ca (.53) — préserve PTR/réputation déjà acquis.
  3. Mettre à jour les enregistrements chez Namespro : MX, DKIM (nouveau sélecteur), vérifier SPF/DMARC.
  4. MX secours .55 : PTR custom Videotron s'il doit émettre ; sinon réception/queue seulement.
  5. 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. Il ne décrit pas encore de code livré.