# [HOT] GUIDE FIREWALL (IPTABLES / NFTABLES) - ULTRA DÉTAILLÉ POUR DÉBUTANTS ABSOLUS

## * AVANT DE COMMENCER : COMPRENDRE LES BASES

### Qu'est-ce qu'un Firewall (Pare-feu) ?

**Analogie de la porte d'entrée :**

Imagine ta maison :
- Tu as une **porte d'entrée** avec une **serrure**
- Tu décides **qui peut entrer** et **qui ne peut pas**
- Tu peux avoir différentes règles :
  - Les membres de la famille -> Toujours autorisés [OK]
  - Les amis -> Autorisés si tu les as invités [OK]
  - Les livreurs -> Autorisés seulement pour déposer un colis [OK]
  - Les inconnus -> REFUSÉS [X]

**Un firewall, c'est exactement pareil pour ton ordinateur !**

```
[WEB] INTERNET (le monde extérieur)
        │
        │ Tentatives de connexion
        [BLACK_DOWN-POINTING_TRIANGLE]
┌────────────────────────────────┐
│   [HOT] FIREWALL (Pare-feu)       │
│                                │
│   Règles de sécurité :         │
│   [OK] Port 80 (Web) -> AUTORISÉ  │
│   [OK] Port 443 (HTTPS) -> OK     │
│   [OK] Port 22 (SSH) -> OK        │
│   [X] Port 23 (Telnet) -> BLOQUÉ │
│   [X] Tout le reste -> REFUSÉ    │
└────────────────────────────────┘
        │
        │ Connexions autorisées uniquement
        [BLACK_DOWN-POINTING_TRIANGLE]
    [CODE] TON SERVEUR
```

### Pourquoi un Firewall est ESSENTIEL ?

**Sans firewall :**
```
[WEB] INTERNET
    │
    ├─ [FISHING_POLE_AND_FISH] Hacker 1 -> Scanne tous les ports
    ├─ [FISHING_POLE_AND_FISH] Hacker 2 -> Essaie d'accéder à SSH
    ├─ [FISHING_POLE_AND_FISH] Bot 1 -> Cherche des vulnérabilités
    ├─ [FISHING_POLE_AND_FISH] Bot 2 -> Tente une attaque DDoS
    └─ [FISHING_POLE_AND_FISH] Bot 3 -> Essaie des mots de passe
        │
        │ TOUS ont accès ! [IMPACT]
        [BLACK_DOWN-POINTING_TRIANGLE]
    [CODE] TON SERVEUR (complètement exposé !)
```

**Avec firewall :**
```
[WEB] INTERNET
    │
    ├─ [FISHING_POLE_AND_FISH] Hacker 1 -> [X] BLOQUÉ (port fermé)
    ├─ [FISHING_POLE_AND_FISH] Hacker 2 -> [X] BLOQUÉ (IP blacklistée)
    ├─ [FISHING_POLE_AND_FISH] Bot 1 -> [X] BLOQUÉ (DROP)
    ├─ [FISHING_POLE_AND_FISH] Bot 2 -> [X] BLOQUÉ (rate limit)
    └─ [OK] Toi (IP autorisée) -> ACCÈS ACCORDÉ
        │
        │ Seules les connexions autorisées passent
        [BLACK_DOWN-POINTING_TRIANGLE]
    [CODE] TON SERVEUR (protégé ! [SECURITE])
```

### Qu'est-ce qu'un port ?

**Analogie de l'immeuble :**

Imagine ton ordinateur comme un **immeuble** :
```
[ENTREPRISE] TON ORDINATEUR (Immeuble)
│
├─ [SORTIE] Appartement 22 (Port 22) <- SSH (connexion à distance)
├─ [SORTIE] Appartement 80 (Port 80) <- HTTP (site web)
├─ [SORTIE] Appartement 443 (Port 443) <- HTTPS (site web sécurisé)
├─ [SORTIE] Appartement 25 (Port 25) <- SMTP (email)
├─ [SORTIE] Appartement 3306 (Port 3306) <- MySQL (base de données)
└─ [SORTIE] Appartement 8080 (Port 8080) <- Application web
```

Chaque **service** (programme) écoute sur un **port spécifique** :
- Quand quelqu'un veut se connecter à ton site web -> Il frappe à la porte **80** ou **443**
- Quand tu veux te connecter en SSH -> Tu frappes à la porte **22**

**Les ports vont de 0 à 65535** :
```
┌─────────────────────────────────────────┐
│ 0 - 1023 : Ports "bien connus"         │
│            (HTTP, SSH, FTP, etc.)       │
│            Nécessitent root             │
├─────────────────────────────────────────┤
│ 1024 - 49151 : Ports "enregistrés"     │
│                (Applications courantes) │
├─────────────────────────────────────────┤
│ 49152 - 65535 : Ports "dynamiques"     │
│                 (Usage temporaire)      │
└─────────────────────────────────────────┘
```

**Ports les plus courants :**

| Port | Service | Description |
|------|---------|-------------|
| 22 | SSH | Connexion à distance sécurisée |
| 80 | HTTP | Sites web (non sécurisé) |
| 443 | HTTPS | Sites web sécurisés (SSL/TLS) |
| 21 | FTP | Transfert de fichiers |
| 25 | SMTP | Envoi d'emails |
| 53 | DNS | Résolution de noms de domaine |
| 67-68 | DHCP | Attribution d'adresses IP |
| 3306 | MySQL | Base de données MySQL |
| 5432 | PostgreSQL | Base de données PostgreSQL |
| 8080 | HTTP-Alt | Serveur web alternatif |

### Les 3 actions possibles du Firewall

Quand une connexion arrive, le firewall a **3 choix** :

#### 1⃣ **ACCEPT** (Accepter) [OK]
```
[MESSAGE] Paquet arrive
    v
[HOT] Firewall : "OK, tu peux passer !"
    v
[CODE] Paquet atteint le serveur
```
- La connexion est **autorisée**
- Le paquet passe et arrive à destination
- **Exemple :** Autoriser le trafic HTTP sur le port 80

#### 2⃣ **DROP** (Abandonner) [SUPPRIMER]
```
[MESSAGE] Paquet arrive
    v
[HOT] Firewall : "STOP !" [silence total]
    v
[X] Pas de réponse (comme si le serveur n'existait pas)
```
- Le paquet est **jeté silencieusement**
- **Aucune réponse** n'est envoyée
- L'expéditeur ne sait pas si le serveur existe
- **Avantage :** Plus sécurisé (discret)
- **Inconvénient :** L'expéditeur attend longtemps (timeout)

#### 3⃣ **REJECT** (Refuser) [INTERDIT]
```
[MESSAGE] Paquet arrive
    v
[HOT] Firewall : "REFUSÉ !"
    v
[SORTIE] Envoie une réponse : "Port fermé" ou "Connexion refusée"
```
- Le paquet est **rejeté**
- Une **réponse d'erreur** est envoyée
- L'expéditeur sait immédiatement que c'est bloqué
- **Avantage :** Rapide (pas de timeout)
- **Inconvénient :** Révèle l'existence du serveur

**Comparaison :**

| Action | Réponse | Temps d'attente | Discrétion | Usage |
|--------|---------|-----------------|------------|-------|
| ACCEPT [OK] | Connexion réussie | Immédiat | N/A | Services autorisés |
| DROP [SUPPRIMER] | Aucune | Long (timeout) | Très discret | Blocage furtif |
| REJECT [INTERDIT] | "Refusé" | Immédiat | Peu discret | Blocage rapide |

### iptables vs nftables : Quelle différence ?

**iptables** et **nftables** sont des outils pour configurer le firewall Linux.

```
┌──────────────────────────────────────────┐
│         HISTOIRE DU FIREWALL LINUX       │
├──────────────────────────────────────────┤
│ 1994-2000 : ipfwadm / ipchains           │
│            (ancien, obsolète)            │
├──────────────────────────────────────────┤
│ 2001-2020 : iptables *                  │
│            (très utilisé, stable)        │
│            C'est le STANDARD actuel      │
├──────────────────────────────────────────┤
│ 2014-maintenant : nftables 🆕            │
│            (moderne, plus simple)        │
│            Remplace progressivement      │
│            iptables                      │
└──────────────────────────────────────────┘
```

#### **iptables** (Ancien mais très répandu)

**Avantages :**
- [OK] Très utilisé (95% des serveurs Linux)
- [OK] Documentation abondante
- [OK] Compatible avec tous les systèmes
- [OK] Tutoriels partout sur Internet

**Inconvénients :**
- [X] Syntaxe complexe et verbeuse
- [X] Plusieurs commandes (`iptables`, `ip6tables`, `arptables`, `ebtables`)
- [X] Difficile à gérer pour les règles complexes

**Exemple de syntaxe iptables :**
```bash
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
```

#### **nftables** (Nouveau et moderne)

**Avantages :**
- [OK] Syntaxe plus simple et lisible
- [OK] Une seule commande pour tout (`nft`)
- [OK] Plus rapide et performant
- [OK] Meilleure gestion des règles complexes

**Inconvénients :**
- [X] Moins de documentation (encore récent)
- [X] Pas disponible sur les très vieux systèmes
- [X] Moins de tutoriels

**Exemple de syntaxe nftables :**
```bash
nft add rule inet filter input tcp dport 80 accept
```

#### Quel outil utiliser ?

**Pour ce tutoriel, on va apprendre les DEUX !**

| Système | Par défaut | Recommandation |
|---------|------------|----------------|
| Ubuntu 18.04 - 20.04 | iptables | Utilise **iptables** (plus de docs) |
| Ubuntu 22.04+ | nftables | Apprends **nftables** (moderne) |
| Debian 10 | iptables | Utilise **iptables** |
| Debian 11+ | nftables | Apprends **nftables** |
| CentOS / RHEL 7 | iptables | Utilise **iptables** |
| CentOS / RHEL 8+ | nftables | Apprends **nftables** |

**Commande pour savoir ce que tu utilises actuellement :**

```bash
# Si cette commande fonctionne, tu as iptables
sudo iptables -L -n

# Si cette commande fonctionne, tu as nftables
sudo nft list ruleset
```

**Bonne nouvelle :** La plupart des systèmes modernes ont **les deux** installés ! On peut utiliser celui qu'on préfère.

---

## [OBJECTIF] OBJECTIF DU PROJET

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

On va **sécuriser notre serveur Linux** en configurant un firewall pour :

1. [OK] **Bloquer tout le trafic par défaut** (politique de sécurité stricte)
2. [OK] **Autoriser uniquement les services nécessaires** :
   - SSH (port 22) pour l'administration à distance
   - HTTP (port 80) pour un site web
   - HTTPS (port 443) pour un site web sécurisé
   - DNS (port 53) si on a un serveur DNS
   - DHCP (ports 67-68) si on a un serveur DHCP
3. [OK] **Protéger contre les attaques courantes** :
   - Attaques par force brute sur SSH
   - Scans de ports
   - Attaques DDoS basiques
4. [OK] **Bloquer des IP malveillantes** spécifiques

### Schéma de la configuration finale

```
[WEB] INTERNET
    │
    │ Tentatives de connexion
    [BLACK_DOWN-POINTING_TRIANGLE]
┌─────────────────────────────────────────┐
│        [HOT] FIREWALL CONFIGURÉ            │
│                                         │
│  POLITIQUE PAR DÉFAUT :                 │
│  [X] INPUT : DROP (tout bloquer)         │
│  [OK] OUTPUT : ACCEPT (tout autoriser)    │
│  [OK] FORWARD : ACCEPT (routage OK)       │
│                                         │
│  RÈGLES SPÉCIFIQUES :                   │
│  [OK] Port 22 (SSH) -> ACCEPT              │
│     └─ Protection brute force (fail2ban)│
│  [OK] Port 80 (HTTP) -> ACCEPT             │
│  [OK] Port 443 (HTTPS) -> ACCEPT           │
│  [OK] Port 53 (DNS) -> ACCEPT              │
│  [OK] Port 67-68 (DHCP) -> ACCEPT          │
│  [OK] ICMP (Ping) -> ACCEPT (limité)       │
│  [OK] Connexions établies -> ACCEPT        │
│  [X] IP blacklistée -> DROP               │
│  [X] Tout le reste -> DROP                │
└─────────────────────────────────────────┘
    │
    │ Seul le trafic autorisé passe
    [BLACK_DOWN-POINTING_TRIANGLE]
[CODE] TON SERVEUR LINUX (sécurisé ! [SECURITE])
```

---

## [DOCS] PARTIE 1 : IPTABLES - CONFIGURATION COMPLÈTE

### [LISTE] Étape 1.1 : Vérifier l'état actuel du firewall

Avant de commencer, voyons ce qui existe déjà.

#### 1. Vérifie si iptables est installé

```bash
sudo iptables --version
```

**Résultat attendu :**
```
iptables v1.8.7 (nf_tables)
```

[OK] Si tu vois une version, c'est installé !

[X] Si tu vois "command not found" :
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install iptables -y

# CentOS/RHEL
sudo yum install iptables -y
```

#### 2. Affiche les règles actuelles

```bash
sudo iptables -L -v -n
```

**Explication de la commande :**
```
sudo iptables -L -v -n
     │        │  │  │
     │        │  │  └─ -n = Affiche les IPs en format numérique
     │        │  │       (ne résout pas les noms de domaine)
     │        │  └──── -v = Verbose (détaillé)
     │        │          Affiche compteurs de paquets
     │        └─────── -L = List (lister les règles)
     └────────────── iptables = Commande principale
```

**Résultat typique (serveur neuf) :**

```
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
```

**Décryptage :**

```
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
  │      │         │
  │      │         └─ Politique par défaut : ACCEPT (tout autorisé)
  │      └─────────── Compteurs (paquets/octets traités)
  └────────────────── Chaîne INPUT (trafic ENTRANT)
```

**Les 3 chaînes principales :**

| Chaîne | Direction | Description |
|--------|-----------|-------------|
| **INPUT** [ENTREE] | ENTRANT | Trafic qui arrive **vers** ton serveur |
| **OUTPUT** [SORTIE] | SORTANT | Trafic qui **part** de ton serveur |
| **FORWARD** <-> | TRANSIT | Trafic qui **traverse** ton serveur (routage) |

**Schéma visuel :**

```
        [WEB] INTERNET
            │
            │
   ┌────────┴────────┐
   │                 │
   [BLACK_DOWN-POINTING_TRIANGLE] INPUT      OUTPUT[BLACK_UP-POINTING_TRIANGLE]
┌──────────────────────┐
│   [CODE] TON SERVEUR     │
│                      │
│  ┌────────────────┐  │
│  │  Applications  │  │
│  └────────────────┘  │
└──────────────────────┘
   │                 │
   │ FORWARD         │
   └────────┬────────┘
            │
            [BLACK_DOWN-POINTING_TRIANGLE]
     [WEB] Autre réseau
```

#### 3. Comprendre la politique par défaut

La **politique par défaut** définit ce qui arrive aux paquets qui ne correspondent à **aucune règle**.

**Deux philosophies possibles :**

**1. Politique permissive (ACCEPT par défaut)** [ATTENTION] PAS SÉCURISÉ
```
Policy: ACCEPT
│
├─ Règle 1 : Bloquer port 23 -> DROP
├─ Règle 2 : Bloquer port 3389 -> DROP
└─ Tout le reste -> [OK] AUTORISÉ (par défaut)
```
- On **bloque** ce qui est dangereux
- Tout le reste passe
- [X] **Problème :** Si on oublie de bloquer quelque chose, c'est ouvert !

**2. Politique restrictive (DROP par défaut)** [OK] SÉCURISÉ
```
Policy: DROP
│
├─ Règle 1 : Autoriser port 22 -> ACCEPT
├─ Règle 2 : Autoriser port 80 -> ACCEPT
├─ Règle 3 : Autoriser port 443 -> ACCEPT
└─ Tout le reste -> [X] BLOQUÉ (par défaut)
```
- On **autorise** seulement le nécessaire
- Tout le reste est bloqué
- [OK] **Avantage :** Même si on oublie quelque chose, c'est fermé par défaut !

**On va utiliser la politique restrictive (DROP) !** [SECURITE]

---

### [SECURITE] Étape 1.2 : Configuration de base (Script sécurisé)

On va créer un **script de configuration** complet et sécurisé.

#### [ATTENTION] AVERTISSEMENT CRITIQUE

**ATTENTION :** Mal configurer le firewall peut **te verrouiller hors de ton serveur** !

Scénario catastrophe :
```
1. Tu bloques tout le trafic entrant (DROP par défaut)
2. Tu oublies d'autoriser SSH (port 22)
3. Ta connexion SSH actuelle se coupe
4. Tu ne peux PLUS te reconnecter ! [INTERDIT]
5. Tu dois accéder physiquement au serveur (console directe)
```

**Solution de sécurité : Tâche cron de déblocage automatique**

On va créer une **tâche planifiée** qui **supprime toutes les règles** après 5 minutes.
- Si la configuration est bonne -> On annule la tâche
- Si tu te verrouilles -> Attends 5 minutes, tout se réinitialise automatiquement !

#### 1. Créé le script de configuration

```bash
sudo nano /root/firewall-config.sh
```

**Copie-colle ce script COMPLET :**

```bash
#!/bin/bash

# ═══════════════════════════════════════════════════════════════
# SCRIPT DE CONFIGURATION FIREWALL IPTABLES
# ═══════════════════════════════════════════════════════════════
# Créé le : 2024-12-06
# Pour : Sécurisation serveur Linux
# ═══════════════════════════════════════════════════════════════

# ────────────────────────────────────────────────────────────────
# VÉRIFICATIONS PRÉLIMINAIRES
# ────────────────────────────────────────────────────────────────

# Vérifier que le script est exécuté en root
if [ "$EUID" -ne 0 ]; then
  echo "[X] ERREUR : Ce script doit être exécuté en root (avec sudo)"
  exit 1
fi

echo "════════════════════════════════════════════════════════════"
echo "  [HOT] CONFIGURATION DU FIREWALL IPTABLES"
echo "════════════════════════════════════════════════════════════"
echo ""

# ────────────────────────────────────────────────────────────────
# SAUVEGARDE DES RÈGLES ACTUELLES
# ────────────────────────────────────────────────────────────────

echo "[PACKAGE] Sauvegarde des règles actuelles..."
iptables-save > /root/iptables-backup-$(date +%Y%m%d-%H%M%S).txt
echo "[OK] Sauvegarde créée dans /root/"
echo ""

# ────────────────────────────────────────────────────────────────
# NETTOYAGE DES RÈGLES EXISTANTES
# ────────────────────────────────────────────────────────────────

echo "[NETTOYAGE] Suppression de toutes les règles existantes..."

# Supprimer toutes les règles
iptables -F
# F = Flush (vider toutes les règles)

# Supprimer toutes les chaînes personnalisées
iptables -X
# X = Delete chain (supprimer les chaînes custom)

# Réinitialiser les compteurs
iptables -Z
# Z = Zero (remettre les compteurs à zéro)

echo "[OK] Règles supprimées"
echo ""

# ────────────────────────────────────────────────────────────────
# POLITIQUE PAR DÉFAUT (TRÈS IMPORTANT !)
# ────────────────────────────────────────────────────────────────

echo "[SECURITE]  Configuration de la politique par défaut..."

# TEMPORAIREMENT : Tout accepter (pour ne pas se bloquer)
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
# -P = Policy (politique par défaut)

echo "[OK] Politique temporaire : ACCEPT (sécurité pendant la config)"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 1 : AUTORISER L'INTERFACE LOOPBACK
# ────────────────────────────────────────────────────────────────

echo "[SYNC] Autorisation de l'interface loopback (127.0.0.1)..."

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Explication :
# -A INPUT = Ajouter (Append) une règle à la chaîne INPUT
# -i lo = Interface loopback (communication interne)
# -j ACCEPT = Jump to ACCEPT (action : accepter)
#
# L'interface loopback (127.0.0.1) = communication du serveur avec lui-même
# ESSENTIEL pour le bon fonctionnement de nombreux services !
#
# Exemples d'usage :
# - MySQL qui écoute sur 127.0.0.1:3306
# - Redis sur 127.0.0.1:6379
# - Communication inter-processus
#
# Si on bloque loopback -> Beaucoup de services cassent ! [X]

echo "[OK] Loopback autorisé"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 2 : AUTORISER LES CONNEXIONS ÉTABLIES ET RELIÉES
# ────────────────────────────────────────────────────────────────

echo "[LIEN] Autorisation des connexions établies et reliées..."

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Explication DÉTAILLÉE :
#
# -m conntrack = Module de suivi de connexion (connection tracking)
# --ctstate = Connection tracking state (état de la connexion)
#
# États possibles :
# - NEW : Nouvelle connexion qui commence
# - ESTABLISHED : Connexion déjà établie (active)
# - RELATED : Connexion reliée à une connexion établie
# - INVALID : Paquet malformé ou incohérent
#
# ESTABLISHED :
# Imagine que tu es sur SSH connecté au serveur.
# - Ta connexion SSH initiale = NEW
# - Tous les paquets suivants = ESTABLISHED
# Sans cette règle, la connexion SSH se couperait immédiatement !
#
# RELATED :
# Exemple : FTP actif
# - Connexion de contrôle (port 21) = ESTABLISHED
# - Connexion de données (port 20) = RELATED
# La connexion de données est "reliée" à la connexion de contrôle
#
# Pourquoi c'est CRUCIAL ?
# Quand tu envoies une requête vers Internet (ex: apt update),
# ta machine initie la connexion (NEW, sortant).
# La réponse qui revient est ESTABLISHED (entrant).
# Sans cette règle, les réponses seraient bloquées ! [X]

echo "[OK] Connexions établies autorisées"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 3 : BLOQUER LES PAQUETS INVALIDES
# ────────────────────────────────────────────────────────────────

echo "[INTERDIT] Blocage des paquets invalides..."

iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# Explication :
# Paquets INVALID = paquets malformés, incohérents ou suspects
#
# Exemples de paquets INVALID :
# - Paquets SYN+FIN (incohérent selon TCP)
# - Réponses à des connexions qui n'existent pas
# - Paquets fragmentés de manière incorrecte
# - Tentatives d'exploits réseau
#
# Ces paquets sont TOUJOURS suspects -> On les jette silencieusement

echo "[OK] Paquets invalides bloqués"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 4 : AUTORISER SSH (PORT 22) AVEC PROTECTION
# ────────────────────────────────────────────────────────────────

echo "[SECURISE] Autorisation SSH (port 22) avec protection brute-force..."

# Protection contre les attaques par force brute
# Limite : 3 nouvelles connexions par minute par IP
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

# Explication LIGNE PAR LIGNE :
#
# Ligne 1 : Enregistrer chaque nouvelle connexion SSH
# -p tcp = Protocole TCP
# --dport 22 = Port de destination 22 (SSH)
# -m conntrack --ctstate NEW = Seulement les NOUVELLES connexions
# -m recent --set = Module "recent" : enregistrer cette IP avec un timestamp
#
# Ligne 2 : Bloquer si trop de tentatives
# -m recent --update = Mettre à jour le compteur pour cette IP
# --seconds 60 = Dans les 60 dernières secondes
# --hitcount 4 = Si 4 tentatives ou plus
# -j DROP = Bloquer silencieusement
#
# Fonctionnement :
# 1. IP 1.2.3.4 tente de se connecter -> Enregistré (tentative 1)
# 2. Même IP tente encore -> Enregistré (tentative 2)
# 3. Encore -> Enregistré (tentative 3)
# 4. 4ème tentative dans la minute -> BLOQUÉ ! [X]
# 5. Après 60 secondes, le compteur se réinitialise
#
# Protection contre :
# - Attaques par force brute (essai de milliers de mots de passe)
# - Scans automatisés
# - Bots malveillants
#
# 3 tentatives/minute = Assez pour un humain, trop lent pour un bot

# Autoriser SSH normalement (pour les connexions non suspectes)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

echo "[OK] SSH autorisé avec protection brute-force"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 5 : AUTORISER HTTP ET HTTPS
# ────────────────────────────────────────────────────────────────

echo "[WEB] Autorisation HTTP (80) et HTTPS (443)..."

iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Explication :
# Port 80 = HTTP (sites web non sécurisés)
# Port 443 = HTTPS (sites web sécurisés avec SSL/TLS)
#
# Si tu héberges un site web, ces ports DOIVENT être ouverts
# Sinon, personne ne pourra accéder à ton site !
#
# Note : Pas de limitation ici car le trafic web est légitime
# et très variable (beaucoup de visiteurs = normal)

echo "[OK] HTTP et HTTPS autorisés"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 6 : AUTORISER DNS (PORT 53)
# ────────────────────────────────────────────────────────────────

echo "[MONDE] Autorisation DNS (port 53)..."

iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT

# Explication :
# DNS utilise principalement UDP, mais aussi TCP dans certains cas
#
# UDP port 53 :
# - Requêtes DNS normales (petites, < 512 octets)
# - 99% du trafic DNS
#
# TCP port 53 :
# - Requêtes DNS volumineuses (> 512 octets)
# - Transferts de zones (AXFR)
# - DNS over TCP (DoT)
#
# Si tu as configuré DNSmasq (comme dans le tuto DHCP),
# ce port DOIT être ouvert pour que les clients puissent
# résoudre les noms de domaine via ton serveur

echo "[OK] DNS autorisé (UDP et TCP)"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 7 : AUTORISER DHCP (PORTS 67-68)
# ────────────────────────────────────────────────────────────────

echo "[RESEAU] Autorisation DHCP (ports 67-68)..."

iptables -A INPUT -p udp --dport 67:68 -j ACCEPT
iptables -A OUTPUT -p udp --sport 67:68 -j ACCEPT

# Explication :
# Port 67 = Serveur DHCP (écoute les demandes)
# Port 68 = Client DHCP (reçoit les réponses)
#
# --dport 67:68 = Ports de destination 67 À 68 (plage)
# --sport 67:68 = Ports source 67 À 68
#
# DHCP utilise UDP (pas TCP) car :
# - Plus rapide (pas de handshake)
# - Pas besoin de fiabilité garantie pour DHCP
#
# Si tu as configuré DNSmasq comme serveur DHCP,
# ces ports DOIVENT être ouverts pour distribuer les IPs

echo "[OK] DHCP autorisé"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 8 : AUTORISER ICMP (PING) AVEC LIMITATION
# ────────────────────────────────────────────────────────────────

echo "[RESEAU] Autorisation ICMP (ping) avec limitation..."

# Autoriser ping, mais limité pour éviter les attaques flood
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

# Explication DÉTAILLÉE :
#
# ICMP = Internet Control Message Protocol
# --icmp-type echo-request = Type 8 (requête ping)
#
# Ligne 1 : Autoriser ping, mais limité
# -m limit = Module de limitation
# --limit 1/s = Maximum 1 paquet par seconde
# --limit-burst 3 = Autoriser un "burst" initial de 3 paquets
# -j ACCEPT = Accepter si dans la limite
#
# Ligne 2 : Bloquer le reste
# Si la limite est dépassée, bloquer silencieusement
#
# Fonctionnement du burst :
# Imagine un seau avec 3 jetons :
# 1. Paquet 1 arrive -> Utilise jeton 1 -> ACCEPTÉ [OK]
# 2. Paquet 2 arrive -> Utilise jeton 2 -> ACCEPTÉ [OK]
# 3. Paquet 3 arrive -> Utilise jeton 3 -> ACCEPTÉ [OK]
# 4. Paquet 4 arrive -> Plus de jetons -> BLOQUÉ [X]
# 5. Attendre 1 seconde -> Le seau se remplit de 1 jeton
# 6. Paquet 5 arrive -> Utilise le nouveau jeton -> ACCEPTÉ [OK]
#
# Pourquoi limiter ping ?
# - Attaque "Ping flood" (DDoS basique)
# - Consomme de la bande passante
# - Peut surcharger le serveur
#
# Avec cette limitation :
# - Ping normal (quelques paquets) -> Fonctionne [OK]
# - Ping flood (milliers de paquets) -> Bloqué [X]

echo "[OK] ICMP autorisé (limité à 1/s)"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 9 : BLOQUER DES IP SPÉCIFIQUES (BLACKLIST)
# ────────────────────────────────────────────────────────────────

echo "[INTERDIT] Configuration de la blacklist IP..."

# Exemple : Bloquer des IPs malveillantes connues
# Décommente et ajoute les IPs que tu veux bloquer

# iptables -A INPUT -s 192.168.1.50 -j DROP
# iptables -A INPUT -s 203.0.113.0/24 -j DROP

# Explication :
# -s = Source (adresse IP source)
# 192.168.1.50 = IP individuelle
# 203.0.113.0/24 = Plage d'IPs (203.0.113.0 à 203.0.113.255)
# -j DROP = Bloquer silencieusement
#
# Utilisation :
# Si tu détectes une IP qui :
# - Tente des attaques
# - Scan des ports
# - Spamme des requêtes
# -> Ajoute-la ici pour la bloquer définitivement
#
# Pour bloquer une IP en live (sans éditer le script) :
# sudo iptables -A INPUT -s 1.2.3.4 -j DROP

echo "[OK] Blacklist configurée (vide par défaut)"
echo ""

# ────────────────────────────────────────────────────────────────
# RÈGLE 10 : PROTECTION CONTRE LES SCANS DE PORTS
# ────────────────────────────────────────────────────────────────

echo "[SECURITE]  Protection contre les scans de ports..."

# Bloquer les scans NULL
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# Bloquer les scans XMAS
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# Bloquer les scans FIN
iptables -A INPUT -p tcp --tcp-flags ALL FIN -j DROP

# Bloquer les scans SYN-FIN
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

# Explication des types de scans :
#
# 1. NULL scan (aucun flag activé)
# Envoie un paquet TCP sans aucun flag
# Utilisé pour détecter des ports ouverts de manière furtive
# Réponse :
# - Port fermé -> RST (reset)
# - Port ouvert -> Pas de réponse
#
# 2. XMAS scan (tous les flags activés)
# Envoie un paquet avec TOUS les flags TCP activés
# Appelé "XMAS" car tous les bits sont allumés comme un sapin de Noël [CHRISTMAS_TREE]
# Même principe que NULL scan
#
# 3. FIN scan (flag FIN uniquement)
# Envoie un paquet avec seulement le flag FIN
# Normalement utilisé pour terminer une connexion
# Ici, envoyé sans connexion établie = suspect !
#
# 4. SYN-FIN scan
# Envoie SYN et FIN en même temps
# Complètement incohérent (on ne peut pas commencer ET finir en même temps)
# TOUJOURS malveillant
#
# Ces scans sont utilisés par des outils comme nmap pour :
# - Cartographier les ports ouverts
# - Trouver des vulnérabilités
# - Préparer une attaque
#
# Aucun trafic légitime n'utilise ces patterns -> On bloque tout !

echo "[OK] Protection contre les scans activée"
echo ""

# ────────────────────────────────────────────────────────────────
# APPLICATION DE LA POLITIQUE PAR DÉFAUT RESTRICTIVE
# ────────────────────────────────────────────────────────────────

echo "[VERROUILLE] Application de la politique par défaut restrictive..."

# MAINTENANT : On applique la vraie politique stricte
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Explication :
# INPUT DROP = Tout le trafic ENTRANT est bloqué par défaut
#              Sauf ce qu'on a explicitement autorisé ci-dessus
#
# FORWARD DROP = Tout le trafic en TRANSIT est bloqué
#                (Important si le serveur fait du routage)
#
# OUTPUT ACCEPT = Tout le trafic SORTANT est autorisé
#                 Le serveur peut initier des connexions librement
#                 (ex: apt update, wget, curl, etc.)
#
# Pourquoi OUTPUT est ACCEPT ?
# - Plus simple à gérer
# - Le serveur a besoin de sortir (mises à jour, etc.)
# - Les réponses aux connexions sortantes sont gérées
#   par la règle ESTABLISHED,RELATED
#
# Si tu veux une sécurité MAXIMALE :
# Change OUTPUT en DROP et autorise seulement ce dont tu as besoin
# (mais c'est beaucoup plus complexe à maintenir)

echo "[OK] Politique par défaut appliquée : INPUT=DROP, OUTPUT=ACCEPT"
echo ""

# ────────────────────────────────────────────────────────────────
# SAUVEGARDE DE LA CONFIGURATION
# ────────────────────────────────────────────────────────────────

echo "[SAUVEGARDE] Sauvegarde de la configuration..."

# Sauvegarder les règles pour qu'elles persistent après reboot
iptables-save > /etc/iptables/rules.v4

# Explication :
# iptables-save = Exporte toutes les règles actuelles
# > /etc/iptables/rules.v4 = Sauvegarde dans le fichier standard
#
# Ce fichier sera lu au démarrage du système par le service
# iptables-persistent (qu'on va installer après)

echo "[OK] Configuration sauvegardée dans /etc/iptables/rules.v4"
echo ""

# ────────────────────────────────────────────────────────────────
# AFFICHAGE DU RÉSUMÉ
# ────────────────────────────────────────────────────────────────

echo "════════════════════════════════════════════════════════════"
echo "  [OK] CONFIGURATION TERMINÉE AVEC SUCCÈS !"
echo "════════════════════════════════════════════════════════════"
echo ""
echo "[GRAPHIQUE] Règles actives :"
echo ""
iptables -L -v -n --line-numbers
echo ""
echo "════════════════════════════════════════════════════════════"
echo "  [ATTENTION]  IMPORTANT : TESTE TA CONNEXION MAINTENANT !"
echo "════════════════════════════════════════════════════════════"
echo ""
echo "1. Ouvre un NOUVEAU terminal (SANS fermer celui-ci !)"
echo "2. Teste la connexion SSH : ssh user@ton-serveur"
echo "3. Si ça fonctionne -> Tout est OK ! [OK]"
echo "4. Si ça ne fonctionne PAS -> Attends 5 minutes, le firewall"
echo "   se réinitialisera automatiquement (si tu as configuré le cron)"
echo ""
echo "Pour annuler la réinitialisation automatique (si tout marche) :"
echo "  sudo at -r 1"
echo ""
echo "════════════════════════════════════════════════════════════"
```

#### 2. Rends le script exécutable

```bash
sudo chmod +x /root/firewall-config.sh
```

**Explication :**
```
chmod = Change mode (modifier les permissions)
+x = Ajouter la permission d'exécution (executable)
```

#### 3. Créé la tâche de sécurité (réinitialisation automatique)

```bash
# Installe le paquet 'at' pour les tâches planifiées
sudo apt install at -y

# Programme la réinitialisation dans 5 minutes
echo "/root/firewall-reset.sh" | sudo at now + 5 minutes
```

Mais d'abord, créé le script de réinitialisation :

```bash
sudo nano /root/firewall-reset.sh
```

**Contenu du script de réinitialisation :**

```bash
#!/bin/bash

# Script de réinitialisation d'urgence
# Restaure une politique permissive pour éviter le verrouillage

# Vider toutes les règles
iptables -F
iptables -X
iptables -Z

# Politique permissive (tout autoriser)
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# Log l'événement
echo "$(date) - Firewall réinitialisé automatiquement" >> /var/log/firewall-reset.log
```

Rends-le exécutable :

```bash
sudo chmod +x /root/firewall-reset.sh
```

#### 4. Exécute le script de configuration

```bash
sudo /root/firewall-config.sh
```

**Résultat attendu :**

Le script va afficher toutes les étapes et se terminer par un résumé.

#### 5. TESTE IMMÉDIATEMENT TA CONNEXION SSH

**[ATTENTION] CRITIQUE : NE FERME PAS TON TERMINAL ACTUEL !**

1. **Ouvre un NOUVEAU terminal** (ou une nouvelle fenêtre SSH)
2. Essaie de te connecter :
   ```bash
   ssh ton-utilisateur@ip-du-serveur
   ```

**Si ça fonctionne [OK] :**
- Tout est OK !
- Annule la réinitialisation automatique :
  ```bash
  sudo atq  # Voir les tâches planifiées
  sudo atrm 1  # Supprimer la tâche n°1 (réinitialisation)
  ```

**Si ça NE fonctionne PAS [X] :**
- NE PANIQUE PAS !
- Attends 5 minutes
- Le firewall se réinitialisera automatiquement
- Tu pourras te reconnecter et corriger le problème

---

### [RECHERCHE] Étape 1.3 : Vérifier et tester la configuration

#### 1. Affiche les règles actives

```bash
sudo iptables -L -v -n --line-numbers
```

**Explication des options :**
```
-L = List (lister)
-v = Verbose (détaillé, affiche les compteurs)
-n = Numeric (format numérique, pas de résolution DNS)
--line-numbers = Affiche le numéro de chaque règle
```

**Résultat attendu :**

```
Chain INPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
2      123  9876 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
3        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
4        5   300 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
5        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
6        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443
...
```

**Décryptage :**

- **Chain INPUT (policy DROP)** -> La politique par défaut est DROP [OK]
- **num** -> Numéro de la règle (utile pour modifier/supprimer)
- **pkts** -> Nombre de paquets traités par cette règle
- **target** -> Action (ACCEPT, DROP, REJECT)
- **prot** -> Protocole (tcp, udp, icmp, all)
- **dpt** -> Port de destination (destination port)

#### 2. Teste depuis ton PC

**a) Teste le ping (ICMP) :**

```bash
ping -c 4 ip-du-serveur
```

[OK] Tu devrais recevoir des réponses (limité à 1/s)

**b) Teste SSH :**

```bash
ssh ton-utilisateur@ip-du-serveur
```

[OK] La connexion doit fonctionner

**c) Teste HTTP (si tu as un serveur web) :**

Dans un navigateur :
```
http://ip-du-serveur
```

[OK] La page doit s'afficher

#### 3. Teste un port fermé

Essaie de te connecter à un port qui n'est PAS autorisé :

```bash
# Teste le port 3389 (RDP Windows, normalement fermé)
telnet ip-du-serveur 3389
```

**Résultat attendu :**

```
Trying ip-du-serveur...
[attend longtemps sans réponse]
telnet: Unable to connect to remote host: Connection timed out
```

[OK] Timeout = Le port est correctement bloqué (DROP)

#### 4. Surveille les logs en temps réel

```bash
# Surveille les nouvelles connexions
sudo watch -n 1 'iptables -L -v -n | head -20'
```

**Explication :**
- `watch -n 1` = Rafraîchir toutes les 1 seconde
- `iptables -L -v -n` = Lister les règles avec compteurs
- `head -20` = Afficher les 20 premières lignes

Tu verras les **compteurs de paquets (pkts)** augmenter en temps réel !

---

### [SAUVEGARDE] Étape 1.4 : Rendre la configuration persistante

**Problème :** Les règles iptables sont **volatiles** = elles disparaissent au redémarrage !

**Solution :** Installer `iptables-persistent`

#### 1. Installe le paquet

```bash
sudo apt install iptables-persistent -y
```

**Pendant l'installation**, on te demandera :

```
Save current IPv4 rules? [yes/no]
```
-> Réponds **yes**

```
Save current IPv6 rules? [yes/no]
```
-> Réponds **yes** (même si tu n'utilises pas IPv6)

#### 2. Vérifie que les règles sont sauvegardées

```bash
ls -l /etc/iptables/
```

**Résultat attendu :**

```
-rw-r--r-- 1 root root 1234 Dec  6 12:00 rules.v4
-rw-r--r-- 1 root root  456 Dec  6 12:00 rules.v6
```

[OK] Les fichiers existent !

#### 3. Teste la persistance

**Méthode 1 : Redémarrer le serveur**

```bash
sudo reboot
```

Après le redémarrage, vérifie :

```bash
sudo iptables -L -v -n
```

[OK] Les règles doivent être toujours là !

**Méthode 2 : Tester sans redémarrer (simulation)**

```bash
# Vide temporairement les règles
sudo iptables -F
sudo iptables -L -n  # Plus de règles !

# Restaure depuis la sauvegarde
sudo iptables-restore < /etc/iptables/rules.v4

# Vérifie
sudo iptables -L -n  # Les règles sont revenues ! [OK]
```

#### 4. Commandes de gestion

**Sauvegarder manuellement les règles actuelles :**

```bash
sudo iptables-save > /etc/iptables/rules.v4
```

**Restaurer les règles depuis le fichier :**

```bash
sudo iptables-restore < /etc/iptables/rules.v4
```

**Redémarrer le service :**

```bash
sudo systemctl restart netfilter-persistent
```

---

### [CONFIG] Étape 1.5 : Gestion quotidienne du firewall

#### Ajouter une règle

**Syntaxe générale :**

```bash
sudo iptables -A CHAIN -p PROTOCOL --dport PORT -j ACTION
```

**Exemples pratiques :**

**1. Autoriser un nouveau port (ex: PostgreSQL 5432) :**

```bash
sudo iptables -A INPUT -p tcp --dport 5432 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4
```

**2. Autoriser une IP spécifique (ex: ton bureau) :**

```bash
sudo iptables -A INPUT -s 203.0.113.50 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4
```

**3. Bloquer une IP malveillante :**

```bash
sudo iptables -A INPUT -s 198.51.100.100 -j DROP
sudo iptables-save > /etc/iptables/rules.v4
```

#### Supprimer une règle

**Méthode 1 : Par numéro de ligne**

```bash
# Affiche les règles avec numéros
sudo iptables -L INPUT --line-numbers

# Supprime la règle n°5
sudo iptables -D INPUT 5

# Sauvegarde
sudo iptables-save > /etc/iptables/rules.v4
```

**Méthode 2 : Par correspondance exacte**

```bash
# Supprime une règle spécifique
sudo iptables -D INPUT -p tcp --dport 8080 -j ACCEPT
```

#### Insérer une règle à une position spécifique

```bash
# Insère une règle EN PREMIÈRE POSITION
sudo iptables -I INPUT 1 -s 192.168.1.100 -j ACCEPT
```

**Différence :**
- `-A` = **Append** (ajoute à la fin)
- `-I` = **Insert** (insère à une position spécifique)

**Pourquoi l'ordre est important ?**

iptables traite les règles **de haut en bas**.
Dès qu'une règle correspond, elle est appliquée et le traitement s'arrête.

**Exemple :**

```bash
# Règle 1 : Bloquer tout le trafic de 192.168.1.0/24
iptables -A INPUT -s 192.168.1.0/24 -j DROP

# Règle 2 : Autoriser 192.168.1.50
iptables -A INPUT -s 192.168.1.50 -j ACCEPT
```

[X] **Problème :** La règle 2 ne sera JAMAIS appliquée !
Pourquoi ? Parce que la règle 1 bloque TOUT le trafic de `192.168.1.0/24` (qui inclut `.50`).

[OK] **Solution :** Inverse l'ordre (autorise d'abord `.50`, puis bloque le reste)

```bash
# Règle 1 : Autoriser 192.168.1.50
iptables -A INPUT -s 192.168.1.50 -j ACCEPT

# Règle 2 : Bloquer le reste de 192.168.1.0/24
iptables -A INPUT -s 192.168.1.0/24 -j DROP
```

---

### [ALERTE] Étape 1.6 : Dépannage et problèmes courants

#### Problème 1 : "Je me suis verrouillé hors du serveur"

**Symptôme :** Tu ne peux plus te connecter en SSH

**Solution 1 : Attendre la réinitialisation automatique (si configurée)**

Si tu as configuré la tâche cron de sécurité, attends 5 minutes.

**Solution 2 : Accès console (VirtualBox, KVM, etc.)**

1. Accède à la console directement (pas SSH)
2. Connecte-toi localement
3. Réinitialise le firewall :

```bash
sudo iptables -F
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
```

**Solution 3 : Mode rescue (serveur dédié)**

Demande à ton hébergeur d'activer le mode rescue, puis réinitialise.

#### Problème 2 : "Un service ne fonctionne plus après le firewall"

**Diagnostic :**

```bash
# Affiche les règles et les compteurs
sudo iptables -L -v -n

# Surveille les paquets bloqués en temps réel
sudo tcpdump -i any -n
```

**Solution :**

Identifie le port du service :

```bash
# Trouve quel port utilise le service
sudo netstat -tulpn | grep nom-du-service
```

Autorise ce port :

```bash
sudo iptables -A INPUT -p tcp --dport NUMERO_PORT -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4
```

#### Problème 3 : "Les règles disparaissent au redémarrage"

**Cause :** `iptables-persistent` n'est pas installé ou ne fonctionne pas

**Solution :**

```bash
# Réinstalle le service
sudo apt install --reinstall iptables-persistent -y

# Force la sauvegarde
sudo iptables-save > /etc/iptables/rules.v4

# Active le service au démarrage
sudo systemctl enable netfilter-persistent
sudo systemctl start netfilter-persistent
```

#### Problème 4 : "Comment voir les paquets bloqués ?"

**Solution : Activer le logging**

```bash
# Ajoute une règle de log AVANT la politique DROP
sudo iptables -I INPUT -j LOG --log-prefix "IPTABLES-DROPPED: " --log-level 4

# Surveille les logs
sudo tail -f /var/log/syslog | grep IPTABLES-DROPPED
```

**Résultat :**

```
Dec  6 12:34:56 server kernel: IPTABLES-DROPPED: IN=eth0 OUT= SRC=203.0.113.50 DST=192.168.1.100 PROTO=TCP SPT=54321 DPT=3389
```

**Décryptage :**
- **SRC** = IP source (qui envoie)
- **DST** = IP destination (ton serveur)
- **PROTO** = Protocole (TCP, UDP, ICMP)
- **SPT** = Port source
- **DPT** = Port destination (le port qu'il essaie d'atteindre)

---

## [DOCS] PARTIE 2 : NFTABLES - CONFIGURATION MODERNE

### 🆕 Introduction à nftables

**nftables** est le **successeur moderne** d'iptables.

**Avantages par rapport à iptables :**

| Critère | iptables | nftables |
|---------|----------|----------|
| **Syntaxe** | Complexe, verbeuse | Simple, lisible |
| **Performance** | Bonne | Meilleure (optimisé) |
| **Commandes** | 4 outils séparés (`iptables`, `ip6tables`, `arptables`, `ebtables`) | 1 seul outil (`nft`) |
| **Gestion des règles** | Difficile pour règles complexes | Facile (tables, chaînes) |
| **Atomicité** | Non (les règles s'appliquent une par une) | Oui (tout ou rien) |
| **Syntaxe IPv4/IPv6** | Séparée | Unifiée |

**Exemple de comparaison :**

**iptables :**
```bash
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
```

**nftables (équivalent) :**
```bash
nft add rule inet filter input tcp dport 80 accept
```

[WHITE_UP_POINTING_INDEX] Une seule commande pour IPv4 **ET** IPv6 !

---

### [LISTE] Étape 2.1 : Installation et vérification

#### 1. Vérifie si nftables est déjà installé

```bash
nft --version
```

**Résultat attendu :**
```
nftables v0.9.8 (E.D.S.)
```

[OK] Si tu vois une version, c'est installé !

[X] Si "command not found" :

```bash
# Ubuntu/Debian
sudo apt update
sudo apt install nftables -y

# CentOS/RHEL
sudo yum install nftables -y
```

#### 2. Vérifie le statut du service

```bash
sudo systemctl status nftables
```

**Si le service n'est pas actif :**

```bash
sudo systemctl enable nftables
sudo systemctl start nftables
```

#### 3. Affiche la configuration actuelle

```bash
sudo nft list ruleset
```

**Si vide (serveur neuf) :**
```
# Aucune règle configurée
```

**Si tu as des règles iptables existantes :**

[ATTENTION] **ATTENTION :** nftables et iptables peuvent coexister, mais c'est source de confusion !

**Recommandation :** Désactive iptables si tu utilises nftables :

```bash
# Désactive iptables
sudo systemctl stop iptables
sudo systemctl disable iptables

# Active nftables
sudo systemctl enable nftables
sudo systemctl start nftables
```

---

### [OUTILS] Étape 2.2 : Comprendre la structure nftables

#### Architecture conceptuelle

```
┌────────────────────────────────────────┐
│          NFTABLES ARCHITECTURE         │
├────────────────────────────────────────┤
│                                        │
│  [PACKAGE] TABLE (famille de protocoles)      │
│     ├─ ip (IPv4)                       │
│     ├─ ip6 (IPv6)                      │
│     ├─ inet (IPv4 + IPv6)              │
│     ├─ arp (ARP)                       │
│     └─ bridge (Pont réseau)            │
│                                        │
│     [LIEN] CHAIN (point d'interception)    │
│        ├─ input (entrant)              │
│        ├─ output (sortant)             │
│        └─ forward (transit)            │
│                                        │
│           [DOC] RULE (règle individuelle) │
│              ├─ Condition              │
│              └─ Action                 │
└────────────────────────────────────────┘
```

**Hiérarchie :**

```
TABLE
  └─ CHAIN
       └─ RULE 1
       └─ RULE 2
       └─ RULE 3
```

**Exemple concret :**

```
Table : inet filter
  └─ Chain : input
       ├─ Rule : tcp dport 22 accept (SSH)
       ├─ Rule : tcp dport 80 accept (HTTP)
       └─ Rule : tcp dport 443 accept (HTTPS)
```

#### Les familles de tables

| Famille | Description | Utilisation |
|---------|-------------|-------------|
| `ip` | IPv4 uniquement | Si tu ne gères que IPv4 |
| `ip6` | IPv6 uniquement | Si tu ne gères que IPv6 |
| `inet` | IPv4 + IPv6 * | **Recommandé** (règles unifiées) |
| `arp` | Protocole ARP | Avancé (résolution MAC/IP) |
| `bridge` | Trafic de pont | Pour les bridges réseau |

**On va utiliser `inet` !** (supporte IPv4 et IPv6 avec les mêmes règles)

#### Les types de chaînes

| Type | Hook | Description |
|------|------|-------------|
| `input` | NF_INET_LOCAL_IN | Paquets **destinés** au système local |
| `output` | NF_INET_LOCAL_OUT | Paquets **émis** par le système local |
| `forward` | NF_INET_FORWARD | Paquets **routés** à travers le système |
| `prerouting` | NF_INET_PRE_ROUTING | Avant décision de routage |
| `postrouting` | NF_INET_POST_ROUTING | Après décision de routage |

**Pour un serveur simple, on n'utilise que `input`, `output`, et `forward`.**

---

### [OUTIL] Étape 2.3 : Configuration complète avec nftables

On va créer un script de configuration identique à celui d'iptables, mais avec nftables.

#### 1. Créé le fichier de configuration

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

**Copie-colle cette configuration COMPLÈTE :**

```bash
#!/usr/sbin/nft -f

# ═══════════════════════════════════════════════════════════════
# CONFIGURATION FIREWALL NFTABLES
# ═══════════════════════════════════════════════════════════════
# Créé le : 2024-12-06
# Pour : Sécurisation serveur Linux (méthode moderne)
# ═══════════════════════════════════════════════════════════════

# ────────────────────────────────────────────────────────────────
# SUPPRESSION DE TOUTES LES RÈGLES EXISTANTES
# ────────────────────────────────────────────────────────────────

flush ruleset

# Explication :
# flush ruleset = Supprime TOUTES les tables, chaînes et règles
# C'est comme un "reset" complet
# On repart d'une ardoise vierge *

# ────────────────────────────────────────────────────────────────
# CRÉATION DE LA TABLE PRINCIPALE
# ────────────────────────────────────────────────────────────────

table inet filter {
  
  # Explication :
  # "table inet filter" = Crée une table nommée "filter"
  # "inet" = Famille (IPv4 + IPv6)
  # Tout ce qui suit (jusqu'à l'accolade fermante) appartient à cette table
  
  # ──────────────────────────────────────────────────────────────
  # CHAÎNE INPUT (Trafic entrant)
  # ──────────────────────────────────────────────────────────────
  
  chain input {
    # Configuration de la chaîne
    type filter hook input priority 0; policy drop;
    
    # Explication ligne par ligne :
    # type filter = Type de chaîne (filter, nat, ou route)
    # hook input = Point d'interception (input, output, forward)
    # priority 0 = Priorité (0 = normal, plus bas = plus tôt)
    # policy drop = Politique par défaut : TOUT BLOQUER [X]
    #
    # [ATTENTION] IMPORTANT : policy drop = Sécurité maximale
    # Tout ce qui n'est PAS explicitement autorisé est bloqué
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 1 : Autoriser l'interface loopback (127.0.0.1)   │
    # └─────────────────────────────────────────────────────────┘
    
    iif lo accept
    
    # Explication :
    # iif = Input interface (interface d'entrée)
    # lo = Loopback (127.0.0.1)
    # accept = Autoriser
    #
    # L'interface loopback est la communication interne du serveur
    # avec lui-même. ESSENTIEL pour :
    # - MySQL sur 127.0.0.1:3306
    # - Redis sur 127.0.0.1:6379
    # - Communication inter-processus
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 2 : Autoriser les connexions établies/reliées    │
    # └─────────────────────────────────────────────────────────┘
    
    ct state established,related accept
    
    # Explication :
    # ct = Connection tracking (suivi de connexion)
    # state established,related = États établi ou relié
    # accept = Autoriser
    #
    # CRUCIAL pour que les connexions déjà établies fonctionnent !
    # Exemple : Tu es connecté en SSH, cette règle permet aux
    # paquets de ta session active de continuer à passer
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 3 : Bloquer les paquets invalides                │
    # └─────────────────────────────────────────────────────────┘
    
    ct state invalid drop
    
    # Explication :
    # Paquets invalides = paquets malformés ou suspects
    # Toujours signe d'une tentative d'attaque ou d'un bug
    # On les jette silencieusement
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 4 : Autoriser SSH (port 22) avec protection      │
    # └─────────────────────────────────────────────────────────┘
    
    # Limite : Maximum 3 nouvelles connexions par minute par IP
    tcp dport 22 ct state new limit rate 3/minute accept
    
    # Explication :
    # tcp dport 22 = TCP port destination 22 (SSH)
    # ct state new = Seulement les NOUVELLES connexions
    # limit rate 3/minute = Maximum 3 tentatives par minute
    # accept = Autoriser si dans la limite
    #
    # Protection contre les attaques par force brute :
    # - Connexion normale : 1-2 tentatives -> OK [OK]
    # - Bot qui essaie 1000 mots de passe : > 3/min -> BLOQUÉ [X]
    #
    # Après 3 tentatives, les suivantes sont ignorées (policy drop)
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 5 : Autoriser HTTP et HTTPS                      │
    # └─────────────────────────────────────────────────────────┘
    
    tcp dport { 80, 443 } accept
    
    # Explication :
    # tcp dport { 80, 443 } = Ports 80 ET 443
    # Les accolades {} permettent de grouper plusieurs valeurs
    # accept = Autoriser
    #
    # Port 80 = HTTP (sites web non sécurisés)
    # Port 443 = HTTPS (sites web sécurisés avec SSL/TLS)
    #
    # Si tu héberges un site web, ces ports DOIVENT être ouverts
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 6 : Autoriser DNS (port 53)                      │
    # └─────────────────────────────────────────────────────────┘
    
    tcp dport 53 accept
    udp dport 53 accept
    
    # Explication :
    # DNS utilise UDP (95% du temps) et TCP (gros transferts)
    # Si tu as DNSmasq ou un serveur DNS, ces ports sont nécessaires
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 7 : Autoriser DHCP (ports 67-68)                 │
    # └─────────────────────────────────────────────────────────┘
    
    udp dport { 67, 68 } accept
    
    # Explication :
    # Port 67 = Serveur DHCP
    # Port 68 = Client DHCP
    # Si tu as DNSmasq comme serveur DHCP, ces ports sont nécessaires
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 8 : Autoriser ICMP (ping) avec limitation        │
    # └─────────────────────────────────────────────────────────┘
    
    icmp type echo-request limit rate 1/second accept
    icmpv6 type echo-request limit rate 1/second accept
    
    # Explication :
    # icmp type echo-request = Requête ping (IPv4)
    # icmpv6 type echo-request = Requête ping (IPv6)
    # limit rate 1/second = Maximum 1 ping par seconde
    # accept = Autoriser si dans la limite
    #
    # Protection contre les attaques "ping flood" (DDoS basique)
    # - Ping normal : OK [OK]
    # - Flood (1000 pings/sec) : Bloqué après le 1er [X]
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 9 : Bloquer des IP spécifiques (blacklist)       │
    # └─────────────────────────────────────────────────────────┘
    
    # Exemple : Bloquer une IP malveillante
    # Décommente et remplace par l'IP à bloquer
    # ip saddr 203.0.113.50 drop
    # ip saddr 198.51.100.0/24 drop
    
    # Explication :
    # ip saddr = IP source address (adresse IP source)
    # drop = Bloquer silencieusement
    # /24 = Plage d'IPs (les 256 IPs de .0 à .255)
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ RÈGLE 10 : Protection contre les scans de ports        │
    # └─────────────────────────────────────────────────────────┘
    
    # Bloquer les scans NULL (aucun flag)
    tcp flags == 0x0 drop
    
    # Bloquer les scans XMAS (tous les flags)
    tcp flags == 0x3f drop
    
    # Bloquer les scans FIN seuls
    tcp flags fin drop
    
    # Bloquer les scans SYN-FIN (incohérent)
    tcp flags & (syn|fin) == (syn|fin) drop
    
    # Explication :
    # Ces types de paquets sont utilisés par des outils comme nmap
    # pour scanner les ports de manière furtive
    # Aucun trafic légitime n'utilise ces patterns
    # On les bloque silencieusement
    
    # ┌─────────────────────────────────────────────────────────┐
    # │ FIN DE LA CHAÎNE INPUT                                  │
    # └─────────────────────────────────────────────────────────┘
    
    # Tout ce qui n'a pas été accepté explicitement ci-dessus
    # sera bloqué par la politique par défaut (policy drop)
  }
  
  # ──────────────────────────────────────────────────────────────
  # CHAÎNE OUTPUT (Trafic sortant)
  # ──────────────────────────────────────────────────────────────
  
  chain output {
    type filter hook output priority 0; policy accept;
    
    # Explication :
    # policy accept = TOUT AUTORISER par défaut
    #
    # Le trafic sortant est généralement sûr :
    # - Le serveur fait des mises à jour (apt, yum)
    # - Il envoie des emails
    # - Il fait des requêtes API
    #
    # Pour une sécurité MAXIMALE, tu pourrais mettre "policy drop"
    # et autoriser seulement les ports nécessaires, mais c'est
    # beaucoup plus complexe à gérer
  }
  
  # ──────────────────────────────────────────────────────────────
  # CHAÎNE FORWARD (Trafic en transit / routage)
  # ──────────────────────────────────────────────────────────────
  
  chain forward {
    type filter hook forward priority 0; policy drop;
    
    # Explication :
    # policy drop = TOUT BLOQUER par défaut
    #
    # La chaîne FORWARD concerne le trafic qui TRAVERSE le serveur
    # (routage entre deux réseaux)
    #
    # Si ton serveur n'est PAS un routeur/gateway :
    # -> Laisse "policy drop" (plus sécurisé)
    #
    # Si ton serveur EST un routeur (ex: firewall d'entreprise) :
    # -> Ajoute des règles pour autoriser le trafic souhaité
    #
    # Pour notre cas (serveur simple), on laisse tout bloqué
  }
}

# ═══════════════════════════════════════════════════════════════
# FIN DE LA CONFIGURATION
# ═══════════════════════════════════════════════════════════════
```

#### 2. Applique la configuration

```bash
sudo nft -f /etc/nftables.conf
```

**Explication :**
```
nft -f FILE = Exécute les commandes depuis un fichier
```

**Résultat attendu :**
```
# Aucune erreur = Succès ! [OK]
```

[X] **Si tu vois une erreur de syntaxe :**
```
Error: syntax error, unexpected TOKEN
```

Vérifie :
1. Les accolades sont bien fermées `{}`
2. Les virgules dans les listes `{ 80, 443 }`
3. Les point-virgules `;` à la fin des lignes importantes

#### 3. Vérifie les règles actives

```bash
sudo nft list ruleset
```

**Résultat attendu : Tu verras toute la configuration affichée.**

#### 4. TESTE IMMÉDIATEMENT TA CONNEXION SSH

Comme pour iptables :
1. Ouvre un NOUVEAU terminal
2. Teste SSH : `ssh user@serveur`
3. [OK] Si ça marche -> Parfait !
4. [X] Si bloqué -> Accède en console et réinitialise

**Réinitialisation d'urgence (console) :**

```bash
sudo nft flush ruleset
sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0\; policy accept\; }
```

---

### [SAUVEGARDE] Étape 2.4 : Rendre la configuration persistante

#### 1. Active le service au démarrage

```bash
sudo systemctl enable nftables
```

#### 2. Vérifie que le fichier de config est bien chargé

```bash
sudo systemctl restart nftables
sudo nft list ruleset
```

[OK] Les règles doivent être là !

#### 3. Teste la persistance

```bash
# Redémarre le serveur
sudo reboot

# Après redémarrage, vérifie
sudo nft list ruleset
```

[OK] Les règles doivent persister !

---

### [CONFIG] Étape 2.5 : Gestion quotidienne avec nftables

#### Ajouter une règle temporairement (en ligne de commande)

**Autoriser un nouveau port :**

```bash
sudo nft add rule inet filter input tcp dport 8080 accept
```

[ATTENTION] **Attention :** Cette règle disparaîtra au redémarrage !

Pour la rendre permanente, ajoute-la dans `/etc/nftables.conf` puis :

```bash
sudo systemctl reload nftables
```

#### Supprimer une règle

**Méthode 1 : Par handle (identifiant)**

```bash
# Liste les règles avec leurs handles
sudo nft -a list ruleset

# Résultat (exemple) :
# table inet filter {
#   chain input {
#     tcp dport 8080 accept # handle 42
#   }
# }

# Supprime la règle avec handle 42
sudo nft delete rule inet filter input handle 42
```

**Méthode 2 : Rééditer le fichier de config**

```bash
sudo nano /etc/nftables.conf
# Supprime la ligne
sudo systemctl reload nftables
```

#### Lister les règles de manière lisible

```bash
# Affichage par défaut (complet)
sudo nft list ruleset

# Afficher seulement la table filter
sudo nft list table inet filter

# Afficher seulement la chaîne input
sudo nft list chain inet filter input
```

#### Sauvegarder la configuration actuelle

```bash
sudo nft list ruleset > /root/nftables-backup-$(date +%Y%m%d).conf
```

#### Restaurer depuis une sauvegarde

```bash
sudo nft -f /root/nftables-backup-20241206.conf
```

---

## [VERROUILLE] PARTIE 3 : SÉCURITÉ AVANCÉE

### [SECURITE] Étape 3.1 : Installer fail2ban (Protection SSH renforcée)

**fail2ban** surveille les logs et **bannit automatiquement** les IPs qui tentent trop de connexions.

#### 1. Installation

```bash
sudo apt install fail2ban -y
```

#### 2. Configuration

```bash
sudo nano /etc/fail2ban/jail.local
```

**Copie-colle cette configuration :**

```ini
[DEFAULT]
# Durée de bannissement (en secondes)
# 3600 = 1 heure
bantime = 3600

# Temps de surveillance (en secondes)
# 600 = 10 minutes
findtime = 600

# Nombre de tentatives avant bannissement
maxretry = 3

[sshd]
enabled = true
port = 22
logpath = /var/log/auth.log
maxretry = 3
```

**Explication :**
- Si une IP rate 3 connexions SSH en 10 minutes
- -> Elle est bannie pour 1 heure

#### 3. Redémarre fail2ban

```bash
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
```

#### 4. Vérifie le statut

```bash
sudo fail2ban-client status sshd
```

**Résultat :**
```
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:
```

---

### [GRAPHIQUE] Étape 3.2 : Monitoring et logs

#### Surveiller les tentatives de connexion

```bash
# Voir les tentatives SSH échouées
sudo grep "Failed password" /var/log/auth.log

# Compter les tentatives par IP
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr
```

#### Surveiller les connexions actives

```bash
# Voir qui est connecté en SSH
who

# Voir toutes les connexions réseau
sudo netstat -tulpn

# Ou avec ss (plus moderne)
sudo ss -tulpn
```

---

## [COURS] RÉCAPITULATIF COMPLET

### [OK] Ce qu'on a appris

1. **Concepts de base** :
   - Firewall = porte d'entrée sécurisée
   - Ports = appartements dans un immeuble
   - Actions : ACCEPT / DROP / REJECT

2. **iptables** :
   - Configuration complète avec script
   - Persistance avec iptables-persistent
   - Protection SSH, HTTP, DNS, DHCP

3. **nftables** :
   - Syntaxe moderne et lisible
   - Configuration unifiée IPv4/IPv6
   - Gestion plus simple

4. **Sécurité avancée** :
   - fail2ban pour protection SSH
   - Limitation de débit (rate limiting)
   - Protection contre scans de ports

### [NOTE] Commandes essentielles à retenir

**iptables :**
```bash
# Lister les règles
sudo iptables -L -v -n

# Sauvegarder
sudo iptables-save > /etc/iptables/rules.v4

# Restaurer
sudo iptables-restore < /etc/iptables/rules.v4
```

**nftables :**
```bash
# Lister les règles
sudo nft list ruleset

# Appliquer un fichier de config
sudo nft -f /etc/nftables.conf

# Flush (tout supprimer)
sudo nft flush ruleset
```

---

## [OBJECTIF] EXERCICES PRATIQUES

### Exercice 1 : Ouvrir un port personnalisé

**Objectif :** Autoriser le port 3000 (Node.js)

**Avec iptables :**
```bash
sudo iptables -A INPUT -p tcp --dport 3000 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4
```

**Avec nftables :**
```bash
sudo nft add rule inet filter input tcp dport 3000 accept
# Ajoute dans /etc/nftables.conf pour persistance
```

### Exercice 2 : Bloquer une IP

**Objectif :** Bloquer l'IP 203.0.113.50

**Avec iptables :**
```bash
sudo iptables -I INPUT -s 203.0.113.50 -j DROP
sudo iptables-save > /etc/iptables/rules.v4
```

**Avec nftables :**
```bash
sudo nft add rule inet filter input ip saddr 203.0.113.50 drop
```

### Exercice 3 : Autoriser une plage d'IPs

**Objectif :** Autoriser uniquement ton réseau local (192.168.1.0/24) à accéder au port 3306 (MySQL)

**Avec iptables :**
```bash
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 3306 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4
```

**Avec nftables :**
```bash
sudo nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 3306 accept
```

---

## [BRAVO] CONCLUSION

**Félicitations ! [BRAVO]**

Tu maîtrises maintenant :
- [OK] Les concepts fondamentaux des firewalls
- [OK] La configuration d'iptables (méthode classique)
- [OK] La configuration de nftables (méthode moderne)
- [OK] La sécurisation d'un serveur Linux
- [OK] La protection contre les attaques courantes

**Ton serveur est maintenant sécurisé ! [SECURITE][VERROUILLE]**

---

### [DOCS] Ressources supplémentaires

- Documentation iptables : `man iptables`
- Documentation nftables : `man nft`
- Wiki nftables : https://wiki.nftables.org/
- fail2ban docs : https://www.fail2ban.org/

---

**[RAPIDE] Prochaine étape suggérée :**
- Configuration d'un VPN (WireGuard ou OpenVPN)
- Mise en place d'un système de détection d'intrusion (IDS)
- Hardening Linux avancé
