# [WEB] GUIDE CONFIGURATION SERVEUR WEB - ULTRA DÉTAILLÉ POUR DÉBUTANTS ABSOLUS

## * AVANT DE COMMENCER : COMPRENDRE LES BASES

### Qu'est-ce qu'un serveur web ?

**Analogie simple :**

Imagine un restaurant :
- [ACCUEIL] **Le restaurant** = Le serveur web (Apache/Nginx)
- [SORTIE] **La porte d'entrée** = Le port (80 ou 443)
- [LISTE] **Le menu** = Tes pages web (HTML, CSS, JS)
- [PERSONNE][COOKING] **Le chef** = Les scripts backend (PHP, Python, Node.js)
- [FORK_AND_KNIFE_WITH_PLATE] **Les serveurs** = Le protocole HTTP qui livre le contenu
- [VERROUILLE] **La porte sécurisée** = HTTPS (avec certificat SSL)

**Quand tu vas sur un site web :**

```
Toi (client) : "Je veux voir example.com"
     v
DNS : "OK, example.com = 93.184.216.34"
     v
Ton navigateur -> [Internet] -> Serveur web (93.184.216.34:80)
     v
Serveur web : "Voici la page HTML"
     v
Ton navigateur affiche la page [OK]
```

---

### Qu'est-ce qu'un port réseau ?

**Définition simple :**
Un port = un "numéro de porte" sur un ordinateur

**Analogie de l'immeuble :**

```
[ENTREPRISE] TON SERVEUR (IP : 192.168.1.100)
├─ [SORTIE] Porte 22   -> SSH (connexion à distance)
├─ [SORTIE] Porte 80   -> HTTP (site web non sécurisé)
├─ [SORTIE] Porte 443  -> HTTPS (site web sécurisé) *
├─ [SORTIE] Porte 3306 -> MySQL (base de données)
└─ [SORTIE] Porte 8080 -> Application web alternative
```

**Les ports les plus importants pour le web :**

| Port | Protocole | Usage | Exemple |
|------|-----------|-------|---------|
| **80** | HTTP | Sites web NON sécurisés | http://example.com |
| **443** | HTTPS | Sites web SÉCURISÉS | https://example.com |
| 8080 | HTTP alternatif | Développement/Test | http://example.com:8080 |
| 8443 | HTTPS alternatif | Développement/Test | https://example.com:8443 |

**Important à savoir :**

1. **Port 80 (HTTP)** :
   - Traffic NON chiffré [X]
   - Mots de passe visibles en clair
   - Google pénalise ces sites
   - À utiliser UNIQUEMENT pour rediriger vers HTTPS

2. **Port 443 (HTTPS)** :
   - Traffic CHIFFRÉ [OK]
   - Cadenas vert dans le navigateur
   - Obligatoire pour les sites modernes
   - Nécessite un certificat SSL

---

### HTTP vs HTTPS : Quelle différence ?

**HTTP (HyperText Transfer Protocol)** :
```
Client -> [Requête en CLAIR] -> Serveur
         "Login: pierre"
         "Password: 123456"
         
[X] N'importe qui peut intercepter et lire !
```

**HTTPS (HTTP Secure)** :
```
Client -> [Requête CHIFFRÉE] -> Serveur
         "Kj#8hF@mP9$xQ..."
         
[OK] Même intercepté, impossible à lire !
```

**Comment HTTPS fonctionne :**

```
1. Client : "Bonjour serveur, je veux parler en sécurité"
2. Serveur : "Voici mon certificat SSL (ma carte d'identité)"
3. Client : "Je vérifie ton certificat... OK, tu es légitime !"
4. Les deux créent une "clé secrète" pour chiffrer
5. Toute la conversation est chiffrée avec cette clé
```

---

### Qu'est-ce qu'un certificat SSL ?

**Analogie de la carte d'identité :**

Un certificat SSL = une carte d'identité pour un site web

Il prouve :
- [OK] "Je suis vraiment example.com"
- [OK] "Je ne suis pas un imposteur"
- [OK] "Tu peux me faire confiance"

**Contenu d'un certificat :**

```
Certificat SSL
├─ Nom du site : example.com
├─ Propriétaire : Société XYZ
├─ Valide du : 01/01/2024 au 01/01/2025
├─ Émis par : Let's Encrypt (autorité de certification)
└─ Signature cryptographique (preuve d'authenticité)
```

**Types de certificats :**

1. **Let's Encrypt** (GRATUIT) *
   - Gratuit et automatique
   - Valide 90 jours (renouvellement auto)
   - Parfait pour 99% des sites

2. **Certificats payants**
   - DigiCert, GlobalSign, etc.
   - Validation étendue (barre verte)
   - Support commercial
   - Utile pour les grandes entreprises

---

### Qu'est-ce qu'un Virtual Host ?

**Problème :**
Tu as UN seul serveur, mais tu veux héberger PLUSIEURS sites web.

**Solution : Virtual Hosts !**

**Analogie de l'hôtel :**

```
[ENTREPRISE] SERVEUR (IP : 93.184.216.34)
│
├─ [ACCUEIL] Virtual Host 1 : example.com
│  └─ Fichiers dans /var/www/example.com
│
├─ [ACCUEIL] Virtual Host 2 : blog.example.com
│  └─ Fichiers dans /var/www/blog
│
└─ [ACCUEIL] Virtual Host 3 : shop.example.com
   └─ Fichiers dans /var/www/shop
```

**Comment ça marche :**

```
Client demande : http://example.com
     v
Serveur web regarde le nom de domaine dans la requête
     v
"Ah ! C'est example.com, je vais dans /var/www/example.com"
     v
Envoie les fichiers de ce dossier [OK]
```

**Sans Virtual Host :**
- 1 serveur = 1 site
- Pour 10 sites -> 10 serveurs [ARGENT][ARGENT][ARGENT]

**Avec Virtual Host :**
- 1 serveur = 100+ sites
- Économique et facile à gérer [OK]

---

### Qu'est-ce qu'un Reverse Proxy ?

**Définition simple :**
Un intermédiaire qui reçoit les requêtes et les transmet à d'autres serveurs.

**Analogie du standard téléphonique :**

```
[TEL] Client appelle l'entreprise
     v
[PERSONNE][PRO] Standardiste (Reverse Proxy)
     v
   "Vous voulez parler à qui ?"
     v
   ├─ Service commercial -> Serveur 1
   ├─ Service technique -> Serveur 2
   └─ Service RH -> Serveur 3
```

**En pratique :**

```
Client -> Nginx (Reverse Proxy) -> Backend
         (Port 80/443)             
              v
         ├─ Application Node.js (Port 3000)
         ├─ Application Python (Port 8000)
         └─ Application Java (Port 8080)
```

**Avantages :**

1. **Sécurité** :
   - Les vrais serveurs sont cachés
   - Seul le proxy est exposé à Internet

2. **Load Balancing** (répartition de charge) :
   - Distribue les requêtes entre plusieurs serveurs
   - Si un serveur tombe, les autres prennent le relais

3. **SSL Termination** :
   - Le proxy gère HTTPS
   - Les backends peuvent rester en HTTP (plus simple)

4. **Cache** :
   - Le proxy garde en mémoire les pages populaires
   - Réponse ultra-rapide [RAPIDE]

---

## [OBJECTIF] OBJECTIF DU PROJET

### Ce qu'on va faire aujourd'hui

On va configurer un serveur web complet avec :

```
┌─────────────────────────────────────────────┐
│ [WEB] SERVEUR WEB COMPLET                      │
│                                              │
│ ┌─────────────────────────────────────────┐ │
│ │ [OUTIL] Nginx (Serveur Web)                  │ │
│ │                                          │ │
│ │ ├─ Port 80 (HTTP)                       │ │
│ │ │  └─ Redirige vers HTTPS                │ │
│ │                                          │ │
│ │ ├─ Port 443 (HTTPS)                     │ │
│ │ │  ├─ Certificat SSL Let's Encrypt      │ │
│ │ │  └─ Sécurité maximale                  │ │
│ │                                          │ │
│ │ ├─ Virtual Hosts                        │ │
│ │ │  ├─ example.com                        │ │
│ │ │  ├─ blog.example.com                   │ │
│ │ │  └─ api.example.com                    │ │
│ │                                          │ │
│ │ └─ Reverse Proxy                        │ │
│ │    └─ Vers app Node.js (port 3000)      │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
```

**Ce que tu vas apprendre :**

[OK] Installer et configurer Nginx
[OK] Comprendre les ports 80 et 443
[OK] Obtenir un certificat SSL gratuit
[OK] Créer des Virtual Hosts
[OK] Configurer un Reverse Proxy
[OK] Mettre en place des redirections
[OK] Sécuriser ton serveur

---

## [LISTE] PRÉREQUIS

Avant de commencer, assure-toi d'avoir :

[OK] Un serveur Linux (Ubuntu 20.04+ ou Debian 10+)
[OK] Accès root ou sudo
[OK] Un nom de domaine pointant vers ton serveur (pour SSL)
[OK] Ports 80 et 443 ouverts dans le pare-feu

**Vérifications préliminaires :**

```bash
# Vérifier la version d'Ubuntu
lsb_release -a

# Vérifier que tu as les droits sudo
sudo whoami
# Devrait afficher : root

# Vérifier la connexion Internet
ping -c 4 google.com
```

---

## [OUTIL] ÉTAPE 1 : INSTALLER NGINX

### Pourquoi Nginx ?

**Nginx vs Apache :**

| Caractéristique | Nginx | Apache |
|-----------------|-------|--------|
| Performance | [RAPIDE] Très rapide | [TURTLE] Plus lent |
| Mémoire | [GREEN_HEART] Faible | [YELLOW_HEART] Moyenne |
| Configuration | [NOTE] Simple | [DOCS] Complexe |
| Popularité | * Netflix, Cloudflare | * WordPress, cPanel |

**Nginx est parfait pour :**
- Sites à fort trafic
- Reverse proxy
- Load balancing
- Configuration moderne

### Installation

**1. Mettre à jour la liste des paquets**

```bash
sudo apt update
```

**Explication :**
- `apt` = Gestionnaire de paquets Ubuntu/Debian
- `update` = Télécharge la liste des derniers programmes disponibles
- NE télécharge PAS les programmes, juste la liste

**Résultat attendu :**
```
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://security.ubuntu.com/ubuntu jammy-security InRelease
...
Reading package lists... Done
```

---

**2. Installer Nginx**

```bash
sudo apt install nginx -y
```

**Explication :**
- `install nginx` = Installe le paquet Nginx
- `-y` = Répond automatiquement "yes" aux questions

**Résultat attendu :**
```
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
  nginx nginx-common nginx-core
...
Setting up nginx (1.18.0-6ubuntu14.4) ...
```

---

**3. Vérifier que Nginx est installé**

```bash
nginx -v
```

**Résultat attendu :**
```
nginx version: nginx/1.18.0 (Ubuntu)
```

---

**4. Vérifier l'état du service**

```bash
sudo systemctl status nginx
```

**Résultat attendu :**
```
[BLACK_CIRCLE] nginx.service - A high performance web server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
   Active: active (running) since Fri 2024-12-06 14:00:00 UTC
           ^^^^^^^^^^^^^^
           IL TOURNE ! [OK]
   ...
```

Si Nginx n'est pas démarré :
```bash
sudo systemctl start nginx
sudo systemctl enable nginx  # Démarrage automatique au boot
```

---

**5. Tester dans le navigateur**

Ouvre un navigateur et va sur :
```
http://[IP-DE-TON-SERVEUR]
```

**Pour trouver l'IP de ton serveur :**
```bash
ip addr show | grep "inet " | grep -v 127.0.0.1
```

**Résultat attendu :**

Tu devrais voir la page par défaut de Nginx :

```
Welcome to nginx!

If you see this page, the nginx web server is 
successfully installed and working.
```

[BRAVO] **Si tu vois cette page, Nginx fonctionne !** [BRAVO]

---

### Comprendre la structure de Nginx

**Fichiers et dossiers importants :**

```
/etc/nginx/
├─ nginx.conf                    <- Configuration principale
├─ sites-available/              <- Configurations de sites (disponibles)
│  └─ default                    <- Site par défaut
├─ sites-enabled/                <- Configurations actives (liens symboliques)
│  └─ default -> ../sites-available/default
├─ conf.d/                       <- Configurations additionnelles
├─ snippets/                     <- Morceaux de config réutilisables
└─ modules-enabled/              <- Modules actifs

/var/www/
└─ html/                         <- Fichiers du site par défaut
   └─ index.nginx-debian.html    <- Page "Welcome to nginx"

/var/log/nginx/
├─ access.log                    <- Log des accès (qui visite ton site)
└─ error.log                     <- Log des erreurs
```

**Workflow des sites :**

```
1. Tu crées une config dans sites-available/
2. Tu crées un lien symbolique vers sites-enabled/
3. Tu recharges Nginx
4. Le site est en ligne ! [OK]
```

**Commandes essentielles :**

```bash
# Tester la configuration (avant de recharger)
sudo nginx -t

# Recharger la configuration (sans couper les connexions)
sudo systemctl reload nginx

# Redémarrer Nginx (coupe les connexions)
sudo systemctl restart nginx

# Arrêter Nginx
sudo systemctl stop nginx

# Voir les logs en temps réel
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
```

---

## [WEB] ÉTAPE 2 : COMPRENDRE LES PORTS 80 ET 443

### Le port 80 (HTTP)

**Fonctionnement :**

```
Client               Internet              Serveur
  │                     │                     │
  │  http://example.com │                     │
  ├────────────────────────────────────────>  │
  │                     │                     │
  │      Requête HTTP (PORT 80)               │
  │      en CLAIR (non chiffré) [X]            │
  │                     │                     │
  │  <────────────────────────────────────────┤
  │      Réponse HTML                         │
  │                     │                     │
```

**Problèmes du HTTP :**

1. **Mots de passe visibles** :
   ```
   POST /login HTTP/1.1
   username=pierre
   password=123456          <- VISIBLE EN CLAIR ! [X]
   ```

2. **Données sensibles exposées** :
   - Numéros de carte bancaire
   - Informations personnelles
   - Messages privés

3. **Man-in-the-Middle attacks** :
   - Quelqu'un peut intercepter et modifier le trafic
   - Injection de code malveillant

4. **Google pénalise** :
   - Les sites HTTP sont marqués "Non sécurisé"
   - Mauvais référencement SEO

---

### Le port 443 (HTTPS)

**Fonctionnement :**

```
Client               Internet              Serveur
  │                     │                     │
  │ https://example.com │                     │
  ├────────────────────────────────────────>  │
  │                     │                     │
  │  1. Demande de certificat SSL             │
  │  <────────────────────────────────────────┤
  │      Voici mon certificat                 │
  │                     │                     │
  │  2. Vérification du certificat [OK]          │
  │                     │                     │
  │  3. Création d'une clé de chiffrement     │
  ├────────────────────────────────────────>  │
  │                     │                     │
  │  4. Tout le trafic est CHIFFRÉ [VERROUILLE]         │
  │      "Kj#8hF@mP9$xQ..."                   │
  ├────────────────────────────────────────>  │
  │  <────────────────────────────────────────┤
  │      "aB$5mK#9pL..."                      │
```

**Avantages du HTTPS :**

[OK] **Confidentialité** : Personne ne peut lire le contenu
[OK] **Intégrité** : Le contenu ne peut pas être modifié
[OK] **Authenticité** : Tu es sûr de parler au bon serveur
[OK] **SEO** : Google favorise les sites HTTPS
[OK] **Confiance** : Cadenas vert dans le navigateur

---

### Vérifier que les ports sont ouverts

**Sur le serveur :**

```bash
# Vérifier que Nginx écoute sur les ports 80 et 443
sudo netstat -tulpn | grep nginx
```

**Résultat attendu :**

```
tcp  0  0  0.0.0.0:80    0.0.0.0:*  LISTEN  1234/nginx
     ^^       ^^
   Proto    Port HTTP

tcp  0  0  0.0.0.0:443   0.0.0.0:*  LISTEN  1234/nginx
                ^^^
              Port HTTPS
```

**Explication :**
- `0.0.0.0:80` = Écoute sur TOUTES les interfaces, port 80
- `LISTEN` = En mode écoute (attend des connexions)
- `1234/nginx` = Processus Nginx (PID 1234)

---

**Depuis un autre ordinateur :**

```bash
# Tester le port 80 (HTTP)
curl -I http://[IP-DU-SERVEUR]

# Tester le port 443 (HTTPS)
curl -I https://[IP-DU-SERVEUR]
```

Si les ports sont bloqués par un pare-feu :

```bash
# Vérifier le pare-feu UFW (Ubuntu)
sudo ufw status

# Autoriser HTTP et HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Recharger le pare-feu
sudo ufw reload
```

---

## [SECURISE] ÉTAPE 3 : OBTENIR UN CERTIFICAT SSL (Let's Encrypt)

### Pourquoi Let's Encrypt ?

**Let's Encrypt** = Autorité de certification GRATUITE et AUTOMATISÉE

**Avantages :**
- [OK] 100% Gratuit
- [OK] Reconnu par tous les navigateurs
- [OK] Renouvellement automatique
- [OK] Installation en 2 minutes

**Certbot** = Outil pour automatiser Let's Encrypt

---

### Installation de Certbot

**1. Installer Certbot et le plugin Nginx**

```bash
sudo apt install certbot python3-certbot-nginx -y
```

**Explication :**
- `certbot` = Programme principal
- `python3-certbot-nginx` = Plugin pour l'intégration Nginx

---

**2. Vérifier l'installation**

```bash
certbot --version
```

**Résultat attendu :**
```
certbot 1.21.0
```

---

### Obtenir le certificat SSL

**[ATTENTION] PRÉREQUIS CRITIQUE :**

Avant de continuer, **ton nom de domaine DOIT pointer vers ton serveur !**

**Vérifie avec :**

```bash
# Remplace example.com par TON domaine
nslookup example.com
```

**Résultat attendu :**
```
Server:     8.8.8.8
Address:    8.8.8.8#53

Name:   example.com
Address: [IP-DE-TON-SERVEUR]    <- DOIT correspondre ! [OK]
```

Si l'IP ne correspond pas :
1. Va dans ton registrar (OVH, Gandi, Namecheap, etc.)
2. Crée un enregistrement DNS de type **A** :
   ```
   example.com  ->  [IP-DE-TON-SERVEUR]
   ```
3. Attends 5-30 minutes (propagation DNS)

---

**3. Obtenir le certificat (méthode automatique)**

```bash
sudo certbot --nginx -d example.com -d www.example.com
```

**Explication ligne par ligne :**

```bash
sudo certbot --nginx -d example.com -d www.example.com
     ^       ^       ^                ^
     │       │       │                └─ Ajoute www.example.com aussi
     │       │       └──────────────────── Domaine principal
     │       └──────────────────────────── Utilise le plugin Nginx
     └──────────────────────────────────── Lance Certbot
```

---

**4. Répondre aux questions**

**Question 1 : Email**
```
Enter email address (used for urgent renewal and security notices):
```

**Réponse :**
- Entre ton email
- Let's Encrypt t'enverra des alertes si le certificat expire

---

**Question 2 : Conditions d'utilisation**
```
Please read the Terms of Service at...
(A)gree/(C)ancel:
```

**Réponse :** Tape `A` et appuie sur Entrée

---

**Question 3 : Redirection HTTP -> HTTPS**
```
Please choose whether or not to redirect HTTP traffic to HTTPS:
1: No redirect
2: Redirect - Make all requests redirect to secure HTTPS access

Select the appropriate number [1-2]:
```

**Réponse :** Tape `2` (toujours rediriger vers HTTPS)

---

**5. Résultat attendu**

```
Congratulations! You have successfully enabled 
https://example.com and https://www.example.com

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   
 - Your cert will expire on 2025-03-06. To obtain a new or tweaked
   version, simply run certbot again with the "certonly" option.
   
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt.
   
 - If you like Certbot, please consider supporting our work by:
   Donating to ISRG / Let's Encrypt
   Donating to EFF
```

[BRAVO] **Félicitations ! Ton site est maintenant en HTTPS !** [BRAVO]

---

### Tester le certificat

**1. Dans le navigateur**

Va sur : `https://example.com`

Tu devrais voir :
- [OK] Un cadenas vert/gris à côté de l'URL
- [OK] "Connexion sécurisée" quand tu cliques dessus

---

**2. Avec SSL Labs** (test professionnel)

Va sur : https://www.ssllabs.com/ssltest/

Entre ton domaine et lance l'analyse.

**Résultat attendu :** Note A ou A+ [OK]

---

### Renouvellement automatique

**Les certificats Let's Encrypt expirent après 90 jours.**

Heureusement, Certbot installe automatiquement une tâche cron pour renouveler !

**Vérifier le renouvellement automatique :**

```bash
# Tester le renouvellement (mode dry-run, ne renouvelle pas vraiment)
sudo certbot renew --dry-run
```

**Résultat attendu :**
```
Cert not due for renewal, but simulating renewal for dry run
...
Congratulations, all simulated renewals succeeded
```

---

**Voir la tâche cron :**

```bash
sudo cat /etc/cron.d/certbot
```

**Contenu :**
```
# Renouvelle 2 fois par jour (à des heures aléatoires)
0 */12 * * * root certbot renew --quiet
```

**Explication :**
- Certbot vérifie 2 fois par jour si les certificats expirent bientôt
- S'ils expirent dans moins de 30 jours, ils sont renouvelés automatiquement
- Tu n'as RIEN à faire ! [BRAVO]

---

## [ACCUEIL] ÉTAPE 4 : CRÉER DES VIRTUAL HOSTS

### Pourquoi des Virtual Hosts ?

**Objectif :** Héberger plusieurs sites sur un seul serveur.

**Exemple de ce qu'on va faire :**

```
Serveur (IP : 93.184.216.34)
│
├─ example.com          -> /var/www/example.com
├─ blog.example.com     -> /var/www/blog
└─ api.example.com      -> /var/www/api
```

---

### Création du premier Virtual Host

**Scénario :** On va créer un site pour `example.com`

---

**1. Créer le dossier du site**

```bash
sudo mkdir -p /var/www/example.com/html
```

**Explication :**
- `/var/www/` = Dossier standard pour les sites web
- `example.com/` = Nom du site
- `html/` = Dossier contenant les fichiers (HTML, CSS, JS, etc.)
- `-p` = Crée les dossiers parents si nécessaire

---

**2. Définir les permissions**

```bash
# Donner la propriété à l'utilisateur www-data (utilisateur Nginx)
sudo chown -R www-data:www-data /var/www/example.com

# Permissions : lecture/écriture pour le propriétaire, lecture pour les autres
sudo chmod -R 755 /var/www/example.com
```

**Explication des permissions :**

```
755 = rwxr-xr-x
      ^^^ ^^^ ^^^
      │││ │││ │││
      │││ │││ └┴┴─ Autres : lecture + exécution
      │││ └┴┴───── Groupe : lecture + exécution
      └┴┴───────── Propriétaire : lecture + écriture + exécution
```

---

**3. Créer une page d'accueil de test**

```bash
sudo nano /var/www/example.com/html/index.html
```

**Contenu :**

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bienvenue sur Example.com</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        .container {
            text-align: center;
        }
        h1 {
            font-size: 3em;
            margin-bottom: 0.5em;
        }
        p {
            font-size: 1.2em;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>[BRAVO] Ça fonctionne !</h1>
        <p>Bienvenue sur <strong>example.com</strong></p>
        <p>Votre serveur web est configuré correctement [OK]</p>
    </div>
</body>
</html>
```

**Sauvegarde :** `Ctrl + O`, `Entrée`, `Ctrl + X`

---

**4. Créer le fichier de configuration Nginx**

```bash
sudo nano /etc/nginx/sites-available/example.com
```

**Configuration COMPLÈTE avec explications :**

```nginx
# ═══════════════════════════════════════════════════════════
# CONFIGURATION VIRTUAL HOST : example.com
# ═══════════════════════════════════════════════════════════

# ───────────────────────────────────────────────────────────
# BLOC 1 : REDIRECTION HTTP -> HTTPS (Port 80)
# ───────────────────────────────────────────────────────────

server {
    # Écouter sur le port 80 (HTTP)
    listen 80;
    listen [::]:80;
    
    # Explication :
    # listen 80;        -> Écoute sur IPv4, port 80
    # listen [::]:80;   -> Écoute sur IPv6, port 80
    
    # Nom de domaine pour ce Virtual Host
    server_name example.com www.example.com;
    
    # Explication :
    # Nginx regarde le header "Host:" dans la requête HTTP
    # Si c'est "example.com" ou "www.example.com", ce bloc s'active
    
    # Redirection permanente vers HTTPS
    return 301 https://$server_name$request_uri;
    
    # Explication détaillée :
    # return 301     -> Code HTTP 301 (Redirection permanente)
    # https://       -> Protocole HTTPS
    # $server_name   -> Variable Nginx = le nom utilisé (example.com ou www.example.com)
    # $request_uri   -> Variable Nginx = le chemin demandé (/blog/article.html)
    #
    # Exemple concret :
    # Client demande : http://example.com/blog/article.html
    # Nginx répond  : "Allez plutôt sur https://example.com/blog/article.html"
    #
    # Codes de redirection :
    # 301 = Permanente (les moteurs de recherche mettent à jour)
    # 302 = Temporaire (les moteurs gardent l'ancienne URL)
    # 307 = Temporaire (garde la méthode POST)
    # 308 = Permanente (garde la méthode POST)
}

# ───────────────────────────────────────────────────────────
# BLOC 2 : CONFIGURATION HTTPS (Port 443)
# ───────────────────────────────────────────────────────────

server {
    # Écouter sur le port 443 (HTTPS)
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    # Explication :
    # ssl         -> Active le SSL/TLS (chiffrement)
    # http2       -> Active HTTP/2 (plus rapide que HTTP/1.1)
    #
    # HTTP/2 avantages :
    # - Multiplexage (plusieurs fichiers en parallèle)
    # - Compression des headers
    # - Server Push (envoie des ressources avant qu'elles soient demandées)
    
    # Nom de domaine
    server_name example.com www.example.com;
    
    # ─── Configuration SSL/TLS ───
    
    # Certificat SSL (clé publique)
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    
    # Clé privée du certificat
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # Explication :
    # fullchain.pem = Certificat + Chaîne de certification
    # privkey.pem   = Clé privée (GARDE SECRET !)
    #
    # Ces fichiers ont été créés par Certbot à l'étape 3
    
    # Paramètres SSL recommandés par Let's Encrypt
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    
    # Explication :
    # options-ssl-nginx.conf = Configuration SSL sécurisée
    #   - Protocoles TLS 1.2 et 1.3 uniquement
    #   - Algorithmes de chiffrement forts
    #   - Pas de SSL 2.0 ou 3.0 (vulnérables)
    #
    # ssl-dhparams.pem = Paramètres Diffie-Hellman
    #   - Pour l'échange de clés sécurisé
    #   - Protège contre certaines attaques
    
    # ─── Dossier racine du site ───
    
    root /var/www/example.com/html;
    
    # Explication :
    # Tous les fichiers sont cherchés dans ce dossier
    # Exemple : /blog/article.html -> /var/www/example.com/html/blog/article.html
    
    # Fichiers index par défaut
    index index.html index.htm index.php;
    
    # Explication :
    # Quand on demande un dossier (ex: /blog/), Nginx cherche dans l'ordre :
    # 1. /blog/index.html
    # 2. /blog/index.htm
    # 3. /blog/index.php
    # Le premier trouvé est envoyé
    
    # ─── Configuration des logs ───
    
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
    
    # Explication :
    # access_log = Journal de tous les accès
    #   Format : IP - Date - URL - Code HTTP - User-Agent
    #   Exemple : 203.0.113.1 [06/Dec/2024:14:30:00] "GET /index.html HTTP/1.1" 200 1234
    #
    # error_log = Journal des erreurs
    #   Erreurs 404, 500, problèmes de permissions, etc.
    
    # ─── Gestion des URLs ───
    
    location / {
        # Essaye de servir le fichier, sinon le dossier, sinon erreur 404
        try_files $uri $uri/ =404;
        
        # Explication :
        # Client demande : /blog/article.html
        # Nginx cherche dans l'ordre :
        # 1. /var/www/example.com/html/blog/article.html (fichier)
        # 2. /var/www/example.com/html/blog/article.html/ (dossier)
        # 3. Si rien trouvé -> Erreur 404
        #
        # Utilité :
        # - Permet les URLs "propres" (/about au lieu de /about.html)
        # - Compatible avec les sites statiques et les SPA (Single Page Apps)
    }
    
    # ─── Gestion des fichiers PHP (si nécessaire) ───
    
    location ~ \.php$ {
        # Inclure les paramètres FastCGI
        include snippets/fastcgi-php.conf;
        
        # Socket PHP-FPM
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        
        # Explication :
        # Si tu as PHP installé, cette section permet d'exécuter les scripts PHP
        # php8.1-fpm.sock = Socket pour communiquer avec PHP-FPM
        # Change "8.1" par ta version de PHP (php -v pour vérifier)
    }
    
    # ─── Bloquer l'accès aux fichiers cachés ───
    
    location ~ /\.(?!well-known).* {
        deny all;
    }
    
    # Explication :
    # Bloque l'accès aux fichiers commençant par "."
    # Exemples : .htaccess, .git, .env, .DS_Store
    #
    # Exception : .well-known/ (nécessaire pour Let's Encrypt)
    #
    # Pourquoi bloquer ?
    # Ces fichiers peuvent contenir des informations sensibles :
    # - Mots de passe de base de données (.env)
    # - Historique Git (.git)
    # - Configuration serveur (.htaccess)
    
    # ─── En-têtes de sécurité ───
    
    # Empêche le navigateur de deviner le type MIME
    add_header X-Content-Type-Options "nosniff" always;
    
    # Protection contre le clickjacking
    add_header X-Frame-Options "SAMEORIGIN" always;
    
    # Active le filtre XSS du navigateur
    add_header X-XSS-Protection "1; mode=block" always;
    
    # Politique de sécurité du contenu (Content Security Policy)
    add_header Content-Security-Policy "default-src 'self' https:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;
    
    # Explication détaillée des en-têtes :
    #
    # 1. X-Content-Type-Options: nosniff
    #    Empêche le navigateur de "deviner" le type de fichier
    #    Exemple : Si tu envoies un fichier .txt contenant du JavaScript,
    #              le navigateur ne l'exécutera PAS
    #
    # 2. X-Frame-Options: SAMEORIGIN
    #    Empêche d'afficher ton site dans une <iframe> d'un autre site
    #    Protège contre le "clickjacking" (piège de clic)
    #
    # 3. X-XSS-Protection: 1; mode=block
    #    Active la protection XSS (Cross-Site Scripting) du navigateur
    #    Si du code malveillant est détecté, la page est bloquée
    #
    # 4. Content-Security-Policy (CSP)
    #    Définit d'où peuvent venir les ressources (scripts, styles, images)
    #    default-src 'self' https: = Autorise ton domaine + HTTPS
    #    script-src = D'où viennent les scripts JavaScript
    #    style-src = D'où viennent les CSS
    #
    # Ces en-têtes protègent contre :
    # - XSS (Cross-Site Scripting)
    # - Clickjacking
    # - Injection de code
    # - Vol de données
}
```

**Sauvegarde :** `Ctrl + O`, `Entrée`, `Ctrl + X`

---

**5. Activer le Virtual Host**

```bash
# Créer un lien symbolique de sites-available vers sites-enabled
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
```

**Explication du lien symbolique :**

```
/etc/nginx/sites-available/example.com  (fichier original)
            │
            │ (lien symbolique)
            v
/etc/nginx/sites-enabled/example.com    (pointeur)
```

**Pourquoi ce système ?**

- **sites-available/** = Toutes les configurations (actives ou non)
- **sites-enabled/** = Uniquement les sites actifs

**Avantage :** Tu peux désactiver un site sans supprimer sa configuration :

```bash
# Désactiver un site
sudo rm /etc/nginx/sites-enabled/example.com

# Réactiver un site
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
```

---

**6. Tester la configuration**

```bash
sudo nginx -t
```

**Résultat attendu :**
```
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

[OK] **Si tu vois ça, la configuration est bonne !**

---

**Si tu vois une erreur :**

```
nginx: [emerg] unknown directive "ssl_certificate" in /etc/nginx/sites-enabled/example.com:10
```

**Solutions courantes :**

1. **Erreur de syntaxe** :
   - Vérifie les points-virgules `;` à la fin des lignes
   - Vérifie les accolades `{ }`

2. **Fichier certificat introuvable** :
   - Vérifie que Certbot a bien créé les certificats
   - `ls -la /etc/letsencrypt/live/example.com/`

3. **Module SSL non chargé** :
   - Rare, mais vérifie : `nginx -V | grep ssl`

---

**7. Recharger Nginx**

```bash
sudo systemctl reload nginx
```

**Explication :**
- `reload` = Recharge la configuration SANS couper les connexions
- Mieux que `restart` qui coupe tout

---

**8. Tester dans le navigateur**

Va sur : `https://example.com`

Tu devrais voir ta page avec :
- [BRAVO] Le message "Ça fonctionne !"
- [VERROUILLE] Le cadenas de sécurité
- [OK] HTTPS activé

---

### Créer un deuxième Virtual Host (blog.example.com)

**Scénario :** Ajouter un sous-domaine pour un blog

---

**1. Ajouter l'enregistrement DNS**

Dans ton registrar, crée :
```
Type: A
Nom: blog
Valeur: [IP-DE-TON-SERVEUR]
```

Attends 5-30 minutes (propagation DNS)

**Vérifier :**
```bash
nslookup blog.example.com
```

---

**2. Créer le dossier**

```bash
sudo mkdir -p /var/www/blog/html
sudo chown -R www-data:www-data /var/www/blog
sudo chmod -R 755 /var/www/blog
```

---

**3. Créer une page de test**

```bash
sudo nano /var/www/blog/html/index.html
```

**Contenu :**

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Blog - Example.com</title>
    <style>
        body {
            font-family: 'Georgia', serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
            background: #f5f5f5;
        }
        h1 {
            color: #333;
            border-bottom: 3px solid #667eea;
            padding-bottom: 10px;
        }
        .article {
            background: white;
            padding: 20px;
            margin: 20px 0;
            border-radius: 8px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }
    </style>
</head>
<body>
    <h1>[NOTE] Blog de Example.com</h1>
    <div class="article">
        <h2>Premier article</h2>
        <p>Bienvenue sur le blog ! Ce sous-domaine est configuré avec un Virtual Host séparé.</p>
    </div>
</body>
</html>
```

---

**4. Créer la configuration Nginx**

```bash
sudo nano /etc/nginx/sites-available/blog.example.com
```

**Configuration :**

```nginx
# HTTP -> HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name blog.example.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    server_name blog.example.com;
    
    # Certificats SSL
    ssl_certificate /etc/letsencrypt/live/blog.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/blog.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    
    # Configuration
    root /var/www/blog/html;
    index index.html index.htm;
    
    # Logs séparés
    access_log /var/log/nginx/blog.access.log;
    error_log /var/log/nginx/blog.error.log;
    
    location / {
        try_files $uri $uri/ =404;
    }
    
    # Sécurité
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
}
```

---

**5. Obtenir le certificat SSL pour le sous-domaine**

```bash
sudo certbot --nginx -d blog.example.com
```

Réponds aux questions (comme avant).

---

**6. Activer et tester**

```bash
# Activer
sudo ln -s /etc/nginx/sites-available/blog.example.com /etc/nginx/sites-enabled/

# Tester
sudo nginx -t

# Recharger
sudo systemctl reload nginx
```

---

**7. Tester dans le navigateur**

Va sur : `https://blog.example.com`

Tu devrais voir la page du blog ! [BRAVO]

---

## [SYNC] ÉTAPE 5 : CONFIGURER UN REVERSE PROXY

### Qu'est-ce qu'un Reverse Proxy ?

**Scénario :** Tu as une application Node.js qui tourne sur le port 3000. Tu veux qu'elle soit accessible via `https://api.example.com` (pas `http://example.com:3000`).

**Solution :** Un Reverse Proxy !

---

### Architecture

```
Client                Nginx (Reverse Proxy)        Backend
  │                           │                       │
  │  https://api.example.com  │                       │
  ├───────────────────────────>                       │
  │         Port 443           │                       │
  │                            │  http://localhost:3000
  │                            ├───────────────────────>
  │                            │      Port 3000        │
  │                            │                       │
  │                            │  <─────────────────────┤
  │                            │      Réponse          │
  │  <─────────────────────────┤                       │
  │         Réponse            │                       │
```

**Avantages :**

1. **Simplicité pour le client** :
   - `https://api.example.com` au lieu de `http://example.com:3000`

2. **Sécurité** :
   - Le backend n'est pas exposé directement
   - Nginx gère SSL/TLS
   - Le backend peut rester en HTTP (plus simple)

3. **Flexibilité** :
   - Changer le backend sans changer l'URL
   - Load balancing (plusieurs backends)

---

### Exemple : Application Node.js

**1. Créer une application Node.js de test**

```bash
# Installer Node.js (si pas déjà installé)
sudo apt install nodejs npm -y

# Créer un dossier pour l'app
mkdir -p ~/app
cd ~/app

# Initialiser un projet Node.js
npm init -y

# Installer Express (framework web)
npm install express
```

---

**2. Créer l'application**

```bash
nano ~/app/server.js
```

**Contenu :**

```javascript
const express = require('express');
const app = express();
const PORT = 3000;

// Route principale
app.get('/', (req, res) => {
    res.json({
        message: 'Bienvenue sur l\'API !',
        status: 'success',
        timestamp: new Date().toISOString()
    });
});

// Route de test
app.get('/api/hello', (req, res) => {
    res.json({
        message: 'Hello from the backend!',
        backend_port: PORT
    });
});

// Démarrer le serveur
app.listen(PORT, 'localhost', () => {
    console.log(`[OK] Serveur démarré sur http://localhost:${PORT}`);
});
```

**Sauvegarde :** `Ctrl + O`, `Entrée`, `Ctrl + X`

---

**3. Tester l'application**

```bash
# Démarrer l'app
node ~/app/server.js
```

**Dans un autre terminal :**

```bash
curl http://localhost:3000
```

**Résultat attendu :**
```json
{
  "message": "Bienvenue sur l'API !",
  "status": "success",
  "timestamp": "2024-12-06T14:30:00.000Z"
}
```

[OK] **L'application fonctionne !**

Arrête l'app : `Ctrl + C`

---

**4. Créer un service systemd (pour que l'app tourne en arrière-plan)**

```bash
sudo nano /etc/systemd/system/nodeapp.service
```

**Contenu :**

```ini
[Unit]
Description=Application Node.js
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/home/[TON-UTILISATEUR]/app
ExecStart=/usr/bin/node /home/[TON-UTILISATEUR]/app/server.js
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
```

[ATTENTION] **Remplace `[TON-UTILISATEUR]` par ton nom d'utilisateur !**

Pour trouver ton utilisateur : `whoami`

---

**5. Donner les permissions**

```bash
# Permettre à www-data d'accéder au dossier
sudo chown -R www-data:www-data ~/app
```

---

**6. Démarrer le service**

```bash
# Recharger systemd
sudo systemctl daemon-reload

# Démarrer le service
sudo systemctl start nodeapp

# Activer au démarrage
sudo systemctl enable nodeapp

# Vérifier l'état
sudo systemctl status nodeapp
```

**Résultat attendu :**
```
[BLACK_CIRCLE] nodeapp.service - Application Node.js
   Active: active (running) since Fri 2024-12-06 14:30:00 UTC
```

---

**7. Configurer Nginx en Reverse Proxy**

```bash
sudo nano /etc/nginx/sites-available/api.example.com
```

**Configuration COMPLÈTE avec explications :**

```nginx
# ═══════════════════════════════════════════════════════════
# REVERSE PROXY : api.example.com -> localhost:3000
# ═══════════════════════════════════════════════════════════

# HTTP -> HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name api.example.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    server_name api.example.com;
    
    # Certificats SSL
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    
    # Logs
    access_log /var/log/nginx/api.access.log;
    error_log /var/log/nginx/api.error.log;
    
    # ─── CONFIGURATION DU REVERSE PROXY ───
    
    location / {
        # Transférer vers le backend
        proxy_pass http://localhost:3000;
        
        # Explication :
        # Toutes les requêtes vers https://api.example.com
        # sont transférées vers http://localhost:3000
        
        # ─── En-têtes à transférer ───
        
        # Transférer l'en-tête Host original
        proxy_set_header Host $host;
        
        # Explication :
        # Sans ça, le backend recevrait "Host: localhost:3000"
        # Avec ça, il reçoit "Host: api.example.com"
        # Utile si le backend doit connaître le domaine d'origine
        
        # Transférer l'IP réelle du client
        proxy_set_header X-Real-IP $remote_addr;
        
        # Explication :
        # Sans ça, le backend verrait l'IP de Nginx (127.0.0.1)
        # Avec ça, il voit l'IP réelle du client
        # Utile pour les logs, la géolocalisation, etc.
        
        # Transférer la chaîne d'IPs (si plusieurs proxies)
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # Explication :
        # Si le client passe par plusieurs proxies :
        # Client (1.2.3.4) -> Proxy1 -> Proxy2 -> Nginx -> Backend
        # Le backend verra : X-Forwarded-For: 1.2.3.4, proxy1_ip, proxy2_ip
        
        # Indiquer que la requête originale était en HTTPS
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Explication :
        # $scheme = "https" (car on est dans le bloc HTTPS)
        # Le backend saura que le client a utilisé HTTPS
        # Utile pour générer des redirections correctes
        
        # ─── Timeouts ───
        
        # Timeout pour la connexion au backend
        proxy_connect_timeout 60s;
        
        # Timeout pour l'envoi de la requête
        proxy_send_timeout 60s;
        
        # Timeout pour la réception de la réponse
        proxy_read_timeout 60s;
        
        # Explication :
        # Si le backend ne répond pas après 60 secondes,
        # Nginx renvoie une erreur 504 (Gateway Timeout)
        #
        # Ajuste selon ton application :
        # - API rapide : 30s
        # - Traitement long : 300s (5 minutes)
        # - Upload de fichiers : 600s (10 minutes)
        
        # ─── Buffering ───
        
        # Activer le buffering (mise en tampon)
        proxy_buffering on;
        
        # Taille du buffer pour les en-têtes
        proxy_buffer_size 4k;
        
        # Nombre et taille des buffers pour le corps
        proxy_buffers 8 4k;
        
        # Explication :
        # Nginx lit la réponse du backend en petits morceaux (4k)
        # et la met en cache avant de l'envoyer au client
        #
        # Avantages :
        # - Libère rapidement le backend (peut traiter d'autres requêtes)
        # - Lisse les débits réseau
        #
        # Désavantage :
        # - Légère latence pour le premier octet
    }
    
    # ─── Gestion des WebSockets (si nécessaire) ───
    
    location /ws/ {
        proxy_pass http://localhost:3000;
        
        # En-têtes spécifiques WebSocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Explication :
        # Les WebSockets nécessitent HTTP/1.1 et des en-têtes spéciaux
        # pour "upgrader" la connexion HTTP en WebSocket
        #
        # Utilise cette section si ton app utilise WebSocket
        # (chat en temps réel, notifications push, etc.)
    }
    
    # ─── En-têtes de sécurité ───
    
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    # CORS (Cross-Origin Resource Sharing) - Si tu as une API publique
    add_header Access-Control-Allow-Origin "*" always;
    add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
    add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
    
    # Explication CORS :
    # Permet aux sites web d'autres domaines d'accéder à ton API
    #
    # Access-Control-Allow-Origin: *
    #   -> Autorise TOUS les domaines (change par ton domaine pour plus de sécurité)
    #
    # Access-Control-Allow-Methods
    #   -> Méthodes HTTP autorisées
    #
    # Access-Control-Allow-Headers
    #   -> En-têtes HTTP autorisés
    #
    # [ATTENTION] Attention : "*" autorise TOUS les domaines !
    # Pour plus de sécurité, remplace par :
    # add_header Access-Control-Allow-Origin "https://monsite.com" always;
}
```

**Sauvegarde :** `Ctrl + O`, `Entrée`, `Ctrl + X`

---

**8. Ajouter le DNS et obtenir le certificat**

```bash
# Ajouter l'enregistrement DNS (dans ton registrar)
# Type: A
# Nom: api
# Valeur: [IP-DU-SERVEUR]

# Attendre la propagation DNS (5-30 min)
nslookup api.example.com

# Obtenir le certificat SSL
sudo certbot --nginx -d api.example.com

# Activer le site
sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/

# Tester et recharger
sudo nginx -t
sudo systemctl reload nginx
```

---

**9. Tester le Reverse Proxy**

```bash
# Test simple
curl https://api.example.com

# Test avec en-têtes
curl -I https://api.example.com

# Test d'une route spécifique
curl https://api.example.com/api/hello
```

**Résultat attendu :**
```json
{
  "message": "Hello from the backend!",
  "backend_port": 3000
}
```

[BRAVO] **Le Reverse Proxy fonctionne !** [BRAVO]

---

## <- ÉTAPE 6 : REDIRECTIONS

### Types de redirections

**1. Redirection 301 (Permanente)**

```nginx
# www -> non-www (ou inverse)
server {
    listen 80;
    listen [::]:80;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    server_name www.example.com;
    
    # Certificats (nécessaires même pour une redirection HTTPS)
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # Redirection permanente vers la version sans www
    return 301 https://example.com$request_uri;
    
    # Explication :
    # Code 301 = Permanente
    # Les moteurs de recherche mettent à jour leurs index
    # Le navigateur met en cache la redirection
}
```

**Cas d'usage :**
- Unifier l'URL (SEO)
- Éviter le contenu dupliqué
- Choisir entre www et non-www

---

**2. Redirection 302 (Temporaire)**

```nginx
server {
    listen 80;
    server_name ancien-site.com;
    
    # Redirection temporaire
    return 302 https://nouveau-site.com$request_uri;
    
    # Explication :
    # Code 302 = Temporaire
    # Les moteurs de recherche gardent l'ancienne URL
    # Utile pour maintenance, tests, etc.
}
```

**Cas d'usage :**
- Maintenance temporaire
- Test A/B
- Migration progressive

---

**3. Redirection d'URLs spécifiques**

```nginx
server {
    listen 443 ssl http2;
    server_name example.com;
    
    # ...configuration SSL...
    
    # Rediriger une URL spécifique
    location = /old-page {
        return 301 /new-page;
    }
    
    # Explication :
    # = /old-page signifie "exactement /old-page"
    # /old-page -> /new-page [OK]
    # /old-page/ -> pas de match [X]
    # /old-page/sub -> pas de match [X]
    
    # Rediriger un dossier entier
    location /blog/ {
        return 301 /articles$request_uri;
    }
    
    # Explication :
    # /blog/article-1 -> /articles/blog/article-1
    # $request_uri garde le chemin complet
    
    # Rediriger avec réécriture
    location ~ ^/product/([0-9]+)$ {
        return 301 /item/$1;
    }
    
    # Explication :
    # Expression régulière : ([0-9]+) capture un ou plusieurs chiffres
    # $1 = premier groupe capturé
    # /product/123 -> /item/123 [OK]
}
```

---

**4. Redirections multiples (table de redirections)**

```nginx
server {
    listen 443 ssl http2;
    server_name example.com;
    
    # ...configuration SSL...
    
    # Map des redirections
    map $request_uri $new_uri {
        /old-contact    /contact;
        /old-about      /about;
        /old-services   /services;
        /blog/2023/     /archives/2023/;
        /shop/          /store/;
    }
    
    # Appliquer les redirections
    if ($new_uri) {
        return 301 $new_uri;
    }
    
    # Explication :
    # map crée une table de correspondances
    # Si $request_uri correspond, $new_uri est défini
    # Le if redirige si $new_uri existe
    #
    # [ATTENTION] Attention : Éviter les if dans Nginx (considéré comme mauvaise pratique)
    # Utiliser plutôt des location {} quand c'est possible
}
```

---

**5. Forcer HTTPS (déjà vu, mais rappel)**

```nginx
# Méthode 1 : Serveur dédié (recommandée)
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

# Méthode 2 : Avec if (non recommandée, mais fonctionne)
server {
    listen 80;
    listen 443 ssl http2;
    server_name example.com;
    
    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }
}
```

---

**6. Redirection selon le User-Agent**

```nginx
server {
    listen 443 ssl http2;
    server_name example.com;
    
    # Rediriger les mobiles vers un sous-domaine
    if ($http_user_agent ~* (mobile|android|iphone)) {
        return 301 https://m.example.com$request_uri;
    }
    
    # Explication :
    # ~* = Regex insensible à la casse
    # (mobile|android|iphone) = Contient un de ces mots
    #
    # [ATTENTION] Attention : Pas recommandé aujourd'hui !
    # Utiliser plutôt du responsive design (CSS)
}
```

---

**7. Redirection après changement de domaine**

```bash
sudo nano /etc/nginx/sites-available/ancien-domaine.com
```

```nginx
server {
    listen 80;
    listen [::]:80;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    server_name ancien-domaine.com www.ancien-domaine.com;
    
    # Certificats (obtenir avec Certbot d'abord)
    ssl_certificate /etc/letsencrypt/live/ancien-domaine.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ancien-domaine.com/privkey.pem;
    
    # Redirection permanente vers le nouveau domaine
    return 301 https://nouveau-domaine.com$request_uri;
    
    # Explication :
    # Toutes les URLs de l'ancien domaine sont redirigées
    # ancien-domaine.com/contact -> nouveau-domaine.com/contact
    # ancien-domaine.com/blog/article -> nouveau-domaine.com/blog/article
    #
    # [OK] Le référencement SEO est préservé
    # [OK] Les visiteurs sont automatiquement redirigés
}
```

---

## [VERROUILLE] ÉTAPE 7 : SÉCURITÉ AVANCÉE

### Configuration SSL/TLS optimale

**1. Fichier de configuration SSL centralisé**

```bash
sudo nano /etc/nginx/snippets/ssl-params.conf
```

**Contenu (configuration ultra-sécurisée) :**

```nginx
# ═══════════════════════════════════════════════════════════
# CONFIGURATION SSL/TLS SÉCURISÉE
# ═══════════════════════════════════════════════════════════

# ─── Protocoles SSL/TLS ───

# Désactiver SSL 2.0 et 3.0 (vulnérables)
# Activer uniquement TLS 1.2 et 1.3
ssl_protocols TLSv1.2 TLSv1.3;

# Explication :
# TLS 1.0 et 1.1 = Obsolètes, vulnérables
# TLS 1.2 = Sécurisé, largement supporté
# TLS 1.3 = Dernière version, plus rapide et plus sûr

# ─── Chiffrements (Cipher Suites) ───

ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';

# Explication :
# ssl_prefer_server_ciphers on = Le serveur choisit l'algorithme de chiffrement
# ssl_ciphers = Liste des algorithmes autorisés (des plus sûrs aux moins sûrs)
#
# Caractéristiques des bons chiffrements :
# - ECDHE = Échange de clés avec forward secrecy
# - GCM = Mode de chiffrement authentifié
# - SHA256/384 = Algorithmes de hachage forts

# ─── Session Cache (Cache de session) ───

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

# Explication :
# ssl_session_cache shared:SSL:10m
#   -> Cache partagé entre tous les workers, 10 Mo
#   -> 1 Mo ≈ 4000 sessions
#   -> 10 Mo ≈ 40 000 sessions
#
# ssl_session_timeout 10m
#   -> Les sessions sont valides 10 minutes
#   -> Permet la reprise de session (connexion plus rapide)
#
# Avantages :
# - Réduction de la latence (pas de re-négociation SSL complète)
# - Moins de charge CPU

# ─── OCSP Stapling ───

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

# Explication :
# OCSP = Online Certificate Status Protocol
# Permet de vérifier si un certificat a été révoqué
#
# Sans OCSP Stapling :
# Client -> Autorité de certification : "Le certificat est-il valide ?"
# (Ajoute de la latence, peut exposer les sites visités)
#
# Avec OCSP Stapling :
# Serveur récupère la réponse OCSP et l'envoie au client
# (Plus rapide, plus privé)
#
# resolver = Serveurs DNS pour résoudre les URLs OCSP
# valid=300s = Cache la réponse pendant 5 minutes

# ─── En-têtes de sécurité ───

# HSTS (HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Explication :
# HSTS force les navigateurs à toujours utiliser HTTPS
# max-age=31536000 = Valide 1 an (365 jours)
# includeSubDomains = Applique aussi aux sous-domaines
# preload = Peut être ajouté à la liste de préchargement des navigateurs
#
# Protection contre :
# - Attaques de rétrogradation (HTTPS -> HTTP)
# - Man-in-the-middle sur la première connexion
#
# [ATTENTION] Attention : Une fois activé, difficile à annuler !
# Teste d'abord avec max-age=300 (5 minutes)

# Empêcher le mime-type sniffing
add_header X-Content-Type-Options "nosniff" always;

# Protection clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;

# Filtre XSS
add_header X-XSS-Protection "1; mode=block" always;

# Content Security Policy
add_header Content-Security-Policy "default-src 'self' https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self' https:; frame-ancestors 'self';" always;

# Explication CSP :
# default-src 'self' https:
#   -> Par défaut, autorise ton domaine et HTTPS uniquement
#
# script-src 'self' 'unsafe-inline' 'unsafe-eval' https:
#   -> Scripts : ton domaine, inline, eval, et HTTPS externe
#   -> 'unsafe-inline' nécessaire pour certains frameworks
#   -> 'unsafe-eval' nécessaire pour certains outils (désactive si possible)
#
# style-src 'self' 'unsafe-inline' https:
#   -> CSS : ton domaine, inline, et HTTPS externe
#
# img-src 'self' data: https:
#   -> Images : ton domaine, data URLs (base64), et HTTPS externe
#
# font-src 'self' data: https:
#   -> Polices : ton domaine, data URLs, et HTTPS externe
#
# connect-src 'self' https:
#   -> Connexions (AJAX, WebSocket) : ton domaine et HTTPS
#
# frame-ancestors 'self'
#   -> Empêche l'inclusion dans des iframes externes

# Referrer Policy
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Explication :
# Contrôle les informations envoyées dans l'en-tête Referer
# strict-origin-when-cross-origin :
#   - Même origine : Envoie l'URL complète
#   - Origine différente HTTPS -> HTTPS : Envoie uniquement l'origine
#   - Origine différente HTTPS -> HTTP : N'envoie rien
#
# Protège la vie privée des utilisateurs

# Permissions Policy (anciennement Feature Policy)
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

# Explication :
# Contrôle l'accès aux APIs du navigateur
# geolocation=() = Désactive la géolocalisation
# microphone=() = Désactive le microphone
# camera=() = Désactive la caméra
#
# Personnalise selon tes besoins :
# geolocation=(self) = Autorise pour ton domaine uniquement
# microphone=(self "https://trusted.com") = Ton domaine + domaine de confiance
```

**Sauvegarde :** `Ctrl + O`, `Entrée`, `Ctrl + X`

---

**2. Utiliser ce snippet dans tes Virtual Hosts**

Au lieu de répéter la config SSL partout, inclus le snippet :

```nginx
server {
    listen 443 ssl http2;
    server_name example.com;
    
    # Certificats
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # Inclure la configuration SSL sécurisée
    include /etc/nginx/snippets/ssl-params.conf;
    
    # ... reste de la configuration ...
}
```

---

### Protection contre les attaques

**1. Limitation du taux de requêtes (Rate Limiting)**

**Fichier : `/etc/nginx/nginx.conf`**

```bash
sudo nano /etc/nginx/nginx.conf
```

**Ajouter dans le bloc `http {` :**

```nginx
http {
    # ... configuration existante ...
    
    # ─── Zone de limitation ───
    
    # Limite : 10 requêtes par seconde par IP
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    
    # Limite pour les APIs : 100 requêtes par minute
    limit_req_zone $binary_remote_addr zone=api:10m rate=100r/m;
    
    # Limite pour les connexions simultanées : 10 par IP
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    
    # Explication :
    # limit_req_zone = Zone pour limiter les requêtes
    # $binary_remote_addr = IP du client (format binaire, économise RAM)
    # zone=general:10m = Nom de la zone "general", 10 Mo de RAM
    # rate=10r/s = 10 requêtes par seconde maximum
    #
    # 10 Mo de RAM ≈ 160 000 IPs mémorisées
    #
    # Unités de temps :
    # r/s = requêtes par seconde
    # r/m = requêtes par minute
    
    # ... reste de la configuration ...
}
```

**Dans ton Virtual Host :**

```nginx
server {
    listen 443 ssl http2;
    server_name example.com;
    
    # Appliquer la limite générale
    limit_req zone=general burst=20 nodelay;
    limit_conn conn_limit 10;
    
    # Explication :
    # limit_req zone=general = Utilise la zone "general"
    # burst=20 = Permet des pics de 20 requêtes d'un coup
    # nodelay = Ne retarde pas les requêtes dans le burst
    #
    # limit_conn conn_limit 10 = Max 10 connexions simultanées par IP
    #
    # Fonctionnement :
    # - Taux moyen : 10 req/s
    # - Burst ponctuel : +20 requêtes autorisées
    # - Au-delà : Erreur 503 (Service Temporarily Unavailable)
    
    location /api/ {
        # Limite spécifique pour l'API
        limit_req zone=api burst=10 nodelay;
        
        proxy_pass http://localhost:3000;
    }
}
```

**Explication du burst :**

```
Sans burst :
Temps:    0s   1s   2s   3s   4s
Requêtes: 5    10   15   8    12
Autorisé: 10   10   10   10   10
Résultat: [X]   [OK]   [X]   [OK]   [X]

Avec burst=20 :
Temps:    0s   1s   2s   3s   4s
Requêtes: 5    10   35   8    12
Autorisé: 10   10   30   10   10
          (base+burst)
Résultat: [OK]   [OK]   [X]   [OK]   [OK]
```

---

**2. Bloquer les User-Agents malveillants**

```nginx
# Fichier : /etc/nginx/nginx.conf

http {
    # Map pour détecter les mauvais bots
    map $http_user_agent $bad_bot {
        default 0;
        ~*bot       1;  # Bots génériques
        ~*crawler   1;  # Crawlers agressifs
        ~*spider    1;  # Spiders
        ~*scraper   1;  # Scrapers
        "~*nikto"   1;  # Scanner de vulnérabilités
        "~*sqlmap"  1;  # Outil d'injection SQL
        "~*nmap"    1;  # Scanner de ports
        ""          1;  # User-Agent vide
    }
    
    # Exceptions pour les bons bots
    map $http_user_agent $good_bot {
        default 0;
        ~*googlebot     1;
        ~*bingbot       1;
        ~*slurp         1;  # Yahoo
        ~*duckduckbot   1;
    }
}
```

**Dans ton Virtual Host :**

```nginx
server {
    # ... configuration ...
    
    # Bloquer les mauvais bots (sauf les bons)
    if ($bad_bot = 1) {
        set $block_bot 1;
    }
    if ($good_bot = 1) {
        set $block_bot 0;
    }
    if ($block_bot = 1) {
        return 403;
    }
}
```

---

**3. Protection contre les injections SQL (pour les URLs)**

```nginx
server {
    # ... configuration ...
    
    # Bloquer les requêtes avec des patterns d'injection SQL
    location ~ (\.|%2e)(\.|%2e)(%2f|%5c|/|\\) {
        return 403;
    }
    
    location ~ (union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|exec|script) {
        return 403;
    }
    
    # Explication :
    # Ces patterns détectent des tentatives d'injection SQL
    # dans les URLs
    #
    # Exemples bloqués :
    # /index.php?id=1' UNION SELECT * FROM users
    # /page.php?id=1; DROP TABLE users;
}
```

---

**4. Limiter la taille des uploads**

```nginx
http {
    # Taille maximum du corps de la requête
    client_max_body_size 20M;
    
    # Explication :
    # Limite la taille des fichiers uploadés à 20 Mo
    # Empêche les attaques par épuisement de disque
    #
    # Ajuste selon tes besoins :
    # - Blog avec images : 20M
    # - Plateforme vidéo : 500M ou plus
    # - API JSON : 1M
}

server {
    # Limite spécifique pour un emplacement
    location /upload/ {
        client_max_body_size 100M;
    }
}
```

---

**5. Timeout pour éviter les connexions lentes**

```nginx
http {
    # Timeout pour lire l'en-tête de la requête
    client_header_timeout 10s;
    
    # Timeout pour lire le corps de la requête
    client_body_timeout 20s;
    
    # Timeout pour envoyer la réponse
    send_timeout 30s;
    
    # Explication :
    # Protection contre les attaques "Slowloris" :
    # - L'attaquant ouvre plein de connexions
    # - Envoie les données très lentement
    # - Sature les connexions du serveur
    #
    # Avec ces timeouts, les connexions lentes sont coupées
}
```

---

**6. Bloquer l'accès à des fichiers sensibles**

```nginx
server {
    # Bloquer .git
    location ~ /\.git {
        deny all;
        return 404;
    }
    
    # Bloquer .env et autres fichiers de configuration
    location ~ /\.(env|htaccess|htpasswd|ini|log|sh|sql|conf)$ {
        deny all;
        return 404;
    }
    
    # Bloquer les sauvegardes
    location ~ \.(bak|backup|old|save|swp|swo)$ {
        deny all;
        return 404;
    }
    
    # Explication :
    # Ces fichiers peuvent contenir :
    # - Mots de passe (.env)
    # - Historique Git (.git)
    # - Configurations serveur (.htaccess)
    # - Sauvegardes de bases de données (.sql, .backup)
    #
    # return 404 = Fait croire que le fichier n'existe pas
    # (Plus discret que 403 qui confirme l'existence)
}
```

---

## [GRAPHIQUE] ÉTAPE 8 : MONITORING ET LOGS

### Analyser les logs

**1. Logs d'accès**

```bash
# Voir les logs en temps réel
sudo tail -f /var/log/nginx/access.log

# Voir les 100 dernières lignes
sudo tail -n 100 /var/log/nginx/access.log

# Chercher une IP spécifique
sudo grep "203.0.113.1" /var/log/nginx/access.log

# Compter les requêtes par IP
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
```

**Format d'une ligne de log :**

```
203.0.113.1 - - [06/Dec/2024:14:30:00 +0000] "GET /index.html HTTP/1.1" 200 1234 "https://google.com" "Mozilla/5.0..."
^           ^ ^  ^                             ^                           ^   ^    ^                   ^
│           │ │  │                             │                           │   │    │                   └─ User-Agent
│           │ │  │                             │                           │   │    └───────────────────── Referer
│           │ │  │                             │                           │   └────────────────────────── Taille réponse
│           │ │  │                             │                           └────────────────────────────── Code HTTP
│           │ │  │                             └────────────────────────────────────────────────────────── Requête
│           │ │  └──────────────────────────────────────────────────────────────────────────────────────── Date/Heure
│           │ └─────────────────────────────────────────────────────────────────────────────────────────── User authentifié
│           └───────────────────────────────────────────────────────────────────────────────────────────── Identifiant client
└───────────────────────────────────────────────────────────────────────────────────────────────────────── IP client
```

---

**2. Logs d'erreurs**

```bash
# Voir les erreurs en temps réel
sudo tail -f /var/log/nginx/error.log

# Chercher les erreurs 404
sudo grep "404" /var/log/nginx/error.log

# Chercher les erreurs 500
sudo grep "500" /var/log/nginx/error.log
```

---

**3. Statistiques utiles**

```bash
# Top 10 des pages visitées
sudo awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

# Top 10 des IPs
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

# Nombre de requêtes par code HTTP
sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

# Bande passante totale
sudo awk '{sum+=$10} END {print sum/1024/1024 " MB"}' /var/log/nginx/access.log
```

---

### Rotation des logs

**Les logs peuvent devenir ÉNORMES !**

Solution : **logrotate** (installé par défaut)

**Configuration : `/etc/logrotate.d/nginx`**

```bash
sudo nano /etc/logrotate.d/nginx
```

**Contenu recommandé :**

```
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi; \
    endscript
    postrotate
        invoke-rc.d nginx rotate >/dev/null 2>&1
    endscript
}
```

**Explication :**

- `daily` = Rotation quotidienne
- `rotate 14` = Garde 14 jours d'archives
- `compress` = Compresse les anciennes archives (.gz)
- `delaycompress` = Ne compresse pas la rotation la plus récente
- `notifempty` = Ne fait rien si le log est vide
- `create 0640 www-data adm` = Permissions du nouveau fichier
- `postrotate` = Commande après rotation (recharge Nginx)

**Tester la rotation :**

```bash
sudo logrotate -d /etc/logrotate.d/nginx  # Dry-run (test)
sudo logrotate -f /etc/logrotate.d/nginx  # Force la rotation
```

---

## [COURS] ÉTAPE 9 : RÉCAPITULATIF ET BONNES PRATIQUES

### Ce qu'on a appris

[OK] **Installer et configurer Nginx**
[OK] **Comprendre les ports 80 et 443**
[OK] **Obtenir un certificat SSL gratuit avec Let's Encrypt**
[OK] **Créer des Virtual Hosts pour héberger plusieurs sites**
[OK] **Configurer un Reverse Proxy vers des applications backend**
[OK] **Mettre en place des redirections HTTP -> HTTPS**
[OK] **Sécuriser le serveur avec des en-têtes et des limitations**
[OK] **Analyser les logs et surveiller l'activité**

---

### Checklist de sécurité

Avant de mettre en production, vérifie :

```
[ ] Certificat SSL installé et valide
[ ] Redirection HTTP -> HTTPS active
[ ] HSTS activé
[ ] En-têtes de sécurité configurés (CSP, X-Frame-Options, etc.)
[ ] Rate limiting activé
[ ] Fichiers sensibles bloqués (.git, .env, etc.)
[ ] Logs configurés et rotation active
[ ] Pare-feu UFW activé (ports 80, 443, 22 uniquement)
[ ] Mises à jour système régulières (apt update && apt upgrade)
[ ] Sauvegarde régulière des configurations
```

---

### Commandes essentielles à retenir

```bash
# Tester la configuration
sudo nginx -t

# Recharger Nginx (sans couper les connexions)
sudo systemctl reload nginx

# Redémarrer Nginx
sudo systemctl restart nginx

# Voir les logs en temps réel
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

# Renouveler les certificats SSL
sudo certbot renew

# Tester le renouvellement SSL
sudo certbot renew --dry-run
```

---

### Ressources utiles

[DOCS] **Documentation officielle :**
- Nginx : https://nginx.org/en/docs/
- Let's Encrypt : https://letsencrypt.org/docs/
- Certbot : https://eff-certbot.readthedocs.io/

[OUTIL] **Outils de test :**
- SSL Labs : https://www.ssllabs.com/ssltest/
- Security Headers : https://securityheaders.com/
- Mozilla Observatory : https://observatory.mozilla.org/

[GUIDE] **Guides avancés :**
- Nginx Optimization : https://www