> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snakysec.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 03 rebuild vps from zero

# Runbook 03 — Reconstruction VPS de zéro

## 1. Quand activer ce runbook

| Scénario                                                                         | Activer ?                                                                                  |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| VPS OVH inaccessible >2h, support OVH confirme perte du serveur                  | **OUI**                                                                                    |
| Datacenter OVH HS (incident type Strasbourg 2021), pas de retour annoncé sous 4h | **OUI**                                                                                    |
| Compromission système confirmée (root malveillant, backdoor)                     | **OUI** mais combiné avec [05-recover-from-ransomware.md](./05-recover-from-ransomware.md) |
| Migration VPS planifiée vers une nouvelle région                                 | OUI mais hors urgence (utiliser ce runbook en mode contrôlé)                               |
| VPS lent ou réseau dégradé                                                       | **NON** (problème ponctuel, pas DR)                                                        |
| Faillite ou suspension compte OVH                                                | **OUI** (pivoter vers Scaleway si OVH indisponible — voir §11)                             |

## 2. Objectifs

* **RPO atteint** : 5 minutes (Postgres) + 24h (Vault et artifacts)
* **RTO cible** : 4 heures
* **WRT cible** : 1 heure (validation fonctionnelle complète)

## 3. Prérequis CRITIQUES

* **Accès compte OVH** (login + password + 2FA YubiKey ou codes de récup)
* **Shares Shamir** disponibles (3 sur 5, cf. runbook 02)
* **Restic password** disponible (KeePass + papier coffre)
* **Code source** disponible :
  * GitLab.com `snakysec/mssp-snakysec-multi-tenants` repo accessible
  * Docker images dans GitLab Container Registry (`registry.gitlab.com/snakysec/mssp-snakysec-multi-tenants/platform:<version>`)
* **Domaine snakysec.com** :
  * DNS records modifiables via OVH UI
  * Backup zone DNS dans `artifacts/dns-zones/snakysec.com.<latest>.bind`
* **Cert TLS** :
  * Let's Encrypt ACME se ré-issue automatiquement (pas de récupération nécessaire)
* **OpenProject (gestion projet)** : hors périmètre runbook DR plateforme V1

## 4. Communication client

```
Objet : SnakySec — Incident d'infrastructure majeur, reconstruction en cours

Notre infrastructure d'hébergement subit un incident significatif. Nous
procédons à une reconstruction complète sur infrastructure de secours.

Durée prévisionnelle : 4 heures depuis maintenant (HH:MM UTC).

Aucune perte de données significative attendue (RPO Postgres 5 minutes,
Vault 24h). Vos audits, rapports et configurations seront restaurés
intégralement.

Si vous êtes vous-même soumis à NIS2 et que cet incident peut impacter votre
propre déclaration de continuité, contactez-nous : contact@snakysec.com.
```

Notification **CSIRT-FR** sous 24h obligatoire (cf. [docs/dr/incident-response/02-csirt-fr-notification.md](../incident-response/02-csirt-fr-notification.md)) car incident significatif sur prestation cyber.

## 5. Procédure de reconstruction

### Étape 5.1 — Provisioning nouveau VPS OVH (T+0 → T+30min)

```
1. Login OVH Manager (manager.ovh.com)
2. Bare Metal & VPS → Order new VPS
3. Spec : VPS Comfort 8 CPU / 16 GB RAM / 160 GB SSD (à ajuster selon volume actuel)
4. OS : Debian 12 (Bookworm) standard, sans aucun panel
5. Region : OVH Gravelines (GRA) — même région que l'original pour latence DNS
6. Boot via OVH custom image NON, partir d'une Debian propre (cleaner forensiquement)
7. SSH key publique : ajouter celle de Nicolas (clé YubiKey ou laptop)
8. Attribuer une IP publique IPv4 + IPv6
```

Patientez \~5-10 min pour provisioning.

### Étape 5.2 — Bootstrap système (T+30min → T+1h)

```bash theme={null}
ssh root@<NEW_VPS_IP>

# Hardening système minimal
apt update && apt upgrade -y
apt install -y ufw fail2ban sudo

# User mssp + sudoers
useradd -m -s /bin/bash mssp
usermod -aG sudo mssp
mkdir -p /home/mssp/.ssh
cp /root/.ssh/authorized_keys /home/mssp/.ssh/
chown -R mssp:mssp /home/mssp/.ssh
chmod 700 /home/mssp/.ssh
chmod 600 /home/mssp/.ssh/authorized_keys

# Firewall : SSH + HTTP/HTTPS only
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

# Disable root SSH login
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd

# Reboot pour appliquer kernel updates
reboot
```

Attendre 1 minute, puis :

```bash theme={null}
ssh mssp@<NEW_VPS_IP>
```

### Étape 5.3 — Installation Docker + Docker Compose v2 (T+1h → T+1h15)

```bash theme={null}
# Install Docker depuis le dépôt officiel
curl -fsSL https://get.docker.com | sudo sh

# Ajouter mssp au groupe docker (login again required after)
sudo usermod -aG docker mssp

# Logout + login
exit
ssh mssp@<NEW_VPS_IP>

# Vérifier
docker --version
docker compose version
```

### Étape 5.4 — Clone du repo + secrets bootstrap (T+1h15 → T+1h30)

```bash theme={null}
sudo mkdir -p /opt/mssp/{app,data,snapshots}
sudo chown -R mssp:mssp /opt/mssp

cd /opt/mssp/app
git clone https://gitlab.com/snakysec/mssp-snakysec-multi-tenants.git .
cd platform

# Créer les volumes externes nécessaires
docker volume create platform_mssp-approle
docker volume create platform_mssp-approle-dr
docker volume create platform_postgres-data
docker volume create platform_vault-data
docker volume create platform_pgbackrest-data
docker volume create platform_pgbackrest-log
docker volume create platform_pgbackrest-spool
docker volume create platform_dr-runtime
docker volume create platform_reports-data
docker volume create platform_archive-data
docker volume create platform_traefik-acme

# Réseau externe pour les overlays compose
docker network create platform_mssp-net
docker network create --internal platform_data-net
```

### Étape 5.5 — Restauration Vault (T+1h30 → T+2h)

Suivre [02-restore-vault-from-snapshot.md](./02-restore-vault-from-snapshot.md)
intégralement à partir de §5.3 (pas besoin de §5.1 / §5.2 — VPS neuf).

À la fin : `vault status` doit reporter `Sealed: false`.

### Étape 5.6 — Restauration PostgreSQL (T+2h → T+3h)

Suivre [01-restore-postgres-pitr.md](./01-restore-postgres-pitr.md) à partir
de §5 (identifier le `target-time`) puis §6 (procédure de restauration).

Pour ce scénario VPS détruit, le `target-time` est probablement le moment de
détection de l'incident (5 min avant le crash réseau).

À la fin : `pg_is_in_recovery()` retourne `false` après promote.

### Étape 5.7 — Restauration artifacts (T+3h → T+3h30)

Suivre [04-restore-artifacts.md](./04-restore-artifacts.md) §5.

Cette étape peut tourner en parallèle de §5.6 si bande passante suffisante.

### Étape 5.8 — Démarrage application + worker (T+3h30 → T+3h45)

```bash theme={null}
make prod
sleep 30
docker compose ps
# tous les services doivent être "running" et "healthy"
```

### Étape 5.9 — Pointage DNS (T+3h45 → T+4h)

Mettre à jour le record A de `snakysec.com` (et tous sous-domaines clients) :

```
1. OVH Manager → Domains → snakysec.com → DNS Zone
2. Modifier record A : "snakysec.com" → <NEW_VPS_IP>
3. Modifier record AAAA : "snakysec.com" → <NEW_VPS_IPv6>
4. Apply changes (TTL était de 300s, propagation rapide)
5. Idem pour wildcard *.snakysec.com (pour les sous-domaines clients)
```

Si le backup mensuel de la zone DNS est plus récent et complet :

```bash theme={null}
# Sur le VPS (artifacts restaurés)
cat /opt/mssp/data/artifacts/dns-zones/snakysec.com.2026-04.bind
# Vérifier que les records correspondent à la prod actuelle
# Si oui, ré-importer via OVH API (ou manuellement)
```

### Étape 5.10 — Validation finale (T+4h → T+5h)

```bash theme={null}
# Test complet via DNS (depuis l'extérieur)
dig +short snakysec.com
# attendu : <NEW_VPS_IP>

curl -sI https://snakysec.com/api/health
# attendu : HTTP/2 200

# Test login plateforme dans navigateur
# - Charger https://snakysec.com
# - Login Entra SSO (Nicolas Global Admin)
# - Vérifier dashboard charge
# - Vérifier qu'on voit les clients existants
# - Vérifier qu'un audit récent est visible
```

Si tout OK, runbook validé. Communication finale aux clients (cf. runbook 01 §8).

## 6. Communication post-incident

Identique runbook 01 §8 + mention : "L'incident a nécessité une reconstruction
complète de notre infrastructure. Toutes les données ont été restaurées sans
perte significative. Aucune information sensible n'a été divulguée."

Procès-verbal détaillé dans `docs/dr/test-results/YYYY-MM-DD-vps-rebuild.md`.

## 7. Notification CSIRT-FR

Cet incident est **significatif** au sens NIS2 (interruption MSSP > 1h). Notif
sous 24h via formulaire CERT-FR + email [csirt@cert.ssi.gouv.fr](mailto:csirt@cert.ssi.gouv.fr) (cf. template
[docs/dr/incident-response/02-csirt-fr-notification.md](../incident-response/02-csirt-fr-notification.md)).

## 8. Coût estimé incident

| Poste                                                | Coût                   |
| ---------------------------------------------------- | ---------------------- |
| Nouveau VPS OVH (provisionnement immédiat)           | \~50 € HT/mois prorata |
| Travail Nicolas (4h)                                 | Coût d'opportunité     |
| Notification clients + post-incident report          | Inclus ops             |
| Notif CSIRT-FR                                       | Gratuit                |
| Activation assurance cyber Stoik (si dommages tiers) | Franchise (\~1000 €)   |

## 9. Hors-périmètre V1

* **Failover automatique multi-DC** : non implémenté V1, reconstruction manuelle 4h. Phase 2.
* **Pilot VPS de spare** : envisageable Phase 2 (\~50€/mois) pour réduire RTO à 1h.

## 10. Erreurs courantes et solutions

| Erreur                                                     | Cause                                                 | Solution                                                                               |
| ---------------------------------------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------- |
| OVH refuse de provisionner (capacity issue dans la région) | Pic de demande (incident OVH généralisé)              | Provisionner dans une autre région OVH (Roubaix, Strasbourg) ou pivoter Scaleway (§11) |
| Docker network create échoue : "network exists"            | Reste d'une tentative précédente                      | `docker network rm <name>` puis re-créer                                               |
| Vault unseal échoue avec les 3 shares                      | Shares pas synchronisées avec le snapshot restauré    | Récupérer enveloppe trustee (cf. runbook 02 §5.6)                                      |
| Application 502 Bad Gateway                                | next-app pas encore healthy ou Vault sealed           | Wait 60s + check `docker logs mssp-app`                                                |
| ACME Let's Encrypt rate-limited                            | Trop de re-issues sur le même domaine en peu de temps | Patienter 1h + retry, ou utiliser staging Let's Encrypt en attendant                   |

## 11. Plan de secours OVH indisponible (pivot Scaleway)

Si OVH est totalement HS (pas de provisionnement possible nulle part) :

```
1. Login Scaleway Console
2. Compute → Create instance
3. Spec : DEV1-L 4 CPU / 8 GB RAM / 80 GB (équivalent OVH Comfort)
4. Region : fr-par-1 (Paris)
5. OS : Debian 12
6. Bootstrap identique à §5.2-5.4
7. Restore identique à §5.5-5.8
8. DNS : modifier records vers IP Scaleway
9. Document décision dans le post-incident report (déviation de l'arch nominale)
```

Cette procédure est testée annuellement (Q3) sur env de test pour ne pas
découvrir les blocages le jour J.

## 12. Validation du runbook

Testé annuellement (Q4, exercice incident complet) avec reconstruction
complète sur un VPS de test temporaire.

| Version | Date       | Auteur             |
| ------- | ---------- | ------------------ |
| 1.0     | 2026-04-26 | Nicolas Schiffgens |
