Securite Flotte SECIVDA — Reference unique¶
REGLE OPERATIONNELLE FORTE : AUCUNE action de securite ne doit etre engagee sans avoir lu ce fichier au prealable. Ouvrir une regle firewall, changer un port, exposer un service, modifier SSH, deployer un nouveau service, faire une MAJ : CONSULTER d'abord ce doc. Toute deviation = derive ; toute MAJ = mise a jour ici en meme temps.
Perimetre : couvre TOUS les serveurs SECIVDA (10 hotes : 5 Dokploy prod + 1 Dokploy tools + bastion + 2 Plesk + 1 Mail catch-all).
Mis a jour : 2026-05-13. Owner : Jeff. Audit retour : trimestriel.
0. Comment utiliser ce document¶
- Avant action securite : ouvrir la fiche du serveur concerne (§3) + verifier surface d'attaque attendue (§4) + appliquer la procedure anti-derive (§5).
- Apres action securite : mettre a jour la fiche du serveur + tableau §4 + historique §8.
- Lors d'une MAJ paquets/kernel/Docker : derouler la checklist post-MAJ (§5.2). NE PAS rebooter sans verifier persistance iptables.
- Audit periodique : tous les 3 mois, executer le scan externe (§6) et confronter au tableau §4.
- Controle automatique : script
secivda-security-check.shdeploye sur tous serveurs + cron quotidien + alerte ntfy si derive (§7).
1. Standards transverses (DOIT etre identique sur TOUS les serveurs Dokploy)¶
Tout ecart sur l'un des items ci-dessous = derive a corriger immediatement. Le controle automatique §7 verifie chaque item.
| # | Item | Standard | Reference memory |
|---|---|---|---|
| 1 | Port SSH | 2222 (jamais 22) | infrastructure.md |
| 2 | SSH PasswordAuth | no (key-only) | idem |
| 3 | SSH AllowUsers | debian uniquement (jamais root) — EXCEPTION bastion-jotelulu : user root par defaut Jotelulu (pas de debian cree par l'image hebergeur). Compensation : SSH key-only + ACL VPN + MFA Kuma. | idem |
| 4 | SSH PermitRootLogin | no | idem |
| 5 | Firewall base | UFW + DOCKER-USER chain (sauf prod-04/05 = iptables direct + netfilter-persistent) | iptables-secivda.md, feedback_docker_user_chain.md |
| 6 | DOCKER-USER pattern | DROP 3000 sauf VPN+bastion+intra-Docker (172.16/12) | §2 ci-dessous |
| 7 | Persistance iptables | systemd docker-iptables-restore.service (BindsTo docker) | feedback_docker_user_persistence.md |
| 8 | Sources admin allowlist | VPN 130.180.220.25/32 + bastion 149.71.44.170/32 UNIQUEMENT | bastion-jotelulu.md |
| 9 | fail2ban | actif + jail sshd + ignoreip = VPN+bastion | fail2ban-config.md |
| 10 | CrowdSec | actif + bouncer iptables-firewall (Dokploy) ou nftables (Plesk/Mail) + ntfy template SECIVDA unifie | crowdsec-ntfy-template.md, monitoring-cve.md |
| 11 | unattended-upgrades | actif + Origins-Pattern packagecloud + Auto-Reboot=false (sauf 04:00 cron explicite) | feedback_auto_updates_tiers.md, feedback_dokploy_unattended_reboot.md |
| 12 | TZ systeme | Europe/Paris (jamais UTC) | feedback_tz_europe_paris.md |
| 13 | Cloudflare-only | Traefik middleware secivda-security-headers@file (default) + excludedIPs anti-bypass | traefik-cloudflare-only.md |
| 14 | Admin allowlist Traefik | secivda-admin-allowlist@file sur tout endpoint admin/* | feedback_traefik_default_middleware.md |
| 15 | Backup | restic chiffre + Synology C2 (Object Lock 30-90j) + Kuma push monitor | backup-secivda.md |
| 16 | Monitoring | Beszel agent (WSS sortant ou listen 45876) + Kuma + Dozzle + AIDE + Lynis + Docker Bench | beszel-monitoring.md, monitoring-cve.md |
| 17 | Secrets | Infisical seul (0 secret en clair Dokploy, 0 secret en clair Gitea) | feedback_no_secrets_in_gitea.md |
| 18 | Docker tag | JAMAIS :latest, toujours version fixe ou digest | feedback_no_latest_docker.md |
| 19 | Maintenance Kuma | Toujours activer AVANT operation downtime | feedback_kuma_maintenance_before_downtime.md, kuma-maintenance-api.md |
| 20 | Affichage secret terminal | INTERDIT (docker compose config, env, printenv) | feedback_no_secrets_terminal.md |
| 21 | Test exposition port externe | check-host.net + tcpdump, JAMAIS depuis VPN/bastion | feedback_external_port_test_protocol.md |
| 22 | exim4 mode | internet (jamais local) + mail [email protected] | infrastructure.md |
| 23 | needrestart | $nrconf{restart} = 'a' (auto) | infrastructure.md |
| 24 | Healthcheck post-reboot | /usr/local/bin/post-reboot-healthcheck.sh + cron @reboot + ntfy topic alertes | idem |
| 25 | MFA admin web | TOTP active sur Kuma, Beszel, Infisical, NocoDB, n8n, Dokploy, Gitea | feedback_mfa_initialization_procedure.md |
2. Pattern DOCKER-USER ISO flotte¶
Fichier : /etc/iptables/docker-user.rules
*filter
:DOCKER-USER - [0:0]
-A DOCKER-USER -s 130.180.220.25/32 -p tcp -m tcp --dport 3000 -j ACCEPT
-A DOCKER-USER -s 149.71.44.170/32 -p tcp -m tcp --dport 3000 -j ACCEPT
-A DOCKER-USER -s 172.16.0.0/12 -d 172.16.0.0/12 -p tcp -m tcp --dport 3000 -j ACCEPT
-A DOCKER-USER -p tcp -m tcp --dport 3000 -j DROP
-A DOCKER-USER -j RETURN
COMMIT
Unit systemd : /etc/systemd/system/docker-iptables-restore.service
[Unit]
Description=Restore Docker iptables DOCKER-USER chain
After=docker.service
BindsTo=docker.service
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore --noflush /etc/iptables/docker-user.rules
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Logique : DROP uniquement port 3000 (Dokploy UI). Autres ports Docker passent par DOCKER chain native. Si exposition admin custom (3001+), ajouter regle ACCEPT VPN+bastion + DROP par port dans le fichier .rules.
3. Fiches detaillees par serveur (10 hotes)¶
3.1 prod-dokploy-01 — 51.83.46.186¶
Hebergeur : OVH | OS : Debian 13 trixie | Docker : 29.x | Dokploy : v0.29.4
Role : Apps prod (portail.secivda.cloud, process.secivda.cloud, futur auth.secivda.cloud / remote.secivda.cloud post-SSO Foundation), services Coqworking (coqworking.fr, n8n.coqworking.fr, stats.coqworking.fr), cloud.addenda.fr.
Surface d'attaque externe :
| Port | Proto | Service | Source autorisee | Defense |
|---|---|---|---|---|
| 80 | tcp | HTTP → Traefik | Public (CF proxied) | Traefik anti-bypass CF + HSTS redirect |
| 443 | tcp+udp | HTTPS / HTTP3 → Traefik | Public (CF proxied) | TLS 1.2/1.3 + middlewares |
| 2222 | tcp | SSH | VPN + bastion | UFW allow, fail2ban, key-only |
| 3000 | tcp | Dokploy UI | VPN + bastion + intra-Docker | DOCKER-USER ISO |
| 21115-21119 | tcp | RustDesk (signalisation/relai) | Public (cf. besoin remote support) | A revisiter (legacy, peut-etre obsolete depuis Guacamole) |
Defenses en place : standards transverses §1 tous appliques. - UFW active : 80, 443 (anywhere), 2222+3000 (VPN+bastion), 21115-21119 RustDesk - DOCKER-USER chain + systemd docker-iptables-restore.service - fail2ban (jail SSH 2222, ignoreip VPN+bastion) - CrowdSec v1.4.6 (bouncer iptables) + collections linux/sshd/traefik/http-cve + ntfy - Lynis hebdo dimanche + AIDE quotidien + Docker Bench mensuel - unattended-upgrades + needrestart auto + healthcheck @reboot - Beszel agent WSS sortant vers bastion - Dozzle agent - restic backup Synology C2 + Kuma push monitor - Traefik v3.6.1 : api.insecure=false, HTTP/3, Let's Encrypt httpChallenge, healthcheck cron /5min - Docker daemon.json : live-restore=false (compat Swarm), no-new-privileges=true, log-driver json-file 50MB/3
Specifique : - Swap 4 Go sur /mnt/disk/swapfile, swappiness=10 - Audit securite : 8.5/10 (2026-02-10) — voir SECURITY_AUDIT_prod-dokploy-01.md - Futur SSO Foundation : ajout PG 17 + Redis 7 (en network bridge Docker, NE PAS exposer host)
Procedure MAJ securite : 1. Maintenance Kuma activee 2. apt update && apt upgrade (unattended fait deja critique) 3. Apres MAJ Docker : iptables -L DOCKER-USER -n doit montrer 4 regles + RETURN 4. Apres reboot : systemctl status docker-iptables-restore.service actif + Traefik UP + healthcheck post-reboot OK 5. Test acces Dokploy UI depuis VPN puis check-host.net depuis externe (port 3000 doit etre FILTERED) 6. Maintenance Kuma desactivee + log changement §8
3.2 prod-dokploy-02 — 51.83.46.172¶
Hebergeur : OVH | OS : Debian 13.3 trixie | Docker : 29.x | Dokploy : latest pinned
Role : Gitea (gitea.secivda.cloud) + 2 runners CI (DinD + Light, gitea-act-runner) + Documenso (signature.secivda.cloud) + audit.secivda.cloud + new.secivda.com staging.
Surface d'attaque externe :
| Port | Proto | Service | Source autorisee | Defense |
|---|---|---|---|---|
| 80, 443 | tcp+udp | Traefik | Public CF | standards |
| 2222 | tcp | SSH | VPN + bastion | standards |
| 3000 | tcp | Dokploy UI | VPN + bastion + intra | DOCKER-USER ISO |
| 22 | tcp | Gitea SSH (Git operations) | Public (mais DNS CF bloque) | Gitea internal port 2223, expose 22 host |
Defenses en place : standards §1 + MFA TOTP admin Gitea + secret-scan deploye 30 repos + Renovate automerge.
Specifique : - Gitea compose : reseau external dokploy-network, routeur gitea explicite - Documenso : volume documenso-production_database, image pinnee au digest - Runners CI : DinD pour build images Docker SECIVDA + Light pour TS/Python - Webhook Dokploy → Gitea : flux interne (pas d'exposition supplementaire)
Sensible : compromission Gitea = compromission codes sources + workflows CI. Defense en profondeur. Restic backup critique + plan rollback Gitea documente.
Procedure MAJ : standards + verifier Gitea Actions runners UP + Documenso DB schema OK apres reboot.
3.3 prod-dokploy-03 — 135.125.205.34¶
Hebergeur : OVH | OS : Debian 13 | Docker : 29.x | Dokploy : v0.29.4
Role : Infisical master (secrets.secivda.cloud — SOURCE UNIQUE secrets flotte) + auth.secivda.cloud legacy (Guacamole — sera renommee remote.* post-P1 SSO Foundation) + moedcare + transfert.
Surface d'attaque externe : 80, 443, 2222, 3000. Pas d'autres ports publics.
Surface INTERNE : - Streaming WAL PostgreSQL 135.125.205.34 → 135.125.203.172:5432 (replica Infisical sur prod-05) - Acces SSH supplementaire depuis prod-05 (replication PG) — whitelist iptables
Defenses : standards §1 + Infisical TOTP MFA admin obligatoire + secrets chiffres at rest (AES-256 par Infisical).
Sensible : compromission = compromission TOUS les secrets flotte. Defense maximale : - 1Password vault SECIVDA = miroir des cles DR critiques (TOTP_ENC_KEY, OIDC_JWT_PRIVATE_KEY, COOKIE_SIGNING_KEYS, MAGIC_LINK_HASH_KEY) - MFA TOTP admin obligatoire + reviewer logs Infisical trimestriel - Replica prod-05 = lecture seule + DR - Backup restic chiffre + Synology C2 + Object Lock 90j
Architecture replication (resolue 2026-05-13) : - Tunnel SSH autossh depuis prod-05 (service systemd infisical-pg-tunnel.service) → cible 172.23.0.4:5432 (IP container PG master sur bridge infisical_infisical-internal) via 127.0.0.1:5433 - Cle dediee id_ed25519_replication sur prod-05, autorisee sur prod-03 /home/debian/.ssh/authorized_keys avec permitopen="172.23.0.4:5432",no-pty,no-X11-forwarding,no-agent-forwarding,command="/bin/false" - sshd /etc/ssh/sshd_config.d/99-hardening.conf : AllowTcpForwarding local (necessaire car no bloque meme avec permitopen) - Slot physique replica_prod05 sur master (evite purge WAL si replica disconnect) - Monitor cron 5 min agent-replication-monitor.sh sur master ET replica (alerte ntfy topic alertes)
Procedure MAJ : standards + JAMAIS toucher PG sans snapshot Infisical + plan rollback documente.
3.4 prod-dokploy-04 — 135.125.204.125¶
Hebergeur : OVH | OS : Debian 13 | Docker : 29.x | Dokploy : v0.29.4
Role : Dozzle hub (logs.secivda.cloud) + Backrest (backup.secivda.cloud) + Listmonk (newsletter.secivda.fr) + ChangeDetection + n8n + remote.secivda.cloud + Convert (convert.secivda.cloud) + canal-montauban + Zio-Ora on-demand.
Specificite vs autres : - PAS DE UFW (desinstalle infra#99 a cause Docker Swarm) - iptables direct + netfilter-persistent save obligatoire apres TOUT changement - Beszel agent en mode listen 45876 (legacy, non-WSS) — voir issue §7.2
Surface d'attaque externe :
| Port | Proto | Service | Source autorisee | Defense |
|---|---|---|---|---|
| 80, 443 | tcp+udp | Traefik | Public CF | standards |
| 2222 | tcp | SSH | VPN + bastion + srv.secivda.com (monitoring Kuma TCP) | iptables INPUT ACCEPT + DROP others |
| 3000 | tcp | Dokploy UI | VPN + bastion | DOCKER-USER ISO |
| 45876 | tcp | Beszel agent (listen) | VPN + bastion | iptables INPUT ACCEPT VPN+bastion + DROP others (fixe 2026-05-13) |
| 7007 | tcp | Dozzle hub (recoit agents prod-01/02/03/05) | Agents Dokploy + VPN | iptables INPUT ACCEPT peers + DROP |
Defenses : standards §1 + INPUT rules iptables saved via netfilter-persistent save.
Specifique : - Tout changement iptables → immediatement sudo netfilter-persistent save sinon perdu au reboot (feedback_iptables_persistence.md) - Kuma + Dozzle hub = critiques pour monitoring flotte - Backrest UI = dashboard restic Synology C2 (auth web) - Phase B planifiee : migration Dozzle hub vers bastion
Issue connue : Beszel listen 45876 a migrer vers WSS sortant comme tools-01 (ISO).
Procedure MAJ : 1. Maintenance Kuma activee 2. MAJ paquets/Docker/kernel 3. Apres reboot, controle : - iptables -L INPUT -n --line-numbers → ACCEPT VPN+bastion 45876/7007/2222 + DROP par defaut - iptables -L DOCKER-USER -n → ISO - systemctl status docker-iptables-restore actif - netfilter-persistent charge rules - Traefik + Kuma + Dozzle UP 4. Maintenance Kuma desactivee + log §8
3.5 prod-dokploy-05 — 135.125.203.172¶
Hebergeur : OVH | OS : Debian 13 | Docker : 29.x | Dokploy : v0.29.4
Role : NocoDB (source unique BDD flotte depuis 2026-02-07) + n8n.secivda.cloud + shlink (link.secivda.cloud) + Infisical postgres-replica + dokploy-postgres + n8n production + notifs (legacy purge 2026-05-10).
Specificite : PAS DE UFW (idem prod-04, Swarm). iptables direct + netfilter-persistent. Infisical replica en network_mode: host → expose 5432 sur IP host.
Surface d'attaque externe :
| Port | Proto | Service | Source autorisee | Defense |
|---|---|---|---|---|
| 80, 443 | tcp+udp | Traefik | Public CF | standards |
| 2222 | tcp | SSH | VPN + bastion + prod-03 | iptables INPUT |
| 3000 | tcp | Dokploy UI | VPN + bastion | DOCKER-USER ISO |
| 5432 | tcp | PG Infisical replica (host network) | VPN + bastion + prod-03 (master) | iptables INPUT ACCEPT VPN+bastion+prod-03 + DROP others (fixe 2026-05-13) |
| 5433 | tcp | postgres-primary local (legacy, loopback) | 127.0.0.1 only | binding interne uniquement |
Defenses : standards §1 + INPUT iptables persistes + NocoDB MFA TOTP admin obligatoire.
Sensible : NocoDB = source unique BDD = compromission = perte data critique. Backup restic toutes les 6h + Object Lock 90j Synology C2.
Procedure MAJ : idem prod-04. Apres reboot verifier 5432 reste DROP par defaut depuis externe (check-host.net).
3.6 tools-dokploy-01 — 217.182.65.74 (NOUVEAU 2026-05-13)¶
Hebergeur : OVH | OS : Debian 13 | Docker : 29.4.3 | Dokploy : v0.29.4 | Reverse DNS : tools-dokploy-01.secivda.cloud OK
Role : DEV runtime (auth.dev. / portail.dev. / remote.dev. / process.dev.) + tools transverse (Loki, Unleash, GlitchTip, Plausible, Mailpit catch-all DEV, pgAdmin, MkDocs docs.secivda.cloud).
Surface d'attaque externe : standards 80, 443, 2222, 3000. Aucun autre port (Beszel = WSS sortant).
Defenses en place : standards transverses §1 tous appliques au bootstrap (TACHES/SSO-Foundation/BOOTSTRAP-LOG-tools-01.md) : - UFW active - DOCKER-USER ISO flotte (aligne 2026-05-13) - systemd docker-iptables-restore.service - fail2ban + ignoreip VPN+bastion - CrowdSec v1.7.x + bouncer iptables + collections + ntfy SECIVDA - unattended-upgrades + Origins-Pattern + Auto-Reboot=false - TZ Europe/Paris - restic + Synology C2 (bucket dedie + Object Lock 30j) - Beszel agent WSS sortant vers bastion (mode moderne) - Infisical client + secrets en boot uniquement - exim4 internet + mail [email protected] - post-reboot-healthcheck.sh @reboot + ntfy
Specifique : - 1Password : VPS tools-dokploy-01 (debian) + Backup - Synology C2 tools-dokploy-01 (restic, immutable 30j) - Mailpit DEV catch-all : aucun envoi reel depuis DEV apps - A faire (Phase L SSO Foundation) : enregistrer Kuma push monitor backup
Procedure MAJ : standards. Apres MAJ Docker, verifier DOCKER-USER ISO maintenu.
3.7 bastion-jotelulu (SRV-SECI02-001) — 149.71.44.170¶
Hebergeur : Jotelulu Paris PAR-FABRIC1 | OS : Debian 12 | Engine : Podman 4.3.1 (PAS Docker)
IP privee : 10.0.0.58/24. ACL Jotelulu : SSH 22 ouvert uniquement depuis VPN SECIVDA.
Role : Bastion SSH (IP secours admin) + Beszel hub (metrics.secivda.cloud) + ntfy (notifs.secivda.cloud) + Uptime Kuma (monitoring.secivda.cloud).
Specificite : Podman + Caddy + systemd (PAS Dokploy, PAS DOCKER-USER chain).
Surface d'attaque externe :
| Port | Proto | Service | Source autorisee | Defense |
|---|---|---|---|---|
| 80, 443 | tcp | Caddy → Kuma/Beszel/ntfy/notifs | Public CF | Caddy TLS + auth web + MFA TOTP |
| 2222 | tcp | SSH | ACL Jotelulu VPN-only (130.180.220.25) + UFW + fail2ban + key-only | Migration 22→2222 effectuee 2026-05-13 (issue #18). Reste user root a migrer vers debian (issue #19). |
| 443 (in) | tcp | Beszel hub (recoit agents WSS) | Tous agents flotte | TLS + cle publique par agent |
Defenses : standards adaptes Podman + Kuma MFA + Beszel MFA + ntfy auth tokens segmentes (publisher tokens specifiques par usage cf. infrastructure.md ligne 228-232).
Sensible : bastion = pivot critique. Si compromis = acces SSH a tous serveurs (depuis ACL Jotelulu). MFA obligatoire toutes UIs. Audit SECURITY_AUDIT_bastion-jotelulu.md.
Procedure MAJ : maintenance Kuma sur Kuma lui-meme. Beszel agents continueront a accumuler logs/metrics, recus a la reprise. ntfy reste UP (independance).
3.8 srv.secivda.com — 152.228.174.94 (+ 6 IPs additionnelles)¶
Hebergeur : OVH | OS : Debian 12 | Stack : Plesk Obsidian | SSH : 2222 user root (legacy, a migrer admin)
Role : Plesk pro (sites SECIVDA legacy non containerises, mail catch-all relayee vers mail.protton.fr).
Specificite : Plesk = stack legacy non containerisee. CrowdSec v1.7.6 (bouncer nftables) + fail2ban Plesk (coexistence) + AIDE + Lynis.
Surface d'attaque externe :
| Port | Proto | Service | Source / Defense |
|---|---|---|---|
| 80, 443 | tcp | nginx Plesk vhosts | Public (CrowdSec + WAF + headers Plesk) |
| 8443, 8447 | tcp | Plesk admin panel | VPN+bastion only (iptables) + Plesk auth + MFA |
| 2222 | tcp | SSH | fail2ban ignoreip VPN + accès depuis prod-04 (monitoring Kuma TCP 2222) |
| 25, 465, 587 | tcp | SMTP Exim Plesk | DOIVENT rester publics (mail) cf. mail-protton.md |
| 110, 143, 993, 995 | tcp | POP3/IMAP Plesk | Public (mail) |
| 53 | tcp+udp | PowerDNS si actif | A verifier (probablement off) |
Defenses : - Plesk patched (CVE-2025-66430/66431 fix 2026-03-11) - CrowdSec v1.7.6 + collections linux/sshd/apache2/nginx/postfix/dovecot/mariadb/http-cve - fail2ban Plesk (avec ignoreip VPN) - AIDE quotidien (exclusions Plesk/vhosts) - Lynis hebdo - Records mail/webmail/imap/smtp en zone Plesk DNS (NE PAS sync CF cf. feedback_plesk_cf_mail_records.md) - DKIM/SPF/DMARC actifs - suexec link verifie post-dist-upgrade (psa-suexec)
Sensible : sites pros + mail. Surveillance Kuma + CrowdSec ntfy.
Procedure MAJ : plesk installer --select-product-id panel --show-components → update. Apres dist-upgrade : verifier readlink -f /usr/lib/apache2/suexec (psa-suexec) + Plesk panel UP + webmails 200.
3.9 srv.link.bzh — 141.94.71.70¶
Hebergeur : OVH | OS : Debian (migration 11→12 planifiee plesk-debian-migration.md) | Stack : Plesk Obsidian
Role : Plesk famille (5 domaines : gueritte.com, eloise.gueritte.com, mathilde-chesneau.com, olivier.gueritte.com, link.bzh).
Surface d'attaque : identique 3.8 (Plesk stack).
Defenses : standards Plesk §3.8. Patche CVE Plesk a jour.
Specifique : voir srv-link-bzh.md. Migration Debian 11→12 planifiee.
Procedure MAJ : idem 3.8.
3.10 mail.protton.fr — 51.91.77.100¶
Hebergeur : OVH | OS : Debian | Engine : Podman + Caddy + systemd
Role : Mailpit catch-all 5 domaines (fauxmail.fr, vraimail.fr, protton.fr, etc.) — capture emails sortants pour audit, pas de relai externe.
Specificite : firewall VPN-only sur 2222 → AUCUN serveur Dokploy ne peut SSH ici (pas de ProxyJump). Si ban fail2ban → console OVH ou attendre 1h. fail2ban ignoreip 130.180.220.25 A FAIRE (cf. infrastructure.md ligne 138).
Surface d'attaque externe :
| Port | Proto | Service | Source / Defense |
|---|---|---|---|
| 80, 443 | tcp | Caddy → Mailpit UI | Public CF + auth web |
| 2222 | tcp | SSH | VPN-only (firewall stricte) + fail2ban + key-only |
| 25, 465, 587 | tcp | SMTP Mailpit (catch-all) | DOIVENT rester publics cf. mail-protton.md |
Defenses : - CrowdSec v1.7.6 + collections linux/sshd/postfix/caddy + ntfy template - AIDE quotidien (exclusions Podman) - Lynis hebdo - Caddy TLS auto Let's Encrypt - exim4 internet mode (port 25 conflit Postfix mais envoie quand meme)
Specifique : Postfix v5.x boky/postfix init scripts dans /docker-init.d/ (cf. infrastructure.md ligne 276). Mailpit Podman compose specifique.
Procedure MAJ : podman stop X && podman rm X AVANT compose up (pas de --force-recreate Podman). Backup restic Synology C2.
4. Surface d'attaque externe consolidee¶
Tableau exhaustif des ports exposes a internet sur chaque serveur. Aucun autre port ne doit etre ouvert sans entree dans ce tableau + regle iptables/UFW + entree §3 + §8.
| Serveur | 80 | 443 | 2222 | 3000 | 5432 | 7007 | 45876 | 25/465/587 | 8443/8447 | 22 | Autres |
|---|---|---|---|---|---|---|---|---|---|---|---|
| prod-dokploy-01 | CF | CF | VPN+B | VPN+B+i | - | - | - | - | - | - | 21115-19 RustDesk (Public, legacy) |
| prod-dokploy-02 | CF | CF | VPN+B | VPN+B+i | - | - | - | - | - | Gitea host (DNS CF bloque) | - |
| prod-dokploy-03 | CF | CF | VPN+B | VPN+B+i | - | - | - | - | - | - | - |
| prod-dokploy-04 | CF | CF | VPN+B+srv-com | VPN+B+i | - | agents | VPN+B | - | - | - | - |
| prod-dokploy-05 | CF | CF | VPN+B+prod-03 | VPN+B+i | VPN+B+prod-03 | - | - | - | - | - | - |
| tools-dokploy-01 | CF | CF | VPN+B | VPN+B+i | - | - | - | - | - | - | - |
| bastion-jotelulu | CF | CF | ACL Jotelulu VPN | - | - | - | - | - | - | - | 443 Beszel WSS in |
| srv.secivda.com | Public | Public | restreint | - | - | - | - | Public | VPN+B | - | 110/143/993/995 mail |
| srv.link.bzh | Public | Public | restreint | - | - | - | - | Public | VPN+B | - | 110/143/993/995 mail |
| mail.protton.fr | CF | CF | VPN-only | - | - | - | - | Public | - | - | - |
Legende : CF = Cloudflare proxied + Traefik anti-bypass | VPN+B = VPN 130.180.220.25 + bastion 149.71.44.170 | i = intra-Docker 172.16/12 | srv-com = 152.228.174.94
5. Procedures anti-derive¶
5.1 Avant tout changement securite¶
- Ouvrir ce fichier
- Identifier serveur cible (§3)
- Verifier surface d'attaque actuelle (§4)
- Activer maintenance Kuma (
/usr/local/bin/kuma-maintenance.sh start <monitor-id>) - Documenter changement (Gitea issue idealement, labels
security+infra) - Executer changement
- Persister regles :
ufw reloadOUnetfilter-persistent save(prod-04/05) OUiptables-save > /etc/iptables/rules.v4 - Tester depuis externe (jamais depuis VPN) → check-host.net
- Mettre a jour fiche §3 + tableau §4 + historique §8
- Desactiver maintenance Kuma + fermer issue Gitea
5.2 Checklist post-MAJ paquets/kernel/Docker (a executer sur chaque serveur apres reboot)¶
ssh -p 2222 debian@<serveur>
# Standards SSH
sudo grep -E '^(Port|PasswordAuthentication|AllowUsers|PermitRootLogin)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf
# UFW (prod-01/02/03/tools-01)
sudo ufw status verbose
# iptables INPUT (prod-04/05)
sudo iptables -L INPUT -n --line-numbers
# DOCKER-USER chain (tous Dokploy)
sudo iptables -L DOCKER-USER -n
# systemd persistance
sudo systemctl status docker-iptables-restore.service
sudo systemctl status netfilter-persistent # prod-04/05
# fail2ban
sudo fail2ban-client status sshd
sudo cat /etc/fail2ban/jail.d/ignoreip.conf
# CrowdSec
sudo cscli decisions list
sudo cscli bouncers list
# unattended-upgrades
sudo grep -E 'Unattended-Upgrade|Auto-Reboot' /etc/apt/apt.conf.d/50unattended-upgrades
# Services critiques
docker ps | grep -E 'traefik|dokploy'
systemctl status post-reboot-healthcheck
# TZ
timedatectl | grep 'Time zone'
Si DOCKER-USER vide apres reboot : bug systemd docker-iptables-restore.service (feedback_docker_user_persistence.md). sudo systemctl restart docker-iptables-restore.
Si iptables INPUT manque rules (prod-04/05) : sudo netfilter-persistent reload.
5.3 Tableau de bord verification (cocher apres action sensible)¶
| Date | Serveur | Action | DOCKER-USER | INPUT | fail2ban | CrowdSec | Maint Kuma | Scan ext OK |
|---|---|---|---|---|---|---|---|---|
| 2026-05-13 | tools-01 | Bootstrap | ✓ | n/a | ✓ | ✓ | n/a | ✓ |
| 2026-05-13 | prod-04 | Beszel 45876 firewall | ✓ | ✓ | ✓ | ✓ | ⏳ | ✓ (8 nodes externes ALL TIMEOUT) |
| 2026-05-13 | prod-05 | PG 5432 firewall | ✓ | ✓ | ✓ | ✓ | ⏳ | ✓ (8 nodes externes ALL TIMEOUT) |
| 2026-05-13 | prod-04 | SSH 2222 ISO check | n/a | ✓ | ✓ | ✓ | n/a | ✓ (8 nodes TIMEOUT) |
| 2026-05-13 | prod-05 | SSH 2222 ISO check | n/a | ✓ | ✓ | ✓ | n/a | ✓ (8 nodes TIMEOUT) |
6. Audits periodiques¶
6.1 Scan externe trimestriel (check-host.net depuis nodes NON-VPN)¶
Verifier que les ports suivants sont FILTERED (pas OPEN, pas CLOSED) : - 22, 23, 2222 (sauf 2222 depuis VPN/bastion) - 3000 (sauf VPN/bastion) - 5432 (sauf VPN/bastion/prod-03 → prod-05) - 6379, 7007, 45876 - 8080, 9090, 9100 (Prometheus metrics potentiels) - 2377, 7946, 4789 (Swarm) - 8443, 8447 (Plesk admin, sauf VPN/bastion) - Tous autres ports admin custom
Verifier que les ports suivants sont OPEN : - 80, 443/tcp, 443/udp (tous, sauf bastion qui n'a pas QUIC ?) - 25, 465, 587 (Plesk + mail) - 110, 143, 993, 995 (Plesk mail)
6.2 Re-audit ISO complet (annuel ou apres incident majeur)¶
Suivre audit_security_2026_05_11.md comme template + audit-template.md.
7. Systeme de controle automatique (anti-derive continu)¶
7.1 Script secivda-security-check.sh (a deployer flotte)¶
Objectif : controler automatiquement les 25 items §1 + DOCKER-USER pattern §2 + surface attaque §4. Alerter ntfy si derive detectee.
Deploiement : - Path : /usr/local/bin/secivda-security-check.sh sur tous serveurs - Owner : root:root mode 0750 - Cron : /etc/cron.d/secivda-security-check quotidien 04:30 local - Output : log /var/log/secivda-security-check.log + notification ntfy si derive (topic alertes)
Items controles par serveur :
# Pseudo-code du script (a developper en Phase suivante)
checks=(
# SSH
"sshd Port == 2222"
"sshd PasswordAuthentication == no"
"sshd PermitRootLogin == no"
"sshd AllowUsers includes debian"
"no listening on :22 (ss -tlnp)"
# Firewall standards (selon serveur)
"UFW active (prod-01/02/03/tools-01) OR netfilter-persistent active (prod-04/05)"
"iptables -L DOCKER-USER -n contains 4 rules + RETURN (pattern ISO)"
"systemctl is-active docker-iptables-restore.service"
# fail2ban
"systemctl is-active fail2ban"
"fail2ban-client status sshd parses OK"
"ignoreip contains 130.180.220.25 AND 149.71.44.170"
# CrowdSec
"systemctl is-active crowdsec"
"cscli bouncers list contains iptables-bouncer (Dokploy) OR nftables-bouncer (Plesk/Mail)"
"ntfy template name == 'secivda'"
# OS hardening
"timedatectl Time zone == Europe/Paris"
"needrestart restart auto config present"
"unattended-upgrades enabled + Auto-Reboot=false (Dokploy) ou OK"
"post-reboot-healthcheck.sh exists + @reboot cron present"
# Backup
"restic latest snapshot < 12h ago"
"restic check OK (every 7 days)"
# Monitoring
"beszel-agent service active (WSS or listen)"
"dozzle agent active (Dokploy non-hub)"
# Surface attaque (selon serveur)
"ss -tlnp listening ports == expected set per server"
"check-host.net last scan results match §4 (cache 24h)"
)
Output normal : aucune notification.
Output derive : ntfy notification topic alertes priority 5 :
[secivda-security] DERIVE detectee sur <serveur>
- <item> : expected <X>, got <Y>
- <item> : ...
Action requise : consulter securite-flotte-reference.md §3.<serveur>
7.2 Controle replication Infisical PG (post-resolution issue §3.3)¶
Objectif : monitorer en continu la replication WAL streaming prod-03 → prod-05.
Sur prod-03 (master) :
SELECT
client_addr,
state,
sync_state,
EXTRACT(EPOCH FROM (now() - reply_time)) AS lag_seconds,
pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replay_lag_bytes
FROM pg_stat_replication;
Sur prod-05 (replica) :
SELECT
status,
sender_host,
sender_port,
conninfo,
received_lsn,
EXTRACT(EPOCH FROM (now() - last_msg_receipt_time)) AS last_msg_age_seconds
FROM pg_stat_wal_receiver;
Implementation : - Script /usr/local/bin/infisical-replication-check.sh sur prod-05 - Cron 5 minutes - Alerte ntfy si : - pg_stat_wal_receiver vide (replication arretee) - last_msg_age_seconds > 60 - replay_lag_bytes > 100 MB - Heartbeat Kuma push monitor type "Push" toutes les 5 min
Test fonctionnel hebdomadaire : - INSERT test row sur master Infisical → verifier presence sur replica < 30s - Si fail → alerte + ouvrir issue Gitea infra automatiquement
7.3 Resolution Infisical replication (2026-05-13) — RESOLU¶
Diagnostic final (5 root causes empilees) :
- IP volatile du PG master container :
172.23.0.2 → 172.23.0.4apres redemarrage du container (incident 2026-05-10). Le tunnel SSH cible une IP obsolete. - Service systemd
infisical-pg-tunnel.serviceIP hardcodee :-L 5433:172.23.0.2:5432. - authorized_keys mal formee sur prod-03 :
restrict,port-forwarding,...maisport-forwardingn'est PAS une option SSH valide.restrictreste actif et bloque tout forward. - sshd_config.d/99-hardening.conf :
AllowTcpForwarding noest un kill-switch absolu, les options authorized_keys ne peuvent QUE restreindre (pas etendre). - Slot de replication INEXISTANT : sans slot, master purge les WAL apres 3 jours d'absence du replica → "WAL segment has already been removed".
- Bonus : crontab
agent-replication-monitor.shconfiguree pour userdebianqui n'a PAS acces docker.sock → script echouait silencieusement depuis le debut. Aucune alerte ntfy emise.
Fix applique 2026-05-13 :
- ✓ Service systemd :
sedIP 172.23.0.2 → 172.23.0.4 + reload + restart - ✓ authorized_keys prod-03 : remplace
restrict,port-forwarding,command="/bin/false"parpermitopen="172.23.0.4:5432",no-pty,no-X11-forwarding,no-agent-forwarding,command="/bin/false" - ✓ sshd_config.d/99-hardening.conf :
AllowTcpForwarding no→local+sshd -t+systemctl reload ssh - ✓ Slot physique cree sur master :
SELECT pg_create_physical_replication_slot('replica_prod05'); - ✓ Stop container replica + mv data dir vers
.bak-YYYYMMDD-HHMMSS(90M sauvegarde) - ✓
pg_basebackupvia container temppostgres:16-alpine+--network host+-h 127.0.0.1 -p 5433 -X stream -P -R -S replica_prod05→ 83.7 MB transferes - ✓ Start container replica → entre en standby + streaming actif (
status=streaming, last_msg_age 9-12s) - ✓ Test fonctionnel : INSERT sur master replique sur replica en < 3 s
- ✓ Crontab
infisical-*.shmigreesdebian→rootsur prod-03 ET prod-05 (fix bug detection automatique)
Verification finale : - Master pg_stat_replication : replicator | 172.23.0.1 | walreceiver | streaming | async | reply_age 3s | replay_lag 0 bytes - Replica pg_stat_wal_receiver : streaming | 127.0.0.1 | 5433 | last_msg_age 9s - Slot replica_prod05 : active=t, restart_lsn=0/2A000060 - Monitor cron : [2026-05-13 11:22:01] OK: Streaming actif (derniere transaction replay il y a 53s)
Dette technique restante : - ~~L'IP 172.23.0.4 reste volatile~~ ✓ RESOLU 2026-05-13 (Option A appliquee) : - /opt/infisical/compose.yaml : network infisical-internal declare explicitement ipam.config: - subnet: 172.23.0.0/16, gateway: 172.23.0.1 - Service postgres : networks.infisical-internal.ipv4_address: 172.23.0.4 - Backup compose : /opt/infisical/compose.yaml.bak.20260513-112732 - Recreate via docker compose up -d (recreate network + 3 containers) : downtime <30s - Replication validee post-recreate : pg_stat_wal_receiver.status=streaming, slot replica_prod05 actif (restart_lsn avance), INSERT/SELECT test (_replication_check id=2) replique en <3s - Au prochain redemarrage container PG master, l'IP reste 172.23.0.4 → permitopen authorized_keys + tunnel SSH restent valides definitivement - Nettoyer /var/lib/docker/volumes/infisical_postgres-replica-data/_data.bak-* apres validation 7 jours (90M) - DROP table _replication_check apres usage (ou la garder comme heartbeat fonctionnel pour §7.2 monitor)
Lecons retenues (a integrer dans §1 standards transverses + §7.1) : - Tout crontab d'agent monitoring DOIT tourner en root (ou groupe docker), sinon docker ps echoue silencieusement - Tout script monitor qui peut echouer silencieusement DOIT envoyer un heartbeat positif a Kuma (push monitor) pour detecter l'absence de retour - Toute connexion replication PG DOIT utiliser un slot physique (sinon WAL purge = re-basebackup obligatoire apres downtime) - IP volatile container Docker = anti-pattern pour services critiques. Toujours fixer IP statique OU passer par DNS docker via sidecar
7.4 Dashboard centralise (Phase ulterieure)¶
A terme, integration des controles §7.1 + §7.2 dans : - Kuma : push monitors par serveur + service - Beszel : dashboards custom metrics - MkDocs docs.secivda.cloud : copie automatique de ce doc + status temps reel
8. Historique des changements securite¶
| Date | Serveur | Type | Detail | Reference |
|---|---|---|---|---|
| 2026-02-10 | prod-01/02 | MAJ | Docker 29.x + Dokploy + Traefik v3.6.1 | infrastructure.md |
| 2026-02-19 | Flotte | Deploiement | unattended-upgrades + needrestart + reboot 04:00 + healthcheck | idem |
| 2026-02-27 | bastion (ntfy) | Hardening | Tokens segmentes par publisher, deny-all default | idem |
| 2026-03-11 | srv-com | Patch CVE | Plesk CVE-2025-66430 + CVE-2025-66431 (escalade root) | idem |
| 2026-03-13 | Flotte | Outils | CrowdSec + Lynis + AIDE + Docker Bench deployes 8/8 | idem |
| 2026-05-04 | prod-03/04/05 | Hardening | fail2ban ignoreip VPN aligne sur 7/8 serveurs | idem ligne 139 |
| 2026-05-06 | Flotte | Deploiement | Traefik anti-bypass CF (excludedIPs middleware) | traefik-cloudflare-only.md |
| 2026-05-07 | bastion | Deploiement | Beszel hub + 7 agents WSS (remplace Netdata) | beszel-monitoring.md |
| 2026-05-10 | Flotte | Hardening | DOCKER-USER pattern ISO + systemd persistance + override systemd Docker | feedback_docker_user_chain.md, feedback_docker_user_persistence.md, feedback_dokploy_unattended_reboot.md |
| 2026-05-10 | bastion | Migration | ntfy migre depuis prod-05 vers bastion (Podman+Caddy+systemd) | infrastructure.md ligne 216 |
| 2026-05-10 | prod-05 | Fix | iptables DNAT figees post-Swarm migration | feedback_iptables_persistence.md |
| 2026-05-11 | prod-04 | Incident | Traefik down post-kernel + auto-reboot unattended | incident_dokploy_kernel_2026_05_10.md |
| 2026-05-11 | prod-04 | Fix | Traefik middleware ipStrategy.depth | incident_traefik_prod04_2026_05_11.md |
| 2026-05-11 | Flotte | Audit | Re-audit 9 serveurs, moyenne 5.83 → 7.83/10 | audit_security_2026_05_11.md |
| 2026-05-12 | Flotte | Deploiement | CrowdSec ntfy template SECIVDA unifie | crowdsec-ntfy-template.md |
| 2026-05-13 | tools-01 | Bootstrap | Provisioning + 12 phases hardening complete | TACHES/SSO-Foundation/BOOTSTRAP-LOG-tools-01.md |
| 2026-05-13 | prod-04 | Fix | Beszel 45876 → iptables INPUT ACCEPT VPN+bastion + DROP others | Ce doc §3.4 |
| 2026-05-13 | prod-05 | Fix | PG 5432 → iptables INPUT ACCEPT VPN+bastion+prod-03 + DROP others | Ce doc §3.5 |
| 2026-05-13 | tools-01 | Alignement | DOCKER-USER pattern ISO flotte | Ce doc §3.6 |
| 2026-05-13 | Flotte | Doc | Creation ce fichier reference securite-flotte-reference.md (10 serveurs + systeme controle) | Ce doc |
| 2026-05-13 | prod-04, prod-05 | Validation externe | check-host.net 8 nodes externes confirment 45876+5432+2222 FILTERED, 443 OPEN (10-150ms) → fixes 2026-05-13 valides | Ce doc §5.3 + §9 issue #6 |
| 2026-05-13 | prod-03 ↔ prod-05 | Fix | Infisical replication restauree : tunnel SSH (IP fix 172.23.0.4) + authorized_keys reformee (permitopen) + sshd AllowTcpForwarding=local + slot replica_prod05 + pg_basebackup 83MB + crontab monitor migre debian→root | Ce doc §7.3 + §9 issue #1 |
| 2026-05-13 | prod-03 | Hardening durabilite | /opt/infisical/compose.yaml : subnet declare + ipv4_address: 172.23.0.4 pour postgres (PG master). Recreate network + 3 containers (downtime <30s). Replication validee : pg_stat_wal_receiver=streaming, INSERT/SELECT test repliques. IP figee = plus de derive future possible. | Ce doc §3.3 + §7.3 |
| 2026-05-13 | Flotte (6 serveurs Dokploy) | Deploiement systeme controle automatique | secivda-security-check.sh v1.0.0 deploye sur prod-01..05 + tools-01. Cron quotidien 04:30. 30 checks: SSH, TZ, fail2ban, CrowdSec, unattended-upgrades, DOCKER-USER pattern, systemd persistance, restic age, beszel, Docker :latest, etc. State JSON /var/lib/secivda-security-check/state.json. Alerte ntfy topic alertes priority 5 si derive. Heartbeat Kuma push optionnel via KUMA_PUSH_URL env. Dry-run flotte a immediatement detecte 4 derives transverses critiques (cf. §9 issues #12-15) prouvant l'utilite du systeme. | Ce doc §7.1 + §9 |
| 2026-05-13 | Script | v1.0.1 | Fix bugs v1.0.0 : (a) restic snapshot age = MAX timestamp (pas premier element JSON), (b) accepte permitrootlogin in {no, prohibit-password, without-password}, (c) exclu images Dokploy-built locales du check :latest (regex / requis pour external), (d) pattern DOCKER-USER iptables -S corrige. | Ce doc §7.1 |
| 2026-05-13 | 5 prod | Hardening SSH | AllowUsers debian ajoute dans 99-hardening.conf sur prod-01..05 + reload sshd | Ce doc §9 issue #13 |
| 2026-05-13 | tools-01 | Finalisation bootstrap | post-reboot-healthcheck.sh deploye (copy depuis prod-01) + ntfy-token.env + cron @reboot + exim4 reconfigure mode=internet | Ce doc §9 issue #15 |
| 2026-05-13 | 6 containers Docker | Epinglage versions | n8n.coqworking.fr → n8nio/n8n:2.20.7, cloud.addenda.fr → owncloud/server:10.16.2, 4× dozzle-agent → amir20/dozzle:v10.5.2. Repo Gitea modifie pour dozzle. Procedure raw composes Dokploy via API documentee. Renovate bumpera. | Ce doc §9 issue #14 |
| 2026-05-13 | Flotte (resultat final) | Audit final post-fixes | 5/6 serveurs 0 drift (prod-01..05 = 28-30 checks tous OK). tools-01 = 1 drift mineur (backup age 15h, issue #16). Surface d'attaque ISO. | Ce doc §3 + §9 |
| 2026-05-13 | bastion-jotelulu | Fix kuma-maintenance.sh MFA TOTP | oathtool installe + seed Base32 push /etc/kuma/totp_seed (600) + script patche (get_totp + KUMA_TOTP env + login socket.io token). Procedure maintenance Kuma operationnelle de nouveau. | Ce doc §9 issue #17 |
| 2026-05-13 | bastion-jotelulu | Migration SSH port 22 → 2222 | Maintenance Kuma #556 (premier test fix MFA) → sshd Port 2222 + UFW allow 2222 VPN + ACL Jotelulu 2222 (action user) + ~/.ssh/config alias Port 2222 + remove Port 22 partout. Test SSH 2222 OK. | Ce doc §3.7 + §9 issue #18 |
| 2026-05-13 | bastion-jotelulu | UFW WG peers alignement | Regle UFW 22/tcp ALLOW 10.10.10.0/24 migree vers 2222/tcp ALLOW 10.10.10.0/24 pour coherence. UFW final : 0 regle 22/tcp restante. | Ce doc §9 issue #20 |
| 2026-05-13 | bastion-jotelulu | Issue #19 fermee N/A | SSH user root est convention Jotelulu (pas de debian cree par image hebergeur). Documente exception §1 item 3. Compensations : key-only + ACL VPN + MFA Kuma. | Ce doc §9 issue #19 |
9. Issues connues a tracker¶
| # | Serveur | Issue | Severite | Action |
|---|---|---|---|---|
| 1 | ~~prod-05 ↔ prod-03~~ | ~~Replication Infisical CASSEE (replica → 127.0.0.1:5433)~~ | ~~High~~ | ✓ RESOLU 2026-05-13 : 5 root causes fixes (IP+authorized_keys+sshd+slot+pg_basebackup) + crontab monitor migre debian→root. Streaming actif, replay_lag=0. Dette: IP statique container a fixer (§7.3 Option A/B/C). |
| 2 | prod-04 | Beszel agent en listen 45876 (legacy) au lieu de WSS | Medium | Migration WSS sortant (ISO tools-01) |
| 3 | mail.protton.fr | fail2ban ignoreip VPN PAS encore configure (8/8 → 7/8) | Medium | Ajouter /etc/fail2ban/jail.d/ignoreip.conf quand ban expire |
| 4 | tools-01 | Kuma push monitor backup pas encore registre | Low | Phase L SSO Foundation |
| 5 | Flotte | Token CF_DNS_API_TOKEN en clair sur 4 Dokploys | Medium | Migrer vers Infisical (feedback_traefik_cf_env_dette.md) |
| 6 | ~~prod-04/05~~ | ~~Test externe check-host.net post-fix non valide (rate-limited 2026-05-13)~~ | ~~Medium~~ | ✓ RESOLU 2026-05-13 : 8 nodes externes (CH,FR,DE,FI,NL,LT,RO,SI,US,...) confirment 45876+5432+2222 FILTERED. Temoin 443 OPEN |
| 7 | Flotte | Memory beszel-monitoring.md annonce "7 agents WSS" alors que prod-04 listen | Low | Maj memory |
| 8 | prod-04 | UFW port 19999 (Netdata legacy) reste ouvert | Low | Fermer regle (Netdata desinstalle 2026-05-07) |
| 9 | bastion | Audit SECURITY_AUDIT_bastion-jotelulu.md a re-verifier post-MFA Kuma/Beszel | Low | Trimestriel |
| 10 | prod-01 | RustDesk ports 21115-21119 ouverts publiquement (legacy ?) | Medium | Verifier utilite + restreindre si obsolete |
| 11 | ~~Flotte~~ | ~~Systeme de controle secivda-security-check.sh pas encore deploye (§7.1)~~ | ~~High~~ | ✓ DEPLOYE 2026-05-13 : v1.0.0 sur 6 Dokploys (prod-01..05 + tools-01). Cron /etc/cron.d/secivda-security-check quotidien 04:30. Source /Users/jeff/CLAUDE/OUTILS/secivda-security-check/. 30 checks couvrent §1 standards + §2 DOCKER-USER. Dry-run flotte a deja revele 4 derives transverses (cf. nouvelles issues #12-15) |
| 12 | ~~prod-01, 02, 03, 04, 05~~ | ~~Restic backup DOWN depuis 2026-05-04~~ | ~~CRITICAL~~ | ✓ FAUX POSITIF 2026-05-13 : bug dans secivda-security-check.sh v1.0.0. restic snapshots --json --latest 1 retourne 1 snapshot PAR groupe (host, paths) et l'extraction head -1 prenait le premier (= le plus ancien) au lieu du plus recent. Backup tourne en realite tous les 6h (logs /var/log/secivda-backup.log 2026-05-13 06:02:56 OK). Fix dans v1.0.1 : cut -d'"' -f4 \| sort \| tail -1. Kuma surveille bien le backup via HEARTBEAT_URL=https://monitoring.secivda.cloud/api/push/b6f1... dans /etc/secivda-backup/config.env (cf. backup-secivda.md). |
| 13 | ~~prod-01, 02, 03, 04, 05~~ | ~~ssh.AllowUsers absente~~ | ~~Medium~~ | ✓ RESOLU 2026-05-13 : AllowUsers debian ajoute dans /etc/ssh/sshd_config.d/99-hardening.conf sur 5/5 prod. Backups conf cree. sshd -t valide. systemctl reload ssh execute (sessions existantes preservees). Verification post-reload via sshd -T \| grep allowusers confirme allowusers debian sur tous serveurs. |
| 14 | ~~prod-01 (3), prod-02 (1), prod-03 (1), prod-05 (1)~~ | ~~6 containers Docker :latest EXTERNES~~ | ~~Medium~~ | ✓ RESOLU 2026-05-13 par agent dokploy : (a) n8nio/n8n:2.20.7 sur prod-01 (n8n.coqworking.fr) — saut 9 versions mineures depuis 2.11.4, surveiller logs migration via Dozzle, (b) owncloud/server:10.16.2 sur prod-01 (cloud.addenda.fr), (c) amir20/dozzle:v10.5.2 sur prod-01/02/03/05 via repo Gitea SECIVDA/monitoring.secivda.cloud (commit "fix(dozzle): epingler agents a v10.5.2"). Tous tests HTTP 200. Renovate prend le relais. Note importante: composes sourceType=raw (n8n + owncloud) requirent compose.update API Dokploy + compose.deploy (modif fichier disque ne suffit pas — DB Dokploy fait foi). |
| 17 | ~~bastion (kuma-maintenance.sh)~~ | ~~Script casse depuis 2026-05-11 MFA TOTP~~ | ~~High~~ | ✓ RESOLU 2026-05-13 : (a) apt install oathtool sur bastion, (b) seed Base32 TOTP extrait depuis 1Password item djo6mgqxzdazcuis4vl2nay6qe (champ OTP value = otpauth URL) puis stocke dans /etc/kuma/totp_seed mode 600 root:root, (c) script patche : ajout get_totp() fonction (oathtool TTL=30s), ajout KUMA_TOTP env var dans podman exec, modif socket.emit("login", {..., token: process.env.KUMA_TOTP}) (ligne 118). Test post-fix : kuma-maintenance.sh list retourne 3 maintenances historiques, monitors retourne la liste. La regle "TOUJOURS maintenance Kuma AVANT downtime" est de nouveau operationnelle. Backup script avant patch : /usr/local/bin/kuma-maintenance.sh.bak-20260513-122700. |
| 18 | ~~bastion-jotelulu~~ | ~~SSH sur port 22 au lieu de 2222~~ | ~~Medium~~ | ✓ RESOLU 2026-05-13 : (a) Maintenance Kuma #556 active 45min (test fix MFA TOTP du jour, OK), (b) sshd /etc/ssh/sshd_config.d/99-secivda-port.conf : Port 2222 (Port 22 retire), (c) UFW : ufw allow 2222 from 130.180.220.25 comment "SSH 2222 SECIVDA VPN" + delete regle 22 VPN, (d) ACL Jotelulu : 2222 ouvert depuis 130.180.220.25 + 22 ferme (action user), (e) ~/.ssh/config alias bastion-jotelulu : ajout Port 2222. Test SSH 2222 OK via alias. Backup sshd_config : /etc/ssh/sshd_config.bak-20260513-125013. |
| ~~19~~ | ~~bastion-jotelulu~~ | ~~SSH user root~~ | ~~Low~~ | ✗ N/A — PAS UN DRIFT : sur Jotelulu, root est l'user systeme par defaut (image Jotelulu, pas de debian cree). Exception documentee dans §1 item 3. SSH key-only + ACL VPN + MFA Kuma compensent. |
| ~~20~~ | ~~bastion-jotelulu~~ | ~~UFW autorise SSH port 22 depuis WG peers~~ | ~~Low~~ | ✓ RESOLU 2026-05-13 : ufw allow 2222/tcp from 10.10.10.0/24 ajoute + ufw delete allow 22/tcp from 10.10.10.0/24 + ufw reload. UFW final : aucune regle 22/tcp restante. 2 regles 2222/tcp (VPN 130.180.220.25 + WG peers 10.10.10.0/24). |
| 15 | ~~tools-01~~ | ~~Bootstrap incomplet : exim4 mode=local, post-reboot-healthcheck.sh absent~~ | ~~Medium~~ | ✓ RESOLU 2026-05-13 : (a) /usr/local/bin/post-reboot-healthcheck.sh copie depuis prod-01 + /etc/dokploy/ntfy-token.env + cron @reboot setup. (b) exim4 reconfigure mode=internet + restart actif. Dry-run apres fix : seul drift restant = backup age 15h (cron tools-01 2x/jour 00/06, premier backup 20:24 nightly = 15h, acceptable pour DEV, a re-check apres prochain backup). |
| 16 | tools-01 | Backup tools-01 frequence 2x/jour (00:05, 06:05) au lieu de 4x/jour standard | Low | Aligner sur freq flotte 4x/jour (00/06/12/18) OU accepter freq differente pour DEV |
10. Liens memoires reference¶
| Theme | Memory |
|---|---|
| Infrastructure base | infrastructure.md |
| Firewall pattern | iptables-secivda.md, feedback_docker_user_chain.md, feedback_docker_user_persistence.md, feedback_iptables_persistence.md, feedback_dokploy_ui_firewall.md |
| SSH / fail2ban | fail2ban-config.md, bastion-jotelulu.md |
| Cloudflare / Traefik | traefik-cloudflare-only.md, feedback_traefik_default_middleware.md, feedback_traefik_cf_env_dette.md, feedback_traefik_dokploy_mount.md, feedback_traefik_acme_watcher_v2.md |
| Monitoring | beszel-monitoring.md, kuma-maintenance-api.md, monitoring-cve.md, feedback_kuma_maintenance_before_downtime.md, feedback_kuma_maintenance_before_action.md |
| Backup | backup-secivda.md |
| Secrets | feedback_no_secrets_in_gitea.md, feedback_no_secrets_terminal.md, feedback_traefik_cf_env_dette.md |
| OS / MAJ | feedback_auto_updates_tiers.md, feedback_dokploy_unattended_reboot.md, feedback_tz_europe_paris.md |
| Audits | audit-template.md, audit_security_2026_05_11.md, audit_issues_2026_05_11.md, SECURITY_AUDIT_bastion-jotelulu.md, security-audit-issues-2026-03-14.md, GIT_SECURITY_AUDIT_2026-03-06.md |
| Bastion / IP secours | bastion-jotelulu.md |
| CrowdSec | crowdsec-ntfy-template.md |
| Plesk | srv-link-bzh.md, plesk-debian-migration.md, feedback_plesk_cf_mail_records.md, feedback_plesk_last_nginx_symlink.md |
| Tests externes | feedback_external_port_test_protocol.md |
| MFA admin | feedback_mfa_initialization_procedure.md |
mail-protton.md | |
| Dokploy specifique | dokploy-config.md, feedback_dokploy_gitea_provider.md, feedback_dokploy_command_field.md, feedback_redis_dokploy_no_password.md |
| Gitea | gitea-config.md, gitea-ci-runners.md, gitea-audit-2026-03-13.md, infra-168-secret-scan-deployment.md |
| Cloudflare DNS | cloudflare-secivda.md, cloudflare-perso.md, cloudflare-api-key-issue.md |
11. Maintenance ce document¶
- Maj obligatoire apres : tout nouveau serveur, toute regle firewall, toute exposition de port, toute modification SSH, toute MAJ securite majeure, tout incident, tout fix issue §9.
- Format : ligne §8 (historique) + maj fiche serveur §3 + maj tableau §4 + items §1 si applicable.
- Propagation : copier dans
docs.secivda.cloud(P0bis MkDocs) une fois deploye, pour visibilite collab. - Reviewer : agent
security-isoen lecture systematique avant toute action sensible. Hook potentiel : pre-action securite → bloque si fichier non lu dans la session. - Versioning : ce doc est en memory persistante Claude Code (
/Users/jeff/.claude/projects/-Users-jeff-CLAUDE/memory/securite-flotte-reference.md).