# [WEB] GUIDE APACHE HTTP SERVER - ULTRA DÉTAILLÉ POUR DÉBUTANTS

## * INTRODUCTION

### Qu'est-ce qu'Apache HTTP Server ?

**Apache HTTP Server** (souvent appelé simplement "Apache") est un **serveur web** open source, gratuit et le plus populaire au monde depuis 1996.

**Analogie simple :**

Imagine Apache comme un **serveur de restaurant** :
- Les clients (navigateurs web) arrivent et demandent des plats (pages web)
- Le serveur (Apache) prend la commande (requête HTTP)
- Va chercher le plat en cuisine (fichiers sur le disque dur)
- Sert le plat au client (renvoie la page web)

**En termes techniques :**

Apache est un logiciel qui :
1. **Écoute** sur un port (généralement 80 pour HTTP, 443 pour HTTPS)
2. **Reçoit** des requêtes HTTP des navigateurs
3. **Traite** ces requêtes (trouve les fichiers demandés)
4. **Renvoie** les réponses (pages HTML, images, CSS, JavaScript, etc.)

---

### [GRAPHIQUE] Apache en chiffres (2024)

- **Part de marché** : ~30% de tous les sites web dans le monde
- **Créé en** : 1995 (première version publique en 1996)
- **Maintenu par** : Apache Software Foundation
- **Licence** : Apache License 2.0 (open source)
- **Langage** : C
- **Sites utilisant Apache** : Adobe, LinkedIn, NASA, Stanford, MIT, et des millions d'autres

---

### [REFLEXION] Pourquoi apprendre Apache ?

**1. Omniprésence dans l'industrie**
- Des millions de sites web tournent sur Apache
- Compétence demandée dans 70%+ des offres d'emploi DevOps/SysAdmin

**2. Polyvalence**
- Héberge des sites statiques (HTML/CSS/JS)
- Supporte PHP, Python, Ruby, Perl, etc.
- Peut servir de reverse proxy
- Load balancing intégré

**3. Stabilité et fiabilité**
- Testé et éprouvé depuis 25+ ans
- Très stable, peu de bugs critiques
- Énorme communauté pour le support

**4. Configuration flexible**
- Très modulaire (+ de 300 modules disponibles)
- Configuration fine et granulaire
- Fichiers `.htaccess` pour configuration décentralisée

**5. Gratuit et open source**
- Aucun coût de licence
- Code source accessible
- Contribution communautaire active

---

### [SCALES] Apache vs autres serveurs web

#### Apache vs Nginx

| Critère | Apache | Nginx |
|---------|--------|-------|
| **Architecture** | Process-based (MPM) | Event-driven (asynchrone) |
| **Performance statique** | Bon | Excellent (2-3x plus rapide) |
| **Performance dynamique** | Excellent (avec mod_php) | Bon (via proxy) |
| **Consommation RAM** | Plus élevée | Plus faible |
| **Configuration** | Plus complexe mais flexible | Plus simple mais moins flexible |
| **Modules** | 300+ modules | Moins de modules natifs |
| **.htaccess** | [OK] Supporté nativement | [X] Non supporté |
| **Cas d'usage** | Sites dynamiques (PHP, etc.) | Sites statiques, reverse proxy |
| **Communauté** | Très large | Large et croissante |

**Quand choisir Apache ?**
- [OK] Tu héberges des sites PHP (WordPress, Joomla, etc.)
- [OK] Tu as besoin de `.htaccess` (configuration décentralisée)
- [OK] Tu veux une configuration très fine et modulaire
- [OK] Tu débutes (documentation plus abondante)

**Quand choisir Nginx ?**
- [OK] Site à très fort trafic (millions de requêtes/jour)
- [OK] Principalement du contenu statique
- [OK] Besoin d'un reverse proxy performant
- [OK] Contraintes de RAM importantes

---

#### Apache vs LiteSpeed vs Caddy

| Serveur | Points forts | Points faibles |
|---------|--------------|----------------|
| **Apache** | Mature, flexible, très documenté | Performance moyenne |
| **Nginx** | Ultra-rapide, faible RAM | Configuration moins flexible |
| **LiteSpeed** | Compatible Apache, très rapide | Version gratuite limitée |
| **Caddy** | HTTPS automatique, config simple | Jeune, moins de modules |

---

### [OBJECTIF] Ce que tu vas apprendre dans ce guide

**Compétences de base :**
- [OK] Installer et configurer Apache
- [OK] Héberger un site web statique
- [OK] Gérer plusieurs sites (Virtual Hosts)
- [OK] Configurer SSL/HTTPS avec Let's Encrypt
- [OK] Lire et comprendre les logs Apache

**Compétences intermédiaires :**
- [OK] Héberger des sites PHP (WordPress)
- [OK] Configurer des redirections et URL rewriting
- [OK] Mettre en place l'authentification
- [OK] Sécuriser Apache contre les attaques courantes
- [OK] Optimiser les performances

**Compétences avancées :**
- [OK] Configurer un reverse proxy
- [OK] Load balancing entre plusieurs serveurs
- [OK] Intégrer Python (Flask/Django) avec Apache
- [OK] Déployer des applications modernes (React, Vue, Angular)
- [OK] Automatiser la configuration avec scripts

---

## [LISTE] PRÉREQUIS

### [ECRAN] Système d'exploitation recommandé

**Ce guide utilise Ubuntu 22.04 LTS, mais fonctionne aussi sur :**
- Ubuntu 20.04, 22.04, 24.04
- Debian 10, 11, 12
- CentOS 7, 8, 9 / Rocky Linux 8, 9
- Fedora 35+
- Arch Linux

**Pour Windows :**
- Apache fonctionne sur Windows, mais moins couramment utilisé
- Mieux : utiliser WSL2 (Windows Subsystem for Linux) avec Ubuntu

**Pour macOS :**
- Apache est préinstallé (mais version souvent ancienne)
- Recommandé : installer via Homebrew

---

### [LOGIQUE] Connaissances requises

**Absolument nécessaire :**
- [OK] Utilisation basique de la ligne de commande Linux
  - Naviguer dans les dossiers (`cd`, `ls`)
  - Éditer des fichiers (`nano`, `vim`)
  - Gérer les permissions (`chmod`, `chown`)
  - Gérer les services (`systemctl`)

**Recommandé (mais pas obligatoire) :**
- HTML/CSS de base (pour comprendre ce qu'Apache sert)
- Notions de réseau (IP, ports, DNS)
- Bases de HTTP (requête, réponse, codes de statut)

**Si tu débutes complètement :**
Pas de panique ! Ce guide explique TOUT en détail. [COURS]

---

### [WEB] Configuration réseau pour les tests

**Configuration recommandée pour apprendre :**

```
┌─────────────────────────────────────────┐
│  [WEB] Internet                            │
└─────────────────────────────────────────┘
                  v
┌─────────────────────────────────────────┐
│  [RESEAU] Box/Routeur (192.168.1.1)           │
└─────────────────────────────────────────┘
                  v
    ┌─────────────────────────────┐
    │                             │
┌───┴───────────┐      ┌──────────┴─────┐
│ [CODE] VM Linux   │      │ [ECRAN] Ton PC      │
│ Apache Server │      │ (Navigateur)   │
│ 192.168.1.100 │      │ 192.168.1.50   │
└───────────────┘      └────────────────┘
```

**Si tu utilises VirtualBox ou VMware :**
- Configure la VM en **mode pont** (Bridge)
- La VM aura une IP sur ton réseau local
- Tu pourras accéder au site depuis ton PC hôte

**Si tu utilises un VPS (serveur cloud) :**
- Tu auras une IP publique
- Configuration DNS nécessaire pour un nom de domaine

---

### [OK] Checklist avant de commencer

**Matériel :**
- [ ] VM Linux (2 Go RAM minimum, 10 Go disque)
- [ ] Connexion Internet fonctionnelle
- [ ] Accès SSH à la VM (ou console directe)

**Logiciels :**
- [ ] Terminal SSH (PuTTY, Windows Terminal, iTerm2, etc.)
- [ ] Éditeur de texte (nano, vim, VS Code avec SSH, etc.)
- [ ] Navigateur web à jour (Chrome, Firefox, Edge)

**Connaissances :**
- [ ] Tu sais te connecter à ta VM en SSH
- [ ] Tu sais éditer un fichier texte en ligne de commande
- [ ] Tu connais la différence entre HTTP et HTTPS (même vaguement)

**Si tout est [OK], tu es prêt ! [RAPIDE]**

---

## [OUTIL] INSTALLATION D'APACHE

### [ENTREE] Installation sur Ubuntu/Debian

#### Étape 1 : Mettre à jour le système

**Pourquoi ?**
- S'assurer d'avoir les dernières versions des paquets
- Éviter les bugs de sécurité

```bash
sudo apt update
```

**Explication :**
- `apt` = Advanced Package Tool (gestionnaire de paquets Debian/Ubuntu)
- `update` = Rafraîchit la liste des paquets disponibles
- Ne fait PAS de mise à jour, juste télécharge les listes

**Résultat attendu :**

```
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
...
Reading package lists... Done
Building dependency tree... Done
```

---

**Optionnel : Mettre à jour tous les paquets**

```bash
sudo apt upgrade -y
```

**Explication :**
- `upgrade` = Met à jour les paquets installés
- `-y` = Accepte automatiquement (pas de confirmation)

**[ATTENTION] Note :** Cela peut prendre plusieurs minutes.

---

#### Étape 2 : Installer Apache

```bash
sudo apt install apache2 -y
```

**Explication :**
- `apache2` = Nom du paquet Apache sur Debian/Ubuntu
- L'installation prend 30 secondes à 2 minutes selon ta connexion

**Résultat attendu :**

```
Reading package lists... Done
Building dependency tree... Done
The following additional packages will be installed:
  apache2-bin apache2-data apache2-utils libapr1 libaprutil1 ...
The following NEW packages will be installed:
  apache2 apache2-bin apache2-data apache2-utils ...
0 upgraded, 15 newly installed, 0 to remove and 0 not upgraded.
...
Setting up apache2 (2.4.52-1ubuntu4.7) ...
Enabling module mpm_event.
Enabling module authz_core.
Enabling module authz_host.
...
Created symlink /etc/systemd/system/multi-user.target.wants/apache2.service
```

**[OK] Si tu vois "Created symlink" et aucune erreur, c'est installé !**

---

#### Étape 3 : Vérifier qu'Apache tourne

**Commande :**

```bash
sudo systemctl status apache2
```

**Explication :**
- `systemctl` = Gestionnaire de services Linux (systemd)
- `status` = Affiche l'état du service
- `apache2` = Nom du service Apache

**Résultat attendu (SUCCÈS) :**

```
[BLACK_CIRCLE] apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-12-16 10:00:00 UTC; 1min ago
                    ^^^^^^^^^^^^^^^
              Apache tourne ! [OK]
       Docs: https://httpd.apache.org/docs/2.4/
   Main PID: 1234 (apache2)
      Tasks: 55 (limit: 2312)
     Memory: 5.2M
        CPU: 50ms
     CGroup: /system.slice/apache2.service
             ├─1234 /usr/sbin/apache2 -k start
             ├─1235 /usr/sbin/apache2 -k start
             └─1236 /usr/sbin/apache2 -k start

Dec 16 10:00:00 ubuntu systemd[1]: Starting The Apache HTTP Server...
Dec 16 10:00:00 ubuntu systemd[1]: Started The Apache HTTP Server.
```

**[OK] Si tu vois "active (running)", Apache fonctionne !**

**Pour quitter cette vue : appuie sur `q`**

---

#### Étape 4 : Tester dans le navigateur

**1. Trouve l'IP de ta VM**

```bash
ip addr show
```

**Ou plus simple :**

```bash
hostname -I
```

**Résultat (exemple) :**

```
192.168.1.100
```

**Note cette IP ! C'est l'adresse de ton serveur web.**

---

**2. Ouvre ton navigateur (sur ton PC hôte)**

**Tape dans la barre d'adresse :**

```
http://192.168.1.100
```

**[ATTENTION] Remplace `192.168.1.100` par TON IP !**

---

**3. Tu devrais voir :**

```
┌──────────────────────────────────────────────┐
│             Apache2 Ubuntu Default Page      │
│                                              │
│         It works!                            │
│                                              │
│  This is the default welcome page used to   │
│  test the correct operation of the Apache2  │
│  server after installation on Ubuntu         │
│  systems.                                    │
│                                              │
│  [Configuration Overview]                    │
│  [Reporting Problems]                        │
└──────────────────────────────────────────────┘
```

**[BRAVO] SI TU VOIS ÇA, APACHE MARCHE ! [BRAVO]**

---

**Si la page ne charge pas :**

**Vérifications :**

**1. Apache tourne bien ?**

```bash
sudo systemctl status apache2
```

**Si "inactive" :**

```bash
sudo systemctl start apache2
```

---

**2. Pare-feu bloque le port 80 ?**

```bash
sudo ufw status
```

**Si le pare-feu est actif et bloque :**

```bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
```

**Explications :**
- Port **80** = HTTP (non chiffré)
- Port **443** = HTTPS (chiffré avec SSL)

---

**3. La VM est en mode pont ?**

**Si tu utilises VirtualBox :**
- Paramètres de la VM -> Réseau
- Mode d'accès réseau : **Accès par pont**

---

**4. Ping fonctionne ?**

```bash
# Depuis ton PC
ping 192.168.1.100
```

**Si pas de réponse, problème réseau (pas Apache).**

---

### [RECHERCHE] Vérifier la version d'Apache installée

```bash
apache2 -v
```

**Résultat (exemple) :**

```
Server version: Apache/2.4.52 (Ubuntu)
Server built:   2024-06-10T15:30:00
```

**Apache 2.4.x est la version actuelle (stable depuis 2012).**

---

### [DOSSIER] Structure des fichiers Apache sur Ubuntu

**Apache installe plusieurs fichiers et dossiers importants :**

```
/etc/apache2/
├── apache2.conf              <- Configuration PRINCIPALE
├── ports.conf                <- Ports (80, 443)
├── envvars                   <- Variables d'environnement
├── magic                     <- Détection des types MIME
│
├── mods-available/           <- Modules disponibles
├── mods-enabled/             <- Modules activés (symlinks)
│
├── conf-available/           <- Configurations disponibles
├── conf-enabled/             <- Configurations activées
│
├── sites-available/          <- Sites disponibles
│   ├── 000-default.conf      <- Site par défaut (HTTP)
│   └── default-ssl.conf      <- Site par défaut (HTTPS)
│
└── sites-enabled/            <- Sites activés (symlinks)
    └── 000-default.conf -> ../sites-available/000-default.conf

/var/www/
└── html/                     <- Dossier web par défaut
    └── index.html            <- Page d'accueil par défaut

/var/log/apache2/
├── access.log                <- Logs des requêtes HTTP
├── error.log                 <- Logs des erreurs
└── other_vhosts_access.log   <- Logs des autres Virtual Hosts
```

---

**Explication de la structure :**

**`/etc/apache2/` = Configuration**

Tout ce qui configure Apache se trouve ici.

---

**`apache2.conf` = Fichier principal**

C'est le "cerveau" d'Apache. Il contient :
- Paramètres globaux
- Inclusion des autres fichiers
- Directives de sécurité
- Performance

**[ATTENTION] Ne modifie jamais ce fichier directement si tu débutes !**
(On le fera plus tard quand tu comprendras bien.)

---

**`ports.conf` = Ports d'écoute**

Dit sur quels ports Apache écoute :
- Port 80 pour HTTP
- Port 443 pour HTTPS

**Exemple de contenu :**

```apache
Listen 80

<IfModule ssl_module>
    Listen 443
</IfModule>
```

---

**`mods-available/` et `mods-enabled/`**

**mods-available/** = Tous les modules disponibles (désactivés)
**mods-enabled/** = Modules activés (symlinks vers mods-available)

**Analogie :**
- `mods-available/` = Boîte à outils complète
- `mods-enabled/` = Outils que tu utilises actuellement

**Activer un module :**

```bash
sudo a2enmod rewrite
```

**Explication :**
- `a2enmod` = Apache2 ENable MODule
- Crée un lien symbolique de `mods-available/` vers `mods-enabled/`

**Désactiver un module :**

```bash
sudo a2dismod rewrite
```

**Explication :**
- `a2dismod` = Apache2 DISable MODule

---

**`sites-available/` et `sites-enabled/`**

**sites-available/** = Tous les sites configurés (désactivés)
**sites-enabled/** = Sites actifs (symlinks)

**Activer un site :**

```bash
sudo a2ensite mon-site.conf
```

**Désactiver un site :**

```bash
sudo a2dissite mon-site.conf
```

---

**`/var/www/html/` = Dossier web par défaut**

C'est ici que tu mets tes fichiers HTML, CSS, JavaScript, images, etc.

**Par défaut, contient :**
- `index.html` = Page d'accueil "It works!"

**Tu peux remplacer ce fichier par le tien :**

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

---

**`/var/log/apache2/` = Logs**

**access.log** = Journal de toutes les requêtes HTTP

**Exemple de ligne :**

```
192.168.1.50 - - [16/Dec/2024:10:00:00 +0000] "GET / HTTP/1.1" 200 3525
```

**Décryptage :**
- `192.168.1.50` = IP du client
- `16/Dec/2024:10:00:00` = Date et heure
- `GET /` = Méthode et URL demandée
- `HTTP/1.1` = Version du protocole
- `200` = Code de statut (200 = OK)
- `3525` = Taille de la réponse en octets

---

**error.log** = Journal des erreurs

**Exemple :**

```
[Mon Dec 16 10:00:00.123456 2024] [core:error] [pid 1234] File does not exist: /var/www/html/favicon.ico
```

**Très utile pour déboguer ! [BUG]**

---

### [CONFIG] Commandes Apache essentielles

**Démarrer Apache :**

```bash
sudo systemctl start apache2
```

---

**Arrêter Apache :**

```bash
sudo systemctl stop apache2
```

---

**Redémarrer Apache (coupe les connexions) :**

```bash
sudo systemctl restart apache2
```

---

**Recharger la configuration (SANS couper les connexions) :**

```bash
sudo systemctl reload apache2
```

**ℹ Préfère `reload` pour les changements de config (plus sûr).**

---

**Activer Apache au démarrage du système :**

```bash
sudo systemctl enable apache2
```

**Résultat :**

```
Synchronizing state of apache2.service with SysV service script...
```

**Maintenant, Apache démarre automatiquement au boot de la VM. [OK]**

---

**Désactiver le démarrage automatique :**

```bash
sudo systemctl disable apache2
```

---

**Vérifier l'état :**

```bash
sudo systemctl status apache2
```

---

**Tester la syntaxe de la configuration (AVANT de recharger) :**

```bash
sudo apache2ctl configtest
```

**Ou :**

```bash
sudo apachectl configtest
```

**Résultat attendu (SUCCÈS) :**

```
Syntax OK
```

**Si erreur :**

```
AH00526: Syntax error on line 42 of /etc/apache2/sites-enabled/mon-site.conf:
Invalid command 'InvalidDirective', perhaps misspelled or...
```

**Apache te dit exactement où est l'erreur ! [OBJECTIF]**

**[ATTENTION] TOUJOURS faire `configtest` avant `reload` !**

---

### [COURS] Récapitulatif : Installation terminée !

**[OK] Ce que tu as fait :**
- Installé Apache sur Ubuntu
- Vérifié qu'il tourne
- Affiché la page par défaut dans le navigateur
- Compris la structure des fichiers
- Appris les commandes essentielles

**[RAPIDE] Prochaine étape : Héberger ton premier site web !**

---

## [WEB] HÉBERGER UN SITE WEB STATIQUE

### [NOTE] Créer un site HTML simple

**On va créer un site web basique pour comprendre le fonctionnement.**

#### Étape 1 : Créer un dossier pour le site

```bash
sudo mkdir -p /var/www/mon-site
```

**Explication :**
- `mkdir` = Make Directory (créer un dossier)
- `-p` = Crée les dossiers parents si nécessaires
- `/var/www/mon-site` = Chemin du nouveau dossier

---

#### Étape 2 : Créer une page HTML

```bash
sudo nano /var/www/mon-site/index.html
```

**Contenu à copier :**

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mon Premier Site Apache</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        .container {
            background: rgba(255, 255, 255, 0.1);
            padding: 40px;
            border-radius: 10px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
        }
        h1 {
            font-size: 3em;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
        }
        .info {
            background: rgba(255, 255, 255, 0.2);
            padding: 20px;
            border-radius: 5px;
            margin-top: 20px;
        }
        .success {
            color: #4ade80;
            font-size: 1.5em;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>[BRAVO] Félicitations !</h1>
        <p class="success">[OK] Ton serveur Apache fonctionne parfaitement !</p>
        
        <div class="info">
            <h2>[GRAPHIQUE] Informations du serveur</h2>
            <p><strong>Serveur Web :</strong> Apache HTTP Server</p>
            <p><strong>Site :</strong> mon-site</p>
            <p><strong>Date :</strong> <span id="date"></span></p>
            <p><strong>Heure :</strong> <span id="time"></span></p>
        </div>
        
        <div class="info">
            <h2>[RAPIDE] Prochaines étapes</h2>
            <ul>
                <li>Ajouter plus de pages HTML</li>
                <li>Ajouter du CSS et du JavaScript</li>
                <li>Configurer HTTPS avec SSL</li>
                <li>Déployer une vraie application</li>
            </ul>
        </div>
    </div>
    
    <script>
        function updateTime() {
            const now = new Date();
            document.getElementById('date').textContent = now.toLocaleDateString('fr-FR');
            document.getElementById('time').textContent = now.toLocaleTimeString('fr-FR');
        }
        updateTime();
        setInterval(updateTime, 1000);
    </script>
</body>
</html>
```

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

---

#### Étape 3 : Définir les bonnes permissions

**Pourquoi ?**
Apache tourne sous l'utilisateur `www-data`. Il faut que cet utilisateur puisse lire les fichiers.

```bash
sudo chown -R www-data:www-data /var/www/mon-site
```

**Explication :**
- `chown` = Change Owner (changer propriétaire)
- `-R` = Récursif (tous les fichiers et sous-dossiers)
- `www-data:www-data` = Utilisateur:Groupe
- `/var/www/mon-site` = Dossier à modifier

---

**Vérifier les permissions :**

```bash
ls -lh /var/www/mon-site
```

**Résultat attendu :**

```
total 4.0K
-rw-r--r-- 1 www-data www-data 2.1K Dec 16 10:00 index.html
```

**Décryptage :**
- `-rw-r--r--` = Permissions (propriétaire peut lire/écrire, autres peuvent lire)
- `www-data www-data` = Propriétaire et groupe
- `2.1K` = Taille du fichier
- `index.html` = Nom du fichier

**[OK] Si tu vois `www-data www-data`, c'est bon !**

---

### [OUTIL] Configurer Apache pour ce site

**Maintenant, il faut dire à Apache d'utiliser ce dossier.**

#### Étape 1 : Créer un fichier de configuration Virtual Host

```bash
sudo nano /etc/apache2/sites-available/mon-site.conf
```

**Contenu à copier :**

```apache
# ═══════════════════════════════════════════════════════════════
# VIRTUAL HOST - MON-SITE
# ═══════════════════════════════════════════════════════════════
# Configuration pour le site "mon-site"
# Écoute sur le port 80 (HTTP)
# ═══════════════════════════════════════════════════════════════

<VirtualHost *:80>
    # Adresse email de l'administrateur du serveur
    # Apparaît dans certains messages d'erreur
    ServerAdmin webmaster@localhost
    
    # Nom du serveur (domaine)
    # Dans notre cas, on utilise l'IP directement
    # Plus tard, on mettra un vrai nom de domaine
    # ServerName mon-site.com
    # ServerAlias www.mon-site.com
    
    # Racine du site web (où sont les fichiers HTML)
    DocumentRoot /var/www/mon-site
    
    # Configuration du répertoire
    <Directory /var/www/mon-site>
        # Options pour ce répertoire
        Options Indexes FollowSymLinks
        
        # Autoriser .htaccess à écraser la configuration
        AllowOverride All
        
        # Contrôle d'accès
        Require all granted
    </Directory>
    
    # Fichiers de logs spécifiques à ce site
    ErrorLog ${APACHE_LOG_DIR}/mon-site-error.log
    CustomLog ${APACHE_LOG_DIR}/mon-site-access.log combined
</VirtualHost>

# ═══════════════════════════════════════════════════════════════
# EXPLICATIONS DÉTAILLÉES
# ═══════════════════════════════════════════════════════════════

# <VirtualHost *:80>
# - * = Toutes les adresses IP du serveur
# - 80 = Port HTTP
# - Signifie : "Ce Virtual Host répond sur toutes les IPs, port 80"

# ServerAdmin webmaster@localhost
# - Email de contact en cas de problème
# - Apparaît dans les pages d'erreur 500

# DocumentRoot /var/www/mon-site
# - Racine du site web
# - Quand on accède à http://IP/, Apache cherche les fichiers ici
# - http://IP/index.html -> /var/www/mon-site/index.html
# - http://IP/about.html -> /var/www/mon-site/about.html

# <Directory /var/www/mon-site>
# - Configuration spécifique à ce dossier
# - Tout ce qui est entre <Directory> et </Directory> s'applique à ce dossier

# Options Indexes FollowSymLinks
# - Indexes = Si pas de index.html, affiche la liste des fichiers
# - FollowSymLinks = Suit les liens symboliques
# 
# Autres options possibles :
# - ExecCGI = Permet d'exécuter des scripts CGI
# - Includes = Permet les Server-Side Includes (SSI)
# - MultiViews = Négociation de contenu
# - None = Aucune option
# - All = Toutes les options

# AllowOverride All
# - Permet aux fichiers .htaccess de modifier la configuration
# - All = Toutes les directives peuvent être écrasées
# - None = .htaccess ignoré
# - Limit = Uniquement les directives de contrôle d'accès
# 
# [ATTENTION] Note de sécurité :
# AllowOverride All est pratique pour développer,
# mais peut impacter les performances en production.
# Préfère AllowOverride None et met tout dans ce fichier.

# Require all granted
# - Autoriser tout le monde à accéder (pas de restriction)
# 
# Autres possibilités :
# - Require all denied = Bloquer tout le monde
# - Require ip 192.168.1.0/24 = Autoriser seulement ce réseau
# - Require host example.com = Autoriser seulement ce domaine

# ErrorLog ${APACHE_LOG_DIR}/mon-site-error.log
# - Fichier de log des erreurs pour CE site
# - ${APACHE_LOG_DIR} = /var/log/apache2/
# - Permet de séparer les logs par site

# CustomLog ${APACHE_LOG_DIR}/mon-site-access.log combined
# - Fichier de log des accès pour CE site
# - "combined" = Format de log détaillé (inclut user-agent, referer, etc.)
# 
# Autres formats possibles :
# - common = Format standard (moins d'infos)
# - vhost_combined = Ajoute le nom du Virtual Host
# - referer = Uniquement le referer
# - agent = Uniquement le user-agent

# ═══════════════════════════════════════════════════════════════
```

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

---

#### Étape 2 : Désactiver le site par défaut

```bash
sudo a2dissite 000-default.conf
```

**Explication :**
- `a2dissite` = Apache2 DISable SITE
- Supprime le lien symbolique dans `sites-enabled/`
- Le site par défaut ne répond plus

**Résultat :**

```
Site 000-default disabled.
To activate the new configuration, you need to run:
  systemctl reload apache2
```

---

#### Étape 3 : Activer notre nouveau site

```bash
sudo a2ensite mon-site.conf
```

**Résultat :**

```
Enabling site mon-site.
To activate the new configuration, you need to run:
  systemctl reload apache2
```

---

#### Étape 4 : Tester la configuration

```bash
sudo apache2ctl configtest
```

**Résultat attendu :**

```
Syntax OK
```

**[OK] Si "Syntax OK", tout est bon !**

---

#### Étape 5 : Recharger Apache

```bash
sudo systemctl reload apache2
```

**Pas de message = Succès ! [OK]**

---

### [MONDE] Tester le site dans le navigateur

**Ouvre ton navigateur et va sur :**

```
http://192.168.1.100
```

**[ATTENTION] Remplace par TON IP !**

**Tu devrais voir :**

```
┌─────────────────────────────────────────┐
│   [BRAVO] Félicitations !                    │
│   [OK] Ton serveur Apache fonctionne      │
│       parfaitement !                    │
│                                         │
│   [GRAPHIQUE] Informations du serveur            │
│   Serveur Web : Apache HTTP Server      │
│   Site : mon-site                       │
│   Date : 16/12/2024                     │
│   Heure : 10:30:45                      │
│                                         │
│   [RAPIDE] Prochaines étapes                  │
│   • Ajouter plus de pages HTML          │
│   • Ajouter du CSS et du JavaScript     │
│   • Configurer HTTPS avec SSL           │
│   • Déployer une vraie application      │
└─────────────────────────────────────────┘
```

**[BRAVO] SI TU VOIS ÇA, BRAVO ! TU AS HÉBERGÉ TON PREMIER SITE ! [BRAVO]**

---

### [FICHIER] Ajouter d'autres pages

**Créons une page "À propos" :**

```bash
sudo nano /var/www/mon-site/about.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>À propos - Mon Site</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            color: white;
        }
        .container {
            background: rgba(255, 255, 255, 0.1);
            padding: 40px;
            border-radius: 10px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
        }
        h1 {
            font-size: 2.5em;
            margin-bottom: 20px;
        }
        a {
            color: #ffd700;
            text-decoration: none;
            font-weight: bold;
        }
        a:hover {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>[GUIDE] À propos de ce site</h1>
        <p>Bienvenue sur mon premier site hébergé avec Apache !</p>
        
        <h2>[OUTILS] Technologies utilisées</h2>
        <ul>
            <li>Serveur Web : Apache HTTP Server 2.4</li>
            <li>Système d'exploitation : Ubuntu 22.04 LTS</li>
            <li>Langages : HTML5, CSS3, JavaScript</li>
        </ul>
        
        <h2>[COURS] Ce que j'ai appris</h2>
        <ul>
            <li>Installer et configurer Apache</li>
            <li>Créer un Virtual Host</li>
            <li>Gérer les permissions de fichiers</li>
            <li>Héberger un site web statique</li>
        </ul>
        
        <p><a href="index.html"><- Retour à l'accueil</a></p>
    </div>
</body>
</html>
```

**Sauvegarde.**

**Maintenant, accède à :**

```
http://192.168.1.100/about.html
```

**Tu devrais voir la nouvelle page ! [BRAVO]**

---

### [LIEN] Créer une navigation entre les pages

**Modifions `index.html` pour ajouter un lien :**

```bash
sudo nano /var/www/mon-site/index.html
```

**Ajoute avant la balise `</div>` de fin :**

```html
        <div class="info">
            <h2>[LIEN] Navigation</h2>
            <p><a href="about.html" style="color: #ffd700;">En savoir plus sur ce site</a></p>
        </div>
```

**Sauvegarde.**

**Rafraîchis la page d'accueil, tu as maintenant un menu ! [OK]**

---

## [ENTREPRISE] HÉBERGER PLUSIEURS SITES (VIRTUAL HOSTS)

### [REFLEXION] Qu'est-ce qu'un Virtual Host ?

**Virtual Host (VH) = Serveur virtuel**

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

**Solution : Virtual Hosts**

**Analogie :**

Imagine un immeuble (le serveur) avec plusieurs appartements (sites web) :
- Appartement 101 : site-a.com
- Appartement 102 : site-b.com
- Appartement 103 : site-c.com

Un seul immeuble, mais chaque appartement est indépendant.

**En pratique :**

Apache peut servir différents sites selon :
1. **Le nom de domaine** (Name-based Virtual Hosts)
   - site-a.com -> /var/www/site-a/
   - site-b.com -> /var/www/site-b/

2. **L'adresse IP** (IP-based Virtual Hosts)
   - 192.168.1.100 -> /var/www/site-a/
   - 192.168.1.101 -> /var/www/site-b/

3. **Le port** (Port-based Virtual Hosts)
   - http://IP:80 -> /var/www/site-a/
   - http://IP:8080 -> /var/www/site-b/

**On va utiliser le Name-based (le plus courant).**

---

### [OUTILS] Créer plusieurs sites

**Créons 3 sites différents :**
- site-a.local
- site-b.local
- site-c.local

---

#### Site A : Portfolio

```bash
# Créer le dossier
sudo mkdir -p /var/www/site-a

# Créer la page
sudo nano /var/www/site-a/index.html
```

**Contenu :**

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Portfolio - Site A</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 900px;
            margin: 0 auto;
            padding: 20px;
            background: #1a1a2e;
            color: #eee;
        }
        h1 { color: #00d9ff; }
        .project {
            background: #16213e;
            padding: 20px;
            margin: 20px 0;
            border-radius: 8px;
            border-left: 4px solid #00d9ff;
        }
    </style>
</head>
<body>
    <h1>[PRO] Mon Portfolio</h1>
    <p>Bienvenue sur mon site portfolio !</p>
    
    <div class="project">
        <h2>Projet 1 : Site E-commerce</h2>
        <p>Développement d'une boutique en ligne avec PHP et MySQL.</p>
    </div>
    
    <div class="project">
        <h2>Projet 2 : Application Mobile</h2>
        <p>Application de gestion de tâches avec React Native.</p>
    </div>
    
    <div class="project">
        <h2>Projet 3 : Serveur Apache</h2>
        <p>Configuration d'un serveur web professionnel.</p>
    </div>
</body>
</html>
```

**Permissions :**

```bash
sudo chown -R www-data:www-data /var/www/site-a
```

---

#### Site B : Blog

```bash
sudo mkdir -p /var/www/site-b
sudo nano /var/www/site-b/index.html
```

**Contenu :**

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Mon Blog - Site B</title>
    <style>
        body {
            font-family: Georgia, serif;
            max-width: 700px;
            margin: 0 auto;
            padding: 20px;
            background: #f5f5f5;
            color: #333;
        }
        article {
            background: white;
            padding: 30px;
            margin: 20px 0;
            border-radius: 5px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        h1 { color: #e74c3c; }
        h2 { color: #2c3e50; }
        .date { color: #7f8c8d; font-size: 0.9em; }
    </style>
</head>
<body>
    <h1>[NOTE] Mon Blog Tech</h1>
    
    <article>
        <h2>Comment configurer Apache</h2>
        <p class="date">16 décembre 2024</p>
        <p>Aujourd'hui, j'ai appris à configurer un serveur Apache avec plusieurs Virtual Hosts. C'est plus simple que je pensais...</p>
    </article>
    
    <article>
        <h2>Introduction à Linux</h2>
        <p class="date">15 décembre 2024</p>
        <p>Linux est un système d'exploitation puissant pour les serveurs. Voici mes premiers pas...</p>
    </article>
</body>
</html>
```

**Permissions :**

```bash
sudo chown -R www-data:www-data /var/www/site-b
```

---

#### Site C : Documentation

```bash
sudo mkdir -p /var/www/site-c
sudo nano /var/www/site-c/index.html
```

**Contenu :**

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Documentation - Site C</title>
    <style>
        body {
            font-family: 'Courier New', monospace;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background: #282c34;
            color: #abb2bf;
        }
        h1 { color: #61dafb; }
        code {
            background: #1e2127;
            padding: 2px 6px;
            border-radius: 3px;
            color: #98c379;
        }
        pre {
            background: #1e2127;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
        }
    </style>
</head>
<body>
    <h1>[DOCS] Documentation Technique</h1>
    
    <h2>Installation d'Apache</h2>
    <pre><code>sudo apt update
sudo apt install apache2 -y</code></pre>
    
    <h2>Créer un Virtual Host</h2>
    <pre><code>sudo nano /etc/apache2/sites-available/mon-site.conf
sudo a2ensite mon-site.conf
sudo systemctl reload apache2</code></pre>
    
    <h2>Tester la configuration</h2>
    <pre><code>sudo apache2ctl configtest</code></pre>
</body>
</html>
```

**Permissions :**

```bash
sudo chown -R www-data:www-data /var/www/site-c
```

---

### [NOTE] Créer les fichiers de configuration Virtual Host

#### Configuration pour Site A

```bash
sudo nano /etc/apache2/sites-available/site-a.conf
```

**Contenu :**

```apache
<VirtualHost *:80>
    ServerName site-a.local
    ServerAlias www.site-a.local
    ServerAdmin admin@site-a.local
    
    DocumentRoot /var/www/site-a
    
    <Directory /var/www/site-a>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/site-a-error.log
    CustomLog ${APACHE_LOG_DIR}/site-a-access.log combined
</VirtualHost>
```

---

#### Configuration pour Site B

```bash
sudo nano /etc/apache2/sites-available/site-b.conf
```

**Contenu :**

```apache
<VirtualHost *:80>
    ServerName site-b.local
    ServerAlias www.site-b.local
    ServerAdmin admin@site-b.local
    
    DocumentRoot /var/www/site-b
    
    <Directory /var/www/site-b>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/site-b-error.log
    CustomLog ${APACHE_LOG_DIR}/site-b-access.log combined
</VirtualHost>
```

---

#### Configuration pour Site C

```bash
sudo nano /etc/apache2/sites-available/site-c.conf
```

**Contenu :**

```apache
<VirtualHost *:80>
    ServerName site-c.local
    ServerAlias www.site-c.local
    ServerAdmin admin@site-c.local
    
    DocumentRoot /var/www/site-c
    
    <Directory /var/www/site-c>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/site-c-error.log
    CustomLog ${APACHE_LOG_DIR}/site-c-access.log combined
</VirtualHost>
```

---

### [OK] Activer tous les sites

```bash
sudo a2ensite site-a.conf
sudo a2ensite site-b.conf
sudo a2ensite site-c.conf
```

**Vérifier la configuration :**

```bash
sudo apache2ctl configtest
```

**Recharger Apache :**

```bash
sudo systemctl reload apache2
```

---

### [WEB] Configurer le fichier hosts (pour les tests locaux)

**Problème :**
On n'a pas de vrais noms de domaine. Comment accéder à `site-a.local` ?

**Solution :**
Modifier le fichier `hosts` pour faire pointer les noms vers notre serveur.

---

**Sur ton PC (pas sur le serveur !) :**

**Windows :**

```
1. Ouvre Notepad en tant qu'administrateur
2. Fichier -> Ouvrir
3. Va dans : C:\Windows\System32\drivers\etc\
4. Change "Documents texte" en "Tous les fichiers"
5. Ouvre le fichier "hosts"
```

**macOS / Linux :**

```bash
sudo nano /etc/hosts
```

---

**Ajoute ces lignes (à la fin) :**

```
192.168.1.100   site-a.local    www.site-a.local
192.168.1.100   site-b.local    www.site-b.local
192.168.1.100   site-c.local    www.site-c.local
```

**[ATTENTION] Remplace `192.168.1.100` par TON IP serveur !**

**Sauvegarde.**

---

### [TEST] Tester les sites

**Ouvre ton navigateur et teste :**

**Site A :**
```
http://site-a.local
```

**Tu devrais voir le portfolio ! [PRO]**

---

**Site B :**
```
http://site-b.local
```

**Tu devrais voir le blog ! [NOTE]**

---

**Site C :**
```
http://site-c.local
```

**Tu devrais voir la documentation ! [DOCS]**

---

**[BRAVO] BRAVO ! Tu héberges maintenant 3 SITES DIFFÉRENTS sur le même serveur Apache ! [BRAVO]**

---

### [GRAPHIQUE] Vérifier les logs séparés

**Chaque site a ses propres logs.**

**Logs de Site A :**

```bash
sudo tail /var/log/apache2/site-a-access.log
```

**Logs de Site B :**

```bash
sudo tail /var/log/apache2/site-b-access.log
```

**Logs de Site C :**

```bash
sudo tail /var/log/apache2/site-c-access.log
```

**Chaque site a son fichier séparé ! Pratique pour le monitoring ! [GRAPHIQUE]**

---

(Partie 1/3 - À suivre avec SSL/HTTPS, PHP, sécurité, performance, etc.)

---

**[OBJECTIF] RÉCAPITULATIF DE CE QUE TU AS APPRIS :**

[OK] Installation d'Apache sur Ubuntu
[OK] Structure des fichiers de configuration
[OK] Commandes essentielles (`systemctl`, `a2ensite`, `a2dissite`, etc.)
[OK] Création d'un site web statique (HTML/CSS/JS)
[OK] Configuration de Virtual Hosts
[OK] Hébergement de plusieurs sites sur un même serveur
[OK] Gestion des permissions (`chown`, `chmod`)
[OK] Logs séparés par site
[OK] Fichier `hosts` pour tester en local

**[RAPIDE] PROCHAINES ÉTAPES (dans les parties suivantes) :**

- Configuration SSL/HTTPS avec Let's Encrypt
- Hébergement de sites PHP (WordPress)
- Authentification et sécurité
- Optimisation des performances
- Reverse proxy et load balancing
- Applications Python (Flask/Django)
- Applications Node.js
- Et bien plus encore !

**Continue vers la partie 2 pour maîtriser Apache comme un pro ! [TROPHEE]**

---

---

# [SECURISE] PARTIE 2 : SSL/HTTPS, MODULES, SÉCURITÉ & PHP

---

## [VERROUILLE] CONFIGURER SSL/HTTPS

### [REFLEXION] Qu'est-ce que SSL/HTTPS ?

**HTTP** = HyperText Transfer Protocol
- Communication **NON CHIFFRÉE** entre navigateur et serveur
- Les données transitent **en clair** sur le réseau
- Vulnérable aux attaques "Man in the Middle"

**HTTPS** = HTTP Secure (HTTP + SSL/TLS)
- Communication **CHIFFRÉE**
- Les données sont illisibles pour un attaquant
- Authentifie le serveur (certificat SSL)
- **Obligatoire** pour toute saisie de données sensibles (mots de passe, cartes bancaires, etc.)

**Analogie :**

HTTP = Envoyer une carte postale
- Tout le monde peut lire le message

HTTPS = Envoyer une lettre dans une enveloppe scellée
- Seul le destinataire peut lire le message

---

### [CLE] Types de certificats SSL

**1. Certificat auto-signé (Self-Signed)**
- [OK] Gratuit
- [OK] Parfait pour tester en local
- [X] Le navigateur affiche un avertissement
- [X] Non adapté pour la production

**2. Let's Encrypt (Certificat gratuit)**
- [OK] Gratuit et automatisé
- [OK] Reconnu par tous les navigateurs
- [OK] Parfait pour la production
- [ATTENTION] Nécessite un nom de domaine public
- [ATTENTION] Renouvellement tous les 90 jours (automatisable)

**3. Certificat commercial (Payant)**
- [OK] Support professionnel
- [OK] Certificats wildcard (*.exemple.com)
- [OK] Certificats EV (Extended Validation) - barre verte
- [X] Coûteux (50€ à 500€+/an)

**Pour apprendre, on va faire LES DEUX :**
1. Certificat auto-signé (test local)
2. Let's Encrypt (vrai certificat gratuit)

---

## [OUTIL] MÉTHODE 1 : Certificat Auto-Signé (Test Local)

### Étape 1 : Activer le module SSL

```bash
sudo a2enmod ssl
```

**Résultat :**

```
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
To activate the new configuration, you need to run:
  systemctl restart apache2
```

**Explication :**
- `ssl` = Module pour supporter HTTPS
- `socache_shmcb` = Cache SSL (partagé entre processus)
- `setenvif` et `mime` = Dépendances activées automatiquement

---

### Étape 2 : Créer un certificat auto-signé

```bash
sudo mkdir /etc/apache2/ssl
```

**Générer le certificat et la clé privée :**

```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/apache2/ssl/apache-selfsigned.key \
  -out /etc/apache2/ssl/apache-selfsigned.crt
```

**Explication de la commande :**

```
openssl       = Outil de gestion de certificats SSL
req           = Créer une demande de certificat
-x509         = Créer un certificat auto-signé (pas une CSR)
-nodes        = Pas de passphrase (password) pour la clé
-days 365     = Validité de 365 jours (1 an)
-newkey rsa:2048 = Créer une nouvelle clé RSA de 2048 bits
-keyout       = Fichier de sortie pour la clé privée
-out          = Fichier de sortie pour le certificat
```

---

**Tu vas être interrogé :**

```
Country Name (2 letter code) [AU]: SN
State or Province Name (full name) [Some-State]: Dakar
Locality Name (eg, city) []: Dakar
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Mon Entreprise
Organizational Unit Name (eg, section) []: IT
Common Name (e.g. server FQDN or YOUR name) []: site-a.local
Email Address []: admin@site-a.local
```

**[ATTENTION] IMPORTANT : Le "Common Name" doit correspondre au nom de domaine !**

**Exemple de remplissage :**
- Country : SN (Sénégal)
- State : Dakar
- Locality : Dakar
- Organization : MonEntreprise
- Organizational Unit : IT
- **Common Name : site-a.local** <- LE PLUS IMPORTANT
- Email : admin@site-a.local

---

**Vérifier les fichiers créés :**

```bash
ls -lh /etc/apache2/ssl/
```

**Résultat :**

```
-rw-r--r-- 1 root root 1.4K Dec 16 10:00 apache-selfsigned.crt
-rw------- 1 root root 1.7K Dec 16 10:00 apache-selfsigned.key
```

**[OK] Deux fichiers créés :**
- `.crt` = Certificat (public, peut être partagé)
- `.key` = Clé privée (SECRÈTE, ne JAMAIS partager !)

---

### Étape 3 : Configurer un Virtual Host HTTPS

**Créer la configuration :**

```bash
sudo nano /etc/apache2/sites-available/site-a-ssl.conf
```

**Contenu :**

```apache
<VirtualHost *:443>
    ServerName site-a.local
    ServerAlias www.site-a.local
    ServerAdmin admin@site-a.local
    
    DocumentRoot /var/www/site-a
    
    # ═════════════════════════════════════════════════════════
    # CONFIGURATION SSL
    # ═════════════════════════════════════════════════════════
    
    # Activer SSL pour ce Virtual Host
    SSLEngine on
    
    # Chemin vers le certificat SSL
    SSLCertificateFile /etc/apache2/ssl/apache-selfsigned.crt
    
    # Chemin vers la clé privée
    SSLCertificateKeyFile /etc/apache2/ssl/apache-selfsigned.key
    
    # ═════════════════════════════════════════════════════════
    # OPTIONS SSL MODERNES (SÉCURITÉ RENFORCÉE)
    # ═════════════════════════════════════════════════════════
    
    # Protocoles SSL/TLS autorisés
    # On désactive SSLv2, SSLv3 (vulnérables)
    # On garde TLSv1.2 et TLSv1.3 (sécurisés)
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    
    # Suites de chiffrement autorisées
    # Liste des algorithmes de chiffrement forts
    SSLCipherSuite 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
    
    # Préférer les suites de chiffrement du serveur
    SSLHonorCipherOrder on
    
    # Compression SSL désactivée (évite CRIME attack)
    SSLCompression off
    
    # ═════════════════════════════════════════════════════════
    # CONFIGURATION DU RÉPERTOIRE
    # ═════════════════════════════════════════════════════════
    
    <Directory /var/www/site-a>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # ═════════════════════════════════════════════════════════
    # LOGS
    # ═════════════════════════════════════════════════════════
    
    ErrorLog ${APACHE_LOG_DIR}/site-a-ssl-error.log
    CustomLog ${APACHE_LOG_DIR}/site-a-ssl-access.log combined
</VirtualHost>
```

---

**Explications détaillées :**

**`<VirtualHost *:443>`**
- Port 443 = Port standard pour HTTPS
- Port 80 = HTTP
- Port 443 = HTTPS

---

**`SSLEngine on`**
- Active le moteur SSL pour ce Virtual Host
- Sans cette ligne, HTTPS ne fonctionnera pas

---

**`SSLCertificateFile` et `SSLCertificateKeyFile`**
- Chemin vers le certificat et la clé privée
- **JAMAIS de clé privée accessible publiquement !**

---

**`SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1`**
- `all` = Tous les protocoles par défaut
- `-SSLv2 -SSLv3` = Désactiver SSLv2 et SSLv3 (failles POODLE, etc.)
- `-TLSv1 -TLSv1.1` = Désactiver TLS 1.0 et 1.1 (obsolètes)
- Reste : **TLSv1.2** et **TLSv1.3** (les seuls sécurisés en 2024)

**Pourquoi ?**
Les anciennes versions de SSL/TLS ont des failles de sécurité connues.

---

**`SSLCipherSuite`**
- Liste des algorithmes de chiffrement autorisés
- On utilise uniquement des algorithmes forts (AES-GCM, ChaCha20, etc.)
- Évite les algorithmes faibles (RC4, DES, 3DES, etc.)

**Explication simple :**
C'est comme choisir la qualité du cadenas pour ta porte :
- Cadenas bon marché = RC4, DES (cassables)
- Cadenas haute sécurité = AES-256, ChaCha20 (incassables avec la technologie actuelle)

---

**`SSLHonorCipherOrder on`**
- Le serveur impose l'ordre de préférence des algorithmes
- Empêche le client de choisir un algorithme faible

---

**`SSLCompression off`**
- Désactive la compression SSL
- Évite l'attaque CRIME (Compression Ratio Info-leak Made Easy)

**Analogie :**
Si tu compresses "motdepasse123" et "motdepasse124", la taille sera légèrement différente.
Un attaquant pourrait deviner le mot de passe en analysant la taille compressée.

---

### Étape 4 : Activer le site HTTPS

```bash
sudo a2ensite site-a-ssl.conf
```

**Tester la configuration :**

```bash
sudo apache2ctl configtest
```

**Recharger Apache :**

```bash
sudo systemctl reload apache2
```

---

### Étape 5 : Tester HTTPS dans le navigateur

**Ouvre :**

```
https://site-a.local
```

**[ATTENTION] Tu verras un AVERTISSEMENT de sécurité :**

```
┌──────────────────────────────────────────┐
│  [ATTENTION] Votre connexion n'est pas privée    │
│                                          │
│  Les pirates peuvent tenter de voler    │
│  vos informations...                     │
│                                          │
│  NET::ERR_CERT_AUTHORITY_INVALID         │
│                                          │
│  [Précédent] [Paramètres avancés]       │
└──────────────────────────────────────────┘
```

**C'EST NORMAL !** Le navigateur ne fait pas confiance au certificat auto-signé.

---

**Pour continuer :**

**Chrome/Edge :**
1. Clique sur "Paramètres avancés"
2. Clique sur "Continuer vers site-a.local (dangereux)"

**Firefox :**
1. Clique sur "Avancé"
2. Clique sur "Accepter le risque et poursuivre"

---

**Tu devrais voir ton site avec HTTPS ! [BRAVO]**

**Dans la barre d'adresse :**

```
[VERROUILLE] Pas sécurisé | https://site-a.local
      ^
Le cadenas est barré (certificat non reconnu)
```

**C'est normal pour un certificat auto-signé ! En production, on utilisera Let's Encrypt.**

---

### [LISTE] Rediriger HTTP vers HTTPS automatiquement

**Problème :**
Les utilisateurs peuvent toujours accéder en HTTP (http://site-a.local).

**Solution :**
Rediriger automatiquement HTTP -> HTTPS.

---

**Modifier le Virtual Host HTTP :**

```bash
sudo nano /etc/apache2/sites-available/site-a.conf
```

**Remplace TOUT le contenu par :**

```apache
<VirtualHost *:80>
    ServerName site-a.local
    ServerAlias www.site-a.local
    
    # Redirection permanente vers HTTPS
    Redirect permanent / https://site-a.local/
    
    # Alternative avec mod_rewrite (plus flexible) :
    # RewriteEngine On
    # RewriteCond %{HTTPS} off
    # RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>
```

**Recharger Apache :**

```bash
sudo systemctl reload apache2
```

---

**Maintenant, teste :**

**HTTP (port 80) :**
```
http://site-a.local
```

**-> Redirigé automatiquement vers :**

```
https://site-a.local
```

**[OK] Parfait ! [BRAVO]**

---

## [MONDE] MÉTHODE 2 : Let's Encrypt (Certificat Gratuit Reconnu)

**[ATTENTION] Prérequis pour Let's Encrypt :**
- Un **nom de domaine public** (acheté chez OVH, Gandi, Namecheap, etc.)
- Ce domaine doit **pointer vers ton serveur** (enregistrement DNS A)
- Le serveur doit être **accessible depuis Internet** (port 80 ouvert)

**Si tu n'as pas de domaine :**
- Utilise le certificat auto-signé pour apprendre
- Ou achète un domaine pas cher (.xyz = 1€/an, .ovh = 3€/an, etc.)

---

### Étape 1 : Installer Certbot

**Certbot** = Outil officiel de Let's Encrypt pour automatiser les certificats.

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

**Explication :**
- `certbot` = Client Let's Encrypt
- `python3-certbot-apache` = Plugin Apache pour Certbot
  (Configure automatiquement Apache pour toi !)

---

### Étape 2 : Obtenir un certificat SSL

**[ATTENTION] REMPLACE `exemple.com` par TON VRAI DOMAINE !**

```bash
sudo certbot --apache -d exemple.com -d www.exemple.com
```

**Explication :**
- `--apache` = Utilise le plugin Apache (configuration automatique)
- `-d exemple.com` = Domaine principal
- `-d www.exemple.com` = Sous-domaine (optionnel mais recommandé)

**Tu peux ajouter plusieurs domaines :**

```bash
sudo certbot --apache -d site1.com -d www.site1.com -d site2.com -d www.site2.com
```

---

**Certbot va te poser des questions :**

```
Enter email address (used for urgent renewal and security notices):
```

**Entre ton email :**

```
admin@exemple.com
```

---

```
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf.
You must agree in order to register with the ACME server.
(A)gree/(C)ancel:
```

**Tape `A` pour accepter.**

---

```
Would you be willing to share your email address with
the Electronic Frontier Foundation?
(Y)es/(N)o:
```

**Tape `N` (ou `Y` si tu veux recevoir des infos de l'EFF).**

---

```
Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - -
1: exemple.com
2: www.exemple.com
- - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces,
or leave input blank to select all options shown (Enter 'c' to cancel):
```

**Tape `Entrée` pour sélectionner tous les domaines.**

---

```
Please choose whether or not to redirect HTTP traffic to HTTPS:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter]:
```

**Tape `2` pour rediriger automatiquement HTTP -> HTTPS.**

---

**Certbot travaille... [HOURGLASS_WITH_FLOWING_SAND]**

```
Requesting a certificate for exemple.com and www.exemple.com
Performing the following challenges:
http-01 challenge for exemple.com
http-01 challenge for www.exemple.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/apache2/sites-available/exemple.com-le-ssl.conf
Deploying Certificate to VirtualHost /etc/apache2/sites-available/exemple.com-le-ssl.conf
Redirecting vhost in /etc/apache2/sites-available/exemple.com.conf to ssl vhost in /etc/apache2/sites-available/exemple.com-le-ssl.conf
```

---

**SUCCÈS ! [BRAVO]**

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

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
  /etc/letsencrypt/live/exemple.com/fullchain.pem
  Your key file has been saved at:
  /etc/letsencrypt/live/exemple.com/privkey.pem
  Your certificate will expire on 2025-03-16.
  To obtain a new or tweaked version of this certificate in the future,
  simply run certbot again with the "certonly" option.
  To non-interactively renew *all* of your certificates, run "certbot renew"
- Your account credentials have been saved in your Certbot
  configuration directory at /etc/letsencrypt.
  You should make a secure backup of this folder now.
```

---

### Étape 3 : Vérifier le certificat

**Ouvre ton navigateur :**

```
https://exemple.com
```

**Dans la barre d'adresse :**

```
[VERROUILLE] Connexion sécurisée | https://exemple.com
      ^
Cadenas vert (certificat reconnu !)
```

**Clique sur le cadenas -> Certificat :**

```
Émis à : exemple.com
Émis par : Let's Encrypt Authority X3
Valide du : 16/12/2024
Valide jusqu'au : 16/03/2025 (90 jours)
```

**[OK] CERTIFICAT SSL GRATUIT ET RECONNU ! [BRAVO]**

---

### [SYNC] Renouvellement automatique

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

**Certbot a configuré un renouvellement automatique.**

**Vérifier :**

```bash
sudo systemctl list-timers | grep certbot
```

**Résultat :**

```
Mon 2024-12-16 12:00:00 UTC  certbot.timer  certbot.service
```

**Un timer systemd vérifie 2 fois par jour si un certificat doit être renouvelé.**

---

**Tester le renouvellement (dry-run) :**

```bash
sudo certbot renew --dry-run
```

**Résultat attendu :**

```
Processing /etc/letsencrypt/renewal/exemple.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
...
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/exemple.com/fullchain.pem (success)
```

**[OK] Le renouvellement automatique fonctionne !**

---

**Renouveler manuellement (si besoin) :**

```bash
sudo certbot renew
```

**Apache est rechargé automatiquement après le renouvellement.**

---

## [MODULE] MODULES APACHE ESSENTIELS

### [DOCS] Qu'est-ce qu'un module Apache ?

**Module** = Extension qui ajoute des fonctionnalités à Apache.

**Analogie :**
Apache = Smartphone de base
Modules = Applications que tu installes

**Exemples :**
- `mod_ssl` = Support HTTPS
- `mod_rewrite` = Réécriture d'URL
- `mod_php` = Exécution de PHP
- `mod_proxy` = Proxy inverse
- `mod_security` = Pare-feu applicatif

**Apache a + de 300 modules disponibles !**

---

### [LISTE] Voir les modules activés

```bash
apache2ctl -M
```

**Ou :**

```bash
apachectl -M
```

**Résultat (extrait) :**

```
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 mpm_event_module (shared)
 auth_basic_module (shared)
 authz_core_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 headers_module (shared)
 mime_module (shared)
 rewrite_module (shared)
 ssl_module (shared)
 ...
```

**Décryptage :**
- `(static)` = Module compilé dans Apache (ne peut pas être désactivé)
- `(shared)` = Module dynamique (peut être activé/désactivé)

---

### [OUTIL] Activer/Désactiver des modules

**Activer un module :**

```bash
sudo a2enmod nom_module
```

**Désactiver un module :**

```bash
sudo a2dismod nom_module
```

**Après activation/désactivation :**

```bash
sudo systemctl reload apache2
```

---

### * Modules les plus utiles

#### 1⃣ **mod_rewrite** (Réécriture d'URL)

**À quoi ça sert ?**
- Transformer des URL "sales" en URL "propres"
- Faire des redirections complexes
- Créer des URL SEO-friendly

**Exemples de transformation :**

```
Avant : http://site.com/article.php?id=123
Après : http://site.com/article/123

Avant : http://site.com/produit.php?categorie=tech&nom=laptop
Après : http://site.com/tech/laptop
```

**Activer :**

```bash
sudo a2enmod rewrite
sudo systemctl reload apache2
```

**Exemple d'utilisation dans .htaccess :**

```apache
RewriteEngine On

# Rediriger article.php?id=123 vers article/123
RewriteRule ^article/([0-9]+)$ article.php?id=$1 [L]

# Forcer HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Rediriger www vers non-www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [L,R=301]
```

---

#### 2⃣ **mod_headers** (Manipulation des en-têtes HTTP)

**À quoi ça sert ?**
- Ajouter/Modifier/Supprimer des en-têtes HTTP
- Sécurité (HSTS, CSP, X-Frame-Options, etc.)
- Cache control
- CORS (Cross-Origin Resource Sharing)

**Activer :**

```bash
sudo a2enmod headers
sudo systemctl reload apache2
```

**Exemples d'utilisation :**

```apache
# Activer HSTS (forcer HTTPS pendant 1 an)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

# Protection contre le clickjacking
Header always set X-Frame-Options "SAMEORIGIN"

# Protection XSS
Header always set X-XSS-Protection "1; mode=block"

# Empêcher le sniffing MIME
Header always set X-Content-Type-Options "nosniff"

# Politique de sécurité du contenu (CSP)
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"

# Activer le cache pour les ressources statiques
<FilesMatch "\.(jpg|jpeg|png|gif|css|js|woff|woff2)$">
    Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
```

---

#### 3⃣ **mod_deflate** (Compression GZIP)

**À quoi ça sert ?**
- Compresser les réponses HTTP avant envoi
- **Réduit drastiquement** la bande passante (50-80%)
- Accélère le chargement des pages

**Exemple :**
- Fichier HTML de 100 Ko -> Compressé à 20 Ko
- Économie : 80% de bande passante !

**Activer :**

```bash
sudo a2enmod deflate
sudo systemctl reload apache2
```

**Configuration (dans un Virtual Host ou .htaccess) :**

```apache
<IfModule mod_deflate.c>
    # Compresser les types de fichiers texte
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/x-font-ttf
    AddOutputFilterByType DEFLATE application/x-font-woff
    AddOutputFilterByType DEFLATE font/opentype
    AddOutputFilterByType DEFLATE image/svg+xml
    
    # Ne PAS compresser les images déjà compressées
    # (jpg, png, gif sont déjà compressés)
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip
</IfModule>
```

**Tester la compression :**

```bash
curl -I -H "Accept-Encoding: gzip" http://site-a.local
```

**Résultat attendu :**

```
HTTP/1.1 200 OK
Content-Encoding: gzip
         ^
   Compression activée ! [OK]
```

---

#### 4⃣ **mod_expires** (Contrôle du cache)

**À quoi ça sert ?**
- Dire au navigateur combien de temps garder les fichiers en cache
- Évite de retélécharger les mêmes fichiers à chaque visite
- Améliore drastiquement les performances

**Activer :**

```bash
sudo a2enmod expires
sudo systemctl reload apache2
```

**Configuration :**

```apache
<IfModule mod_expires.c>
    ExpiresActive On
    
    # Par défaut : 1 mois
    ExpiresDefault "access plus 1 month"
    
    # Images : 1 an (changent rarement)
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"
    
    # CSS et JavaScript : 1 mois
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
    ExpiresByType text/javascript "access plus 1 month"
    
    # Polices : 1 an
    ExpiresByType font/ttf "access plus 1 year"
    ExpiresByType font/otf "access plus 1 year"
    ExpiresByType font/woff "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
    
    # HTML : 1 heure (change plus souvent)
    ExpiresByType text/html "access plus 1 hour"
</IfModule>
```

**Résultat :**

Première visite :
- Télécharge toutes les images, CSS, JS

Deuxième visite (1 heure plus tard) :
- Utilise la version en cache (chargement instantané !)

---

#### 5⃣ **mod_proxy** (Proxy inverse)

**À quoi ça sert ?**
- Faire d'Apache un proxy inverse
- Transférer les requêtes à un autre serveur (Node.js, Python, etc.)
- Load balancing entre plusieurs serveurs backend

**Activer :**

```bash
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel  # Pour WebSockets
sudo systemctl reload apache2
```

**Exemple : Proxy vers une app Node.js (port 3000) :**

```apache
<VirtualHost *:80>
    ServerName app.exemple.com
    
    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>
```

**Maintenant :**
- Requête sur `http://app.exemple.com` -> Transférée à `http://localhost:3000`
- L'utilisateur ne voit que `app.exemple.com` (le port 3000 est caché)

---

#### 6⃣ **mod_security** (Pare-feu applicatif)

**À quoi ça sert ?**
- Protection contre les attaques web (SQL injection, XSS, etc.)
- Filtre les requêtes malveillantes
- Logs détaillés des tentatives d'attaque

**Installation :**

```bash
sudo apt install libapache2-mod-security2 -y
```

**Activer :**

```bash
sudo a2enmod security2
sudo systemctl reload apache2
```

**Configuration de base :**

```bash
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
sudo nano /etc/modsecurity/modsecurity.conf
```

**Cherche et modifie :**

```apache
SecRuleEngine DetectionOnly
```

**Change en :**

```apache
SecRuleEngine On
```

**Installer les règles OWASP (protection contre les attaques courantes) :**

```bash
cd /tmp
git clone https://github.com/coreruleset/coreruleset.git
sudo mv coreruleset/crs-setup.conf.example /etc/modsecurity/crs-setup.conf
sudo mv coreruleset/rules/ /etc/modsecurity/
```

**Activer les règles :**

```bash
sudo nano /etc/apache2/mods-enabled/security2.conf
```

**Ajoute :**

```apache
IncludeOptional /etc/modsecurity/crs-setup.conf
IncludeOptional /etc/modsecurity/rules/*.conf
```

**Redémarrer Apache :**

```bash
sudo systemctl restart apache2
```

**ModSecurity bloque maintenant :**
- Injections SQL (ex: `' OR 1=1 --`)
- Scripts XSS (ex: `<script>alert('XSS')</script>`)
- Path traversal (ex: `../../etc/passwd`)
- Remote code execution
- Et bien plus !

---

## [SECURISE] SÉCURITÉ AVANCÉE

### [VERROUILLE] Cacher la version d'Apache

**Par défaut, Apache révèle sa version :**

```
Server: Apache/2.4.52 (Ubuntu)
```

**Problème :** Les attaquants peuvent cibler les failles connues de cette version.

**Solution :** Masquer la version.

```bash
sudo nano /etc/apache2/conf-available/security.conf
```

**Cherche et modifie :**

```apache
ServerTokens Full
```

**Change en :**

```apache
ServerTokens Prod
```

**Et aussi :**

```apache
ServerSignature On
```

**Change en :**

```apache
ServerSignature Off
```

**Recharger :**

```bash
sudo systemctl reload apache2
```

**Maintenant :**

```
Server: Apache
```

**Juste "Apache", sans version ! [SLEUTH_OR_SPY]**

---

### [INTERDIT] Désactiver le listing de répertoires

**Par défaut, si pas de `index.html`, Apache liste les fichiers :**

```
Index of /dossier/
- fichier1.txt
- fichier2.pdf
- secret.doc
```

**Problème :** Révèle ta structure de fichiers.

**Solution :** Désactiver `Indexes`.

**Dans ton Virtual Host :**

```apache
<Directory /var/www/mon-site>
    Options -Indexes FollowSymLinks
                 ^
           Désactive Indexes
    AllowOverride All
    Require all granted
</Directory>
```

**Ou dans `.htaccess` :**

```apache
Options -Indexes
```

**Maintenant, si pas d'index, Apache affiche :**

```
403 Forbidden
```

**[OK] Tes fichiers sont protégés !**

---

### [CLE] Protéger un répertoire par mot de passe (.htaccess)

**Créer un fichier de mots de passe :**

```bash
sudo htpasswd -c /etc/apache2/.htpasswd admin
```

**Entre le mot de passe (2 fois).**

**Explication :**
- `htpasswd` = Utilitaire pour créer des fichiers de mots de passe
- `-c` = Create (créer le fichier)
- `/etc/apache2/.htpasswd` = Fichier de stockage
- `admin` = Nom d'utilisateur

**Ajouter un autre utilisateur (sans `-c` !) :**

```bash
sudo htpasswd /etc/apache2/.htpasswd utilisateur2
```

---

**Protéger un répertoire :**

**Créer un fichier `.htaccess` dans le dossier à protéger :**

```bash
sudo nano /var/www/mon-site/admin/.htaccess
```

**Contenu :**

```apache
AuthType Basic
AuthName "Zone restreinte - Identification requise"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
```

**Explication :**
- `AuthType Basic` = Authentification basique HTTP
- `AuthName` = Message affiché dans la popup
- `AuthUserFile` = Chemin vers le fichier de mots de passe
- `Require valid-user` = N'importe quel utilisateur valide peut accéder

**Autres options de `Require` :**

```apache
Require user admin           # Seulement l'utilisateur "admin"
Require user admin bob       # admin OU bob
Require group admins         # Groupe "admins" (nécessite un fichier de groupes)
```

---

**Accède au répertoire protégé :**

```
http://site-a.local/admin/
```

**Popup d'authentification :**

```
┌──────────────────────────────────────────┐
│  Zone restreinte - Identification req... │
│                                          │
│  Nom d'utilisateur : [____________]      │
│  Mot de passe :      [____________]      │
│                                          │
│  [Annuler]  [OK]                         │
└──────────────────────────────────────────┘
```

**Entre `admin` et ton mot de passe.**

**[OK] Accès autorisé ! [BRAVO]**

---

### [WEB] Restreindre l'accès par IP

**Autoriser seulement ton réseau local :**

**Dans le Virtual Host ou .htaccess :**

```apache
<Directory /var/www/mon-site/admin>
    Require ip 192.168.1.0/24
</Directory>
```

**Explication :**
- Seules les IPs de 192.168.1.1 à 192.168.1.254 peuvent accéder
- Les autres reçoivent un `403 Forbidden`

---

**Autoriser plusieurs réseaux ou IPs :**

```apache
<Directory /var/www/mon-site/admin>
    Require ip 192.168.1.0/24
    Require ip 10.0.0.0/8
    Require ip 203.0.113.42
</Directory>
```

---

**Bloquer une IP spécifique :**

```apache
<Directory /var/www/mon-site>
    Require all granted
    Require not ip 203.0.113.66
</Directory>
```

**L'IP `203.0.113.66` est bloquée, toutes les autres passent.**

---

(À suivre avec PHP, performance, reverse proxy, etc.)

---

**[OBJECTIF] RÉCAPITULATIF PARTIE 2 :**

[OK] Configuration SSL/HTTPS (auto-signé et Let's Encrypt)
[OK] Redirection HTTP -> HTTPS
[OK] Renouvellement automatique Let's Encrypt
[OK] Modules Apache essentiels (rewrite, headers, deflate, expires, proxy, security)
[OK] Sécurité : masquer version, désactiver indexes
[OK] Protection par mot de passe (.htaccess)
[OK] Restriction d'accès par IP

**[RAPIDE] Partie 3 à venir : PHP, Performance, Reverse Proxy, Applications modernes, etc.**

---

---

# [RAPIDE] PARTIE 3 : PHP, PERFORMANCE, REVERSE PROXY & APPLICATIONS

---

## [POSTGRES] HÉBERGER DES SITES PHP

### [REFLEXION] Qu'est-ce que PHP ?

**PHP** = Hypertext Preprocessor
- Langage de programmation côté serveur
- Génère du HTML dynamiquement
- Utilisé par 77% des sites web (WordPress, Facebook, Wikipedia, etc.)

**Différence HTML vs PHP :**

**HTML (statique) :**
```html
<h1>Bienvenue</h1>
<p>Il est toujours 14h30</p>
```

**PHP (dynamique) :**
```php
<h1>Bienvenue</h1>
<p>Il est <?php echo date('H:i'); ?></p>
```

**Résultat :**
```
Bienvenue
Il est 14:32 (l'heure actuelle !)
```

---

### [PACKAGE] Installation de PHP

**Installer PHP et les extensions courantes :**

```bash
sudo apt install php libapache2-mod-php php-mysql php-curl php-gd php-mbstring php-xml php-zip -y
```

**Explication des paquets :**
- `php` = PHP de base (version 8.1 sur Ubuntu 22.04)
- `libapache2-mod-php` = Module Apache pour exécuter PHP
- `php-mysql` = Support MySQL/MariaDB
- `php-curl` = Requêtes HTTP depuis PHP
- `php-gd` = Manipulation d'images
- `php-mbstring` = Support multi-octets (UTF-8, etc.)
- `php-xml` = Parsing XML
- `php-zip` = Compression/décompression ZIP

---

**Vérifier la version de PHP :**

```bash
php -v
```

**Résultat :**

```
PHP 8.1.2-1ubuntu2.14 (cli) (built: Aug 18 2023 11:41:11) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.2-1ubuntu2.14, Copyright (c), by Zend Technologies
```

**[OK] PHP 8.1 installé !**

---

### [TEST] Tester PHP

**Créer un fichier de test :**

```bash
sudo nano /var/www/html/info.php
```

**Contenu :**

```php
<?php
phpinfo();
?>
```

**Explication :**
- `<?php ... ?>` = Délimiteurs PHP
- `phpinfo()` = Affiche toutes les infos de PHP (version, modules, config, etc.)

**Sauvegarde.**

---

**Accède dans le navigateur :**

```
http://192.168.1.100/info.php
```

**Tu devrais voir :**

```
┌────────────────────────────────────────────┐
│           PHP Version 8.1.2                │
├────────────────────────────────────────────┤
│  System        Linux ubuntu 5.15.0         │
│  Build Date    Aug 18 2023 11:41:11        │
│  Server API    Apache 2.0 Handler          │
│  Configuration /etc/php/8.1/apache2/       │
├────────────────────────────────────────────┤
│  [Modules chargés]                         │
│  [OK] curl                                   │
│  [OK] gd                                     │
│  [OK] json                                   │
│  [OK] mysqli                                 │
│  [OK] openssl                                │
│  ...                                       │
└────────────────────────────────────────────┘
```

**[BRAVO] PHP fonctionne avec Apache ! [BRAVO]**

---

**[ATTENTION] SÉCURITÉ : Supprime ce fichier après le test !**

```bash
sudo rm /var/www/html/info.php
```

**Pourquoi ?**
`phpinfo()` révèle des informations sensibles sur le serveur (chemins, versions, config).
Ne JAMAIS laisser accessible en production !

---

### [DESIGN] Exemple de site PHP dynamique

**Créons un site avec PHP :**

```bash
sudo mkdir -p /var/www/php-site
sudo nano /var/www/php-site/index.php
```

**Contenu :**

```php
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Site PHP Dynamique</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        .card {
            background: rgba(255, 255, 255, 0.1);
            padding: 30px;
            border-radius: 10px;
            margin: 20px 0;
            backdrop-filter: blur(10px);
        }
        h1 { font-size: 2.5em; text-shadow: 2px 2px 4px rgba(0,0,0,0.3); }
        .info { color: #ffd700; font-weight: bold; }
    </style>
</head>
<body>
    <h1>[POSTGRES] Site PHP Dynamique</h1>
    
    <div class="card">
        <h2>[CALENDRIER] Informations en temps réel</h2>
        <p><strong>Date :</strong> <span class="info"><?php echo date('d/m/Y'); ?></span></p>
        <p><strong>Heure :</strong> <span class="info"><?php echo date('H:i:s'); ?></span></p>
        <p><strong>Jour de la semaine :</strong> <span class="info"><?php echo date('l'); ?></span></p>
    </div>
    
    <div class="card">
        <h2>[ECRAN] Informations serveur</h2>
        <p><strong>Ton IP :</strong> <span class="info"><?php echo $_SERVER['REMOTE_ADDR']; ?></span></p>
        <p><strong>Navigateur :</strong> <span class="info"><?php echo $_SERVER['HTTP_USER_AGENT']; ?></span></p>
        <p><strong>Serveur Web :</strong> <span class="info"><?php echo $_SERVER['SERVER_SOFTWARE']; ?></span></p>
        <p><strong>Version PHP :</strong> <span class="info"><?php echo PHP_VERSION; ?></span></p>
    </div>
    
    <div class="card">
        <h2>[GAME_DIE] Nombre aléatoire</h2>
        <p>À chaque rechargement, un nouveau nombre :</p>
        <p style="font-size: 3em; text-align: center;" class="info">
            <?php echo rand(1, 100); ?>
        </p>
    </div>
    
    <div class="card">
        <h2>[NOTE] Formulaire de test</h2>
        <form method="POST">
            <label>Ton nom : </label>
            <input type="text" name="nom" style="padding: 10px; border-radius: 5px; border: none;">
            <button type="submit" style="padding: 10px 20px; background: #ffd700; border: none; border-radius: 5px; font-weight: bold; cursor: pointer;">Envoyer</button>
        </form>
        
        <?php
        if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['nom'])) {
            $nom = htmlspecialchars($_POST['nom']); // Sécurité : échapper les caractères spéciaux
            echo "<p style='margin-top: 20px; font-size: 1.3em;'>[WAVING_HAND_SIGN] Bonjour, <span class='info'>{$nom}</span> !</p>";
        }
        ?>
    </div>
</body>
</html>
```

**Permissions :**

```bash
sudo chown -R www-data:www-data /var/www/php-site
```

---

**Créer le Virtual Host :**

```bash
sudo nano /etc/apache2/sites-available/php-site.conf
```

**Contenu :**

```apache
<VirtualHost *:80>
    ServerName php.local
    ServerAdmin admin@php.local
    
    DocumentRoot /var/www/php-site
    
    <Directory /var/www/php-site>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # Configuration PHP
    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>
    
    # Fichiers d'index (ordre de priorité)
    DirectoryIndex index.php index.html
    
    ErrorLog ${APACHE_LOG_DIR}/php-site-error.log
    CustomLog ${APACHE_LOG_DIR}/php-site-access.log combined
</VirtualHost>
```

**Activer :**

```bash
sudo a2ensite php-site.conf
sudo systemctl reload apache2
```

---

**Ajouter au fichier hosts (sur ton PC) :**

```
192.168.1.100   php.local
```

**Accède à :**

```
http://php.local
```

**Tu verras :**
- Date et heure actuelles (se mettent à jour à chaque rechargement)
- Ton IP
- Infos serveur
- Nombre aléatoire
- Formulaire interactif

**[BRAVO] Site PHP dynamique fonctionnel ! [BRAVO]**

---

### [RAPIDE] PHP-FPM (PHP FastCGI Process Manager)

**mod_php vs PHP-FPM :**

| Critère | mod_php | PHP-FPM |
|---------|---------|---------|
| **Intégration** | Module Apache | Service séparé |
| **Performance** | Bonne | Meilleure (30-50% plus rapide) |
| **Gestion RAM** | Consomme plus | Optimisée |
| **Configuration** | Simple | Un peu plus complexe |
| **Multi-version PHP** | [X] Difficile | [OK] Facile |
| **Recommandé pour** | Sites simples | Sites à fort trafic |

**Pour la production, PHP-FPM est recommandé.**

---

**Installer PHP-FPM :**

```bash
sudo apt install php8.1-fpm -y
```

**Désactiver mod_php :**

```bash
sudo a2dismod php8.1
sudo a2dismod mpm_prefork
```

**Activer MPM Event (plus performant avec FPM) :**

```bash
sudo a2enmod mpm_event
```

**Activer les modules proxy pour FPM :**

```bash
sudo a2enmod proxy_fcgi setenvif
```

**Activer la configuration PHP-FPM :**

```bash
sudo a2enconf php8.1-fpm
```

**Redémarrer Apache :**

```bash
sudo systemctl restart apache2
```

---

**Modifier le Virtual Host pour utiliser FPM :**

```apache
<VirtualHost *:80>
    ServerName php.local
    DocumentRoot /var/www/php-site
    
    <Directory /var/www/php-site>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # Utiliser PHP-FPM au lieu de mod_php
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
    </FilesMatch>
    
    DirectoryIndex index.php index.html
    
    ErrorLog ${APACHE_LOG_DIR}/php-site-error.log
    CustomLog ${APACHE_LOG_DIR}/php-site-access.log combined
</VirtualHost>
```

**Recharger :**

```bash
sudo systemctl reload apache2
```

**Le site fonctionne toujours, mais utilise maintenant PHP-FPM ! [RAPIDE]**

---

## [PACKAGE] DÉPLOYER WORDPRESS

**WordPress** = CMS (Content Management System) le plus populaire au monde
- Propulse 43% de tous les sites web
- Écrit en PHP + MySQL
- Parfait pour tester Apache + PHP + MySQL

---

### Étape 1 : Installer MySQL

```bash
sudo apt install mysql-server -y
```

**Sécuriser MySQL :**

```bash
sudo mysql_secure_installation
```

**Réponds aux questions :**

```
Would you like to setup VALIDATE PASSWORD component? Y
Password validation policy: 1 (MEDIUM)
New password: [ton-mot-de-passe-fort]
Remove anonymous users? Y
Disallow root login remotely? Y
Remove test database? Y
Reload privilege tables? Y
```

---

### Étape 2 : Créer une base de données pour WordPress

```bash
sudo mysql
```

**Dans MySQL :**

```sql
CREATE DATABASE wordpress;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'MotDePasseSecurise123!';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```

**Explication :**
- `CREATE DATABASE wordpress` = Crée la base de données
- `CREATE USER` = Crée un utilisateur MySQL
- `GRANT ALL PRIVILEGES` = Donne tous les droits sur la base
- `FLUSH PRIVILEGES` = Recharge les permissions

---

### Étape 3 : Télécharger WordPress

```bash
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
sudo mv wordpress /var/www/
sudo chown -R www-data:www-data /var/www/wordpress
```

---

### Étape 4 : Configurer le Virtual Host

```bash
sudo nano /etc/apache2/sites-available/wordpress.conf
```

**Contenu :**

```apache
<VirtualHost *:80>
    ServerName wordpress.local
    ServerAdmin admin@wordpress.local
    
    DocumentRoot /var/www/wordpress
    
    <Directory /var/www/wordpress>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # PHP-FPM
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
    </FilesMatch>
    
    ErrorLog ${APACHE_LOG_DIR}/wordpress-error.log
    CustomLog ${APACHE_LOG_DIR}/wordpress-access.log combined
</VirtualHost>
```

**Activer :**

```bash
sudo a2ensite wordpress.conf
sudo systemctl reload apache2
```

---

### Étape 5 : Installer WordPress

**Ajouter au fichier hosts (ton PC) :**

```
192.168.1.100   wordpress.local
```

**Accède à :**

```
http://wordpress.local
```

**Assistant d'installation WordPress :**

1. **Langue :** Français
2. **Base de données :**
   - Nom : `wordpress`
   - Utilisateur : `wpuser`
   - Mot de passe : `MotDePasseSecurise123!`
   - Hôte : `localhost`
   - Préfixe : `wp_`
3. **Informations du site :**
   - Titre : Mon Blog WordPress
   - Identifiant : admin
   - Mot de passe : [génère un mot de passe fort]
   - Email : ton@email.com
4. **Installer WordPress**

**[BRAVO] WordPress est installé ! [BRAVO]**

**Accède au tableau de bord :**

```
http://wordpress.local/wp-admin
```

---

## [RAPIDE] OPTIMISATION DES PERFORMANCES

### [RAPIDE] MPM (Multi-Processing Modules)

**MPM** = Modules qui gèrent comment Apache traite les requêtes.

**3 MPM disponibles :**

#### 1⃣ **mpm_prefork** (Traditionnel)
- **Architecture :** 1 processus = 1 requête
- **Avantages :**
  - Compatible avec mod_php
  - Stable et prévisible
- **Inconvénients :**
  - Consomme beaucoup de RAM
  - Moins performant
- **Quand l'utiliser :**
  - Sites avec mod_php (pas PHP-FPM)
  - Compatibilité maximale

---

#### 2⃣ **mpm_worker** (Multi-threadé)
- **Architecture :** 1 processus = plusieurs threads = plusieurs requêtes
- **Avantages :**
  - Moins de RAM que prefork
  - Plus performant
- **Inconvénients :**
  - Pas compatible avec mod_php (doit utiliser PHP-FPM)
- **Quand l'utiliser :**
  - Sites PHP avec PHP-FPM
  - Serveurs avec RAM limitée

---

#### 3⃣ **mpm_event** (Moderne et recommandé)
- **Architecture :** Comme worker, mais avec gestion asynchrone des connexions Keep-Alive
- **Avantages :**
  - Le plus performant
  - Optimisé pour les connexions persistantes
  - Consommation RAM optimale
- **Inconvénients :**
  - Nécessite PHP-FPM
- **Quand l'utiliser :**
  - TOUJOURS (si PHP-FPM)
  - Production moderne

---

**Voir le MPM actuel :**

```bash
apache2ctl -V | grep MPM
```

**Résultat :**

```
Server MPM:     event
```

---

**Changer de MPM (vers mpm_event) :**

```bash
# Désactiver l'ancien MPM
sudo a2dismod mpm_prefork
sudo a2dismod mpm_worker

# Activer mpm_event
sudo a2enmod mpm_event

# Redémarrer Apache
sudo systemctl restart apache2
```

---

**Configurer mpm_event :**

```bash
sudo nano /etc/apache2/mods-available/mpm_event.conf
```

**Configuration optimisée pour un serveur avec 2 Go RAM :**

```apache
<IfModule mpm_event_module>
    # Nombre de processus serveur au démarrage
    StartServers             2
    
    # Minimum de processus idle (inactifs)
    MinSpareThreads          25
    
    # Maximum de processus idle
    MaxSpareThreads          75
    
    # Nombre de threads par processus enfant
    ThreadsPerChild          25
    
    # Limite maximale de clients simultanés
    # Calcul : ServerLimit × ThreadsPerChild
    # Ici : 16 × 25 = 400 connexions max
    ServerLimit              16
    MaxRequestWorkers        400
    
    # Nombre maximum de requêtes par processus enfant
    # Après ce nombre, le processus est recyclé (évite les fuites mémoire)
    MaxConnectionsPerChild   1000
</IfModule>
```

**Explication des paramètres :**

**StartServers**
- Nombre de processus créés au démarrage
- Plus = démarrage plus rapide, mais plus de RAM au repos

**MinSpareThreads / MaxSpareThreads**
- Threads inactifs en attente de requêtes
- Trop peu = latence si pic de trafic
- Trop = gaspillage de RAM

**ThreadsPerChild**
- Nombre de threads par processus
- Plus = moins de processus (moins de RAM)
- Moins = plus de processus (isolation accrue)

**MaxRequestWorkers** (ex-MaxClients)
- Nombre maximum de connexions simultanées
- Important ! Limite le nombre de visiteurs simultanés
- Calcul : Basé sur ta RAM disponible

**Calcul de MaxRequestWorkers :**

```
RAM disponible pour Apache = 1 Go (sur un serveur de 2 Go)
RAM par connexion ≈ 2-5 Mo (dépend du site)

MaxRequestWorkers = (RAM disponible) / (RAM par connexion)
MaxRequestWorkers = 1000 Mo / 3 Mo ≈ 333

On arrondit : ServerLimit=16, ThreadsPerChild=25 -> 400 connexions
```

**[ATTENTION] Si MaxRequestWorkers est dépassé, les clients reçoivent une erreur 503 !**

**MaxConnectionsPerChild**
- Après X requêtes, le processus est tué et recréé
- Évite les fuites mémoire (memory leaks)
- 0 = processus immortels (déconseillé)
- 1000-10000 = Bon équilibre

---

**Redémarrer Apache :**

```bash
sudo systemctl restart apache2
```

**Vérifier que ça marche :**

```bash
apache2ctl -V | grep MPM
apache2ctl -M | grep mpm
```

---

### [SAUVEGARDE] Keep-Alive (Connexions persistantes)

**Keep-Alive** = Réutiliser une connexion TCP pour plusieurs requêtes HTTP.

**Sans Keep-Alive :**
```
Client -> Serveur : Connexion TCP (3-way handshake)
Client <- Serveur : index.html
Client -> Serveur : FERMETURE
Client -> Serveur : NOUVELLE Connexion TCP
Client <- Serveur : style.css
Client -> Serveur : FERMETURE
Client -> Serveur : NOUVELLE Connexion TCP
Client <- Serveur : script.js
Client -> Serveur : FERMETURE
```

**Avec Keep-Alive :**
```
Client -> Serveur : Connexion TCP
Client <- Serveur : index.html
Client -> Serveur : style.css (MÊME connexion)
Client <- Serveur : style.css
Client -> Serveur : script.js (MÊME connexion)
Client <- Serveur : script.js
Client -> Serveur : FERMETURE (après timeout)
```

**Avantages :**
- Moins de latence (pas de handshake TCP à chaque fois)
- Moins de charge serveur
- Chargement plus rapide (30-50% dans certains cas)

---

**Configuration de Keep-Alive :**

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

**Cherche et modifie :**

```apache
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
```

**Explication :**

**KeepAlive On**
- Active les connexions persistantes

**MaxKeepAliveRequests 100**
- Nombre maximum de requêtes par connexion Keep-Alive
- 0 = illimité (déconseillé)
- 100 = Bon équilibre

**KeepAliveTimeout 5**
- Temps (en secondes) d'attente entre deux requêtes sur la même connexion
- Trop court (1s) = Connexions fermées trop vite (moins d'avantages)
- Trop long (15s) = Connexions inutilisées qui consomment de la RAM
- 5s = Bon compromis

**Recharger :**

```bash
sudo systemctl reload apache2
```

---

### [COMPRESSION] Compression avec mod_deflate

**On l'a vu dans la partie 2, mais voici une config optimisée :**

```bash
sudo nano /etc/apache2/conf-available/compression.conf
```

**Contenu :**

```apache
<IfModule mod_deflate.c>
    # Activer la compression pour ces types MIME
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
    AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript application/x-javascript text/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE font/ttf font/otf font/x-woff font/woff font/woff2
    AddOutputFilterByType DEFLATE image/svg+xml
    
    # Ne PAS compresser les images déjà compressées
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico|webp)$ no-gzip
    
    # Ne PAS compresser pour les vieux navigateurs (bugs)
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    
    # Ajouter l'en-tête Vary (pour les proxy/cache)
    Header append Vary User-Agent env=!dont-vary
</IfModule>
```

**Activer :**

```bash
sudo a2enconf compression
sudo systemctl reload apache2
```

---

### [GRAPHIQUE] Cache avec mod_cache

**mod_cache** = Met en cache les réponses HTTP pour éviter de régénérer le contenu.

**Utile pour :**
- Sites à fort trafic
- Contenu qui change peu souvent
- Réduire la charge CPU/MySQL

**Activer les modules :**

```bash
sudo a2enmod cache
sudo a2enmod cache_disk
sudo systemctl reload apache2
```

**Configuration :**

```bash
sudo nano /etc/apache2/mods-available/cache_disk.conf
```

**Contenu :**

```apache
<IfModule mod_cache_disk.c>
    # Répertoire de cache
    CacheRoot /var/cache/apache2/mod_cache_disk
    
    # Activer le cache
    CacheEnable disk /
    
    # Ne PAS mettre en cache les pages d'admin
    CacheDisable /wp-admin
    CacheDisable /admin
    
    # Taille maximale d'un fichier en cache (en octets)
    CacheMaxFileSize 1000000
    
    # Durée de vie par défaut (secondes)
    CacheDefaultExpire 3600
    
    # Durée max de cache (1 jour = 86400)
    CacheMaxExpire 86400
    
    # Ignorer les en-têtes qui disent "no-cache"
    CacheIgnoreCacheControl On
    
    # Durée minimale de cache
    CacheMinExpire 600
    
    # Gérer les requêtes HEAD
    CacheQuickHandler Off
</IfModule>
```

**Créer le répertoire de cache :**

```bash
sudo mkdir -p /var/cache/apache2/mod_cache_disk
sudo chown -R www-data:www-data /var/cache/apache2/mod_cache_disk
```

**Redémarrer Apache :**

```bash
sudo systemctl restart apache2
```

**Tester le cache :**

```bash
# Première requête (pas en cache)
curl -I http://site-a.local

# Deuxième requête (en cache)
curl -I http://site-a.local
```

**Tu devrais voir :**

```
X-Cache: MISS from localhost (première fois)
X-Cache: HIT from localhost (deuxième fois)
```

---

## [SYNC] REVERSE PROXY

### [REFLEXION] Qu'est-ce qu'un Reverse Proxy ?

**Proxy normal (Forward Proxy) :**
```
Client -> Proxy -> Internet
```

Le proxy agit pour le CLIENT.

**Reverse Proxy :**
```
Client -> Reverse Proxy -> Serveur Backend
```

Le proxy agit pour le SERVEUR.

**Analogie :**

Un reverse proxy = Réceptionniste d'un hôtel
- Le client parle à la réceptionniste
- La réceptionniste redirige vers la bonne chambre (serveur backend)
- Le client ne sait pas quelle chambre exactement

---

**Cas d'usage :**

1. **Héberger une app Node.js derrière Apache**
   - Node.js écoute sur port 3000 (localhost seulement)
   - Apache fait le proxy vers ce port
   - L'utilisateur accède via port 80/443

2. **Load Balancing**
   - Répartir le trafic entre plusieurs serveurs backend

3. **SSL Termination**
   - Apache gère SSL
   - Communication non chiffrée entre Apache et backend (plus rapide)

4. **Cache et compression**
   - Apache met en cache les réponses
   - Compresse avant d'envoyer au client

---

### [VERT] Exemple : Proxyfier une app Node.js

**Créons une app Node.js simple :**

```bash
sudo apt install nodejs npm -y
```

**Créer l'app :**

```bash
mkdir -p /home/$USER/node-app
cd /home/$USER/node-app
```

**Créer `app.js` :**

```bash
nano app.js
```

**Contenu :**

```javascript
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
  res.end(`
    <!DOCTYPE html>
    <html lang="fr">
    <head>
        <meta charset="UTF-8">
        <title>App Node.js</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                max-width: 600px;
                margin: 100px auto;
                padding: 20px;
                background: #2d3748;
                color: white;
                text-align: center;
            }
            h1 { color: #68d391; }
        </style>
    </head>
    <body>
        <h1>[VERT] Application Node.js</h1>
        <p>Cette app tourne sur le port 3000.</p>
        <p>Mais tu y accèdes via Apache (port 80) !</p>
        <p><strong>Timestamp :</strong> ${new Date().toLocaleString('fr-FR')}</p>
    </body>
    </html>
  `);
});

server.listen(3000, 'localhost', () => {
  console.log('[OK] Serveur Node.js en écoute sur http://localhost:3000');
});
```

**Lancer l'app :**

```bash
node app.js
```

**Tu verras :**

```
[OK] Serveur Node.js en écoute sur http://localhost:3000
```

**L'app tourne ! Mais seulement accessible localement (localhost).**

---

**Configurer Apache comme reverse proxy :**

```bash
sudo nano /etc/apache2/sites-available/node-app.conf
```

**Contenu :**

```apache
<VirtualHost *:80>
    ServerName node.local
    ServerAdmin admin@node.local
    
    # Activer le proxy
    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
    
    ErrorLog ${APACHE_LOG_DIR}/node-app-error.log
    CustomLog ${APACHE_LOG_DIR}/node-app-access.log combined
</VirtualHost>
```

**Explication :**

**ProxyPreserveHost On**
- Transmet l'en-tête `Host` original au backend
- Le backend voit `node.local` au lieu de `localhost:3000`

**ProxyPass / http://localhost:3000/**
- Toutes les requêtes sur `/` sont transférées vers `http://localhost:3000/`

**ProxyPassReverse / http://localhost:3000/**
- Réécrit les en-têtes de réponse (Location, etc.)
- Important pour les redirections

---

**Activer le site :**

```bash
sudo a2ensite node-app.conf
sudo systemctl reload apache2
```

**Ajouter au fichier hosts (ton PC) :**

```
192.168.1.100   node.local
```

**Accède à :**

```
http://node.local
```

**[BRAVO] Tu accèdes à l'app Node.js via Apache ! [BRAVO]**

**Port 3000 caché, tout passe par le port 80 standard.**

---

### [VERROUILLE] Ajouter HTTPS au reverse proxy

**Créer un certificat SSL pour node.local :**

```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/apache2/ssl/node.local.key \
  -out /etc/apache2/ssl/node.local.crt \
  -subj "/C=SN/ST=Dakar/L=Dakar/O=MonEntreprise/CN=node.local"
```

**Créer le Virtual Host HTTPS :**

```bash
sudo nano /etc/apache2/sites-available/node-app-ssl.conf
```

**Contenu :**

```apache
<VirtualHost *:443>
    ServerName node.local
    ServerAdmin admin@node.local
    
    # SSL
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/node.local.crt
    SSLCertificateKeyFile /etc/apache2/ssl/node.local.key
    
    # Reverse Proxy
    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
    
    # Headers de sécurité
    Header always set Strict-Transport-Security "max-age=31536000"
    
    ErrorLog ${APACHE_LOG_DIR}/node-app-ssl-error.log
    CustomLog ${APACHE_LOG_DIR}/node-app-ssl-access.log combined
</VirtualHost>
```

**Activer :**

```bash
sudo a2ensite node-app-ssl.conf
sudo systemctl reload apache2
```

**Accède à :**

```
https://node.local
```

**[OK] HTTPS vers app Node.js ! [VERROUILLE]**

---

(À suivre avec Python/Flask, .htaccess avancé, logs, monitoring, dépannage, exercices...)

---

**[OBJECTIF] RÉCAPITULATIF PARTIE 3 :**

[OK] Installation et configuration de PHP
[OK] PHP-FPM pour meilleures performances
[OK] Déploiement de WordPress complet
[OK] Optimisation : MPM Event, Keep-Alive, Compression, Cache
[OK] Reverse Proxy pour applications modernes (Node.js)
[OK] SSL sur reverse proxy

**[RAPIDE] Partie 4 à venir : Python/Flask, .htaccess avancé, Logs, Monitoring, Dépannage, Scripts d'automatisation, Exercices pratiques !**

---

---

# [COURS] PARTIE FINALE : PYTHON, HTACCESS, LOGS, MONITORING & EXERCICES

---

## [PYTHON] HÉBERGER DES APPLICATIONS PYTHON (FLASK/DJANGO)

### [REFLEXION] Python avec Apache : WSGI

**WSGI** = Web Server Gateway Interface
- Interface standard entre serveur web et applications Python
- Permet à Apache de communiquer avec Flask, Django, etc.

**Modules disponibles :**
- `mod_wsgi` = Module Apache pour WSGI
- Alternative : Gunicorn + Apache reverse proxy

**On va voir LES DEUX méthodes.**

---

### [OUTIL] MÉTHODE 1 : mod_wsgi (Intégration directe)

#### Étape 1 : Installer mod_wsgi

```bash
sudo apt install libapache2-mod-wsgi-py3 python3-pip python3-venv -y
```

**Activer le module :**

```bash
sudo a2enmod wsgi
sudo systemctl reload apache2
```

---

#### Étape 2 : Créer une application Flask

**Créer le dossier :**

```bash
sudo mkdir -p /var/www/flask-app
cd /var/www/flask-app
```

**Créer un environnement virtuel Python :**

```bash
sudo python3 -m venv venv
```

**Activer l'environnement :**

```bash
sudo venv/bin/pip install Flask
```

**Créer l'application Flask :**

```bash
sudo nano /var/www/flask-app/app.py
```

**Contenu :**

```python
from flask import Flask, request
from datetime import datetime

app = Flask(__name__)

@app.route('/')
def home():
    return f'''
    <!DOCTYPE html>
    <html lang="fr">
    <head>
        <meta charset="UTF-8">
        <title>App Flask</title>
        <style>
            body {{
                font-family: 'Segoe UI', sans-serif;
                max-width: 700px;
                margin: 50px auto;
                padding: 30px;
                background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
                color: white;
                border-radius: 15px;
                box-shadow: 0 10px 40px rgba(0,0,0,0.3);
            }}
            h1 {{ font-size: 2.5em; margin-bottom: 10px; }}
            .info {{
                background: rgba(255,255,255,0.1);
                padding: 20px;
                border-radius: 10px;
                margin: 20px 0;
            }}
            code {{
                background: rgba(0,0,0,0.3);
                padding: 2px 8px;
                border-radius: 4px;
                font-family: 'Courier New', monospace;
            }}
        </style>
    </head>
    <body>
        <h1>[PYTHON] Application Flask</h1>
        <p>Hébergée avec Apache + mod_wsgi</p>
        
        <div class="info">
            <h2>[GRAPHIQUE] Informations</h2>
            <p><strong>Date/Heure :</strong> {datetime.now().strftime('%d/%m/%Y %H:%M:%S')}</p>
            <p><strong>Ton IP :</strong> {request.remote_addr}</p>
            <p><strong>User Agent :</strong> <code>{request.headers.get('User-Agent')}</code></p>
        </div>
        
        <div class="info">
            <h2>[RAPIDE] Routes disponibles</h2>
            <ul>
                <li><a href="/" style="color: #ffd700;">/ - Accueil</a></li>
                <li><a href="/about" style="color: #ffd700;">/about - À propos</a></li>
                <li><a href="/api/data" style="color: #ffd700;">/api/data - API JSON</a></li>
            </ul>
        </div>
    </body>
    </html>
    '''

@app.route('/about')
def about():
    return '''
    <h1>À propos</h1>
    <p>Cette application Flask démontre l'intégration avec Apache via mod_wsgi.</p>
    <p><a href="/"><- Retour</a></p>
    '''

@app.route('/api/data')
def api_data():
    return {
        'status': 'success',
        'timestamp': datetime.now().isoformat(),
        'message': 'API Flask fonctionnelle !',
        'data': {
            'version': '1.0',
            'server': 'Apache + mod_wsgi'
        }
    }

if __name__ == '__main__':
    app.run(debug=True)
```

---

#### Étape 3 : Créer le fichier WSGI

```bash
sudo nano /var/www/flask-app/app.wsgi
```

**Contenu :**

```python
#!/usr/bin/python3
import sys
import site

# Ajouter le répertoire de l'environnement virtuel
site.addsitedir('/var/www/flask-app/venv/lib/python3.10/site-packages')

# Ajouter le répertoire de l'application
sys.path.insert(0, '/var/www/flask-app')

# Importer l'application Flask
from app import app as application
```

**[ATTENTION] Vérifie le chemin Python (peut être python3.10, python3.11, etc.) :**

```bash
ls /var/www/flask-app/venv/lib/
```

---

#### Étape 4 : Permissions

```bash
sudo chown -R www-data:www-data /var/www/flask-app
sudo chmod -R 755 /var/www/flask-app
```

---

#### Étape 5 : Configuration Apache

```bash
sudo nano /etc/apache2/sites-available/flask-app.conf
```

**Contenu :**

```apache
<VirtualHost *:80>
    ServerName flask.local
    ServerAdmin admin@flask.local
    
    # Fichier WSGI
    WSGIDaemonProcess flask-app python-home=/var/www/flask-app/venv python-path=/var/www/flask-app
    WSGIProcessGroup flask-app
    WSGIScriptAlias / /var/www/flask-app/app.wsgi
    
    # Permissions
    <Directory /var/www/flask-app>
        WSGIProcessGroup flask-app
        WSGIApplicationGroup %{GLOBAL}
        Require all granted
    </Directory>
    
    # Logs
    ErrorLog ${APACHE_LOG_DIR}/flask-app-error.log
    CustomLog ${APACHE_LOG_DIR}/flask-app-access.log combined
</VirtualHost>
```

**Explication :**

**WSGIDaemonProcess flask-app**
- Crée un processus daemon dédié à l'app
- `python-home` = Environnement virtuel
- `python-path` = Répertoire de l'app

**WSGIProcessGroup flask-app**
- Groupe de processus

**WSGIScriptAlias / /var/www/flask-app/app.wsgi**
- Point d'entrée de l'application

---

**Activer :**

```bash
sudo a2ensite flask-app.conf
sudo systemctl reload apache2
```

**Ajouter au fichier hosts (ton PC) :**

```
192.168.1.100   flask.local
```

**Accède à :**

```
http://flask.local
```

**[BRAVO] Application Flask hébergée avec Apache ! [BRAVO]**

---

### [RAPIDE] MÉTHODE 2 : Gunicorn + Reverse Proxy (Recommandé pour production)

**Avantages :**
- Plus performant
- Meilleure gestion des processus
- Plus facile à déployer et redémarrer

---

#### Étape 1 : Installer Gunicorn

```bash
sudo /var/www/flask-app/venv/bin/pip install gunicorn
```

---

#### Étape 2 : Créer un service systemd

```bash
sudo nano /etc/systemd/system/flask-app.service
```

**Contenu :**

```ini
[Unit]
Description=Flask App with Gunicorn
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/flask-app
Environment="PATH=/var/www/flask-app/venv/bin"
ExecStart=/var/www/flask-app/venv/bin/gunicorn --workers 3 --bind localhost:8000 app:app

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

**Explication :**

**--workers 3**
- Nombre de processus workers
- Formule recommandée : (2 × CPU_cores) + 1
- Pour 1 CPU : 3 workers

**--bind localhost:8000**
- Écoute sur localhost, port 8000
- Pas accessible de l'extérieur (sécurité)

---

**Activer et démarrer le service :**

```bash
sudo systemctl daemon-reload
sudo systemctl start flask-app
sudo systemctl enable flask-app
```

**Vérifier :**

```bash
sudo systemctl status flask-app
```

**Résultat attendu :**

```
[BLACK_CIRCLE] flask-app.service - Flask App with Gunicorn
     Active: active (running) since ...
```

---

#### Étape 3 : Configuration Apache reverse proxy

```bash
sudo nano /etc/apache2/sites-available/flask-gunicorn.conf
```

**Contenu :**

```apache
<VirtualHost *:80>
    ServerName flask.local
    ServerAdmin admin@flask.local
    
    # Reverse Proxy vers Gunicorn
    ProxyPreserveHost On
    ProxyPass / http://localhost:8000/
    ProxyPassReverse / http://localhost:8000/
    
    # Headers
    RequestHeader set X-Forwarded-Proto "http"
    RequestHeader set X-Forwarded-Port "80"
    
    ErrorLog ${APACHE_LOG_DIR}/flask-gunicorn-error.log
    CustomLog ${APACHE_LOG_DIR}/flask-gunicorn-access.log combined
</VirtualHost>
```

**Désactiver l'ancien site et activer le nouveau :**

```bash
sudo a2dissite flask-app.conf
sudo a2ensite flask-gunicorn.conf
sudo systemctl reload apache2
```

**Accède à :**

```
http://flask.local
```

**[OK] Flask via Gunicorn derrière Apache ! Plus performant ! [RAPIDE]**

---

**Redémarrer l'app Flask (après modifications) :**

```bash
sudo systemctl restart flask-app
```

**Pas besoin de recharger Apache !**

---

## [FICHIER] .HTACCESS AVANCÉ

### [REFLEXION] Qu'est-ce que .htaccess ?

**.htaccess** = Fichier de configuration Apache par répertoire
- Placé dans un dossier web
- Modifie la configuration Apache pour CE dossier (et sous-dossiers)
- Pas besoin de recharger Apache
- Pratique mais impact performance (désactiver en prod si possible)

---

### [OK] Activer .htaccess

**Dans le Virtual Host, vérifie :**

```apache
<Directory /var/www/mon-site>
    AllowOverride All
</Directory>
```

**`AllowOverride All`** = .htaccess autorisé

**Autres valeurs :**
- `AllowOverride None` = .htaccess ignoré (meilleure performance)
- `AllowOverride Limit` = Seulement les directives d'accès
- `AllowOverride FileInfo` = Seulement les directives de fichiers

---

### [MELANGE] Redirections

**Créer un fichier `.htaccess` :**

```bash
sudo nano /var/www/mon-site/.htaccess
```

---

#### Redirection simple

```apache
# Rediriger ancienne-page.html vers nouvelle-page.html
Redirect 301 /ancienne-page.html /nouvelle-page.html
```

**`301`** = Redirection permanente (SEO-friendly)
**`302`** = Redirection temporaire

---

#### Redirection vers un autre domaine

```apache
# Rediriger tout le trafic vers un nouveau domaine
Redirect 301 / https://nouveau-site.com/
```

---

#### Redirection avec mod_rewrite (plus flexible)

```apache
RewriteEngine On

# Forcer HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Forcer www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Supprimer www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [L,R=301]

# Rediriger les anciennes URLs
RewriteRule ^old-blog/(.*)$ /blog/$1 [R=301,L]

# URLs propres (ex: blog/article-123 -> blog.php?id=123)
RewriteRule ^blog/([0-9]+)$ /blog.php?id=$1 [L]
RewriteRule ^blog/([a-zA-Z0-9-]+)$ /blog.php?slug=$1 [L]
```

**Explication des flags :**
- `[L]` = Last (dernière règle, arrêter le traitement)
- `[R=301]` = Redirection permanente
- `[NC]` = No Case (insensible à la casse)
- `[QSA]` = Query String Append (conserver les paramètres GET)

---

### [VERROUILLE] Protection et sécurité

#### Protéger le fichier .htaccess lui-même

```apache
# Empêcher l'accès au fichier .htaccess
<Files .htaccess>
    Require all denied
</Files>

# Protéger d'autres fichiers sensibles
<FilesMatch "^\.">
    Require all denied
</FilesMatch>
```

---

#### Désactiver le listing de répertoires

```apache
Options -Indexes
```

---

#### Bloquer l'accès à certains fichiers

```apache
# Bloquer l'accès aux fichiers de config
<FilesMatch "\.(env|conf|config|ini|log|sql|bak)$">
    Require all denied
</FilesMatch>

# Bloquer les fichiers de sauvegarde
<FilesMatch "\~$">
    Require all denied
</FilesMatch>
```

---

#### Limitation d'accès par IP

```apache
# Autoriser seulement ton IP
Require ip 192.168.1.50

# Autoriser un réseau
Require ip 192.168.1.0/24

# Bloquer une IP spécifique
Require all granted
Require not ip 203.0.113.66
```

---

#### Authentification basique

```apache
AuthType Basic
AuthName "Zone protégée"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
```

---

### [RAPIDE] Performance et cache

#### Activer la compression

```apache
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/json
</IfModule>
```

---

#### Contrôle du cache

```apache
<IfModule mod_expires.c>
    ExpiresActive On
    
    # Images - 1 an
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    
    # CSS et JS - 1 mois
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
    
    # HTML - 1 heure
    ExpiresByType text/html "access plus 1 hour"
</IfModule>

# Headers de cache alternatifs
<FilesMatch "\.(jpg|jpeg|png|gif|css|js)$">
    Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
```

---

### [SECURITE] Headers de sécurité

```apache
<IfModule mod_headers.c>
    # HSTS (force HTTPS pendant 1 an)
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    
    # Empêcher le clickjacking
    Header always set X-Frame-Options "SAMEORIGIN"
    
    # Bloquer le sniffing MIME
    Header always set X-Content-Type-Options "nosniff"
    
    # Protection XSS
    Header always set X-XSS-Protection "1; mode=block"
    
    # Content Security Policy
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
    
    # Referrer Policy
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    
    # Permissions Policy
    Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>
```

---

### [INTERDIT] Bloquer les bots et scrapers

```apache
RewriteEngine On

# Bloquer les mauvais bots par User-Agent
RewriteCond %{HTTP_USER_AGENT} (badbot|scrapy|curl|wget) [NC]
RewriteRule .* - [F,L]

# Bloquer le hotlinking (vol de bande passante)
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?mon-site\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [F,L]
```

---

## [GRAPHIQUE] LOGS ET MONITORING

### [LISTE] Types de logs Apache

**1. Access Log** (access.log)
- Journal de toutes les requêtes HTTP
- Format standard : Combined Log Format

**2. Error Log** (error.log)
- Erreurs PHP, Apache, 404, 500, etc.
- Niveau de verbosité configurable

---

### [RECHERCHE] Lire les logs

**Access log :**

```bash
sudo tail -f /var/log/apache2/access.log
```

**Exemple de ligne :**

```
192.168.1.50 - - [16/Dec/2024:14:30:45 +0000] "GET /index.html HTTP/1.1" 200 3521 "https://google.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
```

**Décryptage :**
```
192.168.1.50        -> IP du client
-                   -> Identité du client (rarement utilisé)
-                   -> User ID (si authentification)
[16/Dec/2024:...]   -> Date et heure
"GET /index.html..."-> Méthode HTTP et URL
200                 -> Code de statut HTTP
3521                -> Taille de la réponse (octets)
"https://google..." -> Referer (d'où vient le client)
"Mozilla/5.0..."    -> User-Agent (navigateur)
```

---

**Error log :**

```bash
sudo tail -f /var/log/apache2/error.log
```

**Exemple :**

```
[Tue Dec 16 14:30:45.123456 2024] [core:error] [pid 1234] [client 192.168.1.50:52341] AH00128: File does not exist: /var/www/html/favicon.ico
```

**Décryptage :**
```
[Tue Dec 16 ...]    -> Timestamp
[core:error]        -> Module et niveau de log
[pid 1234]          -> ID du processus
[client ...]        -> IP et port du client
AH00128             -> Code d'erreur Apache
File does not...    -> Message d'erreur
```

---

### [HAUSSE] Analyser les logs

**Nombre de requêtes par IP :**

```bash
sudo awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -10
```

**Résultat :**

```
    152 192.168.1.50
     87 192.168.1.51
     43 192.168.1.52
     ...
```

---

**Pages les plus visitées :**

```bash
sudo awk '{print $7}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -10
```

---

**Codes de statut HTTP :**

```bash
sudo awk '{print $9}' /var/log/apache2/access.log | sort | uniq -c | sort -nr
```

**Résultat :**

```
   1523 200
    342 304
     87 404
     12 500
      3 301
```

---

**Erreurs 404 (pages non trouvées) :**

```bash
sudo grep ' 404 ' /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -10
```

---

**Trafic par jour :**

```bash
sudo awk '{print $4}' /var/log/apache2/access.log | cut -d: -f1 | sort | uniq -c
```

**Résultat :**

```
   1234 [15/Dec/2024
   2341 [16/Dec/2024
   1987 [17/Dec/2024
```

---

### [SYNC] Rotation des logs

**Logs Apache peuvent devenir ÉNORMES (plusieurs Go).**

**Solution : logrotate**

**Configuration :**

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

**Contenu (déjà présent, mais voici une config optimisée) :**

```
/var/log/apache2/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 640 root adm
    sharedscripts
    postrotate
        if systemctl is-active apache2 > /dev/null; then
            systemctl reload apache2 > /dev/null
        fi
    endscript
}
```

**Explication :**

**daily**
- Rotation quotidienne
- Alternatives : weekly, monthly

**rotate 14**
- Conserver 14 anciennes versions
- Après 14 jours, suppression automatique

**compress**
- Compresser les vieux logs (gzip)
- Économise beaucoup d'espace disque

**delaycompress**
- Ne compresse pas le fichier le plus récent
- Utile si des processus lisent encore le log

**postrotate**
- Commande à exécuter après rotation
- Ici : recharger Apache pour qu'il utilise le nouveau fichier

---

**Tester la rotation :**

```bash
sudo logrotate -f /etc/logrotate.d/apache2
```

**Vérifier :**

```bash
ls -lh /var/log/apache2/
```

**Résultat :**

```
-rw-r----- 1 root adm  2.1M Dec 16 14:30 access.log
-rw-r----- 1 root adm  1.8M Dec 15 23:59 access.log.1
-rw-r----- 1 root adm  512K Dec 14 23:59 access.log.2.gz
...
```

---

### [GRAPHIQUE] Monitoring en temps réel avec GoAccess

**GoAccess** = Analyseur de logs en temps réel avec interface web.

**Installation :**

```bash
sudo apt install goaccess -y
```

**Analyser les logs en terminal :**

```bash
sudo goaccess /var/log/apache2/access.log
```

**Interface interactive dans le terminal avec :**
- Visiteurs uniques
- Requêtes par seconde
- Pages les plus visitées
- Codes de statut
- OS et navigateurs
- Etc.

---

**Générer un rapport HTML :**

```bash
sudo goaccess /var/log/apache2/access.log -o /var/www/html/report.html --log-format=COMBINED
```

**Accède à :**

```
http://192.168.1.100/report.html
```

**Rapport HTML magnifique avec graphiques ! [GRAPHIQUE]**

---

**Monitoring en temps réel (dashboard live) :**

```bash
sudo goaccess /var/log/apache2/access.log -o /var/www/html/report.html --log-format=COMBINED --real-time-html --daemonize
```

**Maintenant, le rapport se met à jour automatiquement ! [RAPIDE]**

---

## [OUTILS] DÉPANNAGE AVANCÉ

### [ROUGE] Erreurs courantes et solutions

#### Erreur 1 : 403 Forbidden

**Symptôme :**

```
Forbidden
You don't have permission to access this resource.
```

**Causes possibles :**

**1. Permissions fichiers incorrectes**

```bash
# Vérifier les permissions
ls -la /var/www/mon-site/

# Corriger
sudo chown -R www-data:www-data /var/www/mon-site
sudo chmod -R 755 /var/www/mon-site
```

---

**2. Configuration Apache restrictive**

**Dans le Virtual Host, vérifie :**

```apache
<Directory /var/www/mon-site>
    Require all granted  <- Autoriser l'accès
</Directory>
```

**Pas :**

```apache
Require all denied  <- Bloquer l'accès (erreur 403)
```

---

**3. Pas de fichier index**

**Créer un index.html ou configurer DirectoryIndex :**

```apache
DirectoryIndex index.php index.html
```

---

**4. Options -Indexes avec pas d'index**

**Si `.htaccess` contient :**

```apache
Options -Indexes
```

**Et pas de `index.html`, erreur 403.**

**Solution :**
- Ajouter un `index.html`
- Ou supprimer `Options -Indexes`

---

#### Erreur 2 : 404 Not Found

**Symptôme :**

```
Not Found
The requested URL was not found on this server.
```

**Causes possibles :**

**1. Fichier n'existe pas**

**Vérifier :**

```bash
ls -la /var/www/mon-site/la-page.html
```

**Si absent, le créer ou corriger le lien.**

---

**2. DocumentRoot incorrect**

**Dans le Virtual Host :**

```apache
DocumentRoot /var/www/mon-site
```

**Vérifier que le chemin est correct.**

---

**3. Règle mod_rewrite incorrecte**

**Désactiver temporairement mod_rewrite pour tester :**

```bash
sudo a2dismod rewrite
sudo systemctl reload apache2
```

**Si ça marche, le problème vient d'une règle RewriteRule.**

---

#### Erreur 3 : 500 Internal Server Error

**Symptôme :**

```
Internal Server Error
The server encountered an internal error and was unable to complete your request.
```

**C'est l'erreur la plus frustrante ! Plein de causes possibles.**

**Étape 1 : Consulter les logs**

```bash
sudo tail -50 /var/log/apache2/error.log
```

**Le message d'erreur révèlera la cause.**

---

**Causes courantes :**

**1. Erreur de syntaxe dans .htaccess**

**Tester en renommant temporairement :**

```bash
sudo mv /var/www/mon-site/.htaccess /var/www/mon-site/.htaccess.bak
```

**Recharger la page. Si ça marche, l'erreur est dans .htaccess.**

**Vérifier la syntaxe ligne par ligne.**

---

**2. Permissions incorrectes**

**Les scripts PHP/CGI doivent être exécutables :**

```bash
sudo chmod 755 /var/www/mon-site/script.php
```

---

**3. Limite de mémoire PHP dépassée**

**Dans les logs, tu verras :**

```
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted
```

**Solution : Augmenter la limite mémoire :**

```bash
sudo nano /etc/php/8.1/apache2/php.ini
```

**Modifier :**

```ini
memory_limit = 256M
```

**Redémarrer :**

```bash
sudo systemctl restart apache2
```

---

**4. Erreur de syntaxe PHP**

**Dans les logs :**

```
PHP Parse error: syntax error, unexpected '}' in /var/www/mon-site/index.php on line 42
```

**Corriger la ligne 42 du fichier PHP.**

---

#### Erreur 4 : 502 Bad Gateway (Reverse Proxy)

**Symptôme :**

```
Bad Gateway
The proxy server received an invalid response from an upstream server.
```

**Causes :**

**1. L'application backend ne tourne pas**

**Vérifier :**

```bash
sudo systemctl status flask-app
```

**Si inactif, démarrer :**

```bash
sudo systemctl start flask-app
```

---

**2. Mauvais port dans ProxyPass**

**Vérifier dans le Virtual Host :**

```apache
ProxyPass / http://localhost:3000/
```

**Le backend écoute bien sur le port 3000 ?**

```bash
sudo netstat -tulpn | grep 3000
```

---

**3. Timeout trop court**

**Ajouter dans le Virtual Host :**

```apache
ProxyTimeout 300
```

---

#### Erreur 5 : Apache ne démarre pas

**Symptôme :**

```bash
sudo systemctl start apache2
# Job for apache2.service failed...
```

**Étape 1 : Lire les logs systemd**

```bash
sudo journalctl -xeu apache2
```

---

**Causes courantes :**

**1. Erreur de syntaxe dans la config**

**Tester la syntaxe :**

```bash
sudo apache2ctl configtest
```

**Résultat si erreur :**

```
AH00526: Syntax error on line 15 of /etc/apache2/sites-enabled/mon-site.conf:
Invalid command 'InvalidDirective'
```

**Corriger la ligne 15.**

---

**2. Port déjà utilisé**

**Vérifier :**

```bash
sudo netstat -tulpn | grep :80
```

**Si un autre processus utilise le port 80 :**

```bash
sudo systemctl stop nginx  # ou autre serveur web
sudo systemctl start apache2
```

---

**3. Module manquant**

**Dans les logs :**

```
Invalid command 'SSLEngine', perhaps misspelled or defined by a module not included...
```

**Activer le module SSL :**

```bash
sudo a2enmod ssl
sudo systemctl start apache2
```

---

### [OUTIL] Outils de diagnostic

**1. apache2ctl**

```bash
# Tester la syntaxe
sudo apache2ctl configtest

# Lister les modules chargés
sudo apache2ctl -M

# Lister les Virtual Hosts
sudo apache2ctl -S

# Version et options de compilation
sudo apache2ctl -V
```

---

**2. curl (tester les requêtes HTTP)**

```bash
# Requête simple
curl http://site-a.local

# Voir les headers
curl -I http://site-a.local

# Suivre les redirections
curl -L http://site-a.local

# Tester HTTPS
curl -k https://site-a.local  # -k = ignore certificat invalide

# Tester avec un User-Agent spécifique
curl -A "Mozilla/5.0" http://site-a.local
```

---

**3. ab (Apache Bench) - Test de charge**

```bash
# 1000 requêtes, 10 concurrentes
ab -n 1000 -c 10 http://site-a.local/

# Résultat : requêtes/seconde, temps de réponse, etc.
```

**Exemple de résultat :**

```
Requests per second:    523.45 [#/sec] (mean)
Time per request:       19.103 [ms] (mean)
Transfer rate:          1245.78 [Kbytes/sec] received
```

---

**4. htop (Monitoring processus)**

```bash
sudo apt install htop -y
htop
```

**Filtre pour voir seulement Apache :**

Appuie sur `F4`, tape `apache2`, `Entrée`.

**Tu verras :**
- % CPU par processus Apache
- % RAM utilisée
- Nombre de processus

---

## [BOT] SCRIPTS D'AUTOMATISATION

### [GRAPHIQUE] Script de monitoring

**Créer un script de surveillance :**

```bash
sudo nano /usr/local/bin/apache-monitor.sh
```

**Contenu :**

```bash
#!/bin/bash
# ═══════════════════════════════════════════════════════════════
# SCRIPT DE MONITORING APACHE
# ═══════════════════════════════════════════════════════════════

echo "═════════════════════════════════════════════════════════"
echo "  MONITORING APACHE - $(date)"
echo "═════════════════════════════════════════════════════════"
echo ""

# ─────────────────────────────────────────────────────────────
# 1. ÉTAT DU SERVICE
# ─────────────────────────────────────────────────────────────

if systemctl is-active --quiet apache2; then
    echo "[OK] Apache : ACTIF"
else
    echo "[X] Apache : INACTIF"
    echo "[ATTENTION]  Tentative de redémarrage..."
    sudo systemctl start apache2
    if systemctl is-active --quiet apache2; then
        echo "[OK] Redémarrage réussi"
    else
        echo "[X] Échec du redémarrage - Vérifier les logs"
        exit 1
    fi
fi

echo ""

# ─────────────────────────────────────────────────────────────
# 2. UTILISATION DES RESSOURCES
# ─────────────────────────────────────────────────────────────

echo "[GRAPHIQUE] RESSOURCES"
echo "─────────────────────────────────────────────────────────"

# Nombre de processus Apache
PROCESSES=$(ps aux | grep -c [a]pache2)
echo "Processus Apache : $PROCESSES"

# Utilisation RAM
MEMORY=$(ps aux | grep [a]pache2 | awk '{sum+=$6} END {print sum/1024 " Mo"}')
echo "RAM utilisée : $MEMORY"

# Utilisation CPU
CPU=$(ps aux | grep [a]pache2 | awk '{sum+=$3} END {print sum "%"}')
echo "CPU utilisée : $CPU"

echo ""

# ─────────────────────────────────────────────────────────────
# 3. STATISTIQUES DE TRAFIC
# ─────────────────────────────────────────────────────────────

echo "[HAUSSE] TRAFIC (dernières 24h)"
echo "─────────────────────────────────────────────────────────"

ACCESS_LOG="/var/log/apache2/access.log"

# Nombre total de requêtes
TOTAL_REQUESTS=$(wc -l < "$ACCESS_LOG")
echo "Total requêtes : $TOTAL_REQUESTS"

# Requêtes par code de statut
echo ""
echo "Codes de statut :"
awk '{print $9}' "$ACCESS_LOG" | sort | uniq -c | sort -rn | head -5 | while read count code; do
    echo "  $code : $count"
done

# Top 5 IPs
echo ""
echo "Top 5 IPs :"
awk '{print $1}' "$ACCESS_LOG" | sort | uniq -c | sort -rn | head -5 | while read count ip; do
    echo "  $ip : $count requêtes"
done

# Top 5 pages
echo ""
echo "Top 5 pages :"
awk '{print $7}' "$ACCESS_LOG" | sort | uniq -c | sort -rn | head -5 | while read count page; do
    echo "  $page : $count vues"
done

echo ""

# ─────────────────────────────────────────────────────────────
# 4. ERREURS RÉCENTES
# ─────────────────────────────────────────────────────────────

echo "[ROUGE] ERREURS RÉCENTES (10 dernières)"
echo "─────────────────────────────────────────────────────────"

ERROR_LOG="/var/log/apache2/error.log"
tail -10 "$ERROR_LOG" | while read line; do
    echo "  $line"
done

echo ""

# ─────────────────────────────────────────────────────────────
# 5. ESPACE DISQUE
# ─────────────────────────────────────────────────────────────

echo "[SAUVEGARDE] ESPACE DISQUE"
echo "─────────────────────────────────────────────────────────"

DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
echo "Utilisation disque : $DISK_USAGE%"

if [ "$DISK_USAGE" -gt 90 ]; then
    echo "[ATTENTION]  ALERTE : Disque presque plein !"
fi

echo ""

# ─────────────────────────────────────────────────────────────
# 6. TAILLE DES LOGS
# ─────────────────────────────────────────────────────────────

echo "[DOSSIER] TAILLE DES LOGS"
echo "─────────────────────────────────────────────────────────"

LOGS_SIZE=$(du -sh /var/log/apache2/ | awk '{print $1}')
echo "Logs Apache : $LOGS_SIZE"

echo ""
echo "═════════════════════════════════════════════════════════"
```

**Rendre exécutable :**

```bash
sudo chmod +x /usr/local/bin/apache-monitor.sh
```

**Exécuter :**

```bash
sudo /usr/local/bin/apache-monitor.sh
```

**Résultat (exemple) :**

```
═════════════════════════════════════════════════════════
  MONITORING APACHE - Mon 16 Dec 2024 14:30:00 UTC
═════════════════════════════════════════════════════════

[OK] Apache : ACTIF

[GRAPHIQUE] RESSOURCES
─────────────────────────────────────────────────────────
Processus Apache : 6
RAM utilisée : 45.3 Mo
CPU utilisée : 2.1%

[HAUSSE] TRAFIC (dernières 24h)
─────────────────────────────────────────────────────────
Total requêtes : 3542

Codes de statut :
  200 : 3245
  304 : 187
  404 : 95
  301 : 12
  500 : 3

Top 5 IPs :
  192.168.1.50 : 1245 requêtes
  192.168.1.51 : 687 requêtes
  192.168.1.52 : 432 requêtes
  ...

Top 5 pages :
  / : 1234 vues
  /about : 456 vues
  /contact : 234 vues
  ...

[ROUGE] ERREURS RÉCENTES (10 dernières)
─────────────────────────────────────────────────────────
  [error] File does not exist: /var/www/html/favicon.ico
  ...

[SAUVEGARDE] ESPACE DISQUE
─────────────────────────────────────────────────────────
Utilisation disque : 45%

[DOSSIER] TAILLE DES LOGS
─────────────────────────────────────────────────────────
Logs Apache : 234M

═════════════════════════════════════════════════════════
```

---

**Automatiser avec cron (tous les jours à 6h du matin) :**

```bash
sudo crontab -e
```

**Ajouter :**

```bash
0 6 * * * /usr/local/bin/apache-monitor.sh > /var/log/apache-monitor.log 2>&1
```

---

## [COURS] EXERCICES PRATIQUES

### Exercice 1 : Site multi-pages avec navigation *

**Objectif :** Créer un site statique de 5 pages avec menu.

**Mission :**
1. Créer 5 pages HTML (accueil, à propos, services, portfolio, contact)
2. Ajouter un menu de navigation sur toutes les pages
3. Utiliser CSS pour le style
4. Héberger avec Apache

**Bonus :**
- Ajouter des images
- Formulaire de contact fonctionnel (avec PHP ou JavaScript)

---

### Exercice 2 : HTTPS avec Let's Encrypt **

**Objectif :** Sécuriser un site avec un vrai certificat SSL.

**Prérequis :** Avoir un nom de domaine.

**Mission :**
1. Acheter un nom de domaine pas cher (.xyz, .ovh, etc.)
2. Faire pointer le domaine vers ton serveur
3. Installer Certbot
4. Obtenir un certificat Let's Encrypt
5. Configurer la redirection HTTP -> HTTPS

---

### Exercice 3 : Héberger WordPress avec SSL ***

**Objectif :** Site WordPress complet en HTTPS.

**Mission :**
1. Installer MySQL
2. Créer une base de données
3. Télécharger et installer WordPress
4. Configurer Apache (Virtual Host)
5. Installer un thème et des plugins
6. Sécuriser avec SSL (Let's Encrypt)
7. Optimiser les performances (cache, compression)

---

### Exercice 4 : Reverse Proxy avec Load Balancing ****

**Objectif :** Répartir le trafic entre plusieurs backends.

**Mission :**
1. Créer 3 instances d'une app simple (Node.js ou Python) sur ports 3000, 3001, 3002
2. Configurer Apache en reverse proxy avec mod_proxy_balancer
3. Répartir le trafic entre les 3 instances
4. Tester que le load balancing fonctionne
5. Simuler la panne d'un backend et vérifier le failover

---

### Exercice 5 : Monitoring et alertes automatiques *****

**Objectif :** Système de surveillance complet avec alertes.

**Mission :**
1. Installer GoAccess pour monitoring temps réel
2. Créer un script de surveillance qui vérifie :
   - État d'Apache
   - Utilisation CPU/RAM
   - Espace disque
   - Erreurs 500 dans les logs
3. Configurer des alertes email si :
   - Apache tombe
   - Disque > 90%
   - Plus de 10 erreurs 500 en 5 minutes
4. Automatiser avec cron (vérification toutes les 5 minutes)
5. Créer un dashboard HTML avec statistiques

---

## [BRAVO] FÉLICITATIONS !

### [TROPHEE] Ce que tu maîtrises maintenant

**Configuration de base :**
- [OK] Installation d'Apache
- [OK] Structure des fichiers de configuration
- [OK] Virtual Hosts
- [OK] Gestion des modules

**Langages et applications :**
- [OK] Sites statiques (HTML/CSS/JS)
- [OK] PHP (mod_php et PHP-FPM)
- [OK] WordPress
- [OK] Python (Flask/Django avec mod_wsgi et Gunicorn)
- [OK] Node.js (reverse proxy)

**Sécurité :**
- [OK] SSL/HTTPS (auto-signé et Let's Encrypt)
- [OK] Authentification (.htaccess)
- [OK] Restrictions d'accès (IP, user-agent)
- [OK] Headers de sécurité (HSTS, CSP, etc.)
- [OK] ModSecurity (pare-feu applicatif)

**Performance :**
- [OK] MPM (Event, Worker, Prefork)
- [OK] Keep-Alive
- [OK] Compression (mod_deflate)
- [OK] Cache (mod_cache, mod_expires)

**Avancé :**
- [OK] Reverse proxy et load balancing
- [OK] .htaccess (redirections, réécriture d'URL)
- [OK] Logs et monitoring
- [OK] Dépannage complet
- [OK] Scripts d'automatisation

---

### [DOCS] Pour aller plus loin

**1. HTTP/2 et HTTP/3**
- Activer HTTP/2 (mod_http2)
- Préparer HTTP/3 (QUIC)

**2. Conteneurisation**
- Apache dans Docker
- Kubernetes avec Apache Ingress

**3. CDN et Cache distribué**
- Varnish devant Apache
- Cloudflare comme CDN

**4. Haute disponibilité**
- Load balancing avec HAProxy
- Heartbeat/Pacemaker pour failover

**5. Sécurité renforcée**
- Fail2ban contre bruteforce
- OSSEC pour détection d'intrusions
- Hardening avancé

---

### [WEB] Ressources

**Documentation officielle :**
- https://httpd.apache.org/docs/2.4/
- https://httpd.apache.org/docs/2.4/fr/ (en français)

**Communauté :**
- Stack Overflow (tag: apache)
- Server Fault (pour les admins sys)
- Reddit: r/apache, r/sysadmin

**Certifications :**
- **LPIC-2** : Linux Professional (inclut Apache)
- **Red Hat RHCSA/RHCE** : Administration système
- **CompTIA Linux+** : Certif Linux généraliste

---

## [NOTE] COMMANDES DE RÉFÉRENCE RAPIDE

```bash
# ═══════════════════════════════════════════════════════════════
# GESTION DU SERVICE
# ═══════════════════════════════════════════════════════════════

sudo systemctl start apache2       # Démarrer
sudo systemctl stop apache2        # Arrêter
sudo systemctl restart apache2     # Redémarrer (coupe les connexions)
sudo systemctl reload apache2      # Recharger config (sans couper)
sudo systemctl status apache2      # Voir l'état
sudo systemctl enable apache2      # Démarrage automatique
sudo systemctl disable apache2     # Désactiver démarrage auto

# ═══════════════════════════════════════════════════════════════
# CONFIGURATION
# ═══════════════════════════════════════════════════════════════

sudo apache2ctl configtest         # Tester la syntaxe
sudo apache2ctl -M                 # Lister modules chargés
sudo apache2ctl -S                 # Lister Virtual Hosts
sudo apache2ctl -V                 # Version et infos compilation

sudo a2ensite nom-site.conf        # Activer un site
sudo a2dissite nom-site.conf       # Désactiver un site
sudo a2enmod nom-module            # Activer un module
sudo a2dismod nom-module           # Désactiver un module
sudo a2enconf nom-conf             # Activer une config
sudo a2disconf nom-conf            # Désactiver une config

# ═══════════════════════════════════════════════════════════════
# LOGS
# ═══════════════════════════════════════════════════════════════

sudo tail -f /var/log/apache2/access.log      # Suivre access log
sudo tail -f /var/log/apache2/error.log       # Suivre error log
sudo journalctl -fu apache2                   # Logs systemd en temps réel
sudo journalctl -xeu apache2                  # Logs détaillés

# Analyser les logs
sudo grep ' 404 ' /var/log/apache2/access.log
sudo grep 'error' /var/log/apache2/error.log

# ═══════════════════════════════════════════════════════════════
# CERTIFICATS SSL
# ═══════════════════════════════════════════════════════════════

# Let's Encrypt
sudo certbot --apache -d exemple.com         # Obtenir certificat
sudo certbot renew                            # Renouveler manuellement
sudo certbot renew --dry-run                 # Tester renouvellement
sudo certbot certificates                     # Lister certificats

# Auto-signé
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/apache.key \
  -out /etc/ssl/certs/apache.crt

# ═══════════════════════════════════════════════════════════════
# PERMISSIONS
# ═══════════════════════════════════════════════════════════════

sudo chown -R www-data:www-data /var/www/mon-site
sudo chmod -R 755 /var/www/mon-site
sudo chmod 644 /var/www/mon-site/index.html

# ═══════════════════════════════════════════════════════════════
# AUTHENTIFICATION
# ═══════════════════════════════════════════════════════════════

sudo htpasswd -c /etc/apache2/.htpasswd user1    # Créer fichier + user
sudo htpasswd /etc/apache2/.htpasswd user2       # Ajouter user

# ═══════════════════════════════════════════════════════════════
# TEST ET DEBUG
# ═══════════════════════════════════════════════════════════════

curl -I http://site.local                     # Headers HTTP
curl -L http://site.local                     # Suivre redirections
curl -k https://site.local                    # Ignorer erreur SSL
ab -n 1000 -c 10 http://site.local/           # Test de charge

# ═══════════════════════════════════════════════════════════════
# MONITORING
# ═══════════════════════════════════════════════════════════════

sudo goaccess /var/log/apache2/access.log     # Analyser logs
htop                                          # Voir processus

# Statistiques rapides
sudo awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -10
```

---

## [OBJECTIF] CHECKLIST DE MAÎTRISE

**Configuration de base :**
- [ ] Installer Apache
- [ ] Créer un site statique
- [ ] Configurer un Virtual Host
- [ ] Gérer plusieurs sites simultanément

**SSL/HTTPS :**
- [ ] Créer un certificat auto-signé
- [ ] Obtenir un certificat Let's Encrypt
- [ ] Rediriger HTTP vers HTTPS
- [ ] Renouveler automatiquement les certificats

**PHP :**
- [ ] Installer PHP avec Apache
- [ ] Configurer PHP-FPM
- [ ] Héberger un site WordPress
- [ ] Optimiser php.ini

**Sécurité :**
- [ ] Masquer la version d'Apache
- [ ] Désactiver le listing de répertoires
- [ ] Configurer l'authentification par mot de passe
- [ ] Restreindre l'accès par IP
- [ ] Ajouter des headers de sécurité (HSTS, CSP, etc.)
- [ ] Installer ModSecurity

**Performance :**
- [ ] Configurer MPM Event
- [ ] Activer Keep-Alive
- [ ] Configurer la compression (mod_deflate)
- [ ] Gérer le cache (mod_expires, mod_cache)

**Avancé :**
- [ ] Configurer un reverse proxy
- [ ] Héberger une app Python (Flask/Django)
- [ ] Héberger une app Node.js
- [ ] Configurer le load balancing
- [ ] Créer des règles mod_rewrite complexes

**Monitoring :**
- [ ] Lire et analyser les logs Apache
- [ ] Configurer la rotation des logs
- [ ] Installer GoAccess
- [ ] Créer des scripts de monitoring
- [ ] Mettre en place des alertes automatiques

**Dépannage :**
- [ ] Diagnostiquer une erreur 403
- [ ] Diagnostiquer une erreur 404
- [ ] Diagnostiquer une erreur 500
- [ ] Diagnostiquer une erreur 502 (reverse proxy)
- [ ] Résoudre un problème de démarrage d'Apache
- [ ] Utiliser curl pour déboguer
- [ ] Utiliser apache2ctl pour tester

**[OK] Si tu coches toutes ces cases, tu es un EXPERT APACHE ! [TROPHEE]**

---

## [SPEECH_BALLOON] MESSAGE FINAL

**Bravo d'avoir parcouru ce guide complet sur Apache HTTP Server ! [BRAVO]**

Tu es maintenant capable de :
- Installer et configurer Apache comme un professionnel
- Héberger des sites statiques et dynamiques (PHP, Python, Node.js)
- Sécuriser tes sites avec SSL/HTTPS
- Optimiser les performances pour un trafic élevé
- Diagnostiquer et résoudre les problèmes
- Automatiser la surveillance et la maintenance

**Apache est un outil puissant et polyvalent.** Bien que Nginx gagne en popularité pour certains cas d'usage, Apache reste un choix solide et fiable pour la majorité des projets web.

**Continue d'expérimenter, de tester, et d'apprendre !** [RAPIDE]

La meilleure façon de maîtriser Apache est de l'utiliser dans des projets réels. Lance-toi :
- Héberge ton blog personnel
- Crée un portfolio en ligne
- Déploie des applications side-projects
- Contribue à des projets open source

**Bon courage dans tes aventures web ! [WEB]***

---

**FIN DU GUIDE APACHE HTTP SERVER ULTRA-DÉTAILLÉ**

**Auteur :** Guide créé pour les étudiants en génie logiciel
**Date :** Décembre 2024
**Version :** 1.0 - Guide complet et exhaustif

---