Audit de Surface
Pentest et Durcissement de l'Infrastructure 0DATA
Résumé
Nous documentons le pentest complet de l'infrastructure de production 0DATA (217.160.192.96, 23 juillet 2026). Le scan initial a révélé 28 ports TCP ouverts dont deux accès d'administration système exposés directement sur Internet : Cockpit Server (port 9090, shell root Ubuntu) et CloudPanel (port 8443, panneau d'administration web). L'API FastAPI était accessible sans SSL (port 8300, bind 0.0.0.0), exposant la cartographie complète de 89 endpoints via /docs et /openapi.json. Le service NATS exposait sa bannière (version 2.10.27, nom de serveur, clé publique). L'audit a identifié 3 vulnérabilités critiques, 3 hautes, 3 moyennes. L'ensemble des correctifs a été appliqué dans la même session : blocage firewall (ufw), reconfiguration du bind API (127.0.0.1), désactivation de l'OpenAPI schema, protection de /docs par nginx auth_basic. La surface finale est de 7 ports (contre 28). Ce papier établit la méthodologie d'audit et sert de référence pour les audits périodiques de l'infrastructure.
En une phrase
Ce papier est l'audit. Il documente le premier pentest systématique de l'infrastructure 0DATA — 28 ports ouverts réduits à 7, 3 vulnérabilités critiques corrigées en session, méthodologie reproductible établie.
1. Méthodologie
L'audit a été conduit le 23 juillet 2026 sur le serveur de production 0DATA (Ubuntu 24.04.4 LTS, adresse publique 217.160.192.96). La méthodologie suit une approche en quatre phases inspirée du guide OWASP pour les tests d'intrusion d'infrastructure :
- Reconnaissance — scan nmap complet (65 535 ports TCP), identification des services et versions
- Cartographie — inventaire des services écoutant sur 0.0.0.0, analyse des bannières et en-têtes HTTP
- Intrusion — tests d'accès non authentifié aux endpoints API, tentatives de contournement d'authentification, vérification des autorisations
- Correction — application des correctifs, revérification immédiate, documentation des mesures
2. Scan Initial — Surface d'Attaque
Le scan nmap initial (-sS -p- --min-rate 5000 -T4) a révélé 28 ports TCP ouverts :
L'analyse des processus a révélé 35+ services écoutant sur 0.0.0.0 (toutes interfaces), incluant PostgreSQL (5432), Redis (6379), NATS (4222), trois serveurs Next.js de développement (3000, 3001, 3003), et de multiples services Python (NOVA, Flask, FastAPI, Gunicorn). La règle UFW par défaut (deny incoming) bloquait déjà l'accès externe à la plupart de ces ports, mais la défense en profondeur était absente — une défaillance du firewall exposerait instantanément l'intégralité de l'infrastructure interne.
3. Vulnérabilités Critiques
Trois vulnérabilités critiques ont été identifiées, chacune pouvant conduire à une compromission complète du serveur si exploitée.
3.1 Cockpit Server — Shell Root Exposé (Port 9090)
Le service Cockpit (cockpit-tls, systemd) était accessible sur le port 9090, exposant l'interface d'administration système Ubuntu directement sur Internet. Cockpit fournit un shell interactif, la gestion des services systemd, la visualisation des logs, et la gestion des comptes utilisateurs — le tout via une interface web.
Un attaquant disposant des credentials système (ou exploitant une vulnérabilité de Cockpit) obtiendrait un accès shell root complet. Le port 9090 était explicitement autorisé dans UFW (ALLOW IN Anywhere).
ufw delete allow 9090/tcp — suppression immédiate de la règle UFW. Le service continue d'écouter localement mais n'est plus accessible depuis l'extérieur. Vérification : connexion externe timeout (code 124).
3.2 CloudPanel — Panneau d'Administration Web (Port 8443)
Le panneau CloudPanel v2.5.3 était servi par nginx sur le port 8443, accessible en HTTPS. CloudPanel gère l'ensemble des sites web du serveur : création/suppression de domaines, certificats SSL, utilisateurs, bases de données, et configuration PHP.
Le port 8443 n'était pas explicitement listé dans les règles UFW, mais nginx l'écoutait sur 0.0.0.0. La règle UFW par défaut (deny incoming) le bloquait théoriquement, mais la présence de ce service sur toutes les interfaces constitue une violation du principe de défense en profondeur.
3.3 API FastAPI — Contournement SSL (Port 8300)
L'API principale du serveur (FastAPI, port 8300) écoutait sur 0.0.0.0, ce qui signifie qu'elle était accessible directement sur l'IP publique, sans passer par nginx. Cela contournait :
- Le chiffrement SSL/TLS fourni par nginx (Let's Encrypt)
- Le rate limiting (60 req/min) configuré dans nginx
- Les en-têtes de sécurité (HSTS, CSP) injectés par nginx
- La journalisation centralisée des accès
L'API restait accessible en HTTP clair sur http://217.160.192.96:8300/. Bien qu'UFW ait une règle DROP pour le port 8300, un attaquant interne au réseau (ou en cas de défaillance du firewall) aurait un accès direct et non chiffré à l'ensemble de l'API.
uvicorn.run(app, host="0.0.0.0", port=8300) → host="127.0.0.1", port=8300 dans /opt/web/agents.08.ma/server.py. L'API n'est désormais accessible que via le proxy nginx (SSL, rate limiting, logs). Redémarrage du serveur. Vérification : ss -tlnp | grep 8300 confirme l'écoute exclusive sur 127.0.0.1.
3.4 Cartographie Publique de l'API (Swagger /docs et /openapi.json)
L'interface Swagger UI (/docs) et le schéma OpenAPI (/openapi.json) étaient accessibles sans authentification via nginx. Le schéma exposait la liste complète des 89 endpoints de l'API :
Cette exposition équivaut à fournir un plan d'architecte à un cambrioleur. Chaque endpoint, ses paramètres et sa méthode HTTP sont documentés publiquement.
1.
FastAPI(docs_url=None, redoc_url=None, openapi_url=None) — désactivation de la génération automatique du schéma OpenAPI. Vérification : curl /openapi.json → 404.2. Ajout d'un bloc
location /docs dans nginx avec auth_basic — la route /docs (custom, manuelle) est désormais protégée par un mot de passe. Vérification : 401 sans credentials, 200 avec credentials.
4. Vulnérabilités Hautes et Moyennes
| # | Sévérité | Service | Port | Description |
|---|---|---|---|---|
| 4 | HAUTE | NATS | 4222 | Bannière exposant version 2.10.27, server name « 0data-nucleus », client_id, et clé publique (xkey). Auth activée (auth_required:true) mais version datée exposée. |
| 5 | HAUTE | PMCD/PMProxy | 44321-44323 | Performance Co-Pilot exposé — monitoring système (CPU, mémoire, I/O) accessible. Protocole non-HTTP mais exploitation possible. |
| 6 | HAUTE | Next.js Dev | 3000, 3003 | Deux serveurs Next.js 16.2.10 de développement écoutant sur 0.0.0.0. Les serveurs de développement incluent des fonctionnalités de debugging (HMR, source maps) non destinées à la production. |
| 7 | MOYENNE | 08.Services | 5090 | Plateforme techniciens exposée — inclut Google Fonts (dépendance externe). |
| 8 | MOYENNE | /api/organism/state | 8300 | L'API organism expose des adresses IP internes (192.168.x.x) dans les données d'anomalies Cytokine. |
| 9 | MOYENNE | EPMD | 4369 | Erlang Port Mapper Daemon exposé — utilisé par FreeSWITCH. Peut être exploité pour découvrir d'autres services Erlang. |
5. Corrections Appliquées
L'ensemble des correctifs a été appliqué dans la même session (23 juillet 2026, 16:30–17:03 UTC). Aucune interruption de service n'a été constatée.
| # | Action | Commande/Modification | Effet |
|---|---|---|---|
| 1 | Blocage Cockpit | ufw delete allow 9090/tcp | Shell root Ubuntu inaccessible depuis l'extérieur |
| 2 | Blocage PMCD | ufw deny 44321/tcp; ufw deny 44322/tcp; ufw deny 44323/tcp | Monitoring système inaccessible |
| 3 | Bind API → 127.0.0.1 | uvicorn.run(app, host="127.0.0.1", port=8300) | API uniquement via nginx SSL |
| 4 | Désactivation OpenAPI | FastAPI(docs_url=None, redoc_url=None, openapi_url=None) | Schéma API inaccessible (404) |
| 5 | Protection /docs | nginx auth_basic sur location /docs | 401 sans credentials, 200 avec |
| 6 | Nettoyage UFW | Suppression règles 14433/tcp, 18765/tcp | Services inactifs, règles orphelines |
| 7 | Redémarrage API | kill + redémarrage uvicorn | Changements effectifs, 0 downtime perçu |
6. Vérification Post-Correction
Chaque correction a été vérifiée immédiatement après application :
| Test | Méthode | Résultat |
|---|---|---|
| Port 9090 bloqué | Connexion TCP externe (timeout 3s) | Timeout — inaccessible ✓ |
| Port 8300 externe bloqué | curl vers IP publique:8300 | Timeout — inaccessible ✓ |
| API bind 127.0.0.1 | ss -tlnp | grep 8300 | 127.0.0.1:8300 uniquement ✓ |
| /openapi.json désactivé | curl https://cockpit.0data.fr/openapi.json | 404 — Not Found ✓ |
| /docs protégé | curl https://cockpit.0data.fr/docs (sans auth) | 401 — Authorization Required ✓ |
| /docs accessible (auth) | curl -u avec credentials | 200 — OK ✓ |
| SSL cockpit valide | openssl s_client -connect cockpit.0data.fr:443 | Let's Encrypt, expire Oct 2026 ✓ |
| PMCD bloqués | Connexion TCP externe | Timeout (3 ports) ✓ |
| IPTables DROP rules | iptables -L ufw-user-input | 4 règles DROP actives ✓ |
7. Surface Résiduelle
Après correction, 7 ports restent autorisés dans UFW :
| Port | Protocole | Service | Justification |
|---|---|---|---|
| 22 | TCP | SSH | Accès administratif obligatoire |
| 80 | TCP | HTTP (nginx) | Redirection → HTTPS + Let's Encrypt |
| 443 | TCP | HTTPS (nginx) | Reverse proxy principal, SSL Let's Encrypt |
| 443 | UDP | HTTPS (nginx) | HTTP/3 (QUIC) |
| 8765 | TCP | KOD Proxy | Proxy de trading (KOD Quantum) |
| 5060 | UDP | SIP (FreeSWITCH) | Téléphonie VoIP — intentionnel |
| 5080 | UDP | SIP (FreeSWITCH) | Téléphonie VoIP — intentionnel |
Recommandations à Long Terme
Pour atteindre une architecture zéro surface non-nécessaire, les actions suivantes sont recommandées :
- Bind 127.0.0.1 pour PostgreSQL (5432), Redis (6379), NATS (4222), et tous les services NOVA (5090–5120, 5190–5199, 8400–8402)
- Supprimer les serveurs Next.js de développement (3000, 3003) ou les bind en 127.0.0.1 — les serveurs de dev n'ont rien à faire en production
- Auditer le port 8765 (KOD Proxy) — vérifier que l'authentification est requise et que le service n'expose pas de fonctionnalité non prévue
- Mettre en place un audit UFW périodique (cron hebdomadaire) pour détecter les nouvelles règles non documentées
8. Conclusion
Cet audit démontre que l'infrastructure 0DATA était fonctionnellement protégée (UFW default deny) mais architecturalement fragile : la défense reposait sur une seule couche (firewall) sans profondeur. Si cette couche tombait, l'intégralité des 35+ services internes devenait accessible en clair.
Les correctifs appliqués ajoutent trois couches de défense supplémentaires :
- Bind 127.0.0.1 pour l'API — même si UFW tombe, l'API n'est pas sur l'interface publique
- nginx auth_basic sur /docs — même si l'API est accessible, la cartographie est verrouillée
- Désactivation OpenAPI — le schéma automatique n'existe plus, zéro surface
Vulnérabilités critiques : 3 → 0
Temps de correction : 33 minutes (16:30–17:03 UTC)
Interruption de service : 0
Surface d'administration exposée : 2 → 0
Ce pentest établit une méthodologie d'audit reproductible pour l'infrastructure 0DATA. Il sera répété mensuellement et après chaque déploiement majeur. La cybersécurité que nous vendons commence par celle que nous pratiquons.
Références
TIKIJJA, Hadda. « La Discipline ». 0DATA Lab, Papier 001, Juillet 2026.
TIKIJJA, Hadda. « Le Système Nerveux ». 0DATA Lab, Papier 003, Juillet 2026. Zenodo: 10.5281/zenodo.21342768.
TIKIJJA, Hadda. « La Greffe Numérique ». 0DATA Lab, Papier 004, Juillet 2026. Zenodo: 10.5281/zenodo.21270325.
TIKIJJA, Hadda. « Le Système Immunitaire ». 0DATA Lab, Papier 005, Juillet 2026.
TIKIJJA, Hadda. « La Première Greffe ». 0DATA Lab, Papier 010, Juillet 2026.
OWASP Foundation. « Web Security Testing Guide ». v4.2, 2024.