Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 66 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,42 @@

Plateforme CTF open-source pour étudiants et professionnels cybersécurité. Challenges progressifs Blue/Red Team, conteneurisés et isolés par équipe.

> **Projet Annuel — ESGI** · Mastère Sécurité Informatique · 4ᵉ année (M1) · 2025-2026
> Équipe de 4 étudiants. Ce dépôt est la **face technique** (jury/mainteneurs) ; le dépôt
> [**RootMeUp-CTF**](https://github.com/Jacob-dot-bit/RootMeUp-CTF) est destiné aux **joueurs**
> (guides uniquement, sans solutions ni flags).

## Sommaire
- [Contexte](#contexte)
- [Objectif](#objectif)
- [Architecture](#architecture)
- [Prérequis](#prérequis)
- [Accès à la plateforme](#accès-à-la-plateforme)
- [Lancement d'un challenge](#lancement-dun-challenge)
- [Challenges disponibles](#challenges-disponibles)
- [Ajout d'un challenge sur le serveur](#ajout-dun-challenge-sur-le-serveur)
- [Sécurité](#sécurité)
- [Durcissement du serveur](#durcissement-du-serveur)
- [Supervision](#supervision)
- [Équipe projet](#équipe-projet)
- [Liens utiles](#liens-utiles)
- [Licence](#licence)

## Contexte

RootMeUp est une plateforme de *Capture The Flag* pédagogique développée dans le cadre
du Projet Annuel ESGI. Objectif : offrir un environnement d'entraînement cybersécurité
**Blue Team / Red Team**, gratuit et francophone, où chaque équipe dispose d'instances
de challenges **isolées**.

Le projet a connu deux phases :
- **T2** — première version hébergée sur une VM mutualisée de l'école. Ressources
insuffisantes : le disque se remplissait et faisait **crasher CTFd**.
- **T3** — migration vers un **Proxmox dédié** (VM Debian durcie CIS), déploiement des
challenges conteneurisés, puis mise en place d'une **supervision** (Grafana + Prometheus,
alertes Discord) pour *anticiper* les incidents comme la saturation disque plutôt que
de les subir.

## Objectif
- Challenges pratiques isolés par équipe (3 participants)
- Visualisation des scores et saisie des flags via l'interface CTFd
Expand Down Expand Up @@ -30,7 +66,7 @@ flowchart LR
```

Le serveur est une VM Debian durcie selon le benchmark CIS, qui héberge :
- **CTFd** : géré comme un service systemd, accessible sur le port 8000
- **CTFd** : service systemd (gunicorn en local sur `127.0.0.1:8000`), exposé aux joueurs par **Apache** (reverse-proxy sur le port `80`)
- **Docker** : utilisé pour construire et stocker les images des challenges
- **containerd** : runtime de conteneurs qui exécute effectivement les instances de challenges ; sert de lien entre CTFd et les conteneurs lancés
- **CTFdDockerContainersPlugin** : plugin CTFd qui déclenche via containerd la création d'une instance par équipe lors du lancement d'un challenge
Expand All @@ -55,14 +91,19 @@ L'accès à la plateforme se fait via **Tailscale** (réseau privé virtuel), ce
1. Installer Tailscale sur votre poste et se connecter
2. Rejoindre le réseau via le lien d'invitation fourni
3. Récupérer l'IP Tailscale de la VM sur https://login.tailscale.com/admin/machines
4. Accéder à CTFd dans le navigateur :
4. Accéder à CTFd dans le navigateur (Apache écoute sur le port `80`) :

```
http://<IP_TAILSCALE_VM>:8000
http://<IP_TAILSCALE_VM>/
```

5. Créer un compte, rejoindre ou créer une équipe (3 participants max)

![Interface CTFd — liste des challenges](docs/img/ctfd-challenges.png)

> ℹ️ **Vous êtes joueur ?** Les guides pas-à-pas (sans solutions) sont dans le dépôt
> dédié [**RootMeUp-CTF**](https://github.com/Jacob-dot-bit/RootMeUp-CTF).

## Lancement d'un challenge

1. Ouvrir la liste des challenges dans CTFd
Expand All @@ -71,6 +112,8 @@ http://<IP_TAILSCALE_VM>:8000
4. Se connecter à l'instance via l'URL/port indiqués
5. Soumettre le flag dans l'interface CTFd

![Instance de challenge lancée dans CTFd](docs/img/ctfd-instance.png)

## Challenges disponibles

Numérotation par équipe (`N-Blue-Team-*` / `N-Red-Team-*`).
Expand Down Expand Up @@ -107,6 +150,22 @@ docker images | grep mon-challenge

Puis créer le challenge dans CTFd (`Admin Panel > Challenges > Create Challenge > Type: container`) en renseignant l'image, le port et la commande de démarrage.

## Sécurité

Bonnes pratiques appliquées au dépôt et à la plateforme :

- **Aucun secret dans le dépôt** — bien que public (pour le jury), les **vrais flags n'y
figurent pas** : ils sont lus au build depuis un fichier `setup/challenge.env` **gitignoré**
et **rotés** par rapport à toute valeur ayant pu être exposée (voir
[`docs/DEPLOIEMENT.md`](docs/DEPLOIEMENT.md)).
- **Séparation des publics** — les solutions/exploits restent dans ce dépôt technique ; les
joueurs n'ont accès qu'au dépôt [RootMeUp-CTF](https://github.com/Jacob-dot-bit/RootMeUp-CTF)
(guides sans réponses).
- **Isolation** — un conteneur par équipe et par challenge, réseau dédié.
- **Pas d'exposition Internet** — l'accès à la plateforme et à la supervision passe
uniquement par **Tailscale** ; la supervision (Grafana) est servie en **HTTPS**
(TLS terminé par Tailscale, cf. [`docs/SUPERVISION.md`](docs/SUPERVISION.md)).

## Durcissement du serveur

Mesures appliquées conformément au benchmark CIS Debian :
Expand All @@ -122,6 +181,8 @@ Mesures appliquées conformément au benchmark CIS Debian :
Le serveur CTFd est supervisé (métriques temps réel + alertes Discord) via une VM
Grafana + Prometheus dédiée. Détail : **[`docs/SUPERVISION.md`](docs/SUPERVISION.md)**.

![Dashboard Grafana — Node Exporter Full (VM CTFd)](docs/img/grafana-dashboard.png)

## Équipe projet

| Membre | Rôle |
Expand All @@ -133,8 +194,9 @@ Grafana + Prometheus dédiée. Détail : **[`docs/SUPERVISION.md`](docs/SUPERVIS

## Liens utiles

- Dépôt technique (ce dépôt) : https://github.com/Jacob-dot-bit/RootMeUp
- Dépôt joueurs (guides) : https://github.com/Jacob-dot-bit/RootMeUp-CTF
- Suivi des tâches (Trello) : https://trello.com/b/noVfLRlC/rootmeup
- Dépôt GitHub : https://github.com/Jacob-dot-bit/RootMeUp
- Plugin CTFd : https://github.com/Bigyls/CTFdDockerContainersPlugin

## Licence
Expand Down
20 changes: 18 additions & 2 deletions docs/SUPERVISION.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,31 @@ remplacer `${DS_PROMETHEUS}` par `prometheus`).

## Accès

- **Grafana** : `http://100.84.158.83:3000` (via Tailscale). Changer le mot de passe admin par défaut.
- **Prometheus** : `http://100.84.158.83:9090`.
- **Grafana** : **`https://grafana.tail2f7520.ts.net`** (HTTPS via Tailscale, cert Let's Encrypt auto).
- **Prometheus** : `http://100.84.158.83:9090` (tailnet).
- Dashboard : *Dashboards → Node Exporter Full*, sélectionner le job `ctf-vm`.

### HTTPS via Tailscale (`tailscale serve`)
Grafana n'écoute qu'en local (`127.0.0.1:3000`) ; **Tailscale termine le TLS** sur `:443`
et proxifie vers Grafana. Le certificat Let's Encrypt est provisionné et renouvelé
automatiquement pour le nom MagicDNS. Prérequis : *HTTPS Certificates* activé dans la
console admin Tailscale (`login.tailscale.com/admin/dns`).

```bash
# sur la VM Grafana
tailscale serve --bg 3000 # https://<nom>.ts.net/ -> http://127.0.0.1:3000
tailscale serve status # vérifier le mapping
# désactiver si besoin : tailscale serve --https=443 off
```
Côté Grafana (`/etc/grafana/grafana.ini`, section `[server]`) : `domain` et `root_url`
pointent sur `https://grafana.tail2f7520.ts.net/` pour que les liens générés soient corrects.

## Sécurité

- Le **webhook Discord** est un secret : il n'existe **que** dans
`/etc/grafana/provisioning/alerting/discord.yaml` sur la VM Grafana, **jamais dans git**.
- Grafana/Prometheus ne sont pas exposés sur Internet (accès uniquement via Tailscale).
- **Grafana en HTTPS** (TLS terminé par Tailscale, cert Let's Encrypt) — plus de trafic en clair.
- Changer les identifiants Grafana par défaut (`admin`/`admin`).

## Évolutions possibles
Expand Down
Binary file added docs/img/ctfd-challenges.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/ctfd-instance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/grafana-dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.