Repository navigation
Certificates
EN | FR | 🟠 AUTH | /certs/: what is served, until when, and who renews it
What it is for. The
/certs/page (packagesecubox-certs) lists the TLS certificates that HAProxy actually serves, shows how many days each has left, and lets an administrator issue, renew or revoke one. This page also explains the renewal chain, because a certificate can be renewed correctly and still never reach the front end.
- Package:
secubox-certs· page/certs/· API/api/v1/certs/· config/etc/secubox/certs.toml - Related:
haproxyctl cert …(WAF describes the HAProxy → sbxwaf → nginx path), the certificate monitor ofsecubox-metrics.
| Place | Content |
|---|---|
/data/haproxy/certs/<domain>.pem |
what HAProxy serves: one concatenated file (chain + private key) per domain |
/etc/letsencrypt/live/<domain>/ |
the certbot store (fullchain.pem, privkey.pem) |
acme.sh home (~/.acme.sh/<domain>[_ecc]/) |
the acme.sh store (fullchain.cer, <domain>.key); EC certificates carry the _ecc suffix |
The /certs/ page reads /data/haproxy/certs. Expected permissions on every
served file: 0640, owner haproxy:secubox.
Why 0640
haproxy:secubox. The module runs as thesecuboxuser. A.pemleft0600 rootis unreadable for it: before the fix, 14 valid certificates showed up as expired.
Renewing in a store does nothing by itself: HAProxy only reads its own directory. Two mechanisms carry the result, whichever tool issued the certificate.
| Tool | Renewal | Carried to HAProxy by |
|---|---|---|
| certbot | systemd timer, through secubox-certbot (starts certbot even when a pip drift breaks its Python stack) |
the deploy hook /etc/letsencrypt/renewal-hooks/deploy/secubox-haproxy, which runs haproxyctl cert sync after each successful renewal only |
| acme.sh | its own daily cron (02:00) |
certsctl deploy --apply, run by a daily timer at 03:15 (Persistent=true, so a missed run is caught up) |
Both obey the same safety rules:
- Idempotent, and HAProxy is reloaded only if a file changed: a reload cuts live connections.
- Content, not dates, decides: a recent mtime proves nothing.
-
Never shorten a served certificate's life: a
.pemthat expires later than the source is left alone (it may be a wildcard or a manual deposit). - Never replace by an older one, and never deploy when a date is unreadable.
- Atomic write (temporary file then rename): a truncated
.pemwould make HAProxy fail at reload, for all vhosts. - When a domain exists in both stores, acme.sh wins (it manages most of the fleet).
certsctl deploy without --apply only simulates; certsctl status counts
expired / expiring (21 days) / valid. haproxyctl cert sync can be run by hand
at any time.
| State | Rule |
|---|---|
healthy |
more than 30 days left |
warning |
8 to 30 days |
critical |
0 to 7 days |
expired |
already past its end date |
unknown |
the file cannot be read (❔, "illisible" in the page) |
An unreadable certificate is "unknown", never "expired". Almost always it is
a permissions problem (0600 root): run haproxyctl cert sync or fix the mode
to 0640 haproxy:secubox. A read failure is not remembered, so the file becomes
visible as soon as it is readable, and the bulk renewal skips unknown ones.
Actions (administrator): New Cert (a 3-step wizard with pre-flight checks —
DNS resolution, port 80 — then issuance, HTTP or DNS challenge), Renew one
certificate, Renew Expiring (all within 30 days), Revoke (revokes through
certbot and deletes the .pem, then reloads HAProxy).
| Method | Path | Guard | Purpose |
|---|---|---|---|
| GET |
/list, /status, /details/{domain}, /metrics
|
admin session | inventory and detail |
| POST | /check |
admin session | pre-flight checks |
| POST |
/issue, /renew/{domain}, /renew-all
|
administrator | issue and renew |
| DELETE | /revoke/{domain} |
administrator | revoke and delete |
secubox-metrics runs a certificate aggregator every minute (off the event
loop) and publishes valid / expiring_soon / expiring_critical / expired with
the next renewal. It reads /etc/letsencrypt/live/*/cert.pem (thresholds
30 and 7 days by default) — the certbot store, not the served .pem. A
certificate managed only by acme.sh is therefore seen by the page /certs/, not
by this aggregator. The Portal page shows its summary.
An abandoned domain keeps showing as expiring then expired forever, and the renewal tools keep trying. Do it in this order, without revoking unless a key was compromised:
-
Remove the vhost:
haproxyctl vhost remove <name>(it regenerates the HAProxy configuration, so the certificate is no longer referenced). -
Set the
.pemaside: move/data/haproxy/certs/<domain>.pemout of the directory (for example into a dated archive folder with0600rights) instead of deleting it. -
Stop the renewal:
acme.sh --remove -d <domain>(add--eccfor an EC certificate). For a certbot-managed one,certbot delete --cert-name <domain>. - Reload HAProxy and check that the page no longer lists the domain.
Skipping step 3 is the classic trap: the domain disappears from the front end and comes back at the next renewal run.
- Portal — the portal page shows the certificate summary
- WAF — the HAProxy → sbxwaf → nginx path that uses these certificates
-
Configuration —
/etc/secubox/*.toml - Troubleshooting — common faults
- Admin-Panels-Gallery — the common Aurora panel style
SecuBox-Deb · Licence : CMSD-1.0 (Source-Disclosed)
Contact : CyberMind · Gérald Kerma · Notre-Dame-du-Cruet, Savoie
Hardware-Matrix · Acknowledgments · Wiki v2.5.0
SecuBox | FR | DE | 中文 | v3.0.0-alpha.12
- Home
- Architecture
- Trixie | FR
- Hardware-Matrix
- Roadmap
- Profils
- Modules-by-Profile 📦 lite / isp / full : ce qu'embarque chaque profil | FR
- Modules-by-Family 🗂️ les modules par famille | FR
- DNS-Filtrage
- Multiboot ⭐
-
Live-USB-VirtualBox
run-vbox.sh -
Live-USB-QEMU
run-qemu.sh - Live-USB | FR | DE | 中文
- Auto-Load 🚚 boxes sans écran | FR
- First-Boot-Premier-Pas 🧭 premier pas | FR
- Installation | FR | DE | 中文
- ARM-Installation | FR | DE | 中文
- Netboot-Install 🔧 MOCHAbin netboot + signed install
- ESPRESSObin | FR | DE | 中文
- Eye-Remote 📡
- Android-ToolBox 📱 one-tap R3
- Browser-Extension 🧩 cartographie
- QEMU-ARM64 🖥️
- Configuration | FR | DE | 中文
- Troubleshooting | FR | DE | 中文
- ToolBox 👁️ cabine numérique · rapport vie privée
- Anti-Track 🛡️ bloque · empoisonne · anonymise
- Billets 📮 micro-blog gateway · média vignette zoomable
- Messagerie 💬 mur public, messages privés, radio/Billets/BBS centralisés
- Identite-SBX-OS 🪪 personnes, appareils, comptes liés, connexion passive
- Metalogue 🕸️ OSINT suite · Maigret + SpiderFoot (Maltego-style)
- WAF 🛡️ pare-feu applicatif autonome (nft direct, hors-HTTP) | FR
- SOC 🎯 vues rassemblées | FR
- Actor-Intelligence 🕵️ acteurs, échelle de réponse | FR
- NAC 🔐 contrôle d'accès réseau | FR
- Webfilter 🧹 filtrage DNS par catégories et par appareil | FR
- Interceptor 🎯 supervision de l'inspection (sbxmitm, sbxwaf, nDPI) | FR
- Network-Modes 🌐 modes réseau, WAN, interfaces | FR
- Caches-and-Mirrors 💾 caches de la box et dépôt APT local | FR
- Portal 🚪 portail de session | FR
- Certificates 📜 certificats | FR
- Metrics 📊 mesures, sites, cartes, rapport PDF | FR
- SBX-OS 🧩 le Hall en application | FR
- Aurora-Design 🎨 design system admin | FR
- Admin-Panels-Gallery 🖼️ galerie des 37 pages | FR
- ThreatMesh 🛰️ blocklist souveraine (feeds + mesh, sans CAPI) | FR
- Modules 🇬🇧
- MODULES-FR 🇫🇷
- MODULES-DE 🇩🇪
- MODULES-ZH 🇨🇳
-
Operations-Runbook 🛠️ incidents | FR
-
API-Reference | FR | DE | 中文
- Multi-Agent-Worktree — un agent · une issue · une branche