État au 05/08/2026 : l'infrastructure CAPBE est entièrement déployée et
validée. Évolutions : le serveur de messagerie possède son IP publique
dédiée (51.79.11.52, NIC routée Incus) — le mail entre et sort par sa
propre IP — et le domaine mail est capbe.ovh (racine de la zone) :
boîtes @capbe.ovh, serveur mail.capbe.ovh.
Bascule « 1 IP » (05/08/2026) : TOUTE la messagerie (webmail SnappyMail,
JMAP, autoconfig/autodiscover, protocoles SMTP/IMAP/POP3) est servie
DIRECTEMENT par capbe-mail sur 51.79.11.52 — Caddy interne + certificat
wildcard Let's Encrypt. webmail/autoconfig/autodiscover.capbe.ovh résolvent
vers .52 ; le forward 51.79.11.50 ne sert plus que les applications web.
Les anciens noms *.ci.capbe.ovh ont été supprimés (clients à
reconfigurer).
⚠️ Le forward public (
51.79.11.50 → 10.10.10.31, créé uniquement côté Incus, web UI) ne porte plus QUE le web (80/443 → caddy, applications odoo/meca/agro) : les ports mail en ont été retirés (05/08/2026). Toutes les vérifications du smoke-test sont en lecture seule.
1. Pourquoi une seule IP pour le mail (51.79.11.52) ?
| IP | Rôle |
|---|---|
51.79.11.52 |
IP dédiée du serveur mail (NIC routée Incus) — TOUT le mail : SORTIE (egress, vue dans le header Received), entrée (SMTP/IMAP/POP3/JMAP) et le web du mail (webmail, autoconfig/autodiscover — Caddy interne + TLS wildcard) |
51.79.11.50 |
Adresse d'écoute du forward Incus — applications WEB uniquement (odoo/meca/agro, 80/443 → caddy). Plus aucun port mail (retirés le 05/08/2026) |
192.99.150.151 |
IP principale de l'hôte — ne sert plus au mail (bascule « IP dédiée ») |
Un PTR manquant sur l'IP sortante fait plonger le score de réputation
(mail-tester.com, Gmail, Outlook…) : envois dégradés/spam. PTR attendu :
- 51.79.11.52 (egress) → mail.capbe.ovh (mail.capbe.ovh résout vers
cette IP — FCrDNS validé par OVH, constaté en réel).
PTR de
51.79.11.50: purement web, aucun lien avec le mail. Depuis la bascule « 1 IP », il pointe versci.capbe.ovh(corrigé le 05/08/2026 : il indiquait encorewebmail.capbe.ovh— un nom lié au mail qui résout désormais vers.52, FCrDNS cassé)..50ne sert que les applications web (odoo/meca/agro, hub ci) : son PTR ne doit JAMAIS nommer un hôte mail (mail.*,webmail.*…), le mail vit uniquement sur51.79.11.52.
2. Procédure (API OVH — recommandée)
Le jeton OVH avec les droits /ip/* fait tout (le publish-mail-dns.sh le
tente automatiquement, best effort) :
sudo ./publish-mail-dns.sh # A mail/webmail/autoconfig/autodiscover → 51.79.11.52 ; PTR 51.79.11.52 → mail.capbe.ovh
NB : OVH exige que le hostname du PTR RÉSOLVE vers l'IP (contrôle FCrDNS) — c'est pourquoi
mail.capbe.ovhrésout vers l'IP dédiée51.79.11.52. Depuis la bascule « 1 IP », les scripts publientA mail/webmail/autoconfig/ autodiscover→ IP dédiée quand l'egress détectée depuis capbe-mail est une IP locale du conteneur (NIC routée), sinon →PUBLIC_IP(repli forward, PTR viamail-out.capbe.ovh).
À la main (si pas de jeton /ip/*) : manager OVH → Serveurs → IP →
Configurer le reverse → mail.capbe.ovh pour 51.79.11.52.
3. Vérification
dig +short -x 51.79.11.52 # attendu : mail.capbe.ovh. (IP dédiée mail — egress)
dig +short A mail.capbe.ovh # attendu : 51.79.11.52
dig +short A webmail.capbe.ovh # attendu : 51.79.11.52 (depuis la bascule « 1 IP »)
dig +short A autoconfig.capbe.ovh # attendu : 51.79.11.52
dig +short A autodiscover.capbe.ovh # attendu : 51.79.11.52
dig +short MX capbe.ovh # attendu : 10 mail.capbe.ovh.
sudo ./smoke-test.sh # le check PTR de l'egress passe au vert → tout est vert
Le smoke-test vérifie le PTR de l'IP sortante (déduite du SPF
ip4:→ attendumail.capbe.ovh) et les A des hôtes mail (webmail/autoconfig/ autodiscover → IP dédiée) — lecture seule.
4. Test de délivrabilité final — mail-tester.com
4a. Vérifications préalables (depuis l'hôte — records DNS verts avant l'envoi)
# Le smoke-test intègre désormais les checks A + SRV + PTR (tout le §3) :
# (le nombre de checks dépend des conditions : A mail dédiée = si egress locale
# à capbe-mail, PTR = 1 ou 2 IP, boucle mail = optionnelle --mail-loop)
sudo ./smoke-test.sh # tout vert attendu (hors PTR si encore en attente OVH)
# Contrôle manuel des records clés (propagation DNS, ~5–60 min après publication) :
dig +short MX capbe.ovh # attendu : 10 mail.capbe.ovh.
dig +short TXT capbe.ovh # attendu : "v=spf1 mx ip4:<egress> -all" (egress = 51.79.11.52)
dig +short TXT _dmarc.capbe.ovh # attendu : "v=DMARC1; p=quarantine; ..."
dig +short TXT <sélecteur>._domainkey.capbe.ovh # attendu : "v=DKIM1; k=...; p=..." (admin Stalwart → Domaines)
dig +short A mail.capbe.ovh # attendu : 51.79.11.52 (IP dédiée mail)
dig +short A webmail.capbe.ovh # attendu : 51.79.11.52 (IP dédiée mail — bascule « 1 IP »)
dig +short SRV _imap._tcp.capbe.ovh # attendu : 0 0 993 mail.capbe.ovh.
dig +short SRV _submission._tcp.capbe.ovh # attendu : 0 0 587 mail.capbe.ovh.
# PTR (IP sortante uniquement) :
dig +short -x 51.79.11.52 # attendu : mail.capbe.ovh. (egress / IP dédiée)
SPF vérifié côté récepteur : l'envoi sort de l'egress
51.79.11.52, qui est bien listée enip4:dans le SPF — sinon les serveurs stricts répondent 550 SPF fail (constaté en réel, mail-tester.com).
4b. Envoi du test mail-tester
# 1. Ouvre https://www.mail-tester.com → note l'adresse jetable (ex. test-xxxx@mail-tester.com)
# 2. Depuis le serveur, envoie un mail via le relais local (SMTP 587 STARTTLS) :
# NB : le mot de passe passe par une variable d'environnement (--env), PAS en
# argument de python3 — un argv serait visible dans `ps aux` du conteneur.
incus exec capbe-mail --env MAIL_PASS="$(grep '^MAIL_ADMIN_PASS=' playbook/config/secrets.env | cut -d'"' -f2)" -- \
python3 - "admin@capbe.ovh" "test-xxxx@mail-tester.com" <<'PY'
import smtplib, os, sys
sender, dest = sys.argv[1], sys.argv[2]
pw = os.environ["MAIL_PASS"]
s = smtplib.SMTP("127.0.0.1", 587, timeout=15)
s.ehlo(); s.starttls(); s.ehlo()
s.login(sender, pw)
s.sendmail(sender, [dest], "Subject: CAPBE deliverability test\n\nTest final\n")
s.quit(); print("ENVOYE")
PY
# 3. Clique « Then check your score » sur mail-tester.com
Critère de validation : score ≥ 9/10 (SPF ✓, DKIM ✓, DMARC ✓, PTR ✓). Si un point reste faible, voir DEPLOY.md → « Pièges connus » (SPF / PTR).
Après la bascule du domaine (
ci.capbe.ovh→capbe.ovh), refais ce test avec une adresse@capbe.ovh: le score dépend du domaine vu dans l'enveloppe (From), donc du domaine actif dans Stalwart.
4c. Audit automatique — audit-deliverability.sh (rejouable)
Le score mail-tester n'est plus affichable en gratuit (paywall). Pour un audit
automatisé et rejouable : audit-deliverability.sh vérifie pour CHAQUE
compte (admin@, odoo@, meca@, agro@capbe.ovh) :
- A. auth SMTP 587 STARTTLS + envoi réel (chemin complet : mail.capbe.ovh → Stalwart → signature DKIM → cible)
- B. sonde d'enveloppe vers le MX Gmail depuis l'egress réelle (MAIL FROM / RCPT — sans DATA, donc aucune livraison)
- C. chaîne DNS : MX, SPF, DMARC, sélecteurs DKIM (publiés vs DNS), PTR / FCrDNS
sudo ./audit-deliverability.sh # cible interne admin@capbe.ovh (aucun mail externe)
sudo ./audit-deliverability.sh monadresse@gmail.com # audit côté récepteur (4 mails envoyés)
Interprétation : tout « AUTH OK + envoi OK » et « MAIL FROM 250 » =
délivrabilité OK côté émetteur ; la chaîne DNS verte (SPF ip4:<egress>,
DKIM publié, DMARC, PTR + FCrDNS cohérent) = ce que verra le récepteur. Pour
la preuve visuelle (SPF/DKIM/DMARC: PASS), ouvrir un mail reçu → ⋮ →
Afficher l'original. Aucune boîte externe n'est requise pour l'audit de base.
5. Migration du domaine mail vers capbe.ovh
Décision : le domaine des boîtes est passé de ci.capbe.ovh à capbe.ovh
(racine de la zone OVH). En résumé :
- Stalwart :
defaultDomain→capbe.ovh,serverHostname→mail.capbe.ovh, compteadmin@capbe.ovh(ancien compte à supprimer). - DNS : records déplacés à la RACINE de la zone
capbe.ovh(Amail/webmail/autoconfig/autodiscover, MX, SPF TXT,_dmarc, DKIM*._domainkey, SRV_imap._tcpetc.) — publier avecsudo ./publish-mail-dns.sh. - Caddyfile : blocs
mail/webmail/autoconfig/autodiscoveren.capbe.ovh;sudo ./09-caddy-config.sh. - Suppression des anciens records/noms
*.ci.capbe.ovh(choix : pas d'alias — reconfigurer les clients mail : serveurmail.capbe.ovh, adresses@capbe.ovh). - Certificat wildcard Stalwart :
-d capbe.ovh -d '*.capbe.ovh'(DNS-01 OVH, zone racine).
⚠️ La bascule du domaine mail est sans retour pour les adresses : un ancien mail
@ci.capbe.ovhne sera plus délivré (ou à re-router via un alias Stalwart si nécessaire).
5bis. Guide de reconfiguration des clients mail
Après la bascule, chaque client (Thunderbird, Outlook, mobiles, webmail)
doit être reconfiguré — les anciens réglages @ci.capbe.ovh / mail.ci.capbe.ovh
ne fonctionnent plus (anciens noms supprimés).
Réglages universels (tous les clients) :
| Champ | Valeur |
|---|---|
| Adresse e-mail | admin@capbe.ovh (et toute boîte @capbe.ovh) |
| Serveur entrant (IMAP) | mail.capbe.ovh — port 993, SSL/TLS |
| Serveur sortant (SMTP) | mail.capbe.ovh — port 587, STARTTLS (ou 465 SSL) |
| Nom d'utilisateur | l'adresse e-mail complète |
| Webmail | https://webmail.capbe.ovh |
Configuration automatique (recommandée) : Thunderbird et la plupart des clients mobiles détectent tout seuls via les records publiés :
- Thunderbird :
Fichier → Nouveau → Compte existant→ saisir l'adresseadmin@capbe.ovh→ Thunderbird interrogeautoconfig.capbe.ovhet pré-remplit IMAP 993 / SMTP 587 (mail.capbe.ovh). Vérifier que le mot de passe est demandé, puis valider. - Outlook (Windows/Mac) :
Fichier → Comptes → Ajouter un compte→ l'autodiscovery (autodiscover.capbe.ovh+ SRV_autodiscover._tcp) pré-remplit IMAP/SMTP. - Mobiles (Android/iOS) : ajouter un compte e-mail « manuel » avec les réglages ci-dessus, ou scanné depuis le webmail si SnappyMail l'expose.
Pièges à vérifier après reconfiguration :
- L'ancienne boîte
@ci.capbe.ovhne reçoit plus rien — récupérer les mails importants AVANT la bascule, ou créer un alias Stalwart@ci.capbe.ovh→@capbe.ovhsi un relais temporaire est nécessaire. - Vérifier l'envoi : SMTP 587 STARTTLS avec le mot de passe de
admin@capbe.ovh(jamais en clair sur le réseau — le STARTTLS est obligatoire). - Un client configuré en POP3 verra aussi le serveur
mail.capbe.ovh: 995 SSL ou 110 STARTTLS. - L'assistant d'un client peut écrire
mail.capbe.ovhenmail.capbe.ovh:587ou en SSL 465 — les deux écoutent sur capbe-mail.
5ter. Séquence opératoire de bascule (à lancer sur l'hôte, dans l'ordre)
cd /data/CAPBE/playbook
# 1. Publication DNS — records capbe.ovh (A mail → IP dédiée détectée auto),
# MX/SPF/DMARC/DKIM/SRV + nettoyage des anciens records *.ci.capbe.ovh
# + PTR best-effort (jeton /ip/* requis pour les PTR) :
sudo ./publish-mail-dns.sh
# 2. Déploiement du Caddyfile (blocs mail/webmail/autoconfig/autodiscover en
# .capbe.ovh, anciens noms supprimés) + rechargement caddy :
sudo ./09-caddy-config.sh
# 3. Smoke-test — tout doit être vert (records A/SRV/PTR + points d'entrée) :
sudo ./smoke-test.sh
# Boucle mail réelle (SMTP 587 → IMAP 993, message relu) :
sudo ./smoke-test.sh --mail-loop
# 4. Délivrabilité — §4 : audit automatique (audit-deliverability.sh) ou
# mail-tester.com (score ≥ 9/10) — voir §4b/4c ci-dessus
# 5. Reconfiguration des clients mail (@capbe.ovh / mail.capbe.ovh) — §5bis
Si le jeton OVH n'a pas les droits d'écriture (mode manuel affiché par
publish-mail-dns.sh), crée les records listés dans l'espace client OVH puis relancepublish-mail-dns.sh(idempotent — ne crée que les manquants).
6. Sort des conteneurs héritage (agrimeca / agroworoba) — ✅ DÉCOMMISSIONNÉ
⚠️ Décision manuelle, uniquement APRÈS : smoke-test 100 % vert et mail-tester ≥ 9/10. Les projets migrés (capbe-meca / capbe-agro) sont déjà autonomes sur pgis/odoo/fronts.
✅ État au 05/08/2026 — décommissionnement effectué
Les conteneurs héritage agrimeca et agroworoba ne sont plus présents
sur l'hôte (vérifié le 05/08/2026) :
incus list→ aucun conteneuragrimeca/agroworoba(seuls les 7 conteneurscapbe-*tournent, plus 2 hors périmètre arrêtés :db,ubt)crontab -l→ aucune tâche résiduelle référençant les anciens noms/var/backups/→ aucun répertoire de sauvegarde hérité
Les bases migrées (meca_api, agro_api, tenants Odoo meca/agro) tournent sur
capbe-pgis/capbe-odoo ; le décommissionnement n'a affecté aucun service
CAPBE (réseau capbe-br0 séparé). Un dump SQL de sauvegarde agro avait été
committé dans le dépôt source avant suppression (CAPBE-AGRO/src —
« chore: sauvegarde dumps SQL agro avant décommissionnement agroworoba »).
📜 Procédure d'origine (trace pour un autre projet / ré-exploitation)
Par conteneur hérité, dans l'ordre :
incus stop agrimeca # 1. arrêt propre → observer quelques jours
incus start agrimeca # (si besoin de vérifier quelque chose)
# 2. après période d'observation sans régression sur capbe-meca :
incus delete agrimeca # 3. suppression définitive (irréversible !)
# 4. nettoyage : vérifier l'absence de crons / sauvegardes / scripts
# référençant l'ancien nom (grep -i 'agri\|woroba' crontab, /var/backups)
# Répéter pour agroworoba → capbe-agro
Règle d'or : ne supprimer un héritage qu'après la validation finale (smoke-test vert + mail-tester ≥ 9/10). Pour CAPBE, cette étape est faite.
7. Récapitulatif de l'état au 05/08/2026
| Vérification | Résultat |
|---|---|
| Smoke-test | ✅ 27 OK / 0 échec (05/08, après correction du check PTR — dig +short -x requis) |
| Boucle mail SMTP 587 → IMAP 993 | ✅ message relu |
Smoke-test --app-accounts (§7) |
✅ auth SMTP 587 des 4 comptes applicatifs (login seul, aucun envoi) |
| Comptes applicatifs (odoo@/meca@/agro@capbe.ovh) | ✅ créés sur Stalwart (587 STARTTLS, MAIL_APP_*_PASS générés) — Odoo meca/agro + MECA API envoient leurs mails via capbe-mail |
Audit de délivrabilité (audit-deliverability.sh) |
✅ 4/4 comptes AUTH + envoi OK + sonde MX Gmail 250/250 (egress .52) + chaîne DNS verte (SPF/DKIM/DMARC/PTR FCrDNS) |
| Délivrabilité réelle (Gmail) | ✅ Boîte de réception + SPF/DKIM/DMARC : PASS (confirmé par l'utilisateur) |
| SPF / MX / DKIM / DMARC / SRV | ✅ publiés et corrects |
| PTR 51.79.11.52 (IP dédiée mail) | ✅ actif → mail.capbe.ovh (vérifié : NS autoritaires OVH + résolveurs publics) |
| Bascule « 1 IP » | ✅ 05/08/2026 — tout le mail sur 51.79.11.52 ; forward .50 : apps web uniquement (ports mail retirés) |
| Mail : IP dédiée + egress | ✅ 51.79.11.52 (NIC routée Incus, egress vérifié) |
| Domaine mail | ✅ capbe.ovh (boîtes @capbe.ovh, hôte mail.capbe.ovh, anciens noms *.ci.capbe.ovh supprimés) |
| Webmail | ✅ servi directement par capbe-mail sur l'IP dédiée (Caddy interne + TLS wildcard) |
| Admin Stalwart | ✅ https://admin-mail.capbe.ovh (→ /admin/ ; UI de gestion des domaines/comptes/DKIM — proxysée par le Caddy interne, TLS wildcard). Connexion : utilisateur admin + mot de passe de récupération (STALWART_RECOVERY_ADMIN dans /opt/stalwart/etc/stalwart.env sur capbe-mail — ≠ MAIL_ADMIN_PASS) |
| Routage entrant IP dédiée (ufw) | ✅ corrigé le 06/08/2026 — règles ufw route allow to/from 51.79.11.52 ; le trafic ENTRANT était DROPPÉ par FORWARD (admin-mail/webmail/mail injoignables de l'extérieur, ERR_CONNECTION_TIMED_OUT) |
| Cron sauvegardes 02h00 + kits 02h30/02h45 | ✅ confirmés (crontab root) |
| Check-nightly kits (07h30/07h35) | ✅ nuit saine (05/08, meca + agro) |
| Monitoring 5 min + alertes mail | ✅ aucun signal sur 24 h |
| Sort des héritages agrimeca/agroworoba | ✅ décommissionnés (05/08, aucun résidu) |
| Forward public (créé uniquement côté Incus) | ✅ 80/443 → caddy (apps web) — plus aucun port mail |
⚠️ Incident 06/08/2026 — routage entrant de l'IP dédiée
51.79.11.52. Avec ufw actif et sa politique « deny routed » par défaut, le trafic entrant vers la NIC routée (IP dédiée de capbe-mail) était DROPPÉ par la chaîne FORWARD de l'hôte : seules les règles SORTANTES (-s 51.79.11.52) existaient →https://admin-mail.capbe.ovh(et webmail, SMTP/IMAP entrants) répondaient localement mais restaient injoignables depuis Internet (ERR_CONNECTION_TIMED_OUT). Diagnostic : les SYN arrivaient bien sureno1(tcpdump) mais n'atteignaient jamais le veth du conteneur. Correction (appliquée, idempotente dans07-mail.sh§6b) :
bash sudo ufw route allow to 51.79.11.52 # trafic entrant → IP dédiée (indispensable) sudo ufw route allow from 51.79.11.52 # trafic sortant (parité)Vérifié depuis Internet (check-host.net) : 443, 25 et 587 joignables. Le playbook (
07-mail.sh§6b) recrée ces règles à chaque déploiement quand l'IP dédiée est détectée (NIC routée) — rien à faire manuellement en re-run.