Aller au contenu

Dossier d'architectureTOPOLOGY.SYS

Architecture système

Exploration de la topologie technique : de l'interaction utilisateur au pipeline de déploiement continu.

  • 19nœuds sur 2 fluxUtilisateur : 10 • CI/CD : 9
  • 6étapes de pipelineDu tag Git à la bascule vérifiée
  • 6mesures de sécuritéIntégrité, isolation, résilience

[01]Vue d'ensemble

Sélectionnez un nœud sur le diagramme interactif pour analyser ses protocoles, sa sécurité et ses flux.

[02]Flux utilisateur

Cycle de vie d'une requête : du navigateur client à travers Cloudflare et Nginx jusqu'au moteur Nuxt 4.

  1. CLIENT_RUNTIME

    1. Client Vue 3 et lecteur audio HTML5

    L'application s'exécute chez le visiteur : Vue 3 hydrate la page rendue par le serveur. Le lecteur audio HTML5 lit les pistes servies par plages d'octets (HTTP 206). Les pochettes et les liens d'écoute viennent de /api/track-metadata, qui interroge iTunes, Deezer et YouTube côté serveur.

    VUE 3 // HTML5 AUDIO // HTTP 206[ CLIENT_BOUND ]

  2. REVERSE_PROXY_CACHE

    2. Proxy Inverse Cloudflare & Cache CDN Edge

    Cloudflare s'interpose comme mandataire inverse entre le visiteur et l'hôte. Il reçoit tout le trafic public et distribue les fichiers statiques depuis son cache mondial ; l'hôte n'accepte que les connexions de Cloudflare.

    ANYCAST PROXY // CDN CACHE[ PROXIED ]

  3. L3/L4/L7_FILTERING

    3. Filtrage WAF et anti-DDoS Cloudflare

    Cloudflare absorbe en périphérie les attaques par déni de service (protection DDoS incluse) et applique 5 règles WAF anti-bot (scanners, outils, routes non publiques, webhook réservé) ainsi qu'une limitation de débit sur le formulaire de contact et l'Overseer. Nginx limite ensuite chaque IP à 10 requêtes par seconde.

    DDOS PROTECTION // CUSTOM WAF RULES[ PROTECTED ]

  4. FULL_STRICT_TLS

    4. Terminaison SSL/TLS & Cache de Bord

    La négociation TLS se termine sur le point de présence le plus proche du visiteur (TLS 1.2 minimum, HSTS). Les fichiers statiques, icônes et polices locales sont servis depuis ce cache ; Cloudflare joint ensuite l'hôte en SSL Full (strict). Latence mesurée : environ 25 ms.

    EDGE CACHE // FULL STRICT // AOP[ ENCRYPTED ]

  5. PORT_443_ONLY

    5. Passerelle Hôte Nginx & Chiffrement Origin

    Sur l'hôte Linux, Nginx n'écoute que sur le port 443 (TLS 1.2 et 1.3, HSTS) et n'accepte que Cloudflare grâce aux Authenticated Origin Pulls. Il restitue l'IP réelle du visiteur (CF-Connecting-IP), limite chaque IP à 10 requêtes par seconde et répartit les requêtes entre 127.0.0.1:3001 et 127.0.0.1:3002.

    PORT 443 -> LOCAL 3001/3002 // LINUX SERVER[ ISOLATED ]

  6. SSR_&_APIS

    6. Moteur SSR Nuxt 4 & Relais IA / Telegram

    Le moteur Nitro génère le HTML côté serveur et exécute les routes API. Les opérations sensibles (défi anti-spam Breach Protocol, vérification DNS MX des e-mails, inférence NVIDIA NIM, messages Telegram) s'exécutent sur le serveur : les clés d'API restent dans sa configuration et ne sont jamais envoyées au navigateur.

    NVIDIA NIM // TELEGRAM API // SWR[ OPERATIONAL ]

[03]Pipeline CI/CD

Pipeline déclenché par un tag de version : porte qualité, image signée avec cosign, webhook signé HMAC et bascule blue/green.

  1. SEMVER_TAG

    1. Tag de version

    Un tag de version v*.*.* poussé sur GitHub déclenche le déploiement en production.

    GIT OVER SSH // TAG v*.*.*

    Lire le détail

    Le développeur pousse un tag de version v*.*.* vers GitHub par SSH. Chaque push lance déjà la CI sur main, develop et les branches feature ; le déploiement en production ne part que du tag.

  2. QUALITY_GATE

    2. Porte qualité et image Docker

    La CI complète doit passer, puis GitHub Actions construit une image multi-stage Alpine pour amd64 et arm64.

    NODE 24 ALPINE // AMD64 + ARM64

    Lire le détail

    Avant toute publication, le workflow exige la CI complète : ESLint, npm audit (dépendances de production, niveau high), typecheck, Vitest, build Nuxt, tests E2E Playwright (Firefox) et scan Trivy de l'image (CRITICAL et HIGH). Si elle échoue, aucune image n'est publiée. Sinon Buildx construit l'image Alpine multi-stage sans npm.

  3. SIGNED_BY_DIGEST

    3. Publication sur GHCR et signature

    L'image est publiée sur GHCR (version, latest, sha court) puis signée avec cosign, par digest.

    ghcr.io/ardou0/website:X.Y.Z // COSIGN

    Lire le détail

    Une fois la porte passée, l'image est poussée sur GitHub Container Registry avec le GITHUB_TOKEN du workflow, sous trois tags : la version (par exemple 1.4.0), latest et sha- suivi du commit court. Elle est ensuite signée avec cosign en mode keyless (identité OIDC de GitHub Actions, aucune clé stockée), par digest.

  4. CONSTANT_TIME_CHECK

    4. Webhook signé

    Le serveur vérifie en temps constant la signature HMAC-SHA256, l'horodatage et le digest du webhook.

    HMAC-SHA256 // crypto.timingSafeEqual // 5 MIN WINDOW

    Lire le détail

    GitHub Actions envoie un POST vers /api/deploy-webhook, signé HMAC-SHA256 avec un secret partagé (en-tête X-Hub-Signature-256) ; le corps porte le tag, le digest de l'image et un horodatage. Le serveur compare la signature avec crypto.timingSafeEqual, refuse un horodatage à plus de 5 minutes de son heure ou une signature déjà reçue (anti-rejeu) et exige un digest valide. Le HMAC authentifie la requête sans la chiffrer ; le transport est en HTTPS.

  5. FILE_SIGNAL

    5. Dépôt d'un fichier signal

    Le conteneur web, sans accès à Docker, dépose seulement un fichier pending.flag.

    /deploy-flags/pending.flag // NON-ROOT

    Lire le détail

    Le conteneur web tourne sans root et sans socket Docker, et n'exécute aucune commande. Une fois la requête vérifiée, il écrit un fichier JSON pending.flag (tag et digest) dans un volume partagé et envoie « DEPLOYMENT TRIGGERED » sur Telegram : une requête web peut demander un déploiement, pas lancer une commande sur l'hôte.

  6. BLUE_GREEN

    6. Déploiement blue/green et retour arrière

    Le déployeur vérifie la signature, démarre la couleur libre, attend l'état healthy puis bascule ; en cas d'échec, l'ancienne version n'a jamais cessé de servir.

    SOCKET PROXY // COSIGN // HEALTHY

    Lire le détail

    Le conteneur website_deployer lit le fichier signal toutes les 5 s, vérifie la signature cosign du digest, tire l'image par digest et démarre la couleur libre (app-blue sur 3001, app-green sur 3002). Il attend l'état Docker healthy (90 s au plus), garde les deux couleurs 10 s ensemble, puis arrête l'ancienne. En cas d'échec, la nouvelle couleur est retirée : l'ancienne n'a jamais cessé de servir.

[04]Sécurité

Mesures défensives appliquées aux conteneurs, au déploiement et à la surveillance, chacune avec la menace qu'elle vise.

Matrice des mesures de sécurité
Menace viséeMesurePreuve ou état
Menace viséeModification du conteneur après une intrusionMesureConteneur non-root en lecture seuleL'application tourne sous l'utilisateur node, sans capacité Linux (cap_drop ALL, no-new-privileges), avec un système de fichiers en lecture seule : elle n'écrit que dans ses volumes et dans /tmp (tmpfs).Preuve ou étatNODE:NODE // CAP_DROP ALL // RO FSENFORCED
Menace viséeExécution de code à distance (RCE) depuis le webMesureBarrière IPC isolée et proxy du socket DockerLe conteneur web n'a aucun accès à Docker : la mise à jour passe par un fichier signal dans un volume partagé. Le déployeur n'atteint Docker que par un proxy du socket (EXEC, BUILD, COMMIT et SYSTEM désactivés).Preuve ou étatFILE SIGNAL // DOCKER SOCKET PROXYISOLATED
Menace viséeAttaque par analyse temporelle ou rejeu des signatures de déploiementMesureSignature à temps constant et anti-rejeuLes signatures HMAC de déploiement sont comparées à temps constant, et une demande dont l'horodatage s'écarte de plus de 5 minutes de l'heure du serveur est refusée, tout comme une signature déjà acceptée dans cette fenêtre. Chaque échec est écrit dans le journal security.Preuve ou étatCRYPTO.TIMINGSAFEEQUAL // SHA256SECURED
Menace viséeVersion défectueuse mise en ligne après un déploiementMesureSonde de santé et retour arrière réelLa nouvelle version n'est retenue que si Docker la déclare healthy ; sinon elle est retirée et l'ancienne, qui n'a jamais cessé de servir, reste en ligne. La signature cosign est vérifiée avant tout téléchargement.Preuve ou étatHEALTHY ONLY // BLUE/GREENACTIVE
Menace viséeIncident passé inaperçu : déploiement en échec, API d'IA en panne, journal altéré ou non horodatéMesureTélémétrie et relais d'alerteTelegram reçoit les messages de contact, les étapes et issues des déploiements, les erreurs HTTP de l'API NVIDIA et les alertes de la chaîne de journaux (violation, horodatage en retard, écart d'horloge, reprise du verrou). L'état de l'hôte n'est pas mesuré.Preuve ou étatTELEGRAM BOT // DEPLOY + LOG ALERTSMONITORED
Menace viséeVulnérabilités connues (CVE) des images et des dépendancesMesureDétection des CVE et mises à jour proposéesDépendances et image sont contrôlées à chaque push : npm audit, scan Trivy (CRITICAL et HIGH) et Semgrep (aussi chaque dimanche). Dependabot propose chaque lundi des mises à jour npm, Docker et GitHub Actions, soumises à la même porte qualité.Preuve ou étatAUDIT // TRIVY // SEMGREP // DEPENDABOTSCANNED

Parlons-en

Une question sur ce travail, ou envie d'en voir plus ? Écrivez-moi.

Me contacter

Sommaire