docs: cadrage du service de courriel souverain (Stalwart, full self-host)
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>
This commit is contained in:
parent
a5903f192b
commit
1e2c323156
2 changed files with 159 additions and 0 deletions
|
|
@ -1,5 +1,14 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-07-02
|
||||
|
||||
### Ajouté
|
||||
- **`docs/courriel-conception.md`** — cadrage du futur service de courriel souverain :
|
||||
full self-host, suite **Stalwart** (adoptée, enveloppée par un rôle mince), topologie
|
||||
MX primaire + MX secours, intégration identité (LDAP) / DNS / PKI (Let's Encrypt public
|
||||
vs step_ca interne), enregistrements DNS publics, décisions ouvertes (IP/PTR, secours,
|
||||
stockage) et phasage. **Conception seulement — aucun rôle livré.**
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### Ajouté
|
||||
|
|
|
|||
150
docs/courriel-conception.md
Normal file
150
docs/courriel-conception.md
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
# 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 / 80` routables 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)
|
||||
|
||||
1. **IP publique + PTR de prod** — le make-or-break (§2).
|
||||
2. **Emplacement du MX de secours** (§3).
|
||||
3. **Stockage** : embarqué v1 vs PostgreSQL dès le départ (§4).
|
||||
4. **Domaine(s)** desservi(s) : `chezlepro.ca` seul, ou multi-domaines (tenants) ?
|
||||
|
||||
## 11. Phasage proposé
|
||||
|
||||
1. **Vérifier l'IP/PTR** (prérequis bloquant). Sans ça, rien.
|
||||
2. Écrire `serveur_stalwart` + le déployer sur **mail-01** dans le **bac à sable**
|
||||
(interne d'abord, ACME en mode staging/interne).
|
||||
3. Brancher **LDAP** (auth), **step_ca** (interne), **DKIM**.
|
||||
4. Ajouter **mail-02** (MX secours).
|
||||
5. Poser les **enregistrements DNS publics** + basculer l'ACME en production.
|
||||
6. 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é.*
|
||||
Loading…
Reference in a new issue