👋
À propos
Stagiaire en administration d'infrastructures sécurisées (AWOUI × LeGuideInfo), je rassemble ici mes travaux : du poste de travail jusqu'à une production durcie, que j'ai ensuite attaquée moi-même pour vérifier qu'elle tient.
Curieux d'intégrer la sécurité au plus tôt dans le cycle de vie des systèmes : infrastructure as code, conteneurisation, supervision et bonnes pratiques réseau.
Linux (Debian)nginxDockerAnsible
GitNetBird / VPNModSecurityCrowdSecPrometheus / Grafana
🧭
Parcours
Stage — Administration d'infrastructures sécurisées
AWOUI × LeGuideInfo · Septembre 2026 — en cours
Stage — DevSecOps
Express Daryline, Villepinte · Janv. — juin 2026
Stage — Support IT / Infrastructure & Sécurité
CCA Bank, Douala (Cameroun) · Mars — août 2025
Bachelor 3 — Administration d'infrastructures sécurisées
École IPSSI · Déc. 2025 — déc. 2026
Licence professionnelle Réseau & Sécurité
EST LASALLE · Nov. 2024 — août 2025
🧰
Compétences
Système
Linux (Debian)Administration serveurCron
Réseau
VPN / NetBirdPare-feu (UFW)nginxHTTPS / Let's Encrypt
Automatisation & conteneurs
Docker / ComposeAnsibleGit / flux par branche
Sécurité
SSH par cléEn-têtes HTTP / CSPModSecurity (OWASP CRS)CrowdSecGestion des secrets
Supervision
Prometheus / GrafanaBlackbox ExporterntfyAlertmanager (en cours)
🚀
Mes travaux
Neuf étapes progressives du stage, du poste de travail à une production sécurisée et testée.
terminé · le plus récent
Job 09 — Sécurisation de la production
- Accès administrateur durci : SSH par clé uniquement, root interdit, réseau privé seulement
- En-têtes de sécurité (HSTS, CSP) : note A+ sur securityheaders.com
- Pare-feu applicatif ModSecurity (OWASP CRS) en blocage, et CrowdSec qui bannit les attaquants
- Défenses éprouvées par mes propres attaques, avec les erreurs rencontrées
SSHModSecurityCrowdSecCSP
↳ voir la section sécurité
terminé
Job 01 — Poste de travail
- Debian à jour, VPN NetBird connecté à l'overlay privé
- Forge Git configurée, stack Ansible / Docker installée
DebianNetBirdGit
↳ voir sur la forge
terminé
Job 02 — Portfolio en local
- Portfolio personnel en HTML, servi par nginx sur un port dédié
- Versionné sur la forge
HTML/CSSnginx
↳ voir sur la forge
terminé
Job 03 — Conteneurisation
- Dockerfile multi-stage (builder alpine, image finale nginx:alpine)
- docker-compose.yml avec healthcheck, publié sur le port 2026
DockerCompose
↳ voir sur la forge
terminé
Job 04 — Déploiement automatisé
- Playbook Ansible idempotent : inventaire et tâches déclaratives
- Un second lancement renvoie
changed=0
- Test de résilience : page supprimée puis restaurée en une commande
AnsibleYAML
↳ voir sur la forge
terminé
Job 05 — Publication en ligne
- Portfolio publié sur awoui.com/@brundon via l'éditeur AWOUI
- Servi en HTTPS
PublicationHTTPS
↳ voir la page
terminé
Job 06 — Sécurisation du poste et du dépôt
- Pare-feu UFW strict (deny incoming / allow outgoing), mises à jour automatiques
- Audit du dépôt (fichiers et historique) et
.gitignore pour les secrets
- Flux Git par branche et demande de fusion relue, plus de push direct sur
main
UFWGit flow
↳ voir sur la forge
terminé
Job 07 — Supervision
- Sonde HTTP planifiée par cron, alerte automatique via ntfy
- Pile Blackbox / Prometheus / Grafana avec tableau de bord
PrometheusGrafanantfy
↳ voir le tableau de bord
terminé
Job 08 — Le portfolio en production
- Serveur Debian + nginx dédié, nom de domaine pointé en DNS
- Certificat HTTPS Let's Encrypt, déploiement rejouable et versionné
nginxDNSLet's Encrypt
↳ voir sur la forge
🛡️
Sécurité de ma production
Une requête doit franchir plusieurs couches avant d'atteindre le site, et l'administration n'a qu'une seule porte.
Accès administrateurSSH par clé uniquement : pas de mot de passe, connexion en root interdite, liste de comptes autorisés. Joignable seulement par le réseau privé (VPN).
NavigateurHTTPS imposé pendant un an (HSTS), politique CSP limitant les scripts à ceux que j'autorise, version du serveur masquée. Note A+ sur securityheaders.com.
RequêtesPare-feu applicatif ModSecurity avec 914 règles OWASP : au-delà du seuil de 5 points, la requête reçoit un refus 403.
ComportementCrowdSec repère les attaquants et bannit leur adresse pendant 4 heures. Le réseau privé est exempté.
Tout est versionné dans le dépôt, sans secret, et livré par une demande de fusion.
🗺️
Comment ma production est construite
Le chiffrement HTTPS se fait sur mon serveur : le front de la plateforme ne fait qu'aiguiller la connexion sans pouvoir la lire. Chaque requête franchit quatre couches avant d'atteindre la page.
🎯
J'ai testé mes propres défenses
Plutôt que de supposer mon serveur sûr, j'ai attaqué mon propre site et mon propre accès, un test à la fois.
1. Pare-feu applicatif : l'attaque est bloquée, le visiteur préservé
?fichier=/etc/passwd -> 403 (lecture de fichier système)
?q=<script>alert(1)... -> 403 (injection de script)
?id=1' OR '1'='1 -> 403 (injection SQL)
User-Agent: Nikto -> 403 (scanner connu)
visite normale -> 200 (acceptée)
[id 932160] Remote Command Execution: Unix Shell Code Found
[id 949110] score cumulé 30, seuil de blocage 5 -> refus
2. Accès administrateur : rien à deviner
Mot de passe forcé, compte « root », ancien port : trois refus. Seule ma clé, par le réseau privé, ouvre la porte.
3. Le videur : de la détection au bannissement
Je me suis banni moi-même 2 minutes (403, puis 200 après la levée). Puis le vrai test de bout en bout : mon téléphone en 4G a lancé une fausse attaque, reçu le 403, puis la page « CrowdSec Access Forbidden » pour toutes les visites suivantes. Ban levé ensuite à la main.
4. Ce que ces essais m'ont appris
- Un test peut me bannir moi-même : mes premières attaques lancées depuis le serveur ont banni l'adresse du serveur. Depuis, je teste depuis un poste extérieur et je garde la commande de levée de ban sous la main.
- Une règle d'accès mal écrite m'a coupé le terminal de secours : j'avais confondu l'adresse du client et celle du serveur dans la liste des comptes autorisés. Corrigé depuis la console d'administration de la plateforme. Leçon : tester la nouvelle porte avant de fermer l'ancienne.
- Le navigateur peut mentir : une page déjà visitée restait affichée depuis son cache alors que le ban était actif. Les journaux du serveur, eux, ne mentent pas.
- Limite connue : le réseau privé est exempté de bannissement, pour ne jamais me couper de mon propre serveur. Si un poste de ce réseau était compromis, CrowdSec ne le bannirait pas.
- Mon pare-feu a coupé mes propres images : ModSecurity analysait aussi les réponses du serveur et tronquait les images les plus lourdes (règle 959100, « Outbound Anomaly Score »). Le journal d'erreurs m'a donné la cause. Comme le site est statique, j'ai retiré cette seule règle de blocage des réponses : les attaques sur les requêtes reçoivent toujours un 403.
📡
Supervision
Le site est surveillé en continu par une sonde HTTP planifiée (cron), qui journalise son état et déclenche une alerte en temps réel (ntfy) si le site ne répond plus.
Une pile d'observabilité (Blackbox Exporter, Prometheus, Grafana) collecte et affiche l'historique de disponibilité :
⚙️
Comment mon site se déploie
Ce portfolio est lui-même un projet d'infrastructure. Il existe sous trois formes : un conteneur Docker multi-stage avec healthcheck (Job 03), un playbook Ansible idempotent qui le redéploie à l'identique (Job 04), et la production sur nginx avec domaine et HTTPS (Jobs 08 et 09).
Chaque changement passe par une branche et une demande de fusion relue, jamais par un push direct sur main.
🌊
Agenda associatif — Eau Vive Boulogne
Contribution à un projet collectif : l'agenda événementiel de l'association Eau Vive Boulogne, en parallèle du stage individuel.
Projet d'équipe · Bloc 13
Bloc 13 · RGPD (mon bloc)
Mise en conformité RGPD de l'agenda : pages Mentions légales et Politique de confidentialité, livrées par le flux Git standard (branche + demande de fusion) et fusionnées sur main.
RGPDConformitéHTML/CSSTravail d'équipe