# Fichier: python_cheats/cheatsheets/configuration.txt
# Cheatsheet Configuration Linux - Guide Ultra-Détaillé pour Grands Débutants

```
[OK] CONCEPTS FONDAMENTAUX (EXPLICATIONS TRÈS DÉTAILLÉES)

# === QU'EST-CE QU'UN ADMINISTRATEUR LINUX ? ===

# Imagine que Linux est comme un immeuble géant avec des milliers d'appartements
# Un administrateur Linux = Le gardien/gestionnaire de cet immeuble
# Il s'occupe de :
# - Qui peut entrer (utilisateurs et permissions)
# - Que les portes fonctionnent (services)
# - Que l'eau et l'électricité marchent (réseau et système)
# - Réparer les problèmes (dépannage et logs)
# - Faire les mises à jour (maintenance)

# Linux != Windows ou macOS
# Linux = Système d'exploitation libre et gratuit
# Utilisé pour 90% des serveurs web dans le monde!
# Exemples: Ubuntu, CentOS, Debian, Red Hat, Fedora

# === POURQUOI APPRENDRE LA CONFIGURATION LINUX? ===

# Cas d'usage réels:
# 1. Héberger un site web (WordPress, Django, Flask)
# 2. Créer un serveur de base de données (MySQL, PostgreSQL)
# 3. Déployer une application (Docker, Kubernetes)
# 4. Gérer un serveur cloud (AWS, DigitalOcean, Azure)
# 5. Automatiser des tâches (scripts Bash, cron jobs)

# Sans configuration Linux:
# - Ton site web peut être hacké facilement
# - Ton serveur peut crasher sans prévenir
# - Tes données peuvent être perdues
# - Les performances sont mauvaises

# Avec bonne configuration:
# - Sécurité maximale (firewall, SSH, permissions)
# - Haute disponibilité (monitoring, backups)
# - Performances optimales (optimisation système)
# - Facilité de maintenance (logs, automatisation)


# === VOCABULAIRE LINUX (TRÈS IMPORTANT!) ===

# DISTRIBUTION (Distro)
# = Une "saveur" de Linux avec des outils pré-installés
# Analogie: Android vs iOS pour smartphones, Ubuntu vs CentOS pour serveurs
# Principales distributions:
#   - Ubuntu: Facile, grand débutant, communauté énorme
#   - Debian: Stable, pour serveurs professionnels
#   - CentOS/RHEL: Pour entreprises (Red Hat Enterprise Linux)
#   - Fedora: Version "testing" de Red Hat
#   - Arch Linux: Pour experts, très personnalisable

# SHELL / TERMINAL / CONSOLE
# = Interface texte pour taper des commandes
# Analogie: Comme le CMD/PowerShell sur Windows
# Shells populaires:
#   - bash: Le plus courant (Bourne Again Shell)
#   - zsh: Plus moderne, avec auto-complétion
#   - fish: Très user-friendly
# Tu tapes: ls -la
# Le shell exécute: affiche la liste des fichiers

# ROOT / SUPERUSER
# = L'utilisateur tout-puissant sur Linux
# Analogie: Comme "Administrateur" sur Windows
# root peut TOUT faire:
#   - Installer/supprimer des logiciels
#   - Modifier les fichiers système
#   - Créer/supprimer des utilisateurs
#   - Arrêter/redémarrer le serveur
# DANGER: Ne jamais travailler en root par défaut!
# Utiliser sudo pour des commandes ponctuelles

# SUDO (Super User DO)
# = Exécuter une commande avec les privilèges root
# Exemple: sudo apt update
# = "Exécute apt update en tant que root"
# Demande ton mot de passe pour confirmation
# Plus sûr que de se connecter en root

# PACKAGE MANAGER (Gestionnaire de paquets)
# = App Store pour Linux
# Permet d'installer des logiciels facilement
# Selon la distribution:
#   - Ubuntu/Debian: apt ou apt-get
#   - CentOS/RHEL: yum ou dnf
#   - Arch: pacman
# Exemple: sudo apt install nginx
# = Installe le serveur web Nginx

# DAEMON / SERVICE
# = Programme qui tourne en arrière-plan
# Analogie: Comme les services Windows
# Exemples:
#   - sshd: Service SSH pour connexion à distance
#   - nginx: Serveur web
#   - mysqld: Base de données MySQL
#   - cron: Planificateur de tâches
# Contrôle via systemd (systemctl)

# SYSTEMD
# = Gestionnaire de services moderne sur Linux
# Remplace l'ancien init system
# Commandes:
#   - systemctl start nginx: Démarrer Nginx
#   - systemctl stop nginx: Arrêter Nginx
#   - systemctl enable nginx: Démarrer au boot
#   - systemctl status nginx: Voir le statut

# FILESYSTEM (Système de fichiers)
# = Organisation des fichiers sur le disque
# Linux n'a PAS de C:\ ou D:\
# Tout commence à la racine: /
# Structure:
#   /home: Dossiers des utilisateurs
#   /etc: Fichiers de configuration
#   /var: Données variables (logs, cache)
#   /usr: Programmes installés
#   /tmp: Fichiers temporaires
#   /root: Dossier du superuser

# PERMISSIONS
# = Qui peut lire/écrire/exécuter un fichier
# 3 niveaux: User / Group / Others
# 3 permissions: Read / Write / Execute
# Exemple: -rwxr-xr--
#   - rwx: User peut tout faire
#   - r-x: Group peut lire et exécuter
#   - r--: Others peut seulement lire

# PORT
# = Numéro pour identifier un service réseau
# Analogie: Comme un numéro d'appartement
# Ports courants:
#   - 22: SSH (connexion sécurisée)
#   - 80: HTTP (sites web)
#   - 443: HTTPS (sites web sécurisés)
#   - 3306: MySQL
#   - 5432: PostgreSQL
#   - 6379: Redis

# FIREWALL
# = Barrière de sécurité réseau
# Bloque ou autorise les connexions
# Outils:
#   - ufw: Simple, pour Ubuntu
#   - firewalld: Pour CentOS/RHEL
#   - iptables: Bas niveau, complexe


# === COMMENT ÇA MARCHE? (FLUX COMPLET) ===

# 1. Tu achètes un serveur Linux (VPS, cloud, etc)
#    Exemples: DigitalOcean, AWS EC2, Linode, OVH
#    Prix: $5-$50/mois selon les ressources

# 2. Tu te connectes via SSH:
#    ssh root@192.168.1.100
#    (SSH = connexion sécurisée à distance)

# 3. Tu configures le serveur:
#    a. Créer des utilisateurs (pas travailler en root!)
#    b. Configurer le firewall (bloquer les accès non autorisés)
#    c. Installer les logiciels (Nginx, MySQL, Python, etc)
#    d. Configurer les services (démarrage auto, ports, etc)

# 4. Tu déploies ton application:
#    a. Copier le code (git clone, scp, etc)
#    b. Configurer la base de données
#    c. Lancer l'app (Gunicorn, uWSGI, etc)
#    d. Configurer le reverse proxy (Nginx)

# 5. Tu surveilles et maintiens:
#    a. Vérifier les logs régulièrement
#    b. Mettre à jour le système (sécurité!)
#    c. Faire des backups (sauvegardes)
#    d. Optimiser les performances si besoin


[OK] INSTALLATION ET PREMIERS PAS

# === ÉTAPE 1: SE CONNECTER À UN SERVEUR LINUX ===

# Pourquoi? Tu dois accéder au serveur pour le configurer

# === SUR LINUX/macOS (SSH natif) ===

# Ouvre un terminal et tape:
ssh username@server_ip

# Exemple:
ssh root@192.168.1.100

# Qu'il se passe:
# 1. SSH demande le mot de passe
# 2. Tu tapes le mot de passe (ne s'affiche pas!)
# 3. Tu es connecté: root@server:~#

# Première connexion:
# SSH demande: "Êtes-vous sûr de vouloir vous connecter?"
# Tape: yes

# === SUR WINDOWS ===

# Option 1: PowerShell (Windows 10+)
# Même commande que Linux:
ssh username@server_ip

# Option 2: PuTTY (ancien Windows)
# 1. Télécharger PuTTY: https://www.putty.org/
# 2. Installer et ouvrir
# 3. Dans "Host Name": taper server_ip
# 4. Port: 22
# 5. Cliquer "Open"
# 6. Taper username et password

# === SE DÉCONNECTER ===
exit
# ou
logout
# ou
Ctrl+D


# === ÉTAPE 2: VÉRIFIER LE SYSTÈME ===

# Une fois connecté, vérifie quel système tu as:

# Version de la distribution:
cat /etc/os-release

# Affiche:
# NAME="Ubuntu"
# VERSION="22.04.3 LTS (Jammy Jellyfish)"
# ID=ubuntu
# ...

# Version du kernel (noyau Linux):
uname -r

# Affiche:
# 5.15.0-91-generic

# Nom du serveur (hostname):
hostname

# Affiche:
# myserver

# Explications:
# - /etc/os-release: Fichier avec les infos de la distro
# - uname: Commande pour info système
# - hostname: Nom d'hôte du serveur


# === ÉTAPE 3: METTRE À JOUR LE SYSTÈME ===

# TRÈS IMPORTANT: Toujours faire ça en premier!
# Pourquoi? Corriger les bugs et failles de sécurité

# === UBUNTU/DEBIAN ===

# Mettre à jour la liste des packages disponibles:
sudo apt update

# Affiche:
# Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
# Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
# ...
# Reading package lists... Done

# Installer les mises à jour:
sudo apt upgrade

# Demande confirmation: Do you want to continue? [Y/n]
# Tape: Y

# Affiche:
# Reading package lists... Done
# Building dependency tree
# ...
# Unpacking nginx (1.18.0-6ubuntu14.4) ...
# Setting up nginx (1.18.0-6ubuntu14.4) ...

# Tout en une commande (sans confirmation):
sudo apt update && sudo apt upgrade -y

# Explications:
# apt update: Télécharge la liste des packages disponibles
# apt upgrade: Installe les nouvelles versions
# -y: Répond automatiquement "yes"
# &&: Exécute la 2ème commande si la 1ère réussit


# === CentOS/RHEL (ancien, avant CentOS 8) ===

# Mettre à jour:
sudo yum update

# Tout en une commande:
sudo yum update -y


# === CentOS 8+ / Fedora (DNF) ===

# Mettre à jour:
sudo dnf update

# Tout en une commande:
sudo dnf update -y


# === ÉTAPE 4: INSTALLER DES OUTILS ESSENTIELS ===

# Outils de base à avoir sur TOUS les serveurs:

# === UBUNTU/DEBIAN ===

sudo apt install -y \
  curl \
  wget \
  vim \
  nano \
  htop \
  net-tools \
  git \
  build-essential \
  software-properties-common

# Explications des outils:
# - curl: Télécharger des fichiers via HTTP
# - wget: Télécharger des fichiers (alternative à curl)
# - vim: Éditeur de texte puissant (avancé)
# - nano: Éditeur de texte simple (débutant)
# - htop: Moniteur de processus interactif
# - net-tools: Outils réseau (ifconfig, netstat, etc)
# - git: Gestion de versions (pour cloner du code)
# - build-essential: Compilateurs C/C++ (pour compiler du code)
# - software-properties-common: Gérer les dépôts (add-apt-repository)

# Vérifier l'installation:
curl --version
git --version
htop --version


# === CentOS/RHEL ===

sudo yum install -y \
  curl \
  wget \
  vim \
  nano \
  htop \
  net-tools \
  git \
  gcc \
  make


[OK] CONFIGURATION RÉSEAU (INDISPENSABLE)

[HOT] CONFIGURATION RÉSEAU LINUX — EXPLICATION DÉTAILLÉE

La configuration réseau est l’une des compétences les plus importantes d’un administrateur Linux. Sans réseau, un serveur est inutile : pas d’accès SSH, pas de mise à jour, pas d’accès web, pas de monitoring.

On va tout revoir en profondeur :
concepts -> diagnostic -> configuration -> tests -> fichiers système.

[MODULE] 1. Comprendre le réseau Linux

Le réseau détermine comment le serveur communique dans un réseau local ou Internet.
Il repose sur 4 paramètres fondamentaux :

1⃣ Adresse IP

C’est comme l’adresse postale de la machine.

Exemple d’IP privée : 192.168.1.100
-> visible seulement dans un réseau local

Exemple d’IP publique : 203.0.113.5
-> visible sur Internet, attribuée par le fournisseur

Pourquoi deux types d’IP ?

IP publique : donne accès externe, ex: serveur web
IP privée : protège le serveur derrière un routeur ou firewall
Les serveurs en entreprise utilisent presque toujours une IP privée derrière un firewall avec des règles NAT.

2⃣ Masque de sous-réseau (Netmask)

Définit la taille du réseau local.

Exemples :

Masque	Notation	Nombre d’adresses
255.255.255.0	/24	254 machines
255.255.0.0	/16	65 534 machines
255.0.0.0	/8	16 millions

Un serveur : 192.168.1.100/24
-> signifie que le réseau est : 192.168.1.0 – 192.168.1.255

3⃣ Gateway (Passerelle)

C’est le routeur par lequel tout le trafic Internet passe.

Exemple :
192.168.1.1 = routeur local

Si cette valeur est incorrecte, le serveur ne peut pas sortir sur Internet (impossible d’installer des paquets, impossible de ping 8.8.8.8).

4⃣ DNS (Serveur de noms)

DNS convertit les noms (google.com) en IP (142.250.74.110).
Sans DNS :
ping google.com -> [X] ne marche pas
ping 8.8.8.8 -> [OK] marche

Exemples de DNS :
8.8.8.8 (Google)
1.1.1.1 (Cloudflare)
208.67.222.222 (OpenDNS)


# === COMPRENDRE LE RÉSEAU LINUX ===

# Réseau = Comment ton serveur communique avec Internet
# Concepts clés:
# - IP Address: Adresse unique du serveur (ex: 192.168.1.100)
# - Netmask: Sous-réseau (ex: 255.255.255.0 ou /24)
# - Gateway: Routeur par défaut (ex: 192.168.1.1)
# - DNS: Serveur de noms de domaine (ex: 8.8.8.8 = Google DNS)

# Types d'IP:
# - IP Publique: Visible sur Internet (ex: 203.0.113.5)
# - IP Privée: Seulement sur réseau local (ex: 192.168.x.x ou 10.x.x.x)


# === ÉTAPE 1: VOIR LA CONFIGURATION ACTUELLE ===

# Commande moderne (recommandée):
ip addr show

# Affiche:
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
#     inet 127.0.0.1/8 scope host lo
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP
#     inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0

# Explications:
# - lo: Interface loopback (127.0.0.1, connexion à soi-même)
# - eth0: Interface réseau principale (connexion Internet)
# - inet 192.168.1.100/24: IP du serveur avec masque /24

# Ancienne commande (encore utilisée):
ifconfig

# Affiche:
# eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
#         inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255

# Voir les routes (gateway):
ip route show

# Affiche:
# default via 192.168.1.1 dev eth0
# 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100

# Explications:
# - default via 192.168.1.1: Tout le trafic passe par 192.168.1.1
# - dev eth0: Via l'interface eth0

# Voir le DNS:
cat /etc/resolv.conf

# Affiche:
# nameserver 8.8.8.8
# nameserver 8.8.4.4

# Explications:
# - nameserver: Serveur DNS utilisé (ici Google DNS)


# === ÉTAPE 2: CONFIGURER UNE IP STATIQUE ===

# Pourquoi? Pour que l'IP du serveur ne change jamais
# DHCP = IP attribuée automatiquement (peut changer!)
# IP Statique = IP fixe (ne change jamais)

# === UBUNTU 18.04+ (Netplan) ===

# Netplan = Outil de configuration réseau moderne

# Éditer le fichier de config:
sudo nano /etc/netplan/01-netcfg.yaml

# Contenu pour IP statique:
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      gateway4: 192.168.1.1
      nameservers:
        addresses:
          - 8.8.8.8
          - 8.8.4.4

# Explications ligne par ligne:
# version: 2: Version de Netplan
# renderer: networkd: Backend utilisé
# ethernets: Configuration des interfaces Ethernet
# eth0: Nom de l'interface (peut être ens33, enp0s3, etc)
# dhcp4: no: Désactiver DHCP (IP dynamique)
# addresses: IP fixe avec masque /24
# gateway4: Routeur par défaut
# nameservers: Serveurs DNS (Google DNS)

# Sauvegarder: Ctrl+O puis Enter
# Quitter: Ctrl+X

# Appliquer la configuration:
sudo netplan apply

# Vérifier:
ip addr show eth0
# Doit afficher: inet 192.168.1.100/24

# Si erreur:
sudo netplan --debug apply
# Affiche les erreurs de syntaxe

# IMPORTANT: Teste avant de te déconnecter!
ping 8.8.8.8
# Si ça marche: configuration OK
# Si ça ne marche pas: revenir en arrière


# === UBUNTU 16.04 et avant (interfaces) ===

# Éditer le fichier:
sudo nano /etc/network/interfaces

# Contenu:
auto eth0
iface eth0 inet static
  address 192.168.1.100
  netmask 255.255.255.0
  gateway 192.168.1.1
  dns-nameservers 8.8.8.8 8.8.4.4

# Redémarrer le réseau:
sudo systemctl restart networking

# Vérifier:
ip addr show eth0


# === CentOS/RHEL 7 ===

# Éditer le fichier:
sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0

# Contenu:
DEVICE=eth0
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4

# Explications:
# BOOTPROTO=static: IP statique
# ONBOOT=yes: Activer au démarrage
# IPADDR: IP du serveur
# NETMASK: Masque de sous-réseau
# GATEWAY: Routeur
# DNS1/DNS2: Serveurs DNS

# Redémarrer le réseau:
sudo systemctl restart network

# Vérifier:
ip addr show eth0


# === CentOS 8+ / RHEL 8+ (NetworkManager) ===

# Utiliser nmcli (Network Manager CLI):

# Voir les connexions:
nmcli connection show

# Affiche:
# NAME    UUID                                  TYPE      DEVICE
# eth0    5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03  ethernet  eth0

# Configurer IP statique:
sudo nmcli connection modify eth0 \
  ipv4.addresses 192.168.1.100/24 \
  ipv4.gateway 192.168.1.1 \
  ipv4.dns "8.8.8.8 8.8.4.4" \
  ipv4.method manual

# Explications:
# connection modify eth0: Modifier la connexion eth0
# ipv4.addresses: IP et masque
# ipv4.gateway: Routeur
# ipv4.dns: Serveurs DNS (entre guillemets!)
# ipv4.method manual: IP statique (pas DHCP)

# Redémarrer la connexion:
sudo nmcli connection down eth0
sudo nmcli connection up eth0

# Vérifier:
ip addr show eth0


# === ÉTAPE 3: TESTER LA CONNECTIVITÉ ===

# Ping un serveur externe:
ping -c 4 8.8.8.8

# Affiche:
# PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
# 64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=10.2 ms
# 64 bytes from 8.8.8.8: icmp_seq=2 ttl=117 time=9.8 ms
# ...
# 4 packets transmitted, 4 received, 0% packet loss

# Explications:
# -c 4: Envoyer 4 paquets
# 8.8.8.8: Google DNS
# time=10.2 ms: Temps de réponse (ping)
# 0% packet loss: Aucun paquet perdu (connexion OK!)

# Tester un nom de domaine:
ping -c 4 google.com

# Si ça marche: DNS fonctionne!
# Si erreur "unknown host": problème DNS

# Tracer la route vers un serveur:
traceroute google.com

# Affiche tous les routeurs traversés

# Tester un port spécifique:
telnet google.com 80

# Si connexion réussie: port ouvert
# Ctrl+] puis quit pour sortir


# === ÉTAPE 4: FICHIERS RÉSEAU IMPORTANTS ===

# /etc/hosts
# = Associer des noms à des IPs localement
# Utile pour: tester avant DNS, accès rapide

# Éditer:
sudo nano /etc/hosts

# Contenu exemple:
127.0.0.1   localhost
192.168.1.100   myserver myserver.local
192.168.1.10    database db.local

# Explications:
# Chaque ligne: IP <espace> nom(s)
# Quand tu tapes "ssh myserver", ça va vers 192.168.1.100
# Prioritaire sur DNS!

# Tester:
ping myserver
# Ping 192.168.1.100 automatiquement


# /etc/hostname
# = Nom du serveur

# Voir le nom actuel:
cat /etc/hostname

# Affiche:
# myserver

# Changer le nom:
sudo hostnamectl set-hostname newname

# Vérifier:
hostname
# Affiche: newname

# Redémarrer pour appliquer partout:
sudo reboot


# /etc/resolv.conf
# = Configuration DNS

# Éditer:
sudo nano /etc/resolv.conf

# Contenu:
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1

# Explications:
# nameserver: Serveur DNS à utiliser
# Ordre: Essaie le premier, puis le deuxième si échec
# 8.8.8.8: Google DNS
# 1.1.1.1: Cloudflare DNS

# ATTENTION: Sur Ubuntu avec Netplan ou systemd-resolved,
# /etc/resolv.conf est un lien symbolique généré automatiquement!
# Ne pas éditer directement, utiliser Netplan ou:
sudo nano /etc/systemd/resolved.conf

# Contenu:
[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1

# Redémarrer:
sudo systemctl restart systemd-resolved


[OK] GESTION DES UTILISATEURS & PERMISSIONS

# === POURQUOI GÉRER LES UTILISATEURS? ===

# Par défaut, tu te connectes en root = DANGEREUX!
# root peut TOUT faire, même détruire le système par accident
# Meilleure pratique: Créer un utilisateur normal avec sudo

# Cas d'usage:
# - Utilisateur admin: Peut tout faire (via sudo)
# - Utilisateur app: Exécute l'application (limité)
# - Utilisateur backup: Fait les sauvegardes (limité)


# === ÉTAPE 1: CRÉER UN UTILISATEUR ===

# Créer un nouvel utilisateur:
sudo adduser john

# Affiche:
# Adding user `john' ...
# Adding new group `john' (1001) ...
# Adding new user `john' (1001) with group `john' ...
# Creating home directory `/home/john' ...
# Enter new UNIX password:

# Tape le mot de passe (2 fois)
# Puis remplis les infos (optionnel):
# Full Name: John Doe
# Room Number: [Enter]
# Work Phone: [Enter]
# ...

# Explications:
# - adduser: Commande interactive (facile)
# - Crée l'utilisateur john
# - Crée un groupe john
# - Crée le dossier /home/john
# - Demande le mot de passe

# Alternative (moins interactive):
sudo useradd -m -s /bin/bash john

# Explications:
# useradd: Commande bas niveau
# -m: Créer le home directory
# -s /bin/bash: Shell par défaut (bash)
# john: Nom de l'utilisateur

# Définir le mot de passe:
sudo passwd john

# Affiche:
# Enter new UNIX password:
# Retype new UNIX password:


# === ÉTAPE 2: DONNER LES PRIVILÈGES SUDO ===

# Ajouter john au groupe sudo:
sudo usermod -aG sudo john

# Explications:
# usermod: Modifier un utilisateur
# -aG: Ajouter (append) à un groupe
# sudo: Groupe avec privilèges sudo
# john: Utilisateur à modifier

# Sur CentOS/RHEL, le groupe s'appelle "wheel":
sudo usermod -aG wheel john

# Vérifier les groupes de john:
groups john

# Affiche:
# john : john sudo

# Se connecter en tant que john:
su - john

# Affiche:
# john@myserver:~$

# Tester sudo:
sudo apt update

# Demande le mot de passe de john
# Si ça marche: john a bien les droits sudo!


# === ÉTAPE 3: CONFIGURER SUDO EN DÉTAIL ===

# Fichier de configuration sudo:
sudo visudo

# Affiche l'éditeur (nano ou vim) avec:
# /etc/sudoers

# Contenu important:
# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group
%sudo   ALL=(ALL:ALL) ALL

# Explications:
# root ALL=(ALL:ALL) ALL
#   - root: Utilisateur
#   - ALL: Sur tous les hôtes
#   - (ALL:ALL): En tant que n'importe quel utilisateur/groupe
#   - ALL: Peut exécuter toutes les commandes

# %sudo ALL=(ALL:ALL) ALL
#   - %sudo: Groupe sudo (% = groupe)
#   - Même signification

# Exemples de configurations personnalisées:

# Autoriser john à redémarrer sans mot de passe:
john ALL=(ALL) NOPASSWD: /sbin/reboot, /sbin/shutdown

# Autoriser le groupe admins à tout faire:
%admins ALL=(ALL:ALL) ALL

# Autoriser alice à seulement installer des packages:
alice ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get

# IMPORTANT: Utiliser visudo pour éditer!
# Pourquoi? visudo vérifie la syntaxe avant de sauvegarder
# Erreur dans /etc/sudoers = tu ne peux plus utiliser sudo!

# Sauvegarder: Ctrl+O puis Enter
# Quitter: Ctrl+X


# === ÉTAPE 4: PERMISSIONS UNIX ===

# Permissions = Qui peut faire quoi avec un fichier

# Voir les permissions:
ls -l /home/john/

# Affiche:
# drwxr-xr-x 2 john john 4096 Jan 15 10:00 Documents
# -rw-r--r-- 1 john john  220 Jan 15 09:30 .bashrc

# Décryptage:
# -rw-r--r--
# │││││││││└─ Others: r-- (read only)
# ││││││└└└── Group: r-- (read only)
# │││└└└───── User: rw- (read + write)
# └────────── Type: - (fichier) ou d (directory)

# Permissions:
# r = read (4): Lire le fichier
# w = write (2): Modifier le fichier
# x = execute (1): Exécuter le fichier (ou entrer dans le dossier)

# Propriétaire:
# john john
# │    └─ Groupe
# └────── Utilisateur


# === ÉTAPE 5: MODIFIER LES PERMISSIONS (chmod) ===

# Créer un fichier test:
touch /home/john/script.sh

# Voir les permissions:
ls -l /home/john/script.sh
# Affiche: -rw-r--r-- 1 john john 0 Jan 15 10:00 script.sh

# Rendre exécutable pour le propriétaire:
chmod u+x /home/john/script.sh

# Vérifier:
ls -l /home/john/script.sh
# Affiche: -rwxr--r-- 1 john john 0 Jan 15 10:00 script.sh

# Explications:
# chmod: Change mode (modifier permissions)
# u: User (propriétaire)
# +x: Ajouter permission exécute
# script.sh: Fichier à modifier

# Autres exemples:

# Enlever lecture au groupe:
chmod g-r script.sh

# Ajouter écriture aux autres:
chmod o+w script.sh

# Permissions multiples:
chmod u+rwx,g+rx,o+r script.sh

# Notation octale (plus rapide):
chmod 755 script.sh

# Décryptage 755:
# 7 = rwx (4+2+1) pour User
# 5 = r-x (4+0+1) pour Group
# 5 = r-x (4+0+1) pour Others

# Permissions courantes:
# 644: -rw-r--r-- (fichiers normaux)
# 755: -rwxr-xr-x (scripts exécutables)
# 600: -rw------- (fichiers secrets, ex: clés SSH)
# 700: -rwx------ (dossiers privés)
# 777: -rwxrwxrwx (DANGEREUX! Tout le monde peut tout faire)

# Changer récursivement (tous les fichiers d'un dossier):
chmod -R 755 /home/john/Documents
/

# Explications:
# -R: Récursif (tous les sous-dossiers et fichiers)


# === ÉTAPE 6: CHANGER LE PROPRIÉTAIRE (chown) ===

# Changer l'utilisateur propriétaire:
sudo chown alice /home/john/script.sh

# Vérifier:
ls -l /home/john/script.sh
# Affiche: -rwxr--r-- 1 alice john ...

# Changer le groupe:
sudo chown :admins /home/john/script.sh

# Vérifier:
ls -l /home/john/script.sh
# Affiche: -rwxr--r-- 1 alice admins ...

# Changer utilisateur ET groupe:
sudo chown alice:admins /home/john/script.sh

# Récursif:
sudo chown -R alice:admins /home/john/Documents/

# Cas d'usage:
# - Fichiers d'une app appartenant à un utilisateur dédié
# - Logs appartenant au groupe admins


# === ÉTAPE 7: ACL (Access Control Lists) ===

# ACL = Permissions plus fines que rwx
# Permet de donner des permissions spécifiques à plusieurs utilisateurs/groupes

# Installer acl (si pas déjà installé):
sudo apt install acl

# Voir les ACL d'un fichier:
getfacl /home/john/script.sh

# Affiche:
# # file: script.sh
# # owner: john
# # group: john
# user::rwx
# group::r-x
# other::r--

# Donner à alice la permission de lire/écrire:
setfacl -m u:alice:rw /home/john/script.sh

# Vérifier:
getfacl /home/john/script.sh
# Affiche:
# user:alice:rw-

# Explications:
# setfacl: Set File ACL
# -m: Modify
# u:alice:rw: User alice avec read+write
# script.sh: Fichier

# Donner au groupe devs la permission d'exécuter:
setfacl -m g:devs:rx /home/john/script.sh

# Récursif:
setfacl -R -m u:alice:rwx /home/john/Documents/

# Enlever une ACL:
setfacl -x u:alice /home/john/script.sh

# Enlever toutes les ACL:
setfacl -b /home/john/script.sh


# === ÉTAPE 8: SUPPRIMER UN UTILISATEUR ===

# Supprimer un utilisateur (garder le home):
sudo deluser john

# Supprimer utilisateur ET home directory:
sudo deluser --remove-home john

# Alternative:
sudo userdel -r john

# Explications:
# deluser: Commande interactive
# userdel: Commande bas niveau
# -r ou --remove-home: Supprimer /home/john

# Vérifier:
ls /home/
# john ne doit plus apparaître


[OK] SÉCURISATION & CONFIGURATION SSH

# === POURQUOI SSH? ===

# SSH = Secure Shell
# Permet de se connecter à distance de manière sécurisée
# Remplace Telnet (non sécurisé, mot de passe en clair!)
# Port par défaut: 22

# SSH utilise:
# - Chiffrement des données (personne ne peut lire)
# - Authentification par mot de passe OU clé SSH
# - Tunnel sécurisé pour transférer des fichiers (SCP, SFTP)


# === ÉTAPE 1: INSTALLER LE SERVEUR SSH ===

# Sur la plupart des serveurs, SSH est déjà installé
# Pour vérifier:
which sshd

# Affiche:
# /usr/sbin/sshd

# Si pas installé:

# Ubuntu/Debian:
sudo apt install openssh-server

# CentOS/RHEL:
sudo yum install openssh-server

# Démarrer SSH:
sudo systemctl start sshd

# Activer au démarrage:
sudo systemctl enable sshd

# Vérifier le statut:
sudo systemctl status sshd

# Affiche:
# [BLACK_CIRCLE] ssh.service - OpenBSD Secure Shell server
#    Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
#    Active: active (running) since Mon 2024-01-15 10:00:00 UTC


# === ÉTAPE 2: CONFIGURATION DE BASE ===

# Fichier de configuration principal:
sudo nano /etc/ssh/sshd_config

# Contenu important:

# Port SSH (changer pour plus de sécurité):
Port 22
# Recommandation: Changer en 2222 ou autre port non-standard
# Port 2222

# Autoriser connexion root (DANGEREUX!):
PermitRootLogin yes
# Recommandation: Mettre "no" et utiliser un utilisateur normal avec sudo
# PermitRootLogin no

# Authentification par mot de passe:
PasswordAuthentication yes
# Recommandation: Mettre "no" après avoir configuré les clés SSH
# PasswordAuthentication no

# Authentification par clé publique:
PubkeyAuthentication yes

# Fichier des clés autorisées:
AuthorizedKeysFile .ssh/authorized_keys

# Timeout inactivité (en secondes):
ClientAliveInterval 300
ClientAliveCountMax 2
# Déconnecte après 300s * 2 = 10 minutes d'inactivité

# Limiter les utilisateurs autorisés:
AllowUsers john alice bob
# Seulement ces utilisateurs peuvent se connecter

# Ou limiter les groupes:
AllowGroups sshusers admins

# Désactiver X11 Forwarding (si pas nécessaire):
X11Forwarding no

# Désactiver le forwarding de port (si pas nécessaire):
AllowTcpForwarding no

# Afficher un message avant login:
Banner /etc/ssh/banner.txt

# Créer le fichier banner:
sudo nano /etc/ssh/banner.txt

# Contenu:
***********************************************
*  Accès autorisé uniquement                  *
*  Toute activité est surveillée              *
***********************************************

# Sauvegarder: Ctrl+O puis Enter
# Quitter: Ctrl+X

# Redémarrer SSH pour appliquer:
sudo systemctl restart sshd

# Tester depuis un autre terminal (sans fermer le premier!):
ssh john@server_ip


# === ÉTAPE 3: AUTHENTIFICATION PAR CLÉ SSH ===

# Pourquoi? Beaucoup plus sûr que le mot de passe!
# - Mot de passe peut être deviné (brute force)
# - Clé SSH = 2048 ou 4096 bits (impossible à deviner)

# === SUR TON ORDINATEUR (CLIENT) ===

# Générer une paire de clés SSH:
ssh-keygen -t rsa -b 4096 -C "john@example.com"

# Affiche:
# Generating public/private rsa key pair.
# Enter file in which to save the key (/home/john/.ssh/id_rsa):

# Appuie sur Enter pour accepter le chemin par défaut

# Enter passphrase (empty for no passphrase):
# Tape un mot de passe (optionnel mais recommandé!)
# Appuie sur Enter 2 fois si tu ne veux pas de passphrase

# Affiche:
# Your identification has been saved in /home/john/.ssh/id_rsa
# Your public key has been saved in /home/john/.ssh/id_rsa.pub
# The key fingerprint is:
# SHA256:abc123... john@example.com

# Explications:
# -t rsa: Type de clé (RSA)
# -b 4096: Taille de la clé (4096 bits = très sécurisé)
# -C "john@example.com": Commentaire (pour identifier la clé)

# 2 fichiers créés:
# - id_rsa: Clé privée (GARDER SECRET!)
# - id_rsa.pub: Clé publique (à copier sur le serveur)

# Voir la clé publique:
cat ~/.ssh/id_rsa.pub

# Affiche:
# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC... john@example.com


# === COPIER LA CLÉ SUR LE SERVEUR ===

# Méthode automatique (recommandée):
ssh-copy-id john@server_ip

# Affiche:
# /usr/bin/ssh-copy-id: INFO: attempting to log in...
# john@server_ip's password:
# Tape le mot de passe

# Affiche:
# Number of key(s) added: 1
# Now try logging into the machine...

# Tester:
ssh john@server_ip
# Ne demande plus de mot de passe!

# Méthode manuelle:

# 1. Copier la clé publique:
cat ~/.ssh/id_rsa.pub
# Copie tout le contenu

# 2. Se connecter au serveur:
ssh john@server_ip

# 3. Créer le dossier .ssh (si pas déjà existant):
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# 4. Créer/éditer le fichier authorized_keys:
nano ~/.ssh/authorized_keys

# 5. Coller la clé publique (tout sur une seule ligne!)

# 6. Sauvegarder: Ctrl+O puis Enter
# 7. Quitter: Ctrl+X

# 8. Définir les bonnes permissions:
chmod 600 ~/.ssh/authorized_keys

# 9. Se déconnecter:
exit

# 10. Tester:
ssh john@server_ip
# Ne demande plus de mot de passe!


# === ÉTAPE 4: DÉSACTIVER L'AUTHENTIFICATION PAR MOT DE PASSE ===

# Une fois les clés SSH configurées, désactiver les mots de passe!

# Éditer la config SSH:
sudo nano /etc/ssh/sshd_config

# Changer:
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no

# Sauvegarder et redémarrer:
sudo systemctl restart sshd

# ATTENTION: Teste AVANT de fermer ta session actuelle!
# Ouvre un nouveau terminal et teste:
ssh john@server_ip
# Doit fonctionner sans mot de passe

# Si problème: Reviens à la session ouverte et corrige!


# === ÉTAPE 5: FAIL2BAN (PROTECTION CONTRE BRUTE FORCE) ===

# Fail2Ban = Bloque les IPs qui font trop de tentatives de connexion

# Installer:
sudo apt install fail2ban

# Créer un fichier de config local:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Éditer:
sudo nano /etc/fail2ban/jail.local

# Configuration SSH:
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

# Explications:
# enabled = true: Activer la protection SSH
# port = 22: Port SSH (changer si tu as changé le port!)
# maxretry = 3: 3 tentatives ratées maximum
# bantime = 3600: Bannir pendant 1 heure (3600 secondes)
# findtime = 600: Dans une fenêtre de 10 minutes (600 secondes)

# Signifie: Si quelqu'un rate 3 fois le mot de passe en 10 minutes,
# il est banni pendant 1 heure!

# Sauvegarder: Ctrl+O puis Enter
# Quitter: Ctrl+X

# Démarrer Fail2Ban:
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

# Vérifier le statut:
sudo fail2ban-client status sshd

# Affiche:
# 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:

# Voir les IPs bannies:
sudo fail2ban-client status sshd

# Débannir une IP manuellement:
sudo fail2ban-client set sshd unbanip 192.168.1.50


# === ÉTAPE 6: CHANGER LE PORT SSH ===

# Pourquoi? Port 22 = port par défaut = cible des bots
# Changer en 2222 ou autre = moins d'attaques

# Éditer la config:
sudo nano /etc/ssh/sshd_config

# Changer:
Port 2222

# Sauvegarder et redémarrer:
sudo systemctl restart sshd

# Mettre à jour Fail2Ban:
sudo nano /etc/fail2ban/jail.local

# Changer:
[sshd]
port = 2222

# Redémarrer Fail2Ban:
sudo systemctl restart fail2ban

# Se connecter avec le nouveau port:
ssh -p 2222 john@server_ip

# Explications:
# -p 2222: Spécifie le port


[OK] PARE-FEU & SÉCURITÉ RÉSEAU

# === POURQUOI UN PARE-FEU? ===

# Pare-feu (Firewall) = Barrière de sécurité
# Bloque tout par défaut, n'autorise que ce dont tu as besoin
# Exemple: Ton serveur web a besoin de:
#   - Port 80 (HTTP)
#   - Port 443 (HTTPS)
#   - Port 22 (SSH)
# Tout le reste: BLOQUÉ!

# Sans firewall:
# - N'importe qui peut scanner tous les ports
# - Trouver des services vulnérables
# - Attaquer ton serveur

# Avec firewall:
# - Seuls les ports autorisés sont accessibles
# - Tout le reste est invisible


# === ÉTAPE 1: UFW (UBUNTU/DEBIAN - DÉBUTANTS) ===

# UFW = Uncomplicated Firewall
# Interface simple pour iptables

# Installer:
sudo apt install ufw

# Voir le statut:
sudo ufw status

# Affiche:
# Status: inactive

# Stratégie par défaut (tout bloquer):
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Explications:
# deny incoming: Bloquer tout ce qui entre
# allow outgoing: Autoriser tout ce qui sort

# Autoriser SSH (IMPORTANT avant d'activer!):
sudo ufw allow 22/tcp

# Ou si tu as changé le port:
sudo ufw allow 2222/tcp

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

# Ou avec le nom du service:
sudo ufw allow http
sudo ufw allow https
sudo ufw allow ssh

# Voir les règles:
sudo ufw status numbered

# Affiche:
# Status: inactive
#
#      To                         Action      From
#      --                         ------      ----
# [ 1] 22/tcp                     ALLOW IN    Anywhere
# [ 2] 80/tcp                     ALLOW IN    Anywhere
# [ 3] 443/tcp                    ALLOW IN    Anywhere

# Activer le firewall:
sudo ufw enable

# Affiche:
# Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
# Firewall is active and enabled on system startup

# ATTENTION: Si tu n'as pas autorisé SSH avant, tu seras déconnecté!

# Vérifier:
sudo ufw status verbose

# Affiche:
# Status: active
# Logging: on (low)
# Default: deny (incoming), allow (outgoing), disabled (routed)
# New profiles: skip

# Autoriser un port spécifique:
sudo ufw allow 3306/tcp
# Port 3306 = MySQL

# Autoriser une plage de ports:
sudo ufw allow 6000:6007/tcp

# Autoriser depuis une IP spécifique:
sudo ufw allow from 192.168.1.50

# Autoriser un port depuis une IP:
sudo ufw allow from 192.168.1.50 to any port 22

# Bloquer une IP:
sudo ufw deny from 203.0.113.51

# Supprimer une règle:
sudo ufw status numbered
# Affiche les numéros

sudo ufw delete 3
# Supprime la règle numéro 3

# Désactiver le firewall:
sudo ufw disable

# Réinitialiser (supprimer toutes les règles):
sudo ufw reset


# === ÉTAPE 2: FIREWALLD (CentOS/RHEL) ===

# Firewalld = Pare-feu dynamique avec zones

# Installer:
sudo yum install firewalld

# Démarrer:
sudo systemctl start firewalld
sudo systemctl enable firewalld

# Voir le statut:
sudo firewall-cmd --state

# Affiche:
# running

# Voir les zones:
sudo firewall-cmd --get-zones

# Affiche:
# block dmz drop external home internal public trusted work

# Zone par défaut:
sudo firewall-cmd --get-default-zone

# Affiche:
# public

# Voir les règles de la zone public:
sudo firewall-cmd --zone=public --list-all

# Affiche:
# public (active)
#   target: default
#   icmp-block-inversion: no
#   interfaces: eth0
#   sources:
#   services: ssh dhcpv6-client
#   ports:
#   protocols:
#   masquerade: no
#   forward-ports:
#   source-ports:
#   icmp-blocks:
#   rich rules:

# Autoriser un service:
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent

# Explications:
# --zone=public: Dans la zone public
# --add-service=http: Autoriser HTTP
# --permanent: Règle permanente (sinon perdue au reboot)

# Recharger les règles:
sudo firewall-cmd --reload

# Vérifier:
sudo firewall-cmd --zone=public --list-services

# Affiche:
# ssh dhcpv6-client http https

# Autoriser un port:
sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent
sudo firewall-cmd --reload

# Autoriser une plage de ports:
sudo firewall-cmd --zone=public --add-port=6000-6007/tcp --permanent

# Autoriser depuis une IP:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.50" accept' --permanent

# Bloquer une IP:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.51" reject' --permanent

# Supprimer un service:
sudo firewall-cmd --zone=public --remove-service=http --permanent
sudo firewall-cmd --reload

# Supprimer un port:
sudo firewall-cmd --zone=public --remove-port=3306/tcp --permanent
sudo firewall-cmd --reload


# === ÉTAPE 3: IPTABLES (BAS NIVEAU - AVANCÉ) ===

# Iptables = Pare-feu Linux puissant mais complexe
# Utilisé par UFW et Firewalld en arrière-plan

# Voir les règles actuelles:
sudo iptables -L -v -n

# Affiche:
# 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

# Explications:
# -L: List (afficher)
# -v: Verbose (détaillé)
# -n: Numeric (IPs en nombres, pas en noms)

# Politique par défaut (tout bloquer):
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

# Explications:
# -P INPUT DROP: Policy INPUT = DROP (bloquer tout ce qui entre)
# -P FORWARD DROP: Bloquer le forwarding
# -P OUTPUT ACCEPT: Autoriser tout ce qui sort

# Autoriser loopback (localhost):
sudo iptables -A INPUT -i lo -j ACCEPT

# Explications:
# -A INPUT: Append à la chaîne INPUT
# -i lo: Interface loopback
# -j ACCEPT: Jump to ACCEPT (autoriser)

# Autoriser connexions établies:
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Explications:
# -m state: Module state
# --state ESTABLISHED,RELATED: Connexions déjà établies
# Permet de recevoir les réponses des requêtes sortantes

# Autoriser SSH:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Explications:
# -p tcp: Protocole TCP
# --dport 22: Port de destination 22 (SSH)
# -j ACCEPT: Autoriser

# Autoriser HTTP et HTTPS:
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Autoriser depuis une IP spécifique:
sudo iptables -A INPUT -s 192.168.1.50 -j ACCEPT

# Explications:
# -s 192.168.1.50: Source IP

# Bloquer une IP:
sudo iptables -A INPUT -s 203.0.113.51 -j DROP

# Sauvegarder les règles:

# Ubuntu/Debian:
sudo apt install iptables-persistent
sudo netfilter-persistent save

# CentOS/RHEL:
sudo service iptables save

# Voir les règles avec numéros:
sudo iptables -L INPUT -v -n --line-numbers

# Supprimer une règle:
sudo iptables -D INPUT 5
# Supprime la règle numéro 5 dans INPUT

# Réinitialiser (supprimer toutes les règles):
sudo iptables -F
sudo iptables -X
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT


[OK] GESTION DES SERVICES (SYSTEMD)

# === QU'EST-CE QU'UN SERVICE? ===

# Service = Programme qui tourne en arrière-plan
# Exemples:
# - sshd: Serveur SSH
# - nginx: Serveur web
# - mysqld: Base de données
# - cron: Planificateur de tâches

# Systemd = Gestionnaire de services moderne
# Remplace l'ancien "init" (SysVinit, Upstart)
# Utilisé sur Ubuntu 15.04+, CentOS 7+, Debian 8+


# === ÉTAPE 1: COMMANDES DE BASE ===

# Démarrer un service:
sudo systemctl start nginx

# Arrêter un service:
sudo systemctl stop nginx

# Redémarrer un service:
sudo systemctl restart nginx

# Recharger la config (sans redémarrer):
sudo systemctl reload nginx

# Voir le statut:
sudo systemctl status nginx

# Affiche:
# [BLACK_CIRCLE] nginx.service - A high performance web server and a reverse proxy server
#    Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
#    Active: active (running) since Mon 2024-01-15 10:00:00 UTC; 5min ago
#      Docs: man:nginx(8)
#  Main PID: 1234 (nginx)
#     Tasks: 2 (limit: 1137)
#    Memory: 3.2M
#    CGroup: /system.slice/nginx.service
#            ├─1234 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
#            └─1235 nginx: worker process

# Explications:
# Active: active (running): Service tourne
# Loaded: enabled: Démarre automatiquement au boot
# Main PID: 1234: Process ID principal

# Activer au démarrage:
sudo systemctl enable nginx

# Affiche:
# Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service -> /lib/systemd/system/nginx.service

# Désactiver au démarrage:
sudo systemctl disable nginx

# Vérifier si activé:
sudo systemctl is-enabled nginx

# Affiche:
# enabled

# Vérifier si tourne:
sudo systemctl is-active nginx

# Affiche:
# active


# === ÉTAPE 2: VOIR LES SERVICES ===

# Lister tous les services:
sudo systemctl list-units --type=service

# Affiche:
# UNIT                               LOAD   ACTIVE SUB     DESCRIPTION
# accounts-daemon.service            loaded active running Accounts Service
# apache2.service                    loaded active running The Apache HTTP Server
# cron.service                       loaded active running Regular background program processing daemon
# ...

# Lister seulement les services actifs:
sudo systemctl list-units --type=service --state=active

# Lister les services qui ont échoué:
sudo systemctl list-units --type=service --state=failed

# Affiche:
# UNIT                    LOAD   ACTIVE SUB    DESCRIPTION
# my-app.service          loaded failed failed My Application

# Voir les détails d'un échec:
sudo systemctl status my-app.service


# === ÉTAPE 3: VOIR LES LOGS (JOURNALCTL) ===

# Journalctl = Outil pour voir les logs systemd

# Voir les logs d'un service:
sudo journalctl -u nginx

# Affiche les logs depuis le début

# Voir les logs en temps réel:
sudo journalctl -u nginx -f

# Explications:
# -u nginx: Unit nginx
# -f: Follow (comme tail -f)

# Voir les logs depuis aujourd'hui:
sudo journalctl -u nginx --since today

# Depuis une date:
sudo journalctl -u nginx --since "2024-01-15 10:00:00"

# Dernières 50 lignes:
sudo journalctl -u nginx -n 50

# Voir seulement les erreurs:
sudo journalctl -u nginx -p err

# Explications:
# -p err: Priority error (erreurs seulement)
# Niveaux: emerg, alert, crit, err, warning, notice, info, debug

# Voir tous les logs système:
sudo journalctl

# Logs depuis le dernier boot:
sudo journalctl -b

# Logs du boot précédent:
sudo journalctl -b -1


# === ÉTAPE 4: CRÉER UN SERVICE PERSONNALISÉ ===

# Exemple: Service pour une app Python Flask

# Créer le fichier service:
sudo nano /etc/systemd/system/myapp.service

# Contenu:
[Unit]
Description=My Flask Application
After=network.target

[Service]
Type=simple
User=john
WorkingDirectory=/home/john/myapp
Environment="PATH=/home/john/myapp/venv/bin"
ExecStart=/home/john/myapp/venv/bin/gunicorn --bind 0.0.0.0:5000 app:app
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

# Explications ligne par ligne:

# [Unit]: Section de description
# Description: Nom du service
# After=network.target: Démarrer après le réseau

# [Service]: Section de configuration
# Type=simple: Type de service (simple = 1 processus principal)
# User=john: Exécuter en tant que john (pas root!)
# WorkingDirectory: Dossier de travail
# Environment: Variables d'environnement
# ExecStart: Commande à exécuter
# Restart=always: Redémarrer automatiquement en cas de crash
# RestartSec=10: Attendre 10 secondes avant de redémarrer

# [Install]: Section d'installation
# WantedBy=multi-user.target: Démarrer au boot (multi-user = mode serveur)

# Sauvegarder: Ctrl+O puis Enter
# Quitter: Ctrl+X

# Recharger systemd (important après création/modification):
sudo systemctl daemon-reload

# Démarrer le service:
sudo systemctl start myapp

# Voir le statut:
sudo systemctl status myapp

# Activer au démarrage:
sudo systemctl enable myapp

# Voir les logs:
sudo journalctl -u myapp -f


# === ÉTAPE 5: TYPES DE SERVICES ===

# Type=simple
# = Processus principal reste en premier plan
# Utilisé pour: Gunicorn, Node.js apps, scripts simples

# Type=forking
# = Processus principal fork (crée un processus enfant)
# Utilisé pour: Nginx, Apache, MySQL
# Exemple:
[Service]
Type=forking
PIDFile=/var/run/myapp.pid
ExecStart=/usr/local/bin/myapp --daemon

# Type=oneshot
# = Exécute une commande puis se termine
# Utilisé pour: Scripts d'initialisation, backups
# Exemple:
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
RemainAfterExit=yes

# Type=notify
# = Notifie systemd quand prêt
# Utilisé pour: Services qui supportent sd_notify


# === ÉTAPE 6: REDÉMARRAGE AUTOMATIQUE ===

# Redémarrer en cas d'échec:
[Service]
Restart=on-failure
RestartSec=5

# Toujours redémarrer:
[Service]
Restart=always
RestartSec=10

# Ne jamais redémarrer:
[Service]
Restart=no

# Options de Restart:
# - no: Jamais redémarrer
# - on-success: Seulement si succès (code 0)
# - on-failure: Seulement si échec
# - on-abnormal: Si signal/timeout
# - on-abort: Si signal abort
# - on-watchdog: Si watchdog timeout
# - always: Toujours (recommandé pour services critiques)


# === ÉTAPE 7: LIMITER LES RESSOURCES ===

# Limiter la mémoire:
[Service]
MemoryLimit=512M

# Limiter le CPU:
[Service]
CPUQuota=50%

# Limiter le nombre de fichiers ouverts:
[Service]
LimitNOFILE=65536

# Limiter le nombre de processus:
[Service]
LimitNPROC=100


[OK] STOCKAGE, DISQUES ET SYSTÈMES DE FICHIERS

# === COMPRENDRE LE STOCKAGE LINUX ===

# Disque physique -> Partition -> Système de fichiers -> Montage

# Analogie:
# Disque = Terrain
# Partition = Parcelles du terrain
# Système de fichiers = Type de bâtiment (maison, immeuble)
# Montage = Adresse (où accéder)


# === ÉTAPE 1: VOIR LES DISQUES ET PARTITIONS ===

# Lister les disques:
lsblk

# Affiche:
# NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
# sda      8:0    0   50G  0 disk
# ├─sda1   8:1    0    1M  0 part
# ├─sda2   8:2    0    1G  0 part /boot
# └─sda3   8:3    0   49G  0 part /
# sdb      8:16   0  100G  0 disk

# Explications:
# sda: Premier disque (a)
# sda1, sda2, sda3: Partitions sur sda
# sdb: Deuxième disque (b)
# MOUNTPOINT: Où la partition est montée

# Voir les tailles:
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT

# Voir l'utilisation des partitions montées:
df -h

# Affiche:
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda3        49G   15G   32G  32% /
# /dev/sda2       976M  128M  782M  15% /boot
# tmpfs           985M     0  985M   0% /dev/shm

# Explications:
# -h: Human-readable (Go, Mo au lieu d'octets)
# Use%: Pourcentage utilisé
# Mounted on: Point de montage

# Voir les inodes (nombre de fichiers):
df -i

# Affiche:
# Filesystem      Inodes  IUsed   IFree IUse% Mounted on
# /dev/sda3      3276800 245318 3031482    8% /

# Voir les détails d'un disque:
sudo fdisk -l /dev/sda

# Affiche:
# Disk /dev/sda: 50 GiB, 53687091200 bytes, 104857600 sectors
# Units: sectors of 1 * 512 = 512 bytes
# Sector size (logical/physical): 512 bytes / 512 bytes
# I/O size (minimum/optimal): 512 bytes / 512 bytes
# Disklabel type: gpt
# Disk identifier: abc123-def456

# Device       Start       End   Sectors  Size Type
# /dev/sda1     2048      4095      2048    1M BIOS boot
# /dev/sda2     4096   2101247   2097152    1G Linux filesystem
# /dev/sda3  2101248 104857566 102756319   49G Linux filesystem


# === ÉTAPE 2: CRÉER UNE PARTITION ===

# Attention: Données existantes seront perdues!
# Toujours faire un backup avant!

# === AVEC FDISK (MBR/DOS) ===

# Ouvrir fdisk:
sudo fdisk /dev/sdb

# Affiche:
# Welcome to fdisk (util-linux 2.34).
# Command (m for help):

# Commandes:
# m: Afficher l'aide
# p: Afficher les partitions
# n: Nouvelle partition
# d: Supprimer partition
# w: Écrire et quitter
# q: Quitter sans sauvegarder

# Créer une partition:
# Tape: n
# Partition type: p (primary)
# Partition number: 1
# First sector: [Enter] (défaut)
# Last sector: +50G (50 Go)
# Tape: w pour sauvegarder

# Exemple complet:
Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-209715199, default 2048): [Enter]
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-209715199, default 209715199): +50G

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.


# === AVEC PARTED (GPT - MODERN) ===

# GPT = GUID Partition Table (modern, >2TB)

# Ouvrir parted:
sudo parted /dev/sdb

# Créer un label GPT:
(parted) mklabel gpt

# Créer une partition:
(parted) mkpart primary 0% 50GB

# Explications:
# mkpart: Make partition
# primary: Type
# 0%: Début (au début du disque)
# 50GB: Fin (50 Go)

# Voir les partitions:
(parted) print

# Affiche:
# Model: ATA VBOX HARDDISK (scsi)
# Disk /dev/sdb: 107GB
# Sector size (logical/physical): 512B/512B
# Partition Table: gpt
# Disk Flags:
#
# Number  Start   End     Size    File system  Name     Flags
#  1      1049kB  50.0GB  50.0GB               primary

# Quitter:
(parted) quit


# === ÉTAPE 3: CRÉER UN SYSTÈME DE FICHIERS ===

# Après créer la partition, il faut créer un filesystem

# ext4 (recommandé pour Linux):
sudo mkfs.ext4 /dev/sdb1

# Affiche:
# mke2fs 1.45.5 (07-Jan-2020)
# Creating filesystem with 12207104 4k blocks and 3055616 inodes
# Filesystem UUID: abc123-def456
# ...
# Writing superblocks and filesystem accounting information: done

# XFS (bon pour grandes données):
sudo mkfs.xfs /dev/sdb1

# Btrfs (avec snapshots):
sudo mkfs.btrfs /dev/sdb1

# Explications:
# mkfs = make filesystem
# /dev/sdb1 = Partition à formater

# ATTENTION: mkfs EFFACE toutes les données!


# === ÉTAPE 4: MONTER UNE PARTITION ===

# Monter = Rendre accessible à un chemin

# Créer un point de montage:
sudo mkdir /mnt/data

# Monter temporairement:
sudo mount /dev/sdb1 /mnt/data

# Vérifier:
df -h | grep /mnt/data

# Affiche:
# /dev/sdb1        50G   53M   47G   1% /mnt/data

# Créer un fichier test:
sudo touch /mnt/data/test.txt
ls /mnt/data/
# Affiche: test.txt

# Démonter:
sudo umount /mnt/data

# Vérifier:
ls /mnt/data/
# Vide! Le fichier existe toujours sur /dev/sdb1 mais n'est plus accessible


# === ÉTAPE 5: MONTAGE PERMANENT (FSTAB) ===

# /etc/fstab = Fichier de montage automatique au boot

# Voir l'UUID de la partition:
sudo blkid /dev/sdb1

# Affiche:
# /dev/sdb1: UUID="abc123-def456-..." TYPE="ext4" PARTUUID="xyz789..."

# Copier l'UUID

# Éditer fstab:
sudo nano /etc/fstab

# Ajouter une ligne:
UUID=abc123-def456-...  /mnt/data  ext4  defaults  0  2

# Explications des colonnes:
# 1. UUID ou /dev/sdb1: Partition
# 2. /mnt/data: Point de montage
# 3. ext4: Type de filesystem
# 4. defaults: Options (defaults = rw,suid,dev,exec,auto,nouser,async)
# 5. 0: Dump (backup) - 0 = non
# 6. 2: Pass (vérification fsck) - 0=non, 1=root, 2=autres

# Sauvegarder: Ctrl+O puis Enter
# Quitter: Ctrl+X

# Tester sans redémarrer:
sudo mount -a

# Explications:
# mount -a: Mount all (monter tout ce qui est dans fstab)

# Vérifier:
df -h | grep /mnt/data

# Redémarrer pour vérifier:
sudo reboot

# Après reboot:
df -h | grep /mnt/data
# Doit être monté automatiquement!


# === ÉTAPE 6: LVM (LOGICAL VOLUME MANAGER) ===

# LVM = Gestion flexible des disques
# Permet de:
# - Redimensionner des partitions en direct
# - Combiner plusieurs disques
# - Créer des snapshots

# Architecture LVM:
# Physical Volume (PV) -> Volume Group (VG) -> Logical Volume (LV)

# Disque physique -> PV -> VG (pool de stockage) -> LV (partitions logiques)

# === Créer un LVM ===

# 1. Créer un Physical Volume:
sudo pvcreate /dev/sdb

# Affiche:
#   Physical volume "/dev/sdb" successfully created.

# Vérifier:
sudo pvdisplay

# 2. Créer un Volume Group:
sudo vgcreate data_vg /dev/sdb

# Affiche:
#   Volume group "data_vg" successfully created

# Vérifier:
sudo vgdisplay

# 3. Créer un Logical Volume:
sudo lvcreate -L 50G -n data_lv data_vg

# Explications:
# -L 50G: Taille 50 Go
# -n data_lv: Nom du LV
# data_vg: Volume Group

# Vérifier:
sudo lvdisplay

# Affiche:
#   --- Logical volume ---
#   LV Path                /dev/data_vg/data_lv
#   LV Name                data_lv
#   VG Name                data_vg
#   LV Size                50.00 GiB

# 4. Créer un filesystem:
sudo mkfs.ext4 /dev/data_vg/data_lv

# 5. Monter:
sudo mkdir /mnt/lvm_data
sudo mount /dev/data_vg/data_lv /mnt/lvm_data

# 6. Fstab:
sudo nano /etc/fstab

# Ajouter:
/dev/data_vg/data_lv  /mnt/lvm_data  ext4  defaults  0  2

# === Redimensionner un LVM ===

# Agrandir un LV:
sudo lvextend -L +20G /dev/data_vg/data_lv

# Explications:
# -L +20G: Ajouter 20 Go

# Agrandir le filesystem:
sudo resize2fs /dev/data_vg/data_lv

# Vérifier:
df -h | grep lvm_data

# Réduire un LV (DANGER! Faire backup avant):
# 1. Démonter:
sudo umount /mnt/lvm_data

# 2. Vérifier le filesystem:
sudo e2fsck -f /dev/data_vg/data_lv

# 3. Réduire le filesystem:
sudo resize2fs /dev/data_vg/data_lv 30G

# 4. Réduire le LV:
sudo lvreduce -L 30G /dev/data_vg/data_lv

# 5. Remonter:
sudo mount /dev/data_vg/data_lv /mnt/lvm_data


# === ÉTAPE 7: SNAPSHOTS LVM ===

# Snapshot = Photo instantanée du système de fichiers
# Permet de:
# - Faire un backup sans arrêter l'app
# - Revenir en arrière si problème

# Créer un snapshot:
sudo lvcreate -L 10G -s -n data_snapshot /dev/data_vg/data_lv

# Explications:
# -L 10G: Taille du snapshot (pour stocker les changements)
# -s: Snapshot
# -n data_snapshot: Nom du snapshot
# /dev/data_vg/data_lv: LV source

# Vérifier:
sudo lvdisplay /dev/data_vg/data_snapshot

# Monter le snapshot:
sudo mkdir /mnt/snapshot
sudo mount /dev/data_vg/data_snapshot /mnt/snapshot

# Backup du snapshot:
sudo rsync -av /mnt/snapshot/ /backup/data/

# Supprimer le snapshot:
sudo umount /mnt/snapshot
sudo lvremove /dev/data_vg/data_snapshot

# Restaurer depuis un snapshot (revenir en arrière):
sudo lvconvert --merge /dev/data_vg/data_snapshot
# ATTENTION: Les changements depuis le snapshot seront perdus!


[OK] GESTION DES LOGS

# === POURQUOI LES LOGS? ===

# Logs = Journal de bord du serveur
# Enregistrent:
# - Connexions SSH
# - Erreurs système
# - Activités des services
# - Tentatives d'intrusion

# Sans logs:
# - Impossible de diagnostiquer un problème
# - Impossible de savoir qui s'est connecté
# - Impossible de détecter des attaques

# Avec logs:
# - Diagnostic rapide
# - Traçabilité
# - Sécurité


# === ÉTAPE 1: FICHIERS DE LOGS IMPORTANTS ===

# Dossier principal des logs:
ls -lh /var/log/

# Affiche:
# drwxr-xr-x  2 root   root    4.0K Jan 15 10:00 apache2
# -rw-r-----  1 syslog adm      15K Jan 15 10:05 auth.log
# -rw-r-----  1 syslog adm     128K Jan 15 10:05 syslog
# -rw-r-----  1 syslog adm      50K Jan 15 10:05 kern.log
# drwxr-xr-x  2 mysql  mysql   4.0K Jan 15 10:00 mysql

# Logs système principaux:

# /var/log/syslog (Ubuntu/Debian)
# = Log système général
cat /var/log/syslog

# /var/log/messages (CentOS/RHEL)
# = Log système général
cat /var/log/messages

# /var/log/auth.log (Ubuntu/Debian)
# = Logs d'authentification (SSH, sudo, login)
cat /var/log/auth.log

# /var/log/secure (CentOS/RHEL)
# = Logs d'authentification
cat /var/log/secure

# /var/log/kern.log
# = Logs du kernel Linux
cat /var/log/kern.log

# /var/log/boot.log
# = Logs du démarrage
cat /var/log/boot.log

# /var/log/dmesg
# = Messages du kernel au boot
dmesg

# Logs des services:

# /var/log/apache2/access.log
# = Requêtes HTTP vers Apache

# /var/log/apache2/error.log
# = Erreurs Apache

# /var/log/nginx/access.log
# = Requêtes HTTP vers Nginx

# /var/log/nginx/error.log
# = Erreurs Nginx

# /var/log/mysql/error.log
# = Erreurs MySQL

# /var/log/postgresql/postgresql-*.log
# = Logs PostgreSQL


# === ÉTAPE 2: LIRE LES LOGS ===

# Voir les dernières lignes:
tail /var/log/syslog

# Affiche les 10 dernières lignes

# Voir les 50 dernières lignes:
tail -n 50 /var/log/syslog

# Suivre en temps réel:
tail -f /var/log/syslog

# Explications:
# -f: Follow (affiche les nouvelles lignes en direct)
# Ctrl+C pour arrêter

# Voir les premières lignes:
head /var/log/syslog

# Voir tout le fichier:
cat /var/log/syslog

# Paginer (page par page):
less /var/log/syslog

# Commandes dans less:
# Espace: Page suivante
# b: Page précédente
# /texte: Chercher "texte"
# n: Occurrence suivante
# N: Occurrence précédente
# q: Quitter

# Chercher dans un log:
grep "error" /var/log/syslog

# Ignorer la casse:
grep -i "error" /var/log/syslog

# Chercher plusieurs mots:
grep -E "error|warning|critical" /var/log/syslog

# Compter les occurrences:
grep -c "error" /var/log/syslog

# Affiche:
# 42

# Voir les lignes avant et après:
grep -A 5 -B 5 "error" /var/log/syslog

# Explications:
# -A 5: 5 lignes After (après)
# -B 5: 5 lignes Before (avant)


# === ÉTAPE 3: JOURNALCTL (SYSTEMD) ===

# Journalctl = Outil moderne pour les logs systemd

# Voir tous les logs:
sudo journalctl

# Logs depuis aujourd'hui:
sudo journalctl --since today

# Logs depuis une date:
sudo journalctl --since "2024-01-15 10:00:00"

# Logs jusqu'à une date:
sudo journalctl --until "2024-01-15 12:00:00"

# Plage de dates:
sudo journalctl --since "2024-01-15 10:00:00" --until "2024-01-15 12:00:00"

# Dernières 100 lignes:
sudo journalctl -n 100

# Suivre en temps réel:
sudo journalctl -f

# Logs d'un service:
sudo journalctl -u nginx

# Logs du boot actuel:
sudo journalctl -b

# Logs du boot précédent:
sudo journalctl -b -1

# Logs avec priorité:
sudo journalctl -p err

# Priorités:
# emerg (0): Emergency (panique système)
# alert (1): Alert (action immédiate requise)
# crit (2): Critical (critique)
# err (3): Error (erreur)
# warning (4): Warning (avertissement)
# notice (5): Notice (normal mais significatif)
# info (6): Informational (informatif)
# debug (7): Debug (débogage)

# Logs d'un utilisateur:
sudo journalctl _UID=1000

# Trouver ton UID:
id -u

# Exporter en JSON:
sudo journalctl -o json

# Voir la taille des logs:
sudo journalctl --disk-usage

# Affiche:
# Archived and active journals take up 128.0M in the file system.

# Nettoyer les vieux logs:
sudo journalctl --vacuum-time=7d

# Explications:
# --vacuum-time=7d: Garder 7 derniers jours seulement

# Nettoyer par taille:
sudo journalctl --vacuum-size=100M

# Garder seulement 100 Mo de logs


# === ÉTAPE 4: LOGROTATE (ROTATION DES LOGS) ===

# Logrotate = Outil pour gérer la taille des logs
# Pourquoi? Les logs peuvent devenir énormes!
# Logrotate:
# - Archive les vieux logs
# - Compresse les archives
# - Supprime les vieux logs

# Configuration principale:
cat /etc/logrotate.conf

# Affiche:
# # see "man logrotate" for details
# # rotate log files weekly
# weekly
#
# # keep 4 weeks worth of backlogs
# rotate 4
#
# # create new (empty) log files after rotating old ones
# create
#
# # uncompress log files with delay (compresses)
# delaycompress

# Configurations par service:
ls /etc/logrotate.d/

# Affiche:
# apache2  nginx  mysql  rsyslog

# Exemple: Nginx
cat /etc/logrotate.d/nginx

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

# Explications:
# /var/log/nginx/*.log: Fichiers à rotate
# daily: Rotation quotidienne
# rotate 14: Garder 14 archives
# compress: Compresser les archives
# delaycompress: Compresser après 1 rotation (garde 1 non compressé)
# notifempty: Ne pas rotate si vide
# create 0640 www-data adm: Créer nouveau fichier avec permissions
# postrotate: Script à exécuter après rotation

# Créer une config pour ton app:
sudo nano /etc/logrotate.d/myapp

# Contenu:
/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    notifempty
    missingok
    create 0644 john john
    postrotate
        systemctl reload myapp > /dev/null 2>&1
    endscript
}

# Tester la configuration:
sudo logrotate -d /etc/logrotate.d/myapp

# Explications:
# -d: Debug (test sans exécuter)

# Forcer la rotation:
sudo logrotate -f /etc/logrotate.d/myapp

# Explications:
# -f: Force (forcer même si pas nécessaire)


# === ÉTAPE 5: ANALYSER LES LOGS AVEC AWK ===

# AWK = Outil puissant pour traiter les logs

# Voir seulement la colonne 1:
awk '{print $1}' /var/log/auth.log

# Voir les colonnes 1 et 3:
awk '{print $1, $3}' /var/log/auth.log

# Exemple: Extraire les IPs des connexions SSH

# Log exemple:
# Jan 15 10:00:00 server sshd[1234]: Accepted publickey for john from 192.168.1.50 port 56789

# Extraire les IPs:
awk '/Accepted/ {print $11}' /var/log/auth.log

# Affiche:
# 192.168.1.50
# 192.168.1.51
# ...

# Compter les connexions par IP:
awk '/Accepted/ {print $11}' /var/log/auth.log | sort | uniq -c | sort -nr

# Affiche:
#   15 192.168.1.50
#   10 192.168.1.51
#    5 203.0.113.10

# Explications:
# awk: Extraire la colonne 11 (IP)
# sort: Trier les IPs
# uniq -c: Compter les occurrences uniques
# sort -nr: Trier numériquement en ordre décroissant


# === ÉTAPE 6: CENTRALISER LES LOGS (RSYSLOG) ===

# Rsyslog = Service qui gère les logs
# Peut envoyer les logs vers un serveur central

# Configuration:
sudo nano /etc/rsyslog.conf

# Envoyer tous les logs vers un serveur distant:
*.*  @@log-server.example.com:514

# Explications:
# *.*: Toutes les facilities et priorités
# @@: TCP (@ = UDP)
# log-server.example.com: Serveur de logs
# 514: Port syslog

# Redémarrer rsyslog:
sudo systemctl restart rsyslog


[OK] CONFIGURATION DES SERVEURS WEB

# === NGINX (RECOMMANDÉ POUR PRODUCTION) ===

# Nginx = Serveur web rapide et léger
# Utilisé pour:
# - Servir des sites web statiques
# - Reverse proxy pour apps (Flask, Django, Node.js)
# - Load balancing (répartir la charge)

# === ÉTAPE 1: INSTALLER NGINX ===

# Ubuntu/Debian:
sudo apt install nginx

# CentOS/RHEL:
sudo yum install nginx

# Démarrer Nginx:
sudo systemctl start nginx
sudo systemctl enable nginx

# Vérifier:
sudo systemctl status nginx

# Tester dans un navigateur:
# http://server_ip
# Doit afficher: "Welcome to nginx!"


# === ÉTAPE 2: STRUCTURE DES FICHIERS NGINX ===

# Configuration principale:
# /etc/nginx/nginx.conf

# Sites disponibles:
# /etc/nginx/sites-available/

# Sites activés:
# /etc/nginx/sites-enabled/

# Logs:
# /var/log/nginx/access.log
# /var/log/nginx/error.log

# Racine web par défaut:
# /var/www/html/


# === ÉTAPE 3: CRÉER UN SITE STATIQUE ===

# Créer le dossier du site:
sudo mkdir -p /var/www/monsite.com/html

# Créer une page HTML:
sudo nano /var/www/monsite.com/html/index.html

# Contenu:
<!DOCTYPE html>
<html>
<head>
    <title>Mon Site</title>
</head>
<body>
    <h1>Bienvenue sur mon site!</h1>
    <p>Hébergé avec Nginx sur Linux.</p>
</body>
</html>

# Définir les permissions:
sudo chown -R www-data:www-data /var/www/monsite.com

# Créer la config Nginx:
sudo nano /etc/nginx/sites-available/monsite.com

# Contenu:
server {
    listen 80;
    listen [::]:80;

    server_name monsite.com www.monsite.com;

    root /var/www/monsite.com/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    access_log /var/log/nginx/monsite_access.log;
    error_log /var/log/nginx/monsite_error.log;
}

# Explications:
# listen 80: Écouter sur port 80 (HTTP)
# server_name: Domaines acceptés
# root: Dossier racine du site
# index: Fichiers index par défaut
# location /: Configuration pour toutes les URLs
# try_files: Chercher le fichier, sinon 404

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

# Explications:
# ln -s: Créer un lien symbolique
# sites-available: Config disponible
# sites-enabled: Config active

# Tester la configuration:
sudo nginx -t

# Affiche:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful

# Recharger Nginx:
sudo systemctl reload nginx

# Tester:
# http://monsite.com (ou http://server_ip si pas de DNS)


# === ÉTAPE 4: REVERSE PROXY POUR FLASK ===

# Reverse proxy = Nginx reçoit les requêtes et les transmet à Flask

# Créer la config:
sudo nano /etc/nginx/sites-available/flaskapp

# Contenu:
server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    access_log /var/log/nginx/flaskapp_access.log;
    error_log /var/log/nginx/flaskapp_error.log;
}

# Explications:
# proxy_pass http://127.0.0.1:5000: Transmettre vers Flask sur port 5000
# proxy_set_header: Ajouter des headers pour que Flask connaisse l'IP réelle

# Activer:
sudo ln -s /etc/nginx/sites-available/flaskapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx


# === ÉTAPE 5: HTTPS AVEC LET'S ENCRYPT ===

# Let's Encrypt = Certificats SSL gratuits

# Installer Certbot:

# Ubuntu/Debian:
sudo apt install certbot python3-certbot-nginx

# CentOS/RHEL:
sudo yum install certbot python3-certbot-nginx

# Obtenir un certificat:
sudo certbot --nginx -d monsite.com -d www.monsite.com

# Affiche:
# Enter email address (used for urgent renewal and security notices):
# Tape ton email

# Agree to terms? (Y)es/(N)o:
# Tape: Y

# Redirect HTTP to HTTPS? 1 (No) / 2 (Yes):
# Tape: 2 (recommandé)

# Affiche:
# Congratulations! Your certificate and chain have been saved at:
# /etc/letsencrypt/live/monsite.com/fullchain.pem
# /etc/letsencrypt/live/monsite.com/privkey.pem

# Certbot a automatiquement modifié ta config Nginx!

# Vérifier la config:
sudo nano /etc/nginx/sites-available/monsite.com

# Doit maintenant contenir:
server {
    listen 80;
    server_name monsite.com www.monsite.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name monsite.com www.monsite.com;

    ssl_certificate /etc/letsencrypt/live/monsite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/monsite.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    root /var/www/monsite.com/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

# Tester:
# https://monsite.com
# Doit afficher le cadenas vert!

# Renouvellement automatique:
sudo certbot renew --dry-run

# Ajouter un cron job pour renouvellement:
sudo crontab -e

# Ajouter:
0 3 * * * certbot renew --quiet && systemctl reload nginx


[OK] AUTOMATISATION & CRON

# === QU'EST-CE QUE CRON? ===

# Cron = Planificateur de tâches Linux
# Exécute des commandes/scripts automatiquement
# Cas d'usage:
# - Sauvegardes quotidiennes
# - Nettoyage des logs
# - Mises à jour automatiques
# - Envoi de rapports

# === ÉTAPE 1: SYNTAXE CRON ===

# Format d'une ligne cron:
# * * * * * commande
# │ │ │ │ │
# │ │ │ │ └─── Jour de la semaine (0-7, 0 et 7 = Dimanche)
# │ │ │ └───── Mois (1-12)
# │ │ └─────── Jour du mois (1-31)
# │ └───────── Heure (0-23)
# └─────────── Minute (0-59)

# Exemples:

# Tous les jours à 3h du matin:
0 3 * * * /usr/local/bin/backup.sh

# Toutes les heures:
0 * * * * /usr/local/bin/hourly-task.sh

# Toutes les 15 minutes:
*/15 * * * * /usr/local/bin/check.sh

# Tous les lundis à 9h:
0 9 * * 1 /usr/local/bin/weekly-report.sh

# Premier jour de chaque mois:
0 0 1 * * /usr/local/bin/monthly-cleanup.sh

# Toutes les 5 minutes:
*/5 * * * * /usr/local/bin/monitor.sh


# === ÉTAPE 2: GÉRER LES CRON JOBS ===

# Éditer le crontab de l'utilisateur actuel:
crontab -e

# Première fois, choisir un éditeur:
# Select an editor:
#   1. /bin/nano
#   2. /usr/bin/vim.basic
# Tape: 1 (nano pour débutants)

# Ajouter des tâches:
# Backup quotidien à 2h du matin
0 2 * * * /home/john/scripts/backup.sh

# Nettoyage des logs tous les dimanches à minuit
0 0 * * 0 find /var/log/myapp -name "*.log" -mtime +30 -delete

# Vérification toutes les 10 minutes
*/10 * * * * /home/john/scripts/health-check.sh

# Sauvegarder: Ctrl+O puis Enter
# Quitter: Ctrl+X

# Voir les cron jobs:
crontab -l

# Affiche:
# 0 2 * * * /home/john/scripts/backup.sh
# 0 0 * * 0 find /var/log/myapp -name "*.log" -mtime +30 -delete
# */10 * * * * /home/john/scripts/health-check.sh

# Supprimer tous les cron jobs:
crontab -r

# Éditer le crontab d'un autre utilisateur (en tant que root):
sudo crontab -u john -e


# === ÉTAPE 3: CRON SYSTÈME ===

# Cron jobs système (tous les utilisateurs):
# /etc/crontab

# Voir:
cat /etc/crontab

# Affiche:
# SHELL=/bin/sh
# PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# m h dom mon dow user  command
# 17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
# 25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
# 47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
# 52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

# Dossiers pour scripts:
# /etc/cron.hourly/: Toutes les heures
# /etc/cron.daily/: Tous les jours
# /etc/cron.weekly/: Toutes les semaines
# /etc/cron.monthly/: Tous les mois

# Créer un script quotidien:
sudo nano /etc/cron.daily/backup

# Contenu:
#!/bin/bash
rsync -av /var/www/ /backup/www/
echo "Backup completed at $(date)" >> /var/log/backup.log

# Rendre exécutable:
sudo chmod +x /etc/cron.daily/backup

# Le script s'exécutera automatiquement tous les jours!


# === ÉTAPE 4: EXEMPLE COMPLET - SCRIPT DE BACKUP ===

# Créer le dossier des scripts:
mkdir -p ~/scripts

# Créer le script:
nano ~/scripts/backup.sh

# Contenu:
#!/bin/bash

# Configuration
BACKUP_DIR="/backup"
SOURCE_DIRS="/var/www /home/john/myapp /etc/nginx"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
LOG_FILE="/var/log/backup.log"

# Créer le dossier de backup si nécessaire
mkdir -p "$BACKUP_DIR"

# Log de début
echo "[$DATE] Backup started" >> "$LOG_FILE"

# Backup de chaque dossier
for dir in $SOURCE_DIRS; do
    if [ -d "$dir" ]; then
        BACKUP_NAME=$(basename "$dir")
        tar -czf "$BACKUP_DIR/${BACKUP_NAME}_$DATE.tar.gz" "$dir"
        echo "[$DATE] Backed up: $dir" >> "$LOG_FILE"
    else
        echo "[$DATE] Directory not found: $dir" >> "$LOG_FILE"
    fi
done

# Supprimer les backups de plus de 7 jours
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
echo "[$DATE] Deleted old backups (>7 days)" >> "$LOG_FILE"

# Log de fin
echo "[$DATE] Backup completed" >> "$LOG_FILE"

# Rendre exécutable:
chmod +x ~/scripts/backup.sh

# Tester:
~/scripts/backup.sh

# Vérifier les logs:
cat /var/log/backup.log

# Ajouter au crontab:
crontab -e

# Ajouter:
0 2 * * * /home/john/scripts/backup.sh


# === ÉTAPE 5: REDIRECTION DES SORTIES ===

# Par défaut, cron envoie les sorties par email
# Pour rediriger vers un fichier:

# Rediriger stdout vers un fichier:
0 2 * * * /home/john/scripts/backup.sh >> /var/log/backup-cron.log 2>&1

# Explications:
# >>: Append (ajouter à la fin du fichier)
# 2>&1: Rediriger stderr vers stdout

# Ne rien afficher:
0 2 * * * /home/john/scripts/backup.sh > /dev/null 2>&1


[OK] MONITORING & PERFORMANCES

# === POURQUOI MONITORER? ===

# Monitoring = Surveiller le serveur
# Permet de:
# - Détecter les problèmes avant qu'ils deviennent critiques
# - Optimiser les performances
# - Planifier les upgrades

# === ÉTAPE 1: COMMANDES DE BASE ===

# Voir les processus en cours:
top

# Affiche:
# top - 10:00:00 up 5 days, 12:34,  2 users,  load average: 0.15, 0.20, 0.18
# Tasks: 120 total,   1 running, 119 sleeping,   0 stopped,   0 zombie
# %Cpu(s):  5.2 us,  2.1 sy,  0.0 ni, 92.5 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
# MiB Mem :   1987.7 total,    256.3 free,    830.2 used,    901.2 buff/cache
# MiB Swap:   1024.0 total,   1024.0 free,      0.0 used.    987.4 avail Mem
#
#   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
#  1234 john      20   0  156780  12548   8920 S   5.3   0.6   1:23.45 python
#  5678 www-data  20   0  123456   8765   4321 S   2.1   0.4   0:45.12 nginx

# Commandes dans top:
# q: Quitter
# k: Kill un processus (demande le PID)
# M: Trier par mémoire
# P: Trier par CPU
# 1: Voir tous les CPUs

# Htop (plus user-friendly):
htop

# Installer si pas présent:
sudo apt install htop

# Htop permet de:
# - Voir graphiquement CPU, RAM, Swap
# - Trier les processus
# - Tuer des processus avec F9

# Voir l'utilisation mémoire:
free -h

# Affiche:
#               total        used        free      shared  buff/cache   available
# Mem:          1.9Gi       810Mi       250Mi       5.0Mi       900Mi       980Mi
# Swap:         1.0Gi          0B       1.0Gi

# Explications:
# total: RAM totale
# used: RAM utilisée
# free: RAM libre
# buff/cache: RAM utilisée pour cache (libérable si besoin)
# available: RAM réellement disponible

# Voir l'utilisation disque:
df -h

# Voir l'utilisation d'un dossier:
du -sh /var/log

# Affiche:
# 128M    /var/log

# Voir les sous-dossiers:
du -h --max-depth=1 /var

# Voir les processus réseau:
sudo ss -tuln

# Affiche:
# Netid  State   Recv-Q  Send-Q   Local Address:Port    Peer Address:Port
# tcp    LISTEN  0       128            0.0.0.0:22           0.0.0.0:*
# tcp    LISTEN  0       128            0.0.0.0:80           0.0.0.0:*
# tcp    LISTEN  0       128            0.0.0.0:443          0.0.0.0:*

# Explications:
# -t: TCP
# -u: UDP
# -l: LISTEN (ports en écoute)
# -n: Numeric (afficher les numéros de port)

# Ancienne commande (netstat):
sudo netstat -tuln


# Fichier: python_cheats/cheatsheets/configuration.txt (SUITE)

```
[OK] BASE DE DONNÉES (MYSQL/MARIADB & POSTGRESQL)

# === QU'EST-CE QU'UNE BASE DE DONNÉES? ===

# Base de données = Système pour stocker des données de manière organisée
# Comme un classeur géant avec des tiroirs (tables), des dossiers (lignes)
# Exemples d'utilisation:
# - Site e-commerce: produits, clients, commandes
# - Blog: articles, commentaires, utilisateurs
# - Application: données utilisateur, configurations

# MySQL vs MariaDB:
# MySQL = Base de données populaire (Oracle)
# MariaDB = Fork open-source de MySQL (100% compatible)
# PostgreSQL = Base de données avancée (transactions, fonctionnalités riches)

# Différences:
# MySQL/MariaDB: Plus simple, très populaire (WordPress, Drupal)
# PostgreSQL: Plus puissant, meilleur pour applications complexes


# === INSTALLATION MYSQL/MARIADB ===

# === UBUNTU/DEBIAN ===

# Installer MariaDB (recommandé):
sudo apt update
sudo apt install mariadb-server mariadb-client

# Ou MySQL:
sudo apt install mysql-server mysql-client

# Démarrer le service:
sudo systemctl start mariadb
sudo systemctl enable mariadb

# Vérifier:
sudo systemctl status mariadb


# === CENTOS/RHEL ===

# MariaDB:
sudo yum install mariadb-server mariadb

# Ou MySQL:
sudo yum install mysql-server mysql

# Démarrer:
sudo systemctl start mariadb
sudo systemctl enable mariadb


# === ÉTAPE 1: SÉCURISATION INITIALE ===

# Script de sécurisation (TRÈS IMPORTANT!):
sudo mysql_secure_installation

# Questions posées:

# Enter current password for root (enter for none):
# Appuie sur Enter (pas de mot de passe par défaut)

# Set root password? [Y/n]
# Tape: Y
# Enter new password: [tape un mot de passe fort]
# Re-enter new password: [retape le même]

# Remove anonymous users? [Y/n]
# Tape: Y (supprime les utilisateurs anonymes = SÉCURITÉ)

# Disallow root login remotely? [Y/n]
# Tape: Y (root ne peut se connecter que depuis localhost)

# Remove test database and access to it? [Y/n]
# Tape: Y (supprime la DB de test)

# Reload privilege tables now? [Y/n]
# Tape: Y (applique les changements)

# Affiche:
# All done!  If you've completed all of the above steps, your MariaDB
# installation should now be secure.


# === ÉTAPE 2: SE CONNECTER À MYSQL/MARIADB ===

# Connexion en tant que root:
sudo mysql -u root -p

# Explications:
# mysql: Client MySQL
# -u root: User root
# -p: Demander le mot de passe

# Affiche:
# Enter password:
# Tape le mot de passe que tu as défini

# Affiche:
# Welcome to the MariaDB monitor.  Commands end with ; or \g.
# Your MariaDB connection id is 42
# Server version: 10.6.12-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04
# ...
# MariaDB [(none)]>

# Tu es maintenant dans le shell MySQL!


# === ÉTAPE 3: COMMANDES DE BASE ===

# Voir les bases de données:
SHOW DATABASES;

# Affiche:
# +--------------------+
# | Database           |
# +--------------------+
# | information_schema |
# | mysql              |
# | performance_schema |
# +--------------------+

# Créer une base de données:
CREATE DATABASE myapp;

# Vérifier:
SHOW DATABASES;

# Utiliser une base de données:
USE myapp;

# Affiche:
# Database changed

# Créer une table:
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

# Explications:
# id INT AUTO_INCREMENT PRIMARY KEY: ID auto-incrémenté, clé primaire
# VARCHAR(50): Chaîne de caractères, max 50 caractères
# NOT NULL: Obligatoire (ne peut pas être vide)
# UNIQUE: Doit être unique
# TIMESTAMP DEFAULT CURRENT_TIMESTAMP: Date/heure automatique

# Voir les tables:
SHOW TABLES;

# Affiche:
# +----------------+
# | Tables_in_myapp|
# +----------------+
# | users          |
# +----------------+

# Voir la structure d'une table:
DESCRIBE users;

# Affiche:
# +------------+--------------+------+-----+-------------------+
# | Field      | Type         | Null | Key | Default           |
# +------------+--------------+------+-----+-------------------+
# | id         | int(11)      | NO   | PRI | NULL              |
# | username   | varchar(50)  | NO   | UNI | NULL              |
# | email      | varchar(100) | NO   | UNI | NULL              |
# | password   | varchar(255) | NO   |     | NULL              |
# | created_at | timestamp    | NO   |     | CURRENT_TIMESTAMP |
# +------------+--------------+------+-----+-------------------+

# Insérer des données:
INSERT INTO users (username, email, password) 
VALUES ('john', 'john@example.com', 'hashed_password_here');

# Affiche:
# Query OK, 1 row affected (0.01 sec)

# Voir les données:
SELECT * FROM users;

# Affiche:
# +----+----------+-------------------+---------------------+---------------------+
# | id | username | email             | password            | created_at          |
# +----+----------+-------------------+---------------------+---------------------+
# |  1 | john     | john@example.com  | hashed_password_... | 2024-01-15 10:00:00 |
# +----+----------+-------------------+---------------------+---------------------+

# Mettre à jour:
UPDATE users SET email = 'newemail@example.com' WHERE username = 'john';

# Supprimer:
DELETE FROM users WHERE username = 'john';

# Quitter:
EXIT;


# === ÉTAPE 4: CRÉER UN UTILISATEUR & PERMISSIONS ===

# Se connecter en tant que root:
sudo mysql -u root -p

# Créer un utilisateur:
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'strong_password_here';

# Explications:
# appuser: Nom de l'utilisateur
# localhost: Peut se connecter seulement depuis localhost
# IDENTIFIED BY: Mot de passe

# Créer un utilisateur accessible depuis n'importe où:
CREATE USER 'appuser'@'%' IDENTIFIED BY 'strong_password_here';

# Explications:
# %: Wildcard = n'importe quelle IP

# Donner tous les droits sur une base de données:
GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'localhost';

# Explications:
# GRANT ALL PRIVILEGES: Donner tous les droits
# ON myapp.*: Sur la base myapp, toutes les tables (*)
# TO 'appuser'@'localhost': À l'utilisateur appuser

# Donner seulement certains droits:
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'appuser'@'localhost';

# Explications:
# SELECT: Lire
# INSERT: Insérer
# UPDATE: Modifier
# DELETE: Supprimer

# Donner le droit de créer des bases de données:
GRANT CREATE ON *.* TO 'appuser'@'localhost';

# Recharger les privilèges:
FLUSH PRIVILEGES;

# Voir les droits d'un utilisateur:
SHOW GRANTS FOR 'appuser'@'localhost';

# Affiche:
# +----------------------------------------------------------------+
# | Grants for appuser@localhost                                   |
# +----------------------------------------------------------------+
# | GRANT USAGE ON *.* TO `appuser`@`localhost`                    |
# | GRANT ALL PRIVILEGES ON `myapp`.* TO `appuser`@`localhost`     |
# +----------------------------------------------------------------+

# Révoquer des droits:
REVOKE DELETE ON myapp.* FROM 'appuser'@'localhost';
FLUSH PRIVILEGES;

# Supprimer un utilisateur:
DROP USER 'appuser'@'localhost';


# === ÉTAPE 5: ACCÈS DISTANT ===

# Par défaut, MySQL/MariaDB écoute seulement sur localhost
# Pour autoriser les connexions distantes:

# Éditer la config:
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

# Ou pour MySQL:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

# Trouver la ligne:
bind-address = 127.0.0.1

# Changer en:
bind-address = 0.0.0.0

# Explications:
# 127.0.0.1: Écoute seulement localhost
# 0.0.0.0: Écoute toutes les interfaces

# Ou pour écouter une IP spécifique:
bind-address = 192.168.1.100

# Sauvegarder: Ctrl+O puis Enter
# Quitter: Ctrl+X

# Redémarrer MySQL:
sudo systemctl restart mariadb

# Ouvrir le port dans le firewall:
sudo ufw allow 3306/tcp

# Créer un utilisateur distant:
sudo mysql -u root -p

CREATE USER 'remote_user'@'192.168.1.%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON myapp.* TO 'remote_user'@'192.168.1.%';
FLUSH PRIVILEGES;
EXIT;

# Explications:
# 192.168.1.%: Autorise depuis le réseau 192.168.1.x

# Tester depuis une autre machine:
mysql -h 192.168.1.100 -u remote_user -p


# === ÉTAPE 6: SAUVEGARDES (MYSQLDUMP) ===

# mysqldump = Outil pour exporter une base de données

# Sauvegarder une base de données:
mysqldump -u root -p myapp > myapp_backup.sql

# Explications:
# -u root: Utilisateur
# -p: Demander le mot de passe
# myapp: Base de données à sauvegarder
# >: Rediriger vers un fichier
# myapp_backup.sql: Fichier de sauvegarde

# Affiche:
# Enter password:
# Tape le mot de passe

# Vérifier:
ls -lh myapp_backup.sql

# Affiche:
# -rw-r--r-- 1 john john 2.5M Jan 15 10:00 myapp_backup.sql

# Sauvegarder toutes les bases de données:
mysqldump -u root -p --all-databases > all_databases_backup.sql

# Sauvegarder avec compression:
mysqldump -u root -p myapp | gzip > myapp_backup.sql.gz

# Vérifier:
ls -lh myapp_backup.sql.gz

# Affiche:
# -rw-r--r-- 1 john john 450K Jan 15 10:00 myapp_backup.sql.gz

# Sauvegarder une table spécifique:
mysqldump -u root -p myapp users > users_backup.sql

# Sauvegarder avec la date dans le nom:
mysqldump -u root -p myapp | gzip > myapp_backup_$(date +%Y-%m-%d).sql.gz

# Vérifier:
ls -lh myapp_backup_*.sql.gz

# Affiche:
# -rw-r--r-- 1 john john 450K Jan 15 10:00 myapp_backup_2024-01-15.sql.gz


# === ÉTAPE 7: RESTAURATION ===

# Restaurer une base de données:
mysql -u root -p myapp < myapp_backup.sql

# Explications:
# <: Rediriger depuis un fichier
# myapp: Base de données de destination (doit exister!)

# Si la base n'existe pas, la créer d'abord:
mysql -u root -p -e "CREATE DATABASE myapp;"

# Puis restaurer:
mysql -u root -p myapp < myapp_backup.sql

# Restaurer depuis un fichier compressé:
gunzip < myapp_backup.sql.gz | mysql -u root -p myapp

# Ou:
zcat myapp_backup.sql.gz | mysql -u root -p myapp

# Restaurer toutes les bases de données:
mysql -u root -p < all_databases_backup.sql


# === ÉTAPE 8: SCRIPT DE BACKUP AUTOMATIQUE ===

# Créer le script:
nano ~/scripts/mysql-backup.sh

# Contenu:
#!/bin/bash

# Configuration
DB_USER="root"
DB_PASS="your_root_password"
DB_NAME="myapp"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
RETENTION_DAYS=7

# Créer le dossier de backup
mkdir -p "$BACKUP_DIR"

# Backup
mysqldump -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" | gzip > "$BACKUP_DIR/${DB_NAME}_$DATE.sql.gz"

# Vérifier si le backup a réussi
if [ $? -eq 0 ]; then
    echo "[$DATE] Backup successful: ${DB_NAME}_$DATE.sql.gz" >> /var/log/mysql-backup.log
else
    echo "[$DATE] Backup FAILED!" >> /var/log/mysql-backup.log
    exit 1
fi

# Supprimer les backups de plus de X jours
find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "[$DATE] Old backups deleted (>$RETENTION_DAYS days)" >> /var/log/mysql-backup.log

# Rendre exécutable:
chmod +x ~/scripts/mysql-backup.sh

# IMPORTANT: Protéger le fichier (contient le mot de passe!):
chmod 700 ~/scripts/mysql-backup.sh

# Tester:
~/scripts/mysql-backup.sh

# Ajouter au crontab (tous les jours à 2h):
crontab -e

# Ajouter:
0 2 * * * /home/john/scripts/mysql-backup.sh


# === INSTALLATION POSTGRESQL ===

# === UBUNTU/DEBIAN ===

# Installer:
sudo apt update
sudo apt install postgresql postgresql-contrib

# Démarrer:
sudo systemctl start postgresql
sudo systemctl enable postgresql

# Vérifier:
sudo systemctl status postgresql


# === CENTOS/RHEL ===

# Installer:
sudo yum install postgresql-server postgresql-contrib

# Initialiser:
sudo postgresql-setup --initdb

# Démarrer:
sudo systemctl start postgresql
sudo systemctl enable postgresql


# === ÉTAPE 1: SE CONNECTER À POSTGRESQL ===

# PostgreSQL utilise "peer authentication" par défaut
# = Connexion via utilisateur système

# Se connecter en tant que postgres (superuser):
sudo -u postgres psql

# Affiche:
# psql (14.10 (Ubuntu 14.10-0ubuntu0.22.04.1))
# Type "help" for help.
#
# postgres=#

# Tu es dans le shell PostgreSQL!


# === ÉTAPE 2: COMMANDES DE BASE ===

# Voir les bases de données:
\l

# Affiche:
#                                   List of databases
#    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access
# -----------+----------+----------+-------------+-------------+-----------
#  postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
#  template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
#  template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres

# Créer une base de données:
CREATE DATABASE myapp;

# Vérifier:
\l

# Se connecter à une base:
\c myapp

# Affiche:
# You are now connected to database "myapp" as user "postgres".

# Créer une table:
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

# Explications:
# SERIAL: Auto-incrémenté (équivalent AUTO_INCREMENT MySQL)

# Voir les tables:
\dt

# Affiche:
#          List of relations
#  Schema | Name  | Type  |  Owner
# --------+-------+-------+----------
#  public | users | table | postgres

# Voir la structure:
\d users

# Affiche:
#                                     Table "public.users"
#    Column   |            Type             | Collation | Nullable |              Default
# ------------+-----------------------------+-----------+----------+-----------------------------------
#  id         | integer                     |           | not null | nextval('users_id_seq'::regclass)
#  username   | character varying(50)       |           | not null |
#  email      | character varying(100)      |           | not null |
#  password   | character varying(255)      |           | not null |
#  created_at | timestamp without time zone |           |          | CURRENT_TIMESTAMP

# Insérer des données:
INSERT INTO users (username, email, password) 
VALUES ('john', 'john@example.com', 'hashed_password');

# Voir les données:
SELECT * FROM users;

# Quitter:
\q


# === ÉTAPE 3: CRÉER UN UTILISATEUR & PERMISSIONS ===

# Se connecter en tant que postgres:
sudo -u postgres psql

# Créer un utilisateur:
CREATE USER appuser WITH PASSWORD 'strong_password';

# Créer une base de données pour cet utilisateur:
CREATE DATABASE myapp OWNER appuser;

# Donner tous les privilèges:
GRANT ALL PRIVILEGES ON DATABASE myapp TO appuser;

# Se connecter à la base:
\c myapp

# Donner les droits sur toutes les tables:
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO appuser;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO appuser;

# Explications:
# SEQUENCES: Pour les colonnes SERIAL (auto-increment)

# Donner seulement certains droits:
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO appuser;

# Voir les droits:
\du

# Affiche:
#                                    List of roles
#  Role name |                         Attributes                         | Member of
# -----------+------------------------------------------------------------+-----------
#  appuser   |                                                            | {}
#  postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

# Révoquer des droits:
REVOKE DELETE ON ALL TABLES IN SCHEMA public FROM appuser;

# Supprimer un utilisateur:
DROP USER appuser;


# === ÉTAPE 4: ACCÈS DISTANT ===

# Éditer la config d'écoute:
sudo nano /etc/postgresql/14/main/postgresql.conf

# Trouver:
#listen_addresses = 'localhost'

# Changer en:
listen_addresses = '*'

# Explications:
# '*': Écouter toutes les interfaces

# Ou pour une IP spécifique:
listen_addresses = '192.168.1.100'

# Éditer les règles d'accès:
sudo nano /etc/postgresql/14/main/pg_hba.conf

# Ajouter à la fin:
host    all             all             192.168.1.0/24          md5

# Explications:
# host: Connexion TCP/IP
# all: Toutes les bases de données
# all: Tous les utilisateurs
# 192.168.1.0/24: Réseau autorisé
# md5: Authentification par mot de passe

# Sauvegarder et redémarrer:
sudo systemctl restart postgresql

# Ouvrir le port:
sudo ufw allow 5432/tcp

# Tester depuis une autre machine:
psql -h 192.168.1.100 -U appuser -d myapp


# === ÉTAPE 5: SAUVEGARDES (PG_DUMP) ===

# Sauvegarder une base de données:
sudo -u postgres pg_dump myapp > myapp_backup.sql

# Avec compression:
sudo -u postgres pg_dump myapp | gzip > myapp_backup.sql.gz

# Sauvegarder toutes les bases de données:
sudo -u postgres pg_dumpall > all_databases_backup.sql

# Sauvegarder avec la date:
sudo -u postgres pg_dump myapp | gzip > myapp_backup_$(date +%Y-%m-%d).sql.gz

# Format custom (plus rapide pour restaurer):
sudo -u postgres pg_dump -Fc myapp > myapp_backup.dump


# === ÉTAPE 6: RESTAURATION ===

# Restaurer une base de données:
sudo -u postgres psql myapp < myapp_backup.sql

# Depuis un fichier compressé:
gunzip < myapp_backup.sql.gz | sudo -u postgres psql myapp

# Depuis un format custom:
sudo -u postgres pg_restore -d myapp myapp_backup.dump

# Restaurer toutes les bases:
sudo -u postgres psql < all_databases_backup.sql


# === ÉTAPE 7: OPTIMISATION SIMPLE ===

# === INDEXES (MYSQL & POSTGRESQL) ===

# Index = Accélère les recherches
# Comme l'index d'un livre

# Créer un index (MySQL):
CREATE INDEX idx_username ON users(username);

# Créer un index (PostgreSQL):
CREATE INDEX idx_username ON users(username);

# Index sur plusieurs colonnes:
CREATE INDEX idx_user_email ON users(username, email);

# Voir les index (MySQL):
SHOW INDEX FROM users;

# Voir les index (PostgreSQL):
\di

# Supprimer un index:
DROP INDEX idx_username;


# === SLOW QUERY LOG (MYSQL) ===

# Activer le log des requêtes lentes:
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

# Ajouter:
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 2

# Explications:
# slow_query_log = 1: Activer
# long_query_time = 2: Requêtes de plus de 2 secondes

# Redémarrer:
sudo systemctl restart mariadb

# Voir les requêtes lentes:
sudo tail -f /var/log/mysql/slow-query.log


# === SLOW QUERY LOG (POSTGRESQL) ===

# Éditer la config:
sudo nano /etc/postgresql/14/main/postgresql.conf

# Ajouter/modifier:
log_min_duration_statement = 2000

# Explications:
# 2000: Log les requêtes de plus de 2000ms (2 secondes)

# Redémarrer:
sudo systemctl restart postgresql

# Voir les logs:
sudo tail -f /var/log/postgresql/postgresql-14-main.log


[OK] VIRTUALISATION ET CONTENEURS

# === QU'EST-CE QUE LA VIRTUALISATION? ===

# Virtualisation = Créer plusieurs "ordinateurs virtuels" sur un seul ordinateur physique
# Analogie: Comme diviser un grand appartement en plusieurs petits studios

# Types:
# 1. Machines virtuelles (VM): Système complet (kernel, OS, apps)
# 2. Conteneurs: Partagent le kernel, seulement les apps isolées

# VM vs Conteneurs:
# VM: Plus lourdes, isolation complète, différents OS
# Conteneurs: Légers, démarrent en secondes, même OS


# === DOCKER (CONTENEURS) ===

# Docker = Plateforme de conteneurisation
# Permet de:
# - Empaqueter une app avec ses dépendances
# - Déployer facilement partout
# - Isoler les apps

# === INSTALLATION DOCKER ===

# === UBUNTU/DEBIAN ===

# Installer les dépendances:
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common

# Ajouter la clé GPG de Docker:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Ajouter le dépôt Docker:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Installer Docker:
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Démarrer Docker:
sudo systemctl start docker
sudo systemctl enable docker

# Vérifier:
sudo systemctl status docker


# === CENTOS/RHEL ===

# Installer:
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Démarrer:
sudo systemctl start docker
sudo systemctl enable docker


# === AJOUTER L'UTILISATEUR AU GROUPE DOCKER ===

# Pour utiliser Docker sans sudo:
sudo usermod -aG docker $USER

# Se déconnecter et reconnecter pour appliquer

# Vérifier:
docker --version

# Affiche:
# Docker version 24.0.7, build afdd53b


# === ÉTAPE 1: COMMANDES DOCKER DE BASE ===

# Télécharger une image:
docker pull nginx

# Affiche:
# Using default tag: latest
# latest: Pulling from library/nginx
# a2abf6c4d29d: Pull complete
# ...
# Status: Downloaded newer image for nginx:latest

# Voir les images:
docker images

# Affiche:
# REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
# nginx        latest    605c77e624dd   2 weeks ago    141MB

# Lancer un conteneur:
docker run -d -p 8080:80 --name my-nginx nginx

# Explications:
# run: Lancer un conteneur
# -d: Detached (en arrière-plan)
# -p 8080:80: Port 8080 de l'hôte -> port 80 du conteneur
# --name my-nginx: Nom du conteneur
# nginx: Image à utiliser

# Affiche:
# abc123def456...

# Vérifier:
docker ps

# Affiche:
# CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
# abc123def456   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:8080->80/tcp   my-nginx

# Tester dans un navigateur:
# http://localhost:8080
# Doit afficher la page Nginx!

# Voir les logs:
docker logs my-nginx

# Suivre les logs:
docker logs -f my-nginx

# Entrer dans le conteneur:
docker exec -it my-nginx /bin/bash

# Explications:
# exec: Exécuter une commande
# -it: Interactive + TTY (terminal interactif)
# /bin/bash: Shell bash

# Tu es maintenant DANS le conteneur!
# root@abc123def456:/#

# Sortir:
exit

# Arrêter le conteneur:
docker stop my-nginx

# Démarrer le conteneur:
docker start my-nginx

# Redémarrer:
docker restart my-nginx

# Supprimer le conteneur:
docker rm my-nginx

# Supprimer avec force (si en cours):
docker rm -f my-nginx

# Supprimer une image:
docker rmi nginx


# === ÉTAPE 2: DOCKERFILE ===

# Dockerfile = Recette pour créer une image Docker

# Créer un dossier:
mkdir myapp
cd myapp

# Créer une app simple:
nano app.py

# Contenu:
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello from Docker!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

# Créer requirements.txt:
nano requirements.txt

# Contenu:
Flask==2.3.0

# Créer le Dockerfile:
nano Dockerfile

# Contenu:
# Image de base
FROM python:3.11-slim

# Dossier de travail
WORKDIR /app

# Copier les fichiers
COPY requirements.txt .
COPY app.py .

# Installer les dépendances
RUN pip install --no-cache-dir -r requirements.txt

# Exposer le port
EXPOSE 5000

# Commande de démarrage
CMD ["python", "app.py"]

# Construire l'image:
docker build -t myapp:1.0 .

# Explications:
# build: Construire une image
# -t myapp:1.0: Tag (nom:version)
# .: Utiliser le Dockerfile du dossier actuel

# Affiche:
# [+] Building 15.3s (10/10) FINISHED
# ...
# => => naming to docker.io/library/myapp:1.0

# Vérifier:
docker images

# Affiche:
# REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
# myapp        1.0       xyz789abc123   10 seconds ago   150MB

# Lancer:
docker run -d -p 5000:5000 --name myapp-container myapp:1.0

# Tester:
curl http://localhost:5000

# Affiche:
# Hello from Docker!


# === ÉTAPE 3: VOLUMES (PERSISTANCE DES DONNÉES) ===

# Volume = Stockage persistant pour les conteneurs
# Pourquoi? Les conteneurs sont éphémères (données perdues à l'arrêt)

# Créer un volume:
docker volume create mydata

# Voir les volumes:
docker volume ls

# Affiche:
# DRIVER    VOLUME NAME
# local     mydata

# Utiliser un volume:
docker run -d -v mydata:/data --name data-container ubuntu sleep 3600

# Explications:
# -v mydata:/data: Monter le volume mydata dans /data du conteneur

# Créer un fichier dans le conteneur:
docker exec data-container touch /data/test.txt

# Arrêter et supprimer le conteneur:
docker rm -f data-container

# Recréer avec le même volume:
docker run -d -v mydata:/data --name data-container2 ubuntu sleep 3600

# Vérifier que le fichier existe toujours:
docker exec data-container2 ls /data

# Affiche:
# test.txt

# Les données ont persisté!

# Bind mount (monter un dossier de l'hôte):
docker run -d -v /home/john/myapp:/app --name bind-container ubuntu sleep 3600

# Explications:
# -v /home/john/myapp:/app: Monter le dossier de l'hôte dans /app

# Supprimer un volume:
docker volume rm mydata


# === ÉTAPE 4: RÉSEAUX DOCKER ===

# Réseau = Permet aux conteneurs de communiquer

# Voir les réseaux:
docker network ls

# Affiche:
# NETWORK ID     NAME      DRIVER    SCOPE
# abc123def456   bridge    bridge    local
# xyz789abc123   host      host      local
# def456abc789   none      null      local

# Créer un réseau:
docker network create mynetwork

# Lancer des conteneurs sur le même réseau:
docker run -d --network mynetwork --name web nginx
docker run -d --network mynetwork --name app myapp:1.0

# Les conteneurs peuvent communiquer par leur nom:
docker exec app ping web

# Affiche:
# PING web (172.18.0.2) 56(84) bytes of data.
# 64 bytes from web.mynetwork (172.18.0.2): icmp_seq=1 ttl=64 time=0.123 ms

# Inspecter un réseau:
docker network inspect mynetwork

# Supprimer un réseau:
docker network rm mynetwork


# === ÉTAPE 5: DOCKER COMPOSE ===

# Docker Compose = Orchestrer plusieurs conteneurs
# Un seul fichier pour définir toute une stack

# Créer docker-compose.yml:
nano docker-compose.yml

# Contenu:
version: '3.9'

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    networks:
      - mynetwork

  app:
    build: .
    ports:
      - "5000:5000"
    environment:
      - FLASK_ENV=production
    networks:
      - mynetwork
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - mynetwork

networks:
  mynetwork:
    driver: bridge

volumes:
  pgdata:

# Explications:
# services: Liste des conteneurs
# web: Nginx
# app: Notre app Flask
# db: PostgreSQL
# depends_on: app attend que db soit prêt
# networks: Tous sur le même réseau
# volumes: Volume persistant pour PostgreSQL

# Lancer la stack:
docker-compose up -d

# Affiche:
# Creating network "myapp_mynetwork" with driver "bridge"
# Creating volume "myapp_pgdata" with default driver
# Creating myapp_db_1  ... done
# Creating myapp_app_1 ... done
# Creating myapp_web_1 ... done

# Voir les conteneurs:
docker-compose ps

# Affiche:
#     Name                   Command               State           Ports
# --------------------------------------------------------------------------------
# myapp_app_1    python app.py                    Up      0.0.0.0:5000->5000/tcp
# myapp_db_1     docker-entrypoint.sh postgres    Up      5432/tcp
# myapp_web_1    /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8080->80/tcp

# Voir les logs:
docker-compose logs -f

# Arrêter:
docker-compose stop

# Démarrer:
docker-compose start

# Arrêter et supprimer:
docker-compose down

# Arrêter et supprimer les volumes:
docker-compose down -v


# === KVM/QEMU (MACHINES VIRTUELLES) ===

# KVM = Kernel-based Virtual Machine
# QEMU = Émulateur

# === INSTALLATION ===

# Ubuntu/Debian:
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager

# CentOS/RHEL:
sudo yum install qemu-kvm libvirt virt-install virt-manager

# Ajouter l'utilisateur au groupe:
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER

# Démarrer libvirt:
sudo systemctl start libvirtd
sudo systemctl enable libvirtd

# Vérifier:
sudo systemctl status libvirtd

# Vérifier le support KVM:
sudo kvm-ok

# Affiche:
# INFO: /dev/kvm exists
# KVM acceleration can be used


# === CRÉER UNE VM AVEC VIRT-MANAGER (GUI) ===

# Lancer virt-manager:
virt-manager

# 1. Cliquer sur "Create a new virtual machine"
# 2. Choisir "Local install media (ISO image or CDROM)"
# 3. Parcourir et sélectionner l'ISO (ex: ubuntu-22.04.iso)
# 4. Allouer RAM et CPU (ex: 2048 MB, 2 CPUs)
# 5. Créer un disque (ex: 20 GB)
# 6. Nommer la VM (ex: ubuntu-vm)
# 7. Cliquer "Finish"

# La VM démarre automatiquement!


# === CRÉER UNE VM EN LIGNE DE COMMANDE ===

# Créer une VM:
virt-install \
  --name ubuntu-vm \
  --ram 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/ubuntu-vm.qcow2,size=20 \
  --os-variant ubuntu22.04 \
  --network bridge=virbr0 \
  --graphics vnc \
  --cdrom /path/to/ubuntu-22.04.iso

# Explications:
# --name: Nom de la VM
# --ram: Mémoire en MB
# --vcpus: Nombre de CPUs
# --disk: Disque virtuel
# --os-variant: Type d'OS
# --network: Réseau
# --graphics vnc: VNC pour accès graphique
# --cdrom: ISO d'installation

# Lister les VMs:
virsh list --all

# Affiche:
#  Id   Name        State
# ---------------------------
#  1    ubuntu-vm   running

# Démarrer une VM:
virsh start ubuntu-vm

# Arrêter une VM:
virsh shutdown ubuntu-vm

# Forcer l'arrêt:
virsh destroy ubuntu-vm

# Supprimer une VM:
virsh undefine ubuntu-vm

# Se connecter à une VM (console):
virsh console ubuntu-vm


[OK] SAUVEGARDES & RESTAURATION

# === POURQUOI DES SAUVEGARDES? ===

# Sauvegardes = Copies de sécurité
# Indispensables pour:
# - Panne matérielle (disque HS)
# - Erreur humaine (rm -rf / par accident!)
# - Attaque (ransomware, hack)
# - Désastre (incendie, inondation)

# Règle 3-2-1:
# 3 copies des données
# 2 supports différents (disque + cloud)
# 1 copie hors site (distant)


# === RSYNC (SYNCHRONISATION) ===

# Rsync = Outil puissant pour synchroniser des fichiers
# Copie seulement les différences (rapide!)

# Syntaxe de base:
rsync [options] source destination

# Sauvegarder un dossier:
rsync -av /var/www/ /backup/www/

# Explications:
# -a: Archive (préserve permissions, dates, liens)
# -v: Verbose (affiche les détails)
# /var/www/: Source (/ à la fin = contenu du dossier)
# /backup/www/: Destination

# Affiche:
# sending incremental file list
# ./
# index.html
# css/style.css
# ...
# sent 1,234 bytes  received 35 bytes  2,538.00 bytes/sec
# total size is 12,345  speedup is 9.73

# Options utiles:

# -z: Compresser pendant le transfert
rsync -avz /var/www/ /backup/www/

# --delete: Supprimer les fichiers dans la destination qui n'existent plus dans la source
rsync -av --delete /var/www/ /backup/www/

# --exclude: Exclure des fichiers/dossiers
rsync -av --exclude='*.log' --exclude='cache/' /var/www/ /backup/www/

# --dry-run: Test (ne fait rien, affiche ce qui serait fait)
rsync -av --dry-run /var/www/ /backup/www/

# --progress: Afficher la progression
rsync -av --progress /var/www/ /backup/www/

# Sauvegarder vers un serveur distant:
rsync -avz /var/www/ user@remote-server:/backup/www/

# Explications:
# user@remote-server: Utilisateur et serveur distant
# /backup/www/: Chemin sur le serveur distant

# Sauvegarder depuis un serveur distant:
rsync -avz user@remote-server:/var/www/ /backup/www/


# === SCP (SECURE COPY) ===

# SCP = Copie sécurisée via SSH

# Copier un fichier vers un serveur:
scp file.txt user@remote-server:/path/to/destination/

# Copier un dossier:
scp -r /var/www user@remote-server:/backup/

# Explications:
# -r: Récursif (dossiers)

# Copier depuis un serveur:
scp user@remote-server:/path/to/file.txt /local/path/

# Copier avec compression:
scp -C file.txt user@remote-server:/path/

# Explications:
# -C: Compression


# === SFTP (SECURE FTP) ===

# SFTP = FTP sécurisé via SSH

# Se connecter:
sftp user@remote-server

# Affiche:
# Connected to remote-server.
# sftp>

# Commandes SFTP:

# Voir le dossier distant:
ls

# Voir le dossier local:
lls

# Changer de dossier distant:
cd /path/to/folder

# Changer de dossier local:
lcd /local/path

# Upload un fichier:
put file.txt

# Upload un dossier:
put -r folder/

# Download un fichier:
get file.txt

# Download un dossier:
get -r folder/

# Quitter:
exit


# === TAR & GZIP (ARCHIVAGE) ===

# Tar = Créer des archives
# Gzip = Compresser

# Créer une archive:
tar -cvf archive.tar /var/www

# Explications:
# -c: Create (créer)
# -v: Verbose (afficher)
# -f: File (fichier de sortie)

# Créer une archive compressée:
tar -czvf archive.tar.gz /var/www

# Explications:
# -z: Gzip (compresser)

# Extraire une archive:
tar -xvf archive.tar

# Explications:
# -x: Extract (extraire)

# Extraire une archive compressée:
tar -xzvf archive.tar.gz

# Extraire dans un dossier spécifique:
tar -xzvf archive.tar.gz -C /path/to/destination/

# Voir le contenu sans extraire:
tar -tzvf archive.tar.gz

# Explications:
# -t: List (lister)


# === SCRIPT DE BACKUP COMPLET ===

# Créer le script:
nano ~/scripts/full-backup.sh

# Contenu:
#!/bin/bash

# Configuration
BACKUP_DIR="/backup"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
LOG_FILE="/var/log/backup.log"
RETENTION_DAYS=7

# Dossiers à sauvegarder
DIRS_TO_BACKUP=(
    "/var/www"
    "/etc"
    "/home"
)

# Créer le dossier de backup
mkdir -p "$BACKUP_DIR/$DATE"

echo "[$DATE] Backup started" >> "$LOG_FILE"

# Backup de chaque dossier
for dir in "${DIRS_TO_BACKUP[@]}"; do
    if [ -d "$dir" ]; then
        BACKUP_NAME=$(echo "$dir" | tr '/' '_')
        tar -czvf "$BACKUP_DIR/$DATE/${BACKUP_NAME}.tar.gz" "$dir" 2>&1 | tee -a "$LOG_FILE"
        
        if [ ${PIPESTATUS[0]} -eq 0 ]; then
            echo "[$DATE] Successfully backed up: $dir" >> "$LOG_FILE"
        else
            echo "[$DATE] FAILED to backup: $dir" >> "$LOG_FILE"
        fi
    else
        echo "[$DATE] Directory not found: $dir" >> "$LOG_FILE"
    fi
done

# Backup MySQL
mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --all-databases | gzip > "$BACKUP_DIR/$DATE/mysql_all_databases.sql.gz"
echo "[$DATE] MySQL backup completed" >> "$LOG_FILE"

# Supprimer les backups de plus de X jours
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
echo "[$DATE] Old backups deleted (>$RETENTION_DAYS days)" >> "$LOG_FILE"

echo "[$DATE] Backup completed successfully" >> "$LOG_FILE"

# Rendre exécutable:
chmod +x ~/scripts/full-backup.sh

# Ajouter au crontab (tous les jours à 2h):
crontab -e

# Ajouter:
0 2 * * * /home/john/scripts/full-backup.sh


[OK] CONFIGURATION DU BOOT & GRUB

# === QU'EST-CE QUE GRUB? ===

# GRUB = GRand Unified Bootloader
# Premier programme qui se lance au démarrage
# Permet de:
# - Choisir quel OS démarrer (si plusieurs)
# - Passer des options au kernel
# - Démarrer en mode rescue

# === FICHIER DE CONFIGURATION ===

# Fichier principal:
sudo nano /etc/default/grub

# Contenu important:

# Timeout (temps d'attente menu):
GRUB_TIMEOUT=5

# OS par défaut:
GRUB_DEFAULT=0

# Explications:
# 0 = premier dans la liste
# "saved" = dernier utilisé

# Cacher le menu:
GRUB_HIDDEN_TIMEOUT=0

# Options du kernel:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

# Explications:
# quiet: Moins de messages au boot
# splash: Écran de démarrage graphique

# Options avancées:
GRUB_CMDLINE_LINUX=""

# Exemples d'options kernel utiles:

# Activer le mode texte (pas de GUI):
GRUB_CMDLINE_LINUX_DEFAULT="text"

# Désactiver le splash screen:
GRUB_CMDLINE_LINUX_DEFAULT="nosplash"

# Désactiver IPv6:
GRUB_CMDLINE_LINUX="ipv6.disable=1"

# Limiter la RAM (pour tester):
GRUB_CMDLINE_LINUX="mem=2G"


# === APPLIQUER LES CHANGEMENTS ===

# Ubuntu/Debian:
sudo update-grub

# Affiche:
# Sourcing file `/etc/default/grub'
# Generating grub configuration file ...
# Found linux image: /boot/vmlinuz-5.15.0-91-generic
# Found initrd image: /boot/initrd.img-5.15.0-91-generic
# done

# CentOS/RHEL:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

# Redémarrer pour tester:
sudo reboot


# === MODE RESCUE ===

# Si le système ne boot pas, utiliser le mode rescue

# Au démarrage:
# 1. Appuyer sur Shift (ou Esc) pendant le boot
# 2. Le menu GRUB apparaît
# 3. Sélectionner "Advanced options"
# 4. Sélectionner "(recovery mode)"

# Ou ajouter temporairement au boot:
# 1. Appuyer sur 'e' sur l'entrée GRUB
# 2. Trouver la ligne qui commence par "linux"
# 3. Ajouter à la fin: single
# ou: systemd.unit=rescue.target
# 4. Appuyer sur Ctrl+X pour booter

# Mode emergency (encore plus basique):
# Ajouter: systemd.unit=emergency.target


# === PROTÉGER GRUB PAR MOT DE PASSE ===

# Générer un mot de passe hashé:
grub-mkpasswd-pbkdf2

# Affiche:
# Enter password:
# Reenter password:
# PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.ABC123...

# Copier le hash

# Créer un fichier de config:
sudo nano /etc/grub.d/40_custom

# Ajouter:
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.ABC123...

# Explications:
# superusers="admin": Utilisateur admin
# password_pbkdf2: Hash du mot de passe

# Régénérer GRUB:
sudo update-grub

# Maintenant, modifier le boot nécessite le mot de passe!


[OK] CONFIGURATION DES QUOTAS DISQUE

# === POURQUOI DES QUOTAS? ===

# Quotas = Limites d'espace disque par utilisateur/groupe
# Empêche un utilisateur de remplir tout le disque

# === INSTALLATION ===

# Ubuntu/Debian:
sudo apt install quota

# CentOS/RHEL:
sudo yum install quota


# === ACTIVER LES QUOTAS ===

# Éditer fstab:
sudo nano /etc/fstab

# Trouver la partition (ex: /home):
UUID=abc-123  /home  ext4  defaults  0  2

# Ajouter les options de quota:
UUID=abc-123  /home  ext4  defaults,usrquota,grpquota  0  2

# Explications:
# usrquota: Quotas utilisateur
# grpquota: Quotas groupe

# Sauvegarder et remonter:
sudo mount -o remount /home

# Créer les fichiers de quotas:
sudo quotacheck -cug /home

# Explications:
# -c: Create (créer)
# -u: User quotas
# -g: Group quotas

# Affiche:
# quotacheck: Scanning /dev/sda3 [/home] done
# quotacheck: Checked 15 directories and 234 files

# Activer les quotas:
sudo quotaon /home

# Vérifier:
sudo quotaon -p /home

# Affiche:
# group quota on /home (/dev/sda3) is on
# user quota on /home (/dev/sda3) is on


# === DÉFINIR DES QUOTAS ===

# Éditer les quotas d'un utilisateur:
sudo edquota -u john

# Affiche un éditeur avec:
# Disk quotas for user john (uid 1000):
#   Filesystem  blocks  soft  hard  inodes  soft  hard
#   /dev/sda3   10240   0     0     125     0     0

# Explications:
# blocks: Espace utilisé (en Ko)
# soft: Limite souple (avertissement)
# hard: Limite dure (blocage)
# inodes: Nombre de fichiers

# Exemple de configuration:
#   Filesystem  blocks  soft    hard    inodes  soft  hard
#   /dev/sda3   10240   500000  550000  125     5000  6000

# Explications:
# soft: 500 Mo (avertissement)
# hard: 550 Mo (blocage total)
# inodes soft: 5000 fichiers (avertissement)
# inodes hard: 6000 fichiers (blocage)

# Copier les quotas d'un utilisateur à un autre:
sudo edquota -p john -u alice

# Définir un quota de groupe:
sudo edquota -g developers

# Définir une période de grâce:
sudo edquota -t

# Affiche:
# Grace period before enforcing soft limits for users:
# Time units may be: days, hours, minutes, or seconds
#   Filesystem  Block grace period  Inode grace period
#   /dev/sda3   7days               7days

# Explications:
# Grace period: Temps après dépassement soft avant blocage


# === VOIR LES QUOTAS ===

# Voir les quotas d'un utilisateur:
sudo quota -u john

# Affiche:
# Disk quotas for user john (uid 1000):
#      Filesystem  blocks  quota  limit  grace  files  quota  limit  grace
#      /dev/sda3   450000  500000 550000         4500   5000   6000

# Voir les quotas de tous les utilisateurs:
sudo repquota /home

# Affiche:
# *** Report for user quotas on device /dev/sda3
# Block grace time: 7days; Inode grace time: 7days
#                         Block limits                File limits
# User            used    soft    hard  grace    used  soft  hard  grace
# ----------------------------------------------------------------------
# root      --  102400       0       0          1234     0     0
# john      --  450000  500000  550000          4500  5000  6000
# alice     --  120000  500000  550000           850  5000  6000

# Voir son propre quota (en tant qu'utilisateur):
quota

# Désactiver les quotas:
sudo quotaoff /home


[OK] CONFIGURATION DU PROXY & ACCÈS INTERNET

# === POURQUOI UN PROXY? ===

# Proxy = Intermédiaire entre toi et Internet
# Utilisé pour:
# - Entreprises (filtrage, contrôle)
# - Sécurité (anonymat)
# - Cache (accélérer)

# === VARIABLES D'ENVIRONNEMENT ===

# Définir pour la session actuelle:
export http_proxy="http://proxy.example.com:8080"
export https_proxy="http://proxy.example.com:8080"
export ftp_proxy="http://proxy.example.com:8080"
export no_proxy="localhost,127.0.0.1,.local"

# Explications:
# http_proxy: Proxy pour HTTP
# https_proxy: Proxy pour HTTPS
# no_proxy: Ne pas utiliser le proxy pour ces adresses

# Avec authentification:
export http_proxy="http://username:password@proxy.example.com:8080"
export https_proxy="http://username:password@proxy.example.com:8080"

# Définir de manière permanente:
nano ~/.bashrc

# Ajouter à la fin:
export http_proxy="http://proxy.example.com:8080"
export https_proxy="http://proxy.example.com:8080"
export no_proxy="localhost,127.0.0.1"

# Sauvegarder et recharger:
source ~/.bashrc

# Pour tous les utilisateurs:
sudo nano /etc/environment

# Ajouter:
http_proxy="http://proxy.example.com:8080"
https_proxy="http://proxy.example.com:8080"
no_proxy="localhost,127.0.0.1"


# === PROXY APT (UBUNTU/DEBIAN) ===

# Créer le fichier de config:
sudo nano /etc/apt/apt.conf.d/95proxies

# Contenu:
Acquire::http::proxy "http://proxy.example.com:8080/";
Acquire::https::proxy "http://proxy.example.com:8080/";

# Avec authentification:
Acquire::http::proxy "http://username:password@proxy.example.com:8080/";
Acquire::https::proxy "http://username:password@proxy.example.com:8080/";

# Tester:
sudo apt update


# === PROXY YUM/DNF (CENTOS/RHEL) ===

# Éditer la config:
sudo nano /etc/yum.conf

# Ajouter:
proxy=http://proxy.example.com:8080
proxy_username=username
proxy_password=password

# Tester:
sudo yum update


# === PROXY GIT ===

# Configuration globale:
git config --global http.proxy http://proxy.example.com:8080
git config --global https.proxy http://proxy.example.com:8080

# Avec authentification:
git config --global http.proxy http://username:password@proxy.example.com:8080

# Voir la config:
git config --global --list

# Supprimer le proxy:
git config --global --unset http.proxy
git config --global --unset https.proxy


# === PROXY DOCKER ===

# Créer le fichier de config:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

# Contenu:
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080"
Environment="HTTPS_PROXY=http://proxy.example.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1"

# Recharger et redémarrer:
sudo systemctl daemon-reload
sudo systemctl restart docker

# Vérifier:
sudo systemctl show --property=Environment docker


[OK] CONFIGURATION DNS LOCAL

# === QU'EST-CE QU'UN DNS? ===

# DNS = Domain Name System
# Traduit les noms de domaine en adresses IP
# Exemple: google.com -> 142.250.185.78

# DNS local = Serveur DNS sur ton réseau
# Utilisé pour:
# - Résolution rapide (cache)
# - Noms personnalisés (server1.local, server2.local)
# - Bloquer des domaines (publicité, malware)

# === DNSMASQ (SIMPLE) ===

# DNSmasq = Serveur DNS/DHCP léger

# Installation (besoin d'internet avant de choisir le réseau interne qui était par pont):
sudo apt install dnsmasq    

# Vérifier le nom du server
sudo nano etc/hostname

# Configuration:
sudo nano /etc/dnsmasq.conf

# Contenu important:

# Interface d'écoute:
interface=eth0

# Ne pas écouter sur localhost:
bind-interfaces

# Serveurs DNS en amont:
server=8.8.8.8
server=8.8.4.4

# Domaine local:
domain=local
expand-hosts

# Fichier hosts local:
addn-hosts=/etc/hosts.dnsmasq

# Cache:
cache-size=1000

# Logs:
log-queries
log-facility=/var/log/dnsmasq.log

# Créer le fichier hosts:
sudo nano /etc/hosts.dnsmasq

# Contenu:
192.168.1.100  server1.local  server1
192.168.1.101  server2.local  server2
192.168.1.102  web.local      web

# Redémarrer:
sudo systemctl restart dnsmasq

# Tester:
dig server1.local @localhost

# Affiche:
# ; <<>> DiG 9.18.12 <<>> server1.local @localhost
# ...
# server1.local.          0       IN      A       192.168.1.100


# === BIND9 (AVANCÉ) ===

# === Ancien Méthode de configuration avec BIND9

# BIND9 = Serveur DNS professionnel

# Installation  (besoin d'internet avant de choisir le réseau interne qui était par pont):
sudo apt install bind9 bind9utils bind9-doc

Sortie:
  Reading package lists... Done
  Building dependency tree... Done
  Reading state information... Done
  The following additional packages will be installed:
    bind9-host dnsutils libdns-export1110 libirs-export91 libisc-export1105
    libisccc-export1100 libisccfg-export1102 liblmdb0
  Suggested packages:
    resolvconf
  The following NEW packages will be installed:
  ...


# Vérifier le nom du server
sudo nano etc/hostname

#sortie: 
  server1

# Vérification de l'ip du serveur 
ifconfig

#sortie:
  eth0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 08:00:27:3b:5c:a1  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 24  bytes 1920 (1.8 KiB)
        TX packets 24  bytes 1920 (1.8 KiB)

Pourquoi “l’IP est sautée” ?

Dans cet exemple :

-> L’interface eth0 est UP (active), mais :

elle n’a reçu aucune adresse IP
il n’y a pas de ligne inet ...

donc elle n’est pas configurée, typiquement :

DHCP ne répond pas
l’interface n’est pas configurée dans /etc/network/interfaces ou NetworkManager
câble débranché
WiFi non connecté
-> L’interface lo (loopback) garde son IP 127.0.0.1 (normal).

# Fixer l'adresse IP temporairement pour test rapide
ifconfig eth0 192.168.1.100

# Vérification du fixage
ifconfig

Sortie:
  eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::a00:27ff:fe3b:5ca1  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:3b:5c:a1  txqueuelen 1000  (Ethernet)
        RX packets 15432  bytes 12.5 MiB
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12810  bytes 10.2 MiB
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 32  bytes 2560 (2.5 KiB)
        TX packets 32  bytes 2560 (2.5 KiB)


# Configuration du fichier de résolution du nom de domaine:
sudo nano /etc/resolv.conf

# Contenu par défaut:
nameserver 127.0.0.53
options edns0 trust-ad

# Modification du contenu
nameserver 192.168.1.100
search momo.sn
options edns0 trust-ad

# Voir le contenu de bind9
ls etc/bind

Sortie:
  bind.keys
  db.0
  db.127
  db.255
  db.empty
  db.local
  db.root
  named.conf
  named.conf.default-zones
  named.conf.local
  named.conf.options
  rndc.key
  zones.rfc1918

| ------------------------------ | ---------------------------------------------------- |
| Fichier                        | Rôle                                                 |
| ------------------------------ | ---------------------------------------------------- |
| **named.conf**                 | Fichier principal qui inclut les autres.             |
| **named.conf.options**         | Options globales (forwarders, recursion, listen...). |
| **named.conf.local**           | Là où tu mets tes zones personnalisées.              |
| **named.conf.default-zones**   | Zones par défaut (localhost, reverse locales).       |
| **zones.rfc1918**              | Configuration des zones inverses privées.            |
| **db.local**, **db.127**, etc. | Fichiers de zones DNS préconfigurés.                 |
| **rndc.key**                   | Clé de contrôle sécurisée pour `rndc`.               |
| **bind.keys**                  | Clés DNSSEC racine.                                  |
| ------------------------------ | ---------------------------------------------------- |


# Créer une zone:
sudo nano /etc/bind/named.conf.local

Sortie:
  //
  // Do any local configuration here
  //
  
  // Consider adding the 1918 zones here, if they are not used in your
  // organization
  //include "/etc/bind/zones.rfc1918";


# Contenu à ajouter:
zone "momo.sn" {
    type master;
    file "/etc/bind/db.momo.sn";
};

zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/db.192.168.1";
};


# Copier le fichier db.local dans direct
cp /etc/bind/db.local /etc/bind/db.momo.sn

# Ouvrir le fichier direct
nano /etc/bind/db.momo.sn

Sortie:
  ;
  ; BIND data file for local loopback interface
  ;
  $TTL    604800
  @       IN      SOA     localhost. root.localhost. (
                                2         ; Serial
                          604800         ; Refresh
                            86400         ; Retry
                          2419200         ; Expire
                          604800 )       ; Negative Cache TTL
  ;
  @       IN      NS      localhost.
  @       IN      A       127.0.0.1
  @       IN      AAAA    ::1


# Contenu pour créer la zone:
$TTL    604800
@       IN      SOA     server1.momo.sn. root.server1.momo.sn. (
                              2024011501         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@           IN      NS      server1.momo.sn.
server1     IN      A       192.168.1.100
www         IN      CNAME   server1.momo.sn.


# Copier le fichier direct dans inverse
cp etc/bind/db.momo.sn etc/bind/db.192.168.1

# Créer la zone inverse:
sudo nano /etc/bind/db.192.168.1

# Contenu à ajouter:
$TTL    604800
@       IN      SOA     server1.momo.sn. admin.momo.sn. (
                              2024011501         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@         IN      NS      server1.momo.sn.
100       IN      PTR     server1.momo.sn.


# Vérifier la config:
sudo named-checkconf
sudo named-checkzone momo.sn /etc/bind/db.momo.sn
sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192.168.1

nslockup www

# Redémarrer:
sudo systemctl restart bind9

# Tester:
dig www.momo.sn @192.168.1.100

# Reverse DNS:
dig -x 192.168.1.100 @192.168.1.100



# === Méthode Moderne de configuration avec BIND9

# BIND9 = Serveur DNS professionnel

# Installation  (besoin d'internet avant de choisir le réseau interne qui était par pont):
sudo apt install bind9 bind9utils bind9-doc

# Vérifier le nom du server
sudo nano etc/hostname

# Configuration principale:
sudo nano /etc/bind/named.conf.options

# Contenu:
options {
    directory "/var/cache/bind";

    forwarders {
        8.8.8.8;
        8.8.4.4;
    };

    dnssec-validation auto;
    listen-on { any; };
    allow-query { any; };
};

# Créer une zone:
sudo nano /etc/bind/named.conf.local

# Contenu:
zone "local" {
    type master;
    file "/etc/bind/db.local";
};

zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/db.192.168.1";
};

# Créer le fichier de zone:
sudo nano /etc/bind/db.local

# Contenu:
$TTL    604800
@       IN      SOA     ns1.local. admin.local. (
                              2024011501         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      ns1.local.
ns1     IN      A       192.168.1.100
server1 IN      A       192.168.1.100
server2 IN      A       192.168.1.101
web     IN      A       192.168.1.102

# Créer la zone reverse:
sudo nano /etc/bind/db.192.168.1

# Contenu:
$TTL    604800
@       IN      SOA     ns1.local. admin.local. (
                              2024011501         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      ns1.local.
100     IN      PTR     server1.local.
101     IN      PTR     server2.local.
102     IN      PTR     web.local.

# Vérifier la config:
sudo named-checkconf
sudo named-checkzone local /etc/bind/db.local
sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192.168.1

# Redémarrer:
sudo systemctl restart bind9

# Tester:
dig server1.local @192.168.1.100

# Reverse DNS:
dig -x 192.168.1.100 @192.168.1.100


Parfait, analysons **la différence entre les deux configurations BIND9** que tu as présentées :

1⃣ **Ancienne méthode**
2⃣ **Méthode moderne**

Je vais te détailler **les différences majeures**, **les avantages et inconvénients**.

---

# 1⃣ **Ancienne méthode**

### Caractéristiques

* Zones définies directement avec un domaine réel ou interne (`momo.sn`)
* Fichiers forward/reverse créés à partir de `db.local` (copie + modification)
* `/etc/bind/named.conf.options` par défaut (non modifié ou très peu)
* Résolution DNS dépend principalement des zones internes créées
* Les forwarders (Google DNS) non obligatoires, souvent manquants
* SOA et NS modifiés manuellement dans chaque fichier copié

### Avantages

* Simple à mettre en place pour un réseau interne
* Convient pour tests et petits labos

### Inconvénients

* Plus de risque d’erreurs en copiant `db.local`
* Forwarders absents -> pas de résolution vers Internet par défaut
* Moins “standard” pour une utilisation professionnelle
* Pas de séparation claire entre options globales et zones
* Fichiers de zones moins modulaires

---

# 2⃣ **Méthode moderne**

### Caractéristiques

* Utilisation correcte de `/etc/bind/named.conf.options` pour options globales
* Forwarders définis (`8.8.8.8`, `8.8.4.4`) -> résolution DNS publique automatique
* Zones forward/reverse séparées (`db.local`, `db.192.168.1`)
* SOA et NS cohérents et structurés
* Permet d’écouter sur toutes les interfaces (`listen-on { any; };`)
* `allow-query { any; };` -> définit qui peut interroger le DNS
* Ne copie plus aveuglément `db.local`, mais crée une zone propre

### Avantages

* Conforme aux bonnes pratiques BIND9
* Forwarders -> Internet résolu automatiquement
* Plus sécurisé et modulable pour réseau interne ou mixte
* Plus facile à maintenir et à faire évoluer
* Compatible pour usage professionnel ou lab réseau complexe

### Inconvénients

* Plus de fichiers à gérer (séparation `named.conf.options` et zones)
* Nécessite de comprendre le rôle de chaque fichier (options globales vs zones)
* Un peu plus de configuration initiale

---

# 3⃣ **Résumé comparatif**

| Critère           | Ancienne méthode           | Méthode moderne                                                |
| ----------------- | -------------------------- | -------------------------------------------------------------- |
| Fichiers utilisés | Copie `db.local` -> modifié | Fichiers forward/reverse séparés                               |
| Options globales  | Par défaut / minimale      | `named.conf.options` bien défini (forwarders, écoute, queries) |
| Forwarders        | Souvent absents            | Définis (Google DNS)                                           |
| Bonne pratique    | Non                        | Oui                                                            |
| Sécurité          | Limitée                    | Améliorée (ACL possibles)                                      |
| Maintenabilité    | Faible                     | Élevée                                                         |
| Usage recommandé  | Test / labo                | Réseau interne ou semi-pro / pro                               |

---

# 4⃣ **En résumé**

* **Ancienne méthode** : facile pour un labo, mais fragile, peu professionnelle.
* **Méthode moderne** : standard, modulable, forwarders inclus, prête pour un vrai réseau.

[IDEE] **Règle générale :**
Toujours séparer **options globales** et **zones**, et éviter de copier `db.local` tel quel pour créer des zones.

                      ┌─────────────────────────────┐
                      │       Serveur Linux         │
                      │        BIND9 DNS            │
                      └─────────────────────────────┘
                                    │
                        écoute sur eth0:192.168.1.x
                                    │
                                    [BLACK_DOWN-POINTING_TRIANGLE]

 ┌─────────────────────────────┐           ┌─────────────────────────────┐
 │      ANCIENNE MÉTHODE       │           │      MÉTHODE MODERNE        │
 └─────────────────────────────┘           └─────────────────────────────┘
          │                                         │
          │                                         │
          [BLACK_DOWN-POINTING_TRIANGLE]                                         [BLACK_DOWN-POINTING_TRIANGLE]

1. Fichiers de zones                          1. Fichiers de zones
   - Copie de db.local                        - Fichier forward : db.momo.sn
   - db.local -> direct -> inverse              - Fichier reverse : db.192.168.1
   - SOA/NS souvent modifiés à la main       - SOA et NS cohérents
   - A/AAAA modifiés à la main                - Enregistrements A et PTR corrects

2. Options globales                           2. Options globales
   - Peu ou pas définies                        - named.conf.options
   - Forwarders absents                         - Forwarders 8.8.8.8 / 8.8.4.4
   - Écoute par défaut                          - listen-on { any; }
   - allow-query implicite                       - allow-query { any; }

3. Résolution                                 3. Résolution
   - Seulement zones internes                   - Zones internes + forwarders
   - Pas de fallback DNS                        - Permet résolution Internet
   - Fragile, erreurs possibles                 - Stable et standard

4. Maintenabilité                             4. Maintenabilité
   - Fichiers mêlés, copies                     - Fichiers séparés, modulaires
   - Difficulté d’évolution                     - Facile à maintenir et étendre

---


# [DOCS] GUIDE COMPLET : CONFIGURATION DNS POUR GRANDS DÉBUTANTS

## [OBJECTIF] QU'EST-CE QU'UN DNS ? (Comprendre les bases)

### [ACCUEIL] Analogie de l'annuaire téléphonique

Imagine le DNS comme **l'annuaire téléphonique d'Internet** :
- Tu veux appeler ton ami "Jean Dupont" (nom de domaine : google.com)
- Mais ton téléphone a besoin du numéro (adresse IP : 142.250.185.78)
- L'annuaire fait la traduction pour toi

**Sans DNS :** Tu devrais mémoriser `142.250.185.78` au lieu de taper `google.com`  
**Avec DNS :** Tu tapes simplement `google.com` et le DNS trouve l'adresse IP pour toi

### [SYNC] Comment ça fonctionne ?

```
Toi -> "Je veux aller sur google.com" 
       v
DNS -> "Ok, l'adresse c'est 142.250.185.78"
       v
Ton navigateur -> Se connecte à 142.250.185.78
```

### [ENTREPRISE] DNS Local vs DNS Public

**DNS Public (Google, Cloudflare)** = L'annuaire de toute la ville
- Connaît tous les sites Internet
- Mais ne connaît pas tes serveurs personnels

**DNS Local (sur ton réseau)** = Ton carnet d'adresses personnel
- Connaît tes serveurs : `server1.local`, `nas.local`
- Plus rapide (pas besoin d'aller sur Internet)
- Tu contrôles tout

---

## [RAPIDE] MÉTHODE 1 : DNSMASQ (Pour débutants)

### [PACKAGE] Pourquoi DNSmasq ?

**Analogie :** DNSmasq c'est comme un **assistant personnel intelligent**
- Simple à configurer (parfait pour débuter)
- Léger en ressources
- Fait DNS + DHCP (distribution d'adresses IP)

### [ENTREE] ÉTAPE 1 : Installation

```bash
sudo apt install dnsmasq
```

**Qu'est-ce que cette commande fait ?**
- `sudo` = Exécute en tant qu'administrateur (comme "Exécuter en tant qu'admin" sous Windows)
- `apt` = Le gestionnaire de paquets (comme un App Store pour Linux)
- `install` = Télécharge et installe
- `dnsmasq` = Le logiciel serveur DNS

---

### [CONFIG] ÉTAPE 2 : Configuration principale

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

**Explication :**
- `nano` = Éditeur de texte simple (comme Notepad)
- `/etc/dnsmasq.conf` = Fichier de configuration principal

#### [FICHIER] Contenu du fichier expliqué ligne par ligne :

# /etc/dnsmasq.conf

# This is the main configuration file for dnsmasq.
# The only active line is a comment by default.

# Listen on this specific interface only:
# interface=

# Specify IP addresses for upstream DNS servers:
# server=

# Domain for local hosts:
# domain=

# Add additional hosts:
# addn-hosts=


```bash
# 1⃣ INTERFACE D'ÉCOUTE
interface=eth0
```
**Ce que ça fait :** Dit à DNSmasq d'écouter sur la carte réseau `eth0`  
**Analogie :** C'est comme dire "Prends les appels uniquement sur ton téléphone fixe, pas sur ton portable"  
**Pour trouver ton interface :** Tape `ip a` et cherche ton interface réseau principale

```bash
# 2⃣ NE PAS ÉCOUTER SUR LOCALHOST
bind-interfaces
```
**Ce que ça fait :** Empêche DNSmasq d'écouter sur toutes les interfaces  
**Pourquoi c'est important :** Évite les conflits avec d'autres services DNS  
**Analogie :** "Je réponds uniquement aux appels sur mon réseau local, pas à toutes les lignes"

```bash
# 3⃣ SERVEURS DNS EN AMONT (Upstream DNS)
server=8.8.8.8
server=8.8.4.4
```
**Ce que ça fait :** Quand DNSmasq ne connaît pas un domaine, il demande à Google DNS  
**Analogie :** Si quelqu'un te demande un numéro que tu n'as pas, tu regardes dans l'annuaire officiel  
**Alternatives :**
- `1.1.1.1` (Cloudflare - rapide et privé)
- `9.9.9.9` (Quad9 - sécurisé)

```bash
# 4⃣ DOMAINE LOCAL
domain=local
expand-hosts
```
**Ce que ça fait :**
- `domain=local` : Ajoute automatiquement `.local` à tes noms de serveurs
- `expand-hosts` : Active cette fonctionnalité

**Exemple pratique :**
- Tu tapes : `ssh server1`
- DNSmasq comprend : `ssh server1.local`
- **Analogie :** Comme l'autocomplétion sur ton téléphone

```bash
# 5⃣ FICHIER HOSTS PERSONNALISÉ
addn-hosts=/etc/hosts.dnsmasq
```
**Ce que ça fait :** Dit à DNSmasq de lire tes associations IP <-> nom depuis ce fichier  
**Pourquoi un fichier séparé ?** Pour ne pas mélanger avec `/etc/hosts` du système  
**Analogie :** Ton carnet d'adresses perso (séparé de celui du téléphone)

```bash
# 6⃣ CACHE DNS
cache-size=1000
```
**Ce que ça fait :** Mémorise 1000 réponses DNS récentes  
**Avantage :** Réponse instantanée pour les sites que tu visites souvent  
**Analogie :** Comme garder les numéros fréquents en mémoire rapide  
**Valeurs recommandées :**
- Petit réseau (1-5 PC) : `500`
- Moyen (5-20 PC) : `1000`
- Grand (20+ PC) : `2000`

```bash
# 7⃣ LOGS (Journaux)
log-queries
log-facility=/var/log/dnsmasq.log
```
**Ce que ça fait :**
- `log-queries` : Enregistre toutes les requêtes DNS
- `log-facility` : Où stocker les logs

**Utilité :** Voir qui demande quoi, détecter des problèmes  
**Voir les logs :** `sudo tail -f /var/log/dnsmasq.log`  
**[ATTENTION] Attention :** Génère beaucoup de données, désactive en production

---

### [LISTE] ÉTAPE 3 : Créer le fichier hosts personnalisé

```bash
sudo nano /etc/hosts.dnsmasq
```

#### Contenu expliqué :

```bash
192.168.1.100  server1.local  server1
```

**Structure :** `ADRESSE_IP  NOM_COMPLET  ALIAS`

**Décomposition :**
1. `192.168.1.100` = L'adresse IP du serveur
2. `server1.local` = Nom de domaine complet (FQDN)
3. `server1` = Raccourci (alias optionnel)

**Exemple d'utilisation :**
```bash
ping server1          # [OK] Fonctionne
ping server1.local    # [OK] Fonctionne aussi
ssh user@server1      # [OK] Se connecte à 192.168.1.100
```

**Analogie :** 
- `192.168.1.100` = Numéro de téléphone complet (+33 6 12 34 56 78)
- `server1.local` = Nom complet (Jean Dupont Entreprise)
- `server1` = Surnom (Jean)

---

### [SYNC] ÉTAPE 4 : Redémarrer le service

```bash
sudo systemctl restart dnsmasq
```

**Qu'est-ce que `systemctl` ?**
- C'est le gestionnaire de services Linux
- Permet de démarrer/arrêter/redémarrer des programmes

**Commandes utiles :**
```bash
sudo systemctl status dnsmasq    # Voir si ça tourne
sudo systemctl stop dnsmasq      # Arrêter
sudo systemctl start dnsmasq     # Démarrer
sudo systemctl enable dnsmasq    # Démarrer automatiquement au boot
```

---

### [TEST] ÉTAPE 5 : Tester la configuration

```bash
dig server1.local @localhost
```

**Décomposition de la commande :**
- `dig` = Outil de diagnostic DNS (comme un testeur)
- `server1.local` = Le nom à résoudre
- `@localhost` = Demande au DNS local (pas à Google)

**Résultat attendu :**
```
;; ANSWER SECTION:
server1.local.    0    IN    A    192.168.1.100
```

**Traduction :** "server1.local correspond à 192.168.1.100"

**Tests supplémentaires :**
```bash
# Test simple avec ping
ping server1.local

# Test avec nslookup
nslookup server1.local localhost

# Vérifier les logs en temps réel
sudo tail -f /var/log/dnsmasq.log
```

---

## [ENTREPRISE] MÉTHODE 2 : BIND9 (Pour utilisateurs avancés)

### [COURS] Pourquoi BIND9 ?

**Analogie :** Si DNSmasq est une **épicerie de quartier**, BIND9 est un **hypermarché**

**Avantages :**
- [OK] Utilisé par 70% des serveurs DNS mondiaux
- [OK] Gère des millions de domaines
- [OK] Fonctionnalités avancées (DNSSEC, zones secondaires, etc.)

**Inconvénients :**
- [X] Plus complexe à configurer
- [X] Consomme plus de ressources
- [X] Fichiers de configuration plus nombreux

---

### [ENTREE] ÉTAPE 1 : Installation

```bash
sudo apt install bind9 bind9utils bind9-doc
```

**Explication des paquets :**
- `bind9` = Le serveur DNS principal
- `bind9utils` = Outils de diagnostic (`dig`, `nslookup`, etc.)
- `bind9-doc` = Documentation complète

---

### [CONFIG] ÉTAPE 2 : Configuration principale

```bash
sudo nano /etc/bind/named.conf.options
```

**Rôle de ce fichier :** Configure les **options globales** de BIND9

#### [FICHIER] Contenu expliqué :

```bash
options {
    # 1⃣ RÉPERTOIRE DE TRAVAIL
    directory "/var/cache/bind";
```
**Ce que ça fait :** Définit où BIND9 stocke ses fichiers temporaires  
**Analogie :** L'espace de travail/bureau où poser ses documents  
**Ne pas modifier** sauf besoin spécifique

```bash
    # 2⃣ SERVEURS FORWARDERS
    forwarders {
        8.8.8.8;
        8.8.4.4;
    };
```
**Ce que ça fait :** Si BIND9 ne connaît pas un domaine, il demande à ces serveurs  
**Analogie :** Tes sources de référence quand tu ne sais pas  
**[ATTENTION] Important :** Terminer chaque ligne par `;`

```bash
    # 3⃣ VALIDATION DNSSEC
    dnssec-validation auto;
```
**Ce que ça fait :** Active la vérification de sécurité des réponses DNS  
**Analogie :** Vérifier la signature sur un document officiel  
**Laisser sur `auto`** (recommandé pour la sécurité)

```bash
    # 4⃣ INTERFACE D'ÉCOUTE
    listen-on { any; };
```
**Ce que ça fait :** Écoute sur toutes les interfaces réseau  
**Alternatives :**
- `listen-on { 192.168.1.100; };` = Écoute uniquement sur cette IP
- `listen-on { localhost; };` = Écoute uniquement localement

```bash
    # 5⃣ QUI PEUT INTERROGER LE SERVEUR
    allow-query { any; };
};
```
**Ce que ça fait :** Autorise tout le monde à faire des requêtes  
**[ATTENTION] Sécurité :** En production, restreindre :
```bash
allow-query { 192.168.1.0/24; localhost; };
```
**Traduction :** Seuls les PC de ton réseau local peuvent interroger

---

### [DOSSIER] ÉTAPE 3 : Créer les zones DNS

```bash
sudo nano /etc/bind/named.conf.local
```

**Rôle de ce fichier :** Déclare tes **zones DNS personnalisées**

#### [FICHIER] Contenu expliqué :

```bash
# 1⃣ ZONE DIRECTE (Nom -> IP)
zone "local" {
    type master;
    file "/etc/bind/db.local";
};
```

**Décomposition :**
- `zone "local"` = Nom de ta zone (tous les `*.local`)
- `type master` = C'est le serveur principal (pas une copie)
- `file` = Où sont stockées les données de cette zone

**Analogie :** Tu déclares que tu es responsable de l'annuaire pour tous les noms se terminant par `.local`

```bash
# 2⃣ ZONE REVERSE (IP -> Nom)
zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/db.192.168.1";
};
```

**Ce que ça fait :** Permet de retrouver le nom depuis l'IP (reverse DNS)

**Pourquoi cette syntaxe bizarre ?**
- `192.168.1.X` devient `1.168.192.in-addr.arpa`
- L'ordre est inversé (c'est la norme DNS)

**Utilité :** Certaines applications vérifient le reverse DNS (emails, SSH)

---

### [NOTE] ÉTAPE 4 : Créer le fichier de zone directe

```bash
sudo nano /etc/bind/db.local
```

#### [FICHIER] Contenu expliqué ligne par ligne :

```bash
$TTL    604800
```
**TTL = Time To Live** (Temps de vie)  
**Ce que ça fait :** Durée pendant laquelle la réponse peut être mise en cache  
**604800 secondes = 7 jours**  
**Analogie :** "Cette info est valable 7 jours, après demande à nouveau"

**Valeurs courantes :**
- `300` (5 min) = Pour zones qui changent souvent
- `3600` (1h) = Standard
- `86400` (1 jour) = Pour zones stables

```bash
@       IN      SOA     ns1.local. admin.local. (
```

**SOA = Start of Authority** (Début d'autorité)  
**Ce que ça fait :** Définit le serveur responsable de cette zone

**Décomposition :**
- `@` = Représente la zone elle-même (`local`)
- `IN` = Internet (classe de réseau)
- `SOA` = Type d'enregistrement
- `ns1.local.` = Nom du serveur DNS ([ATTENTION] le `.` final est **obligatoire**)
- `admin.local.` = Email de l'admin (le `@` devient un `.`)

```bash
                              2024011501         ; Serial
```
**Serial = Numéro de série**  
**Format recommandé :** `AAAAMMJJNN` (Année Mois Jour + compteur)  
**Utilité :** Indique quand la zone a été modifiée  
**[ATTENTION] IMPORTANT :** Incrémenter à chaque modification sinon les serveurs secondaires ne se mettent pas à jour

**Exemple :**
- 1ère modification du 15/01/2024 : `2024011501`
- 2ème modification du même jour : `2024011502`

```bash
                         604800         ; Refresh
```
**Refresh = Rafraîchissement**  
**Ce que ça fait :** Fréquence de vérification pour les serveurs secondaires  
**604800 = 7 jours**  
**Analogie :** "Vérifie s'il y a du nouveau toutes les semaines"

```bash
                          86400         ; Retry
```
**Retry = Nouvelle tentative**  
**Ce que ça fait :** Si le refresh échoue, réessayer après ce délai  
**86400 = 1 jour**

```bash
                        2419200         ; Expire
```
**Expire = Expiration**  
**Ce que ça fait :** Si aucune mise à jour après ce délai, considérer la zone invalide  
**2419200 = 28 jours**  
**Analogie :** "Si je n'ai pas de nouvelles en 28 jours, considère que l'info n'est plus bonne"

```bash
                         604800 )       ; Negative Cache TTL
```
**Negative Cache = Cache des réponses négatives**  
**Ce que ça fait :** Durée de mémorisation des "ce domaine n'existe pas"  
**Utilité :** Évite de redemander 100 fois pour un nom qui n'existe pas

```bash
;
@       IN      NS      ns1.local.
```
**NS = Name Server** (Serveur de noms)  
**Ce que ça fait :** Déclare quel serveur est responsable de la zone  
**Analogie :** "Pour tout ce qui concerne `.local`, demande à `ns1.local`"

```bash
ns1     IN      A       192.168.1.100
```
**A = Address** (Adresse IPv4)  
**Ce que ça fait :** Associe un nom à une adresse IP  
**Structure :** `NOM    TYPE    IP`

```bash
server1 IN      A       192.168.1.100
server2 IN      A       192.168.1.101
web     IN      A       192.168.1.102
```
**Ce sont tes enregistrements personnalisés**

**Résultat :**
- `server1.local` -> `192.168.1.100`
- `server2.local` -> `192.168.1.101`
- `web.local` -> `192.168.1.102`

---

### [SYNC] ÉTAPE 5 : Créer la zone reverse

```bash
sudo nano /etc/bind/db.192.168.1
```

#### [FICHIER] Contenu expliqué :

```bash
$TTL    604800
@       IN      SOA     ns1.local. admin.local. (
                              2024011501
                         604800
                          86400
                        2419200
                         604800 )
;
@       IN      NS      ns1.local.
```
**Même structure que la zone directe**

```bash
100     IN      PTR     server1.local.
101     IN      PTR     server2.local.
102     IN      PTR     web.local.
```

**PTR = Pointer** (Pointeur)  
**Ce que ça fait :** Associe une IP à un nom (inverse de A)

**Structure :** `DERNIER_OCTET    PTR    NOM_COMPLET`

**Exemple :**
- `100` = Dernier octet de `192.168.1.100`
- `PTR` = Type d'enregistrement
- `server1.local.` = Nom complet ([ATTENTION] le `.` final est obligatoire)

**Résultat :**
- `192.168.1.100` -> `server1.local`
- `192.168.1.101` -> `server2.local`

---

### [OK] ÉTAPE 6 : Vérifier la configuration

```bash
# 1⃣ Vérifier la syntaxe globale
sudo named-checkconf
```
**Si pas d'erreur :** Aucun message = tout est bon [OK]  
**Si erreur :** Le fichier et la ligne sont indiqués

```bash
# 2⃣ Vérifier la zone directe
sudo named-checkzone local /etc/bind/db.local
```
**Résultat attendu :**
```
zone local/IN: loaded serial 2024011501
OK
```

```bash
# 3⃣ Vérifier la zone reverse
sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192.168.1
```

**Résultat attendu :**
```
zone 1.168.192.in-addr.arpa/IN: loaded serial 2024011501
OK
```

---

### [SYNC] ÉTAPE 7 : Redémarrer BIND9

```bash
sudo systemctl restart bind9
```

**Vérifier le statut :**
```bash
sudo systemctl status bind9
```

**Si erreur, voir les logs :**
```bash
sudo journalctl -u bind9 -f
```

---

### [TEST] ÉTAPE 8 : Tests complets

```bash
# 1⃣ Test résolution directe
dig server1.local @192.168.1.100
```
**Résultat attendu :**
```
;; ANSWER SECTION:
server1.local.    604800    IN    A    192.168.1.100
```

```bash
# 2⃣ Test résolution reverse
dig -x 192.168.1.100 @192.168.1.100
```
**Résultat attendu :**
```
;; ANSWER SECTION:
100.1.168.192.in-addr.arpa. 604800 IN PTR server1.local.
```

```bash
# 3⃣ Test avec ping
ping server1.local
```

---

## 🆚 DNSMASQ vs BIND9 : Que choisir ?

|------------------------|-----------------------|----------------------------|
| Critère                | DNSmasq               | BIND9                      |
|------------------------|-----------------------|----------------------------|
| **Difficulté**         | * Facile             | **** Difficile        |
| **Vitesse de config**  | 10 minutes            | 1-2 heures                 |
| **Ressources**         | Très léger            | Moyen                      |
| **Fonctionnalités**    | Basiques              | Avancées                   |
| **Meilleur pour**      | Maison, petit bureau  | Entreprise, production     |
|------------------------|-----------------------|----------------------------|

**Recommandation :**
- [ACCUEIL] **Débuter ou réseau domestique** -> DNSmasq
- [ENTREPRISE] **Apprendre le DNS professionnel** -> BIND9
- [COURS] **Passer une certification** -> BIND9

---

## [COURS] RÉSUMÉ POUR RETENIR

### [MODULE] Les concepts clés

1. **DNS = Traducteur** (nom -> IP)
2. **Zone directe** = Annuaire (nom -> IP)
3. **Zone reverse** = Annuaire inversé (IP -> nom)
4. **Cache** = Mémoire des réponses récentes
5. **Forwarders** = À qui demander si on ne sait pas

### [OUTILS] Ordre de configuration

**DNSmasq :**
1. Installer -> 2. Configurer `/etc/dnsmasq.conf` -> 3. Créer `/etc/hosts.dnsmasq` -> 4. Redémarrer -> 5. Tester

**BIND9 :**
1. Installer -> 2. Configurer options -> 3. Déclarer zones -> 4. Créer fichiers de zones -> 5. Vérifier -> 6. Redémarrer -> 7. Tester

---

## 🆘 DÉPANNAGE RAPIDE

### [X] "dig: command not found"
```bash
sudo apt install dnsutils
```

### [X] DNSmasq ne démarre pas
```bash
# Vérifier les erreurs
sudo systemctl status dnsmasq
# Voir les logs
sudo journalctl -u dnsmasq -n 50
```

### [X] BIND9 ne résout pas les noms
```bash
# Vérifier le port 53
sudo netstat -tulpn | grep :53
# Voir les logs
sudo tail -f /var/log/syslog | grep named
```

# [RECHERCHE] COMMENT TROUVER OU FIXER L'ADRESSE IP DU SERVEUR

## [IMPORTANT] PARTIE 1 : TROUVER L'ADRESSE IP ACTUELLE

### Méthode 1 : Avec `ip` (Recommandé - Moderne)

```bash
ip addr show
```

**ou version courte :**
```bash
ip a
```

**Résultat typique :**
```
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
    inet 127.0.0.1/8 scope host lo
       ^ Adresse localhost (ignorer)

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
    inet 192.168.1.50/24 brd 192.168.1.255 scope global eth0
         ^^^^^^^^^^^^
         TON ADRESSE IP ACTUELLE
```

**Comment lire :**
- `lo` = Interface loopback (ignorer)
- `eth0` = Carte réseau filaire [PLUGIN]
- `wlan0` = Carte WiFi [RESEAU]
- `inet 192.168.1.50` = **C'EST TON ADRESSE IP ACTUELLE**

---

### Méthode 2 : Avec `ifconfig` (Ancien mais fonctionne)

```bash
ifconfig
```

**Si la commande n'existe pas :**
```bash
sudo apt install net-tools
```

**Résultat :**
```
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
      inet 192.168.1.50  netmask 255.255.255.0
           ^^^^^^^^^^^^
           TON ADRESSE IP
```

---

### Méthode 3 : Avec `hostname` (La plus simple)

```bash
hostname -I
```

**Résultat :**
```
192.168.1.50
```

**Cette commande affiche directement l'IP, sans détails supplémentaires.**

---

## [OBJECTIF] ANALOGIE : Comprendre les adresses IP

Imagine ton réseau local comme **un immeuble** :

```
[ENTREPRISE] Immeuble : 192.168.1.0/24
   ├── [SORTIE] Appartement 1 : 192.168.1.1 (Box/Routeur)
   ├── [SORTIE] Appartement 50 : 192.168.1.50 (Ton serveur ACTUELLEMENT)
   ├── [SORTIE] Appartement 100 : 192.168.1.100 (Ce qu'on veut fixer)
   └── [SORTIE] Appartement 254 : 192.168.1.254 (Dernier dispo)
```

**Actuellement :** Ton serveur est à l'appartement 50 (192.168.1.50)  
**Objectif :** Le déménager à l'appartement 100 (192.168.1.100)

---

## [OUTIL] PARTIE 2 : FIXER UNE ADRESSE IP STATIQUE

### [ATTENTION] IMPORTANT : Choisir une bonne adresse IP

**Règles d'or :**

1. **Respecter la plage de ton réseau**
   ```
   Si ta box est sur 192.168.1.1
   -> Ton serveur doit être 192.168.1.XXX
   ```

2. **Éviter les conflits**
   ```
   [OK] Utiliser 192.168.1.100-254 (généralement libres)
   [X] Éviter 192.168.1.2-50 (souvent utilisés par DHCP)
   ```

3. **Vérifier que l'IP est libre**
   ```bash
   ping 192.168.1.100 -c 4
   ```
   **Si aucune réponse :** L'IP est libre [OK]  
   **Si réponse :** L'IP est déjà utilisée [X] (choisir une autre)

---

Pour savoir *exactement* si ta box (routeur) est sur **192.168.1.1**, tu n’as pas besoin de deviner : il existe plusieurs méthodes simples. Je vais t’expliquer **comme à un bébé**, étape par étape, sans brûler les étapes.

---

# [BABY_BOTTLE] Comment savoir si ma box est sur 192.168.1.1 ?

Ta box Internet possède une **adresse IP locale**, appelée **gateway** ou **passerelle**.
C’est l’IP par laquelle tous tes appareils passent pour aller sur Internet.

Pour vérifier cette adresse, tu peux utiliser **n’importe quelle machine** de ton réseau : ton PC, ton Linux, même ton téléphone.

Voici **toutes les méthodes**, les plus simples d’abord.

---

# [1er] MÉTHODE 1 — Sur Linux (la plus précise)

Ouvre un terminal et tape :

```
ip route
```

Tu obtiens un résultat comme :

```
default via 192.168.1.1 dev eth0
```

-> **C’est ici !**

* `default` = route par défaut
* `via 192.168.1.1` = ton routeur
* `dev eth0` = la carte réseau utilisée

Donc **ta box = 192.168.1.1**.

---

# [2e] MÉTHODE 2 — Toujours sur Linux (version ultra simple)

Tape :

```
ip r | grep default
```

Exemple :

```
default via 192.168.0.1 dev wlan0
```

-> La gateway = **192.168.0.1**

---

# [3e] MÉTHODE 3 — Sur Windows

Ouvre un PowerShell ou CMD :

```
ipconfig
```

Regarde dans la partie :

```
Default Gateway . . . . . . : 192.168.1.1
```

-> C’est ton routeur.

---

# [MOBILE] MÉTHODE 4 — Sur Android

1. Va dans **Paramètres**
2. **Wi-Fi**
3. Clique sur ton réseau Wi-Fi
4. Cherche :

   * **Passerelle**
   * **Routeur**
   * **Gateway**

Tu verras par exemple :

```
Passerelle : 192.168.1.1
```

---

# [GREEN_APPLE] MÉTHODE 5 — Sur iPhone/iPad

1. Réglages
2. Wi-Fi
3. Appuie sur le petit **i** à droite du réseau
4. Cherche **Routeur**

Exemple :

```
Routeur : 192.168.1.1
```

---

# [LOGIQUE] COMMENT INTERPRÉTER LE RÉSULTAT ?

Voici les cas possibles.

### [OK] Si tu vois **192.168.1.1**

-> Ton réseau est en **192.168.1.X**, parfait !
Tu peux mettre ton serveur DNS sur **192.168.1.100**.

### [OK] Si tu vois **192.168.0.1**

-> Ton réseau est en **192.168.0.X**
-> Ton serveur DNS doit être **192.168.0.100** (par exemple)

### [OK] Si tu vois **10.0.0.1**

-> Ton réseau est en **10.0.0.X**
-> Serveur DNS = **10.0.0.100**

### [OK] Si tu vois **192.168.43.1**

-> Tu es peut-être connecté via **partage de connexion téléphone**
-> Mieux vaut ne pas configurer un serveur DNS dans ce cas.

---

# [MODULE] CONSEIL POUR NE PAS FAIRE D’ERREUR

Ne choisis *jamais* l’adresse IP de ton serveur au hasard.

Toujours suivre :

```
IP du serveur = même réseau que la gateway
```

Exemples :

| Gateway     | Réseau      | Serveur DNS possible |
| ----------- | ----------- | -------------------- |
| 192.168.1.1 | 192.168.1.X | 192.168.1.100        |
| 192.168.0.1 | 192.168.0.X | 192.168.0.150        |
| 10.0.0.1    | 10.0.0.X    | 10.0.0.50            |
| 172.16.0.1  | 172.16.0.X  | 172.16.0.70          |

---

# [STOP] ERREURS FRÉQUENTES (et comment les éviter)

### [X] Erreur 1 : mettre une IP qui n’est pas dans le même réseau

Exemple : serveur = 192.168.1.50
gateway = 192.168.0.1
-> Le serveur ne pourra pas sortir sur Internet.

### [X] Erreur 2 : utiliser une IP déjà prise

Résultat : conflits, coupures réseau, DNS KO.

### [X] Erreur 3 : utiliser une IP que le DHCP peut attribuer

Ex : DHCP = 192.168.1.10–100
Tu mets ton serveur sur 192.168.1.50
-> Conflit possible.

Toujours vérifier le DHCP dans ta box.

---

### [OUTILS] MÉTHODE 1 : Avec Netplan (Ubuntu 18.04+, Debian 11+)

**Netplan** = Système moderne de configuration réseau

#### Étape 1 : Identifier le fichier de configuration

```bash
ls /etc/netplan/
```

**Résultat typique :**
```
00-installer-config.yaml
ou
01-netcfg.yaml
```

#### Étape 2 : Sauvegarder la config actuelle (IMPORTANT !)

```bash
sudo cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.backup
```

**Pourquoi ?** Si tu fais une erreur, tu peux restaurer :
```bash
sudo cp /etc/netplan/00-installer-config.yaml.backup /etc/netplan/00-installer-config.yaml
```

#### Étape 3 : Éditer la configuration

```bash
sudo nano /etc/netplan/00-installer-config.yaml
```

#### Étape 4 : Remplacer le contenu

**[ROUGE] Configuration ACTUELLE (DHCP - IP automatique) :**
```yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
```

**[VERT] NOUVELLE configuration (IP FIXE) :**
```yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses:
          - 127.0.0.1
          - 8.8.8.8
```

#### [GUIDE] EXPLICATION LIGNE PAR LIGNE :

```yaml
network:
  version: 2
```
**Ce que ça fait :** Indique la version de Netplan (toujours 2)

```yaml
  ethernets:
    eth0:
```
**Ce que ça fait :** Configure l'interface réseau `eth0`  
**[ATTENTION] IMPORTANT :** Remplace `eth0` par TON interface (trouve-la avec `ip a`)  
**Exemples courants :**
- `eth0` = Câble réseau
- `enp0s3` = Câble sur VirtualBox/VMware
- `wlan0` = WiFi
- `ens18` = Proxmox

```yaml
      dhcp4: no
```
**Ce que ça fait :** Désactive l'attribution automatique d'IP  
**Analogie :** "Je ne veux plus qu'on m'attribue un numéro d'appartement aléatoire"

```yaml
      addresses:
        - 192.168.1.100/24
```
**Ce que ça fait :** Fixe l'adresse IP à 192.168.1.100  
**Le `/24` expliqué :**
- `/24` = Masque de sous-réseau 255.255.255.0
- Signifie : "Mon réseau va de 192.168.1.1 à 192.168.1.254"

**Autres exemples :**
```yaml
- 192.168.0.100/24    # Si ta box est sur 192.168.0.1
- 10.0.0.100/24       # Si ta box est sur 10.0.0.1
```

```yaml
      routes:
        - to: default
          via: 192.168.1.1
```
**Ce que ça fait :** Définit la passerelle par défaut (ta box/routeur)  
**Analogie :** "Pour sortir de l'immeuble (aller sur Internet), passe par le gardien (routeur)"  
**[ATTENTION] À ADAPTER :** Remplace `192.168.1.1` par l'IP de TA box

**Comment trouver l'IP de ta box ?**
```bash
ip route | grep default
```
**Résultat :**
```
default via 192.168.1.1 dev eth0
            ^^^^^^^^^^^
            IP de ta box
```

```yaml
      nameservers:
        addresses:
          - 127.0.0.1
          - 8.8.8.8
```
**Ce que ça fait :** Définit les serveurs DNS à utiliser  
**Explication :**
- `127.0.0.1` = Ton serveur DNS local (DNSmasq ou BIND9)
- `8.8.8.8` = Google DNS (en secours si ton DNS local ne répond pas)

**Alternatives :**
```yaml
- 127.0.0.1          # Ton DNS local (si tu configures DNSmasq/BIND9)
- 1.1.1.1            # Cloudflare (rapide et privé)
- 9.9.9.9            # Quad9 (sécurisé)
- 192.168.1.1        # DNS de ta box
```

#### Étape 5 : Vérifier la syntaxe YAML (CRUCIAL !)

```bash
sudo netplan try
```

**Ce que ça fait :**
- Applique la config pendant 120 secondes
- Si tu perds la connexion SSH, elle s'annule automatiquement
- Si tout fonctionne, tape `ENTRÉE` pour confirmer

**[ATTENTION] ATTENTION : YAML est TRÈS sensible à l'indentation !**

**[X] ERREUR (espaces incorrects) :**
```yaml
network:
version: 2        # [X] Pas d'indentation
  ethernets:
```

**[OK] CORRECT (2 espaces par niveau) :**
```yaml
network:
  version: 2      # [OK] 2 espaces
  ethernets:
    eth0:         # [OK] 4 espaces
      dhcp4: no   # [OK] 6 espaces
```

#### Étape 6 : Appliquer définitivement

**Si `netplan try` fonctionne :**
```bash
sudo netplan apply
```

**Cette commande applique la configuration de manière permanente.**

#### Étape 7 : Vérifier la nouvelle IP

```bash
ip a show eth0
```

**Résultat attendu :**
```
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>
    inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0
         ^^^^^^^^^^^^^
         [OK] SUCCÈS !
```

**Tester la connectivité :**
```bash
# Test de la passerelle (box)
ping 192.168.1.1 -c 4

# Test d'Internet
ping google.com -c 4
```

---

### [OUTILS] MÉTHODE 2 : Avec /etc/network/interfaces (Debian ancien, Ubuntu < 18.04)

#### Étape 1 : Sauvegarder

```bash
sudo cp /etc/network/interfaces /etc/network/interfaces.backup
```

#### Étape 2 : Éditer

```bash
sudo nano /etc/network/interfaces
```

#### Étape 3 : Configuration

**[ROUGE] Configuration ACTUELLE (DHCP) :**
```bash
auto eth0
iface eth0 inet dhcp
```

**[VERT] NOUVELLE configuration (IP FIXE) :**
```bash
auto eth0
iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 127.0.0.1 8.8.8.8
```

#### [GUIDE] EXPLICATION LIGNE PAR LIGNE :

```bash
auto eth0
```
**Ce que ça fait :** Active automatiquement l'interface au démarrage  
**Analogie :** "Allume la lumière automatiquement quand j'entre dans la pièce"

```bash
iface eth0 inet static
```
**Ce que ça fait :**
- `iface eth0` = Configure l'interface eth0
- `inet` = IPv4 (pas IPv6)
- `static` = IP fixe (pas DHCP)

```bash
    address 192.168.1.100
```
**Ce que ça fait :** Fixe l'adresse IP  
**[ATTENTION] À ADAPTER :** Selon ton réseau

```bash
    netmask 255.255.255.0
```
**Ce que ça fait :** Définit le masque de sous-réseau  
**Équivalent de `/24` dans Netplan**

**Tableau de correspondance :**
| Notation CIDR | Masque | Nombre d'IPs |
|---------------|---------|--------------|
| /24 | 255.255.255.0 | 254 IPs |
| /16 | 255.255.0.0 | 65534 IPs |
| /8 | 255.0.0.0 | 16 millions |

```bash
    gateway 192.168.1.1
```
**Ce que ça fait :** Définit la passerelle (routeur)

```bash
    dns-nameservers 127.0.0.1 8.8.8.8
```
**Ce que ça fait :** Définit les serveurs DNS  
**Séparés par des espaces, pas de virgules**

#### Étape 4 : Redémarrer le réseau

```bash
sudo systemctl restart networking
```

**Ou redémarrer complètement :**
```bash
sudo reboot
```

---

## [OBJECTIF] RÉCAPITULATIF : PROCESSUS COMPLET

### [LISTE] Checklist étape par étape

```
[ ] 1. Trouver mon IP actuelle
   -> ip a

[ ] 2. Choisir une nouvelle IP libre
   -> ping 192.168.1.100 -c 4

[ ] 3. Identifier mon interface réseau
   -> ip a (eth0, enp0s3, wlan0...)

[ ] 4. Trouver l'IP de ma box/routeur
   -> ip route | grep default

[ ] 5. Sauvegarder la config actuelle
   -> sudo cp /etc/netplan/XX.yaml /etc/netplan/XX.yaml.backup

[ ] 6. Éditer la configuration
   -> sudo nano /etc/netplan/XX.yaml

[ ] 7. Tester la config (sécurité !)
   -> sudo netplan try

[ ] 8. Appliquer définitivement
   -> sudo netplan apply

[ ] 9. Vérifier la nouvelle IP
   -> ip a

[ ] 10. Tester la connectivité
   -> ping 192.168.1.1
   -> ping google.com
```

---

## [HOT] CAS PRATIQUES RÉELS

### Cas 1 : Box Orange (Livebox)

```yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1        # IP typique Livebox
      nameservers:
        addresses:
          - 127.0.0.1
          - 80.10.246.2           # DNS Orange (optionnel)
```

### Cas 2 : Box SFR (SFR Box)

```yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1        # IP typique SFR Box
      nameservers:
        addresses:
          - 127.0.0.1
          - 109.0.66.10           # DNS SFR (optionnel)
```

### Cas 3 : Box Free (Freebox)

```yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.0.100/24        # [ATTENTION] Free utilise 192.168.0.X
      routes:
        - to: default
          via: 192.168.0.254      # [ATTENTION] IP typique Freebox
      nameservers:
        addresses:
          - 127.0.0.1
          - 212.27.40.240         # DNS Free (optionnel)
```

# [REFLEXION] EXCELLENTE QUESTION ! Pourquoi pas `ifconfig` ?

## [RAPIDE] RÉPONSE COURTE

Tu **PEUX** utiliser `ifconfig eth0 192.168.1.50`, **MAIS** :

```
[X] Configuration TEMPORAIRE (perdue au redémarrage)
[OK] Configuration PERMANENTE (survit au redémarrage)
```

**Analogie :** 
- `ifconfig` = Écrire ton adresse au **crayon** [EDIT] (effacé au prochain nettoyage)
- Netplan/interfaces = Graver ton adresse dans le **marbre** [MOYAI] (permanent)

---

## [GRAPHIQUE] COMPARAISON DÉTAILLÉE

### Méthode 1 : `ifconfig` (Temporaire)

```bash
sudo ifconfig eth0 192.168.1.50 netmask 255.255.255.0
```

**[OK] Avantages :**
- [RAPIDE] Instantané (pas de redémarrage)
- [OBJECTIF] Parfait pour **tester** rapidement
- [OUTIL] Utile pour **dépanner** temporairement

**[X] Inconvénients :**
- [IMPACT] **PERDU au redémarrage** du serveur
- [IMPACT] **PERDU** si l'interface réseau redémarre
- [ATTENTION] Ne configure pas la passerelle (gateway)
- [ATTENTION] Ne configure pas les DNS
- [ATTENTION] Commande **obsolète** (remplacée par `ip`)

---

### Méthode 2 : Netplan/interfaces (Permanent)

```yaml
# /etc/netplan/config.yaml
network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - 192.168.1.50/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses: [8.8.8.8]
```

**[OK] Avantages :**
- [VERROUILLE] **PERMANENT** (survit aux redémarrages)
- [WEB] Configure **tout** (IP, gateway, DNS)
- [DOSSIER] Configuration **centralisée**
- [RAPIDE] Méthode **moderne** et recommandée

**[X] Inconvénients :**
- [TEMPS] Nécessite un redémarrage réseau
- [NOTE] Plus verbeux (plusieurs lignes)

---

## [TEST] DÉMONSTRATION PRATIQUE

### Scénario : Configuration avec `ifconfig`

```bash
# Étape 1 : Configurer l'IP temporairement
sudo ifconfig eth0 192.168.1.50 netmask 255.255.255.0

# Étape 2 : Vérifier ([OK] ça marche !)
ip a show eth0
# inet 192.168.1.50/24

# Étape 3 : Tester la connectivité
ping 192.168.1.1
# [OK] Fonctionne

# Étape 4 : Mais essayer d'aller sur Internet
ping google.com
# [X] Network unreachable
```

**Pourquoi ça ne marche pas ?**

Parce qu'il **manque des éléments essentiels** :

```
[OK] Adresse IP      : 192.168.1.50     (configurée)
[X] Passerelle      : ???              (NON configurée)
[X] DNS             : ???              (NON configuré)
```

**Analogie :** Tu as une adresse postale (IP), mais :
- Pas de facteur (passerelle) pour acheminer ton courrier
- Pas d'annuaire (DNS) pour trouver les autres adresses

---

### Configuration COMPLÈTE avec `ifconfig` + `route` + `resolv.conf`

```bash
# 1⃣ Configurer l'IP
sudo ifconfig eth0 192.168.1.50 netmask 255.255.255.0

# 2⃣ Configurer la passerelle (gateway)
sudo route add default gw 192.168.1.1 eth0

# 3⃣ Configurer les DNS
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
```

**Maintenant ça fonctionne... MAIS :**

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

# Après redémarrage, vérifie l'IP
ip a
# [X] OUPS ! L'IP est revenue à celle attribuée par DHCP
# (exemple: 192.168.1.73 au lieu de 192.168.1.50)
```

**[IMPACT] Tout a été perdu !**

---

## [OBJECTIF] QUAND UTILISER CHAQUE MÉTHODE ?

### Utilise `ifconfig` / `ip` (Temporaire) pour :

**1. Tester rapidement une configuration**
```bash
# Tu veux voir si une IP fonctionne avant de la fixer
sudo ifconfig eth0 192.168.1.100 netmask 255.255.255.0
sudo route add default gw 192.168.1.1
ping google.com  # Test
```

**2. Dépanner une connexion cassée**
```bash
# Le réseau ne marche plus, tu veux une solution rapide
sudo ifconfig eth0 up
sudo dhclient eth0  # Récupérer une IP automatique
```

**3. Changer temporairement d'IP pour une tâche précise**
```bash
# Tu dois te connecter à un équipement sur un autre réseau
sudo ifconfig eth0 10.0.0.50 netmask 255.255.255.0
# Faire ta tâche
# Puis revenir à la config normale avec un reboot
```

---

### Utilise Netplan/interfaces (Permanent) pour :

**1. Configurer un serveur de production**
```yaml
# L'IP doit survivre aux redémarrages
network:
  version: 2
  ethernets:
    eth0:
      addresses: [192.168.1.100/24]
```

**2. Configurer des services réseau (DNS, Web, etc.)**
```bash
# Un serveur DNS DOIT avoir une IP fixe permanente
```

**3. Toute configuration destinée à durer**
```bash
# Si tu veux garder cette config plus de 5 minutes
```

---

## [SYNC] COMMANDES MODERNES : `ip` remplace `ifconfig`

### [ATTENTION] IMPORTANT : `ifconfig` est **OBSOLÈTE**

```bash
# [X] Ancienne méthode (deprecated depuis 2009)
sudo ifconfig eth0 192.168.1.50 netmask 255.255.255.0
sudo route add default gw 192.168.1.1

# [OK] Nouvelle méthode (recommandée)
sudo ip addr add 192.168.1.50/24 dev eth0
sudo ip route add default via 192.168.1.1
```

**Pourquoi `ip` est meilleur ?**
- [RAPIDE] Plus rapide
- [OBJECTIF] Plus précis
- [MOBILE] Supporte IPv6
- [OUTIL] Plus de fonctionnalités
- [OK] Activement maintenu

---

## [GUIDE] TABLEAU DE CORRESPONDANCE

| Tâche | Ancienne commande (`ifconfig`) | Nouvelle commande (`ip`) |
|-------|-------------------------------|--------------------------|
| **Voir les IPs** | `ifconfig` | `ip addr` ou `ip a` |
| **Ajouter une IP** | `ifconfig eth0 192.168.1.50 netmask 255.255.255.0` | `ip addr add 192.168.1.50/24 dev eth0` |
| **Supprimer une IP** | `ifconfig eth0 0.0.0.0` | `ip addr del 192.168.1.50/24 dev eth0` |
| **Activer interface** | `ifconfig eth0 up` | `ip link set eth0 up` |
| **Désactiver interface** | `ifconfig eth0 down` | `ip link set eth0 down` |
| **Voir les routes** | `route -n` | `ip route` |
| **Ajouter route** | `route add default gw 192.168.1.1` | `ip route add default via 192.168.1.1` |

---

## [DEMARRAGE] EXEMPLE COMPLET : Les 3 approches côte à côte

### Scénario : Fixer l'IP 192.168.1.100 sur eth0

#### Approche 1 : Temporaire avec `ifconfig` (obsolète)

```bash
# Configuration
sudo ifconfig eth0 192.168.1.100 netmask 255.255.255.0
sudo route add default gw 192.168.1.1 eth0
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

# [OK] Fonctionne MAINTENANT
# [X] Perdu au redémarrage
```

---

#### Approche 2 : Temporaire avec `ip` (moderne)

```bash
# Configuration
sudo ip addr add 192.168.1.100/24 dev eth0
sudo ip route add default via 192.168.1.1
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

# [OK] Fonctionne MAINTENANT
# [X] Perdu au redémarrage
```

---

#### Approche 3 : Permanent avec Netplan

```bash
# Éditer la config
sudo nano /etc/netplan/01-config.yaml
```

```yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses:
          - 8.8.8.8
```

```bash
# Appliquer
sudo netplan apply

# [OK] Fonctionne MAINTENANT
# [OK] Fonctionne APRÈS REDÉMARRAGE
```

---

## [LOGIQUE] STRATÉGIE RECOMMANDÉE : COMBINAISON DES DEUX

### Workflow professionnel :

```bash
# Étape 1 : Tester temporairement avec ip
sudo ip addr add 192.168.1.100/24 dev eth0
sudo ip route add default via 192.168.1.1

# Étape 2 : Vérifier que ça fonctionne
ping 192.168.1.1        # Test gateway
ping google.com         # Test Internet

# Étape 3 : Si OK, fixer de manière permanente
sudo nano /etc/netplan/01-config.yaml
# [Configurer comme expliqué plus haut]

# Étape 4 : Supprimer la config temporaire
sudo ip addr del 192.168.1.100/24 dev eth0

# Étape 5 : Appliquer la config permanente
sudo netplan apply
```

**Avantage de cette méthode :**
- [TEST] Tu testes d'abord (sécurisé)
- [OK] Tu ne rends permanent que ce qui fonctionne
- [RAPIDE] Pas besoin de redémarrer pour tester

---

## [IDEE] CAS D'USAGE RÉELS

### Cas 1 : Dépannage rapide

**Situation :** Le réseau ne marche plus après une mise à jour

```bash
# Solution temporaire immédiate
sudo ip link set eth0 up
sudo ip addr add 192.168.1.50/24 dev eth0
sudo ip route add default via 192.168.1.1

# [OK] Le réseau refonctionne
# Ensuite, chercher la cause et corriger la config permanente
```

---

### Cas 2 : Configuration de serveur DNS

**Situation :** Tu installes DNSmasq, tu DOIS avoir une IP fixe permanente

```bash
# [X] MAUVAIS : Configuration temporaire
sudo ip addr add 192.168.1.100/24 dev eth0
sudo apt install dnsmasq
# Le DNS fonctionnera JUSQU'AU PROCHAIN REDÉMARRAGE

# [OK] BON : Configuration permanente AVANT d'installer
sudo nano /etc/netplan/01-config.yaml
# [Fixer l'IP à 192.168.1.100]
sudo netplan apply
sudo apt install dnsmasq
# Le DNS fonctionnera TOUJOURS
```

---

### Cas 3 : Test de configuration avant déploiement

**Situation :** Tu veux tester une nouvelle IP sans casser la config actuelle

```bash
# Ajouter une DEUXIÈME IP temporaire (la première reste)
sudo ip addr add 192.168.1.200/24 dev eth0

# Tester avec cette nouvelle IP
ping -I 192.168.1.200 google.com

# Si ça marche, l'adopter de manière permanente
# Si ça ne marche pas, simplement supprimer
sudo ip addr del 192.168.1.200/24 dev eth0
```

---

## [COURS] RÉSUMÉ : QUELLE MÉTHODE CHOISIR ?

```
┌─────────────────────────────────────────────────┐
│     DOIS-JE UTILISER ifconfig/ip OU Netplan ?   │
├─────────────────────────────────────────────────┤
│                                                 │
│  Test rapide < 5 min ?                          │
│  └──> [OK] ifconfig / ip (temporaire)             │
│                                                 │
│  Configuration serveur de production ?          │
│  └──> [OK] Netplan (permanent)                    │
│                                                 │
│  Dépannage d'urgence ?                          │
│  └──> [OK] ifconfig / ip (temporaire)             │
│                                                 │
│  Installer un service réseau (DNS/Web) ?        │
│  └──> [OK] Netplan (permanent)                    │
│                                                 │
│  L'IP doit survivre au redémarrage ?            │
│  └──> [OK] Netplan (permanent)                    │
│                                                 │
│  Configuration définitive ?                     │
│  └──> [OK] TOUJOURS Netplan                       │
│                                                 │
└─────────────────────────────────────────────────┘
```

---

## [CLE] CONCLUSION

**Ta question était excellente !** Oui, `ifconfig eth0 192.168.1.50` fonctionne, mais c'est comme :

[CAMPING] **Planter une tente** (temporaire) vs [ACCUEIL] **Construire une maison** (permanent)

Pour un **serveur DNS** que tu configures, tu veux une **maison solide** (Netplan), pas une **tente qui s'envole au premier redémarrage** !

**Conseil final :** Utilise les deux !
1. Teste avec `ip` (rapide)
2. Rends permanent avec Netplan (fiable)

[BRAVO] Voilà pourquoi je t'ai montré Netplan plutôt que `ifconfig` !

---

## 🆘 DÉPANNAGE : PROBLÈMES FRÉQUENTS

### [X] Problème 1 : "Connexion perdue après netplan apply"

**Cause :** Erreur dans la configuration (interface incorrecte, IP en conflit)

**Solution :**
1. Connecte-toi physiquement au serveur (clavier/écran)
2. Restaure la sauvegarde :
   ```bash
   sudo cp /etc/netplan/00-installer-config.yaml.backup /etc/netplan/00-installer-config.yaml
   sudo netplan apply
   ```

---

### [X] Problème 2 : "Network unreachable"

**Cause :** Mauvaise passerelle (gateway)

**Vérification :**
```bash
ip route
```

**Si pas de "default via", c'est le problème.**

**Solution :**
```bash
# Ajouter temporairement la route
sudo ip route add default via 192.168.1.1

# Puis corriger dans /etc/netplan/
```

---

### [X] Problème 3 : "Temporary failure in name resolution"

**Cause :** DNS mal configuré

**Test :**
```bash
cat /etc/resolv.conf
```

**Devrait contenir :**
```
nameserver 127.0.0.1
nameserver 8.8.8.8
```

**Solution temporaire :**
```bash
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
```

**Solution permanente :** Corriger `nameservers` dans `/etc/netplan/`

---

### [X] Problème 4 : Conflit d'adresse IP

**Symptôme :**
```
RTNETLINK answers: File exists
```

**Cause :** Une autre machine utilise déjà 192.168.1.100

**Solution :**
1. Identifier le coupable :
   ```bash
   # Sur la machine en conflit
   sudo arp-scan --localnet | grep 192.168.1.100
   ```

2. Choisir une autre IP (ex: 192.168.1.101)

---

## [COURS] CONSEILS DE PRO

### [OK] Bonnes pratiques

1. **Toujours sauvegarder avant de modifier**
   ```bash
   sudo cp config config.backup
   ```

2. **Documenter tes IPs** (crée un fichier texte)
   ```
   192.168.1.1   -> Box/Routeur
   192.168.1.100 -> Serveur DNS
   192.168.1.101 -> Serveur Web
   192.168.1.102 -> NAS
   ```

3. **Utiliser une plage dédiée**
   ```
   192.168.1.2-99   -> DHCP (automatique)
   192.168.1.100-200 -> Serveurs (fixe)
   ```

4. **Tester avec `netplan try`** (jamais `netplan apply` directement en SSH)

5. **Garder un accès physique** pendant les modifications réseau

---

Voilà ! Tu sais maintenant tout pour trouver et fixer l'adresse IP de ton serveur ! [BRAVO]

Bonne configuration ! [BRAVO]

```


Guide complet pour tester ton DNS depuis ta machine physique

# [OBJECTIF] OUI, C'EST POSSIBLE ! Guide complet pour tester ton DNS depuis ta machine physique

## [GUIDE] COMPRENDRE LA SITUATION

### [CONSTRUCTION] Ton architecture actuelle

```
┌─────────────────────────────────────────┐
│     [CODE] MACHINE PHYSIQUE (Windows/Mac)   │
│                                         │
│  ┌────────────────────────────────────┐ │
│  │  [ECRAN] VIRTUALBOX                     │ │
│  │                                    │ │
│  │  ┌──────────────────────────────┐  │ │
│  │  │ [LINUX] VM LINUX (Serveur DNS)    │  │ │
│  │  │ IP: 192.168.1.100            │  │ │
│  │  │ DNSmasq ou BIND9 actif       │  │ │
│  │  └──────────────────────────────┘  │ │
│  └────────────────────────────────────┘ │
└─────────────────────────────────────────┘
```

**Objectif :** Faire communiquer ta machine physique avec le DNS de ta VM.

---

## [SIGNAL] PRÉREQUIS : Vérifier le mode réseau de ta VM

### [RECHERCHE] Pourquoi c'est crucial ?

VirtualBox propose plusieurs modes réseau. **Seuls 2 modes permettent la communication** :

|------------------------|-------------------------|-----------------------------|-----------------------------|
| Mode                   | Communication VM <-> Hôte | Communication VM <-> Internet | Recommandation              |
|------------------------|-------------------------|-----------------------------|-----------------------------|
| **NAT**                |        [X] NON           |            [OK] OUI           | [X] Ne fonctionne PAS       |
| **Accès par pont**     |        [OK] OUI           |            [OK] OUI           | [OK] **RECOMMANDÉ**          |
| **Réseau interne**     |        [X] NON           |            [X] NON           | [X] Ne fonctionne PAS       |
| **Réseau privé hôte**  |        [OK] OUI           |            [X] NON           | [ATTENTION] Fonctionne mais complexe|
|------------------------|-------------------------|-----------------------------|-----------------------------|

---

## [CONFIG] ÉTAPE 1 : CONFIGURER LE MODE RÉSEAU (Accès par pont)

### [IMPORTANT] Sur VirtualBox (VM éteinte)

1. **Ouvre VirtualBox**
2. **Sélectionne ta VM** (ne la démarre pas encore)
3. **Clique sur "Configuration" ([CONFIG])**
4. **Va dans "Réseau"**
5. **Onglet "Adaptateur 1"** :
   - [OK] Cocher "Activer la carte réseau"
   - **Mode d'accès réseau :** Sélectionner **"Accès par pont"**
   - **Nom :** Choisir ta carte réseau physique :
     - [PLUGIN] `Realtek...` ou `Intel...` (Ethernet)
     - [RESEAU] `Wireless...` (WiFi)
6. **Clique sur "OK"**

### [FRAME_WITH_PICTURE] Illustration :

```
┌────────────────────────────────────┐
│  Configuration - Ma VM Linux       │
├────────────────────────────────────┤
│  Réseau                            │
│  ┌──────────────────────────────┐  │
│  │ Adaptateur 1                 │  │
│  │ [x] Activer la carte réseau    │  │
│  │                              │  │
│  │ Mode d'accès réseau:         │  │
│  │ [Accès par pont [BLACK_DOWN-POINTING_TRIANGLE]]           │  │
│  │                              │  │
│  │ Nom:                         │  │
│  │ [Realtek PCIe GbE [BLACK_DOWN-POINTING_TRIANGLE]]         │  │
│  └──────────────────────────────┘  │
└────────────────────────────────────┘
```

---

## [RAPIDE] ÉTAPE 2 : DÉMARRER LA VM ET VÉRIFIER L'IP

### 1⃣ Démarre ta VM Linux

### 2⃣ Vérifie son adresse IP

```bash
ip a
```

**Résultat attendu :**

```
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>
    inet 192.168.1.50/24 brd 192.168.1.255
         ^^^^^^^^^^^^
    TON IP ACTUELLE (peut être différente de 192.168.1.100)
```

### [OBJECTIF] Comprendre ce résultat

**Si tu vois une IP comme `192.168.1.X` :**
- [OK] **PARFAIT !** Ta VM est sur le même réseau que ta machine physique
- Elle a reçu une IP automatiquement (DHCP)

**Si tu vois `10.0.2.15` :**
- [X] **PROBLÈME !** Tu es encore en mode NAT
- Retourne à l'ÉTAPE 1 et vérifie le mode réseau

---

## [OUTIL] ÉTAPE 3 : FIXER L'ADRESSE IP DE LA VM (Optionnel mais recommandé)

### [IDEE] Pourquoi fixer l'IP ?

**Analogie :** C'est comme donner une adresse fixe à ta maison au lieu d'un numéro temporaire.

**Avantages :**
- L'IP ne change jamais -> Configuration stable
- Plus facile à mémoriser (`192.168.1.100`)
- Pas de surprise au redémarrage

---

### Méthode A : Avec Netplan (Ubuntu 18.04+, Debian 11+)

#### 1⃣ Vérifier si tu utilises Netplan

```bash
ls /etc/netplan/
```

**Si tu vois un fichier `.yaml` :** Tu utilises Netplan [OK]

#### 2⃣ Éditer la configuration

```bash
sudo nano /etc/netplan/01-netcfg.yaml
```

**[ATTENTION] Le nom du fichier peut varier :**
- `00-installer-config.yaml`
- `50-cloud-init.yaml`
- etc.

#### 3⃣ Contenu à utiliser (copie/colle)

```yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses:
          - 8.8.8.8
          - 8.8.4.4
```

#### [GUIDE] Explication ligne par ligne

```yaml
network:
  version: 2                    # Version de Netplan
  renderer: networkd            # Moteur de réseau utilisé
  ethernets:                    # Configuration des cartes Ethernet
    eth0:                       # Nom de ta carte réseau
      dhcp4: no                 # Désactive l'IP automatique
      addresses:
        - 192.168.1.100/24      # TON IP FIXE + masque réseau
      routes:
        - to: default
          via: 192.168.1.1      # IP DE TA BOX (passerelle)
      nameservers:
        addresses:
          - 8.8.8.8             # DNS Google (pour accès Internet)
          - 8.8.4.4
```

#### 4⃣ Appliquer la configuration

```bash
sudo netplan apply
```

#### 5⃣ Vérifier

```bash
ip a | grep eth0
```

**Résultat attendu :**
```
inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0
```

---

### Méthode B : Avec /etc/network/interfaces (Debian anciennes versions)

#### 1⃣ Éditer le fichier

```bash
sudo nano /etc/network/interfaces
```

#### 2⃣ Contenu à utiliser

```bash
# Interface loopback (ne pas toucher)
auto lo
iface lo inet loopback

# Configuration de eth0
auto eth0
iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 8.8.8.8 8.8.4.4
```

#### 3⃣ Redémarrer le réseau

```bash
sudo systemctl restart networking
```

#### 4⃣ Vérifier

```bash
ip a | grep eth0
```

---

## [TEST] ÉTAPE 4 : TESTER LA COMMUNICATION VM <-> MACHINE PHYSIQUE

### [SYNC] Test 1 : Depuis la VM -> Machine physique

#### 1⃣ Trouver l'IP de ta machine physique

**Sur Windows :**
1. Ouvre **Invite de commandes** (`Win + R` -> tape `cmd` -> Entrée)
2. Tape :
```cmd
ipconfig
```
3. Cherche **"Carte Ethernet"** ou **"Carte WiFi"**
4. Note l'**"Adresse IPv4"** (ex: `192.168.1.10`)

**Sur Mac :**
1. Ouvre **Terminal**
2. Tape :
```bash
ifconfig | grep "inet " | grep -v 127.0.0.1
```

**Sur Linux :**
```bash
ip a
```

#### 2⃣ Ping depuis la VM

```bash
ping 192.168.1.10 -c 4
```

**Remplace `192.168.1.10` par l'IP de ta machine physique**

**Résultat attendu :**
```
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.5 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.4 ms
[OK] 4 packets transmitted, 4 received, 0% packet loss
```

**Si ça ne fonctionne pas :**
- [X] Vérifier le pare-feu de ta machine physique
- [X] Vérifier le mode réseau VirtualBox

---

### [SYNC] Test 2 : Depuis la machine physique -> VM

#### Sur Windows (Invite de commandes)

```cmd
ping 192.168.1.100
```

#### Sur Mac/Linux (Terminal)

```bash
ping 192.168.1.100 -c 4
```

**Résultat attendu :**
```
Réponse de 192.168.1.100 : octets=32 temps<1ms TTL=64
[OK] Communication réussie
```

---

## [OBJECTIF] ÉTAPE 5 : CONFIGURER LE DNS SUR TA MACHINE PHYSIQUE

### [DESIGN] Schéma de fonctionnement

```
┌─────────────────────────────────────┐
│  [CODE] MACHINE PHYSIQUE                │
│  Configuration DNS:                 │
│  Serveur DNS préféré: 192.168.1.100 │
│           │                         │
│           [BLACK_DOWN-POINTING_TRIANGLE]                         │
│  "Où est server1.local ?"           │
└───────────┬─────────────────────────┘
            │
            │ Question DNS
            [BLACK_DOWN-POINTING_TRIANGLE]
┌─────────────────────────────────────┐
│  [LINUX] VM LINUX (192.168.1.100)        │
│  DNSmasq/BIND9 répond:              │
│  "server1.local = 192.168.1.100"    │
└─────────────────────────────────────┘
```

---

### Sur Windows 10/11

#### 1⃣ Ouvrir les paramètres réseau

**Méthode rapide :**
1. `Win + R`
2. Tape : `ncpa.cpl`
3. Entrée

#### 2⃣ Configurer la carte réseau

1. **Clique droit** sur ta carte réseau (Ethernet ou WiFi)
2. **Propriétés**
3. **Double-clique** sur "Protocole Internet version 4 (TCP/IPv4)"
4. **En bas :** Sélectionne **"Utiliser l'adresse de serveur DNS suivante"**
5. **Remplis :**
   ```
   Serveur DNS préféré:   192.168.1.100
   Serveur DNS auxiliaire: 8.8.8.8
   ```
6. **OK** -> **OK**

#### 3⃣ Vider le cache DNS

```cmd
ipconfig /flushdns
```

---

### Sur Mac

#### 1⃣ Ouvrir les préférences réseau

1. **Pomme** () -> **Préférences Système**
2. **Réseau**
3. Sélectionne ta connexion (Ethernet ou WiFi)
4. **Avancé...**

#### 2⃣ Configurer le DNS

1. **Onglet DNS**
2. **Clique sur le "+"** sous "Serveurs DNS"
3. **Ajoute :** `192.168.1.100`
4. **(Optionnel) Ajoute :** `8.8.8.8`
5. **OK** -> **Appliquer**

#### 3⃣ Vider le cache DNS

```bash
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
```

---

### Sur Linux (autre machine)

#### 1⃣ Éditer resolv.conf

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

#### 2⃣ Ajouter en premier

```
nameserver 192.168.1.100
nameserver 8.8.8.8
```

**[ATTENTION] Attention :** Sur certaines distributions, ce fichier est régénéré au redémarrage.

#### 3⃣ Solution permanente (systemd-resolved)

```bash
sudo nano /etc/systemd/resolved.conf
```

**Contenu :**
```ini
[Resolve]
DNS=192.168.1.100 8.8.8.8
```

**Redémarrer :**
```bash
sudo systemctl restart systemd-resolved
```

---

## [TEST] ÉTAPE 6 : TESTER LA RÉSOLUTION DNS

### Test 1 : Avec `nslookup` (Windows/Mac/Linux)

```cmd
nslookup server1.local 192.168.1.100
```

**Résultat attendu :**
```
Serveur :   ns1.local
Address:    192.168.1.100

Nom :    server1.local
Address:  192.168.1.100
```

[OK] **Ça fonctionne !** Ton DNS répond correctement.

---

### Test 2 : Avec `dig` (Mac/Linux)

```bash
dig server1.local @192.168.1.100
```

**Résultat attendu :**
```
;; ANSWER SECTION:
server1.local.    604800    IN    A    192.168.1.100
```

---

### Test 3 : Avec `ping`

```bash
ping server1.local
```

**Résultat attendu :**
```
PING server1.local (192.168.1.100) 56(84) bytes of data.
64 bytes from server1.local (192.168.1.100): icmp_seq=1...
```

[OK] **Parfait !** Le nom est résolu automatiquement.

---

## [BRAVO] RÉSUMÉ COMPLET

### [OK] Checklist de vérification

- [ ] Mode réseau VirtualBox = **Accès par pont**
- [ ] VM a une IP `192.168.1.X` (même réseau que ta machine)
- [ ] Ping VM -> Machine physique fonctionne
- [ ] Ping Machine physique -> VM fonctionne
- [ ] DNS configuré sur la machine physique (`192.168.1.100`)
- [ ] `nslookup server1.local 192.168.1.100` retourne l'IP correcte
- [ ] `ping server1.local` fonctionne

---

## 🆘 DÉPANNAGE

### [X] "Délai d'attente de la demande dépassé" lors du ping

**Causes possibles :**
1. **Pare-feu bloque** (Windows Defender, pare-feu Linux)
2. **Mauvais mode réseau** (encore en NAT)
3. **IP incorrecte**

**Solutions :**
```bash
# Sur la VM Linux, désactiver temporairement le pare-feu
sudo ufw disable

# Sur Windows, autoriser ICMP (ping)
# Panneau de configuration -> Pare-feu Windows -> Paramètres avancés
# Règles de trafic entrant -> Activer "Partage de fichiers (Demande d'écho ICMPv4)"
```

---

### [X] "Le serveur n'a pas pu être trouvé" avec nslookup

**Causes :**
1. Le service DNS n'est pas démarré sur la VM
2. Mauvaise configuration DNS

**Solutions :**
```bash
# Vérifier le statut du service
sudo systemctl status dnsmasq    # ou bind9

# Si inactif, démarrer
sudo systemctl start dnsmasq     # ou bind9

# Vérifier que le port 53 écoute
sudo netstat -tulpn | grep :53
```

---

### [X] DNS ne résout que dans un sens

**Si `nslookup server1.local 192.168.1.100` fonctionne**
**Mais `ping server1.local` (sans @IP) ne fonctionne pas**

**Cause :** Configuration DNS de ta machine physique incorrecte

**Solution :** Reprendre l'ÉTAPE 5 et vérifier que `192.168.1.100` est bien le **premier** serveur DNS.

---

## [COURS] TU AS RÉUSSI !

Si tous les tests passent, **BRAVO** ! [BRAVO]

Tu as maintenant :
- [OK] Un serveur DNS fonctionnel sur ta VM
- [OK] Une communication réseau VM <-> Machine physique
- [OK] Une résolution de noms personnalisés depuis ta machine

**Prochaines étapes possibles :**
- Ajouter d'autres enregistrements DNS (web.local, nas.local)
- Configurer un serveur web sur la VM et y accéder via `http://web.local`
- Mettre en place un réseau local complet avec plusieurs VMs

# [OBJECTIF] EXCELLENTE QUESTION ! Tu as raison d'être confus !

## [REFLEXION] LE PROBLÈME QUE TU AS IDENTIFIÉ

Tu dis : 
> "Pourquoi on peut tester la communication à l'ÉTAPE 4, alors qu'on n'a RIEN configuré sur la machine physique ?"

**TU AS 100% RAISON !** [BRAVO]

J'ai sauté des étapes importantes. Laisse-moi t'expliquer **EXACTEMENT** ce qui se passe en réalité.

---

## [LOGIQUE] COMPRENDRE CE QUI SE PASSE VRAIMENT

### [RESEAU] Avec le mode "Accès par pont" (Bridge)

Quand tu mets VirtualBox en mode **"Accès par pont"**, voici ce qui se passe :

```
┌─────────────────────────────────────────────────┐
│          [ACCUEIL] TON RÉSEAU LOCAL                    │
│                                                 │
│  ┌──────────┐         ┌──────────┐            │
│  │   Box    │[BLACK_LEFT-POINTING_POINTER]────────┤ Machine  │            │
│  │ (Routeur)│         │ Physique │            │
│  │          │         │          │            │
│  │ DHCP     │[BLACK_LEFT-POINTING_POINTER]────┐   └──────────┘            │
│  │ actif    │     │                            │
│  └──────────┘     │   ┌──────────┐            │
│                   └───┤    VM    │            │
│                       │  Linux   │            │
│                       └──────────┘            │
│                                                 │
│  La VM est vue comme UN APPAREIL NORMAL        │
│  (comme un PC, un téléphone, une imprimante)   │
└─────────────────────────────────────────────────┘
```

### [OK] Ce qui fonctionne AUTOMATIQUEMENT (sans config)

**1. La VM reçoit une IP automatiquement**
- Ta Box (routeur) a un serveur DHCP actif
- Dès que la VM démarre en mode pont, elle demande une IP
- La Box lui donne une IP libre (ex: `192.168.1.50`)

**2. La communication réseau fonctionne**
- La VM peut communiquer avec TOUS les appareils du réseau
- Ta machine physique peut communiquer avec la VM
- **AUCUNE configuration nécessaire** pour le **ping** simple

### [X] Ce qui NE fonctionne PAS automatiquement

**1. La résolution DNS personnalisée**
- Ta machine physique ne sait pas qu'il y a un serveur DNS sur la VM
- Elle continue d'utiliser le DNS de ta Box (ou Google DNS)
- `ping server1.local` -> **NE FONCTIONNE PAS**

**2. Les noms personnalisés ne sont pas accessibles**
- `server1.local` n'existe que dans la VM
- Ta machine physique ne le connaît pas

---

## [OUTIL] CE QU'IL FAUT FAIRE **VRAIMENT** (Guide corrigé)

Je vais te donner l'ordre EXACT, sans sauter d'étapes.

---

## [OK] ÉTAPE 0 : VÉRIFICATIONS DE BASE (À faire en PREMIER)

### [RECHERCHE] Sur ta machine physique

#### Windows :

**1. Trouver l'IP de ta machine physique**

Ouvre **Invite de commandes** (`Win + R` -> `cmd` -> Entrée)

```cmd
ipconfig
```

**Cherche cette section :**
```
Carte Ethernet Ethernet:
   Adresse IPv4. . . . . . . . . . . . . .: 192.168.1.10
   Masque de sous-réseau. . . . . . . . . : 255.255.255.0
   Passerelle par défaut. . . . . . . . . : 192.168.1.1
```

**Note ces 3 informations :**
- [EDIT] Ton IP : `192.168.1.10` (exemple)
- [EDIT] Ton masque : `255.255.255.0`
- [EDIT] Ta passerelle (Box) : `192.168.1.1`

---

#### Mac :

**1. Trouver l'IP de ta machine**

Ouvre **Terminal**

```bash
ifconfig | grep "inet " | grep -v 127.0.0.1
```

**Résultat :**
```
inet 192.168.1.10 netmask 0xffffff00 broadcast 192.168.1.255
```

**2. Trouver ta passerelle**

```bash
netstat -nr | grep default
```

**Résultat :**
```
default            192.168.1.1        UGSc           en0
```

---

#### Linux (autre machine) :

```bash
ip a
ip route | grep default
```

---

### [NOTE] RÉCAPITULATIF DE TES INFOS

Remplis ce tableau **AVANT de continuer** :

| Info | Valeur (exemple) | Ta valeur |
|------|------------------|-----------|
| IP de ta machine physique | 192.168.1.10 | ________ |
| Masque réseau | 255.255.255.0 | ________ |
| Passerelle (Box) | 192.168.1.1 | ________ |
| Plage réseau | 192.168.1.X | ________ |

---

## [OK] ÉTAPE 1 : CONFIGURATION VIRTUALBOX (déjà expliqué)

(Voir la réponse précédente - Mode "Accès par pont")

---

## [OK] ÉTAPE 2 : DÉMARRER LA VM ET VÉRIFIER

### 1⃣ Démarre ta VM Linux

### 2⃣ Vérifie son adresse IP

```bash
ip a
```

**Résultat :**
```
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>
    inet 192.168.1.50/24 brd 192.168.1.255
         ^^^^^^^^^^^^
```

### [OBJECTIF] IMPORTANT : Vérifier que c'est la bonne plage

**Si ta machine physique est sur `192.168.1.10`**
**Alors ta VM DOIT être sur `192.168.1.X`** (même plage)

**[OK] Exemples CORRECTS :**
- Machine physique : `192.168.1.10`
- VM : `192.168.1.50` -> **BON** [OK]

**[X] Exemples INCORRECTS :**
- Machine physique : `192.168.1.10`
- VM : `10.0.2.15` -> **MAUVAIS** [X] (mode NAT actif)
- VM : `192.168.56.10` -> **MAUVAIS** [X] (réseau hôte uniquement)

---

## [OK] ÉTAPE 3 : PREMIER TEST (Communication réseau simple)

### [TEST] Test 1 : VM -> Machine physique

**Sur la VM Linux**, tape :

```bash
ping 192.168.1.10 -c 4
```

**[ATTENTION] REMPLACE `192.168.1.10` par L'IP DE TA MACHINE PHYSIQUE**

**Résultat attendu :**
```
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.5 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.4 ms
64 bytes from 192.168.1.10: icmp_seq=3 ttl=64 time=0.3 ms
64 bytes from 192.168.1.10: icmp_seq=4 ttl=64 time=0.4 ms

--- 192.168.1.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss
```

**[OK] Si ça fonctionne :** PARFAIT ! La communication réseau est établie

**[X] Si ça ne fonctionne pas :**

### [HOT] DÉPANNAGE IMMÉDIAT

#### Cause 1 : Pare-feu Windows bloque les pings

**Solution sur Windows :**

1. Ouvre **Panneau de configuration**
2. **Système et sécurité** -> **Pare-feu Windows Defender**
3. **Paramètres avancés** (à gauche)
4. **Règles de trafic entrant** (à gauche)
5. Cherche : **"Partage de fichiers et d'imprimantes (Demande d'écho - ICMPv4-In)"**
6. **Clique droit** -> **Activer la règle**

**Ou en ligne de commande (Admin) :**

```cmd
netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow
```

---

#### Cause 2 : Mauvais mode réseau VirtualBox

Retourne à l'ÉTAPE 1, vérifie que c'est bien **"Accès par pont"**

---

### [TEST] Test 2 : Machine physique -> VM

**Sur ta machine physique :**

**Windows :**
```cmd
ping 192.168.1.50
```

**Mac/Linux :**
```bash
ping 192.168.1.50 -c 4
```

**[ATTENTION] REMPLACE `192.168.1.50` par L'IP DE TA VM**

**Résultat attendu :**
```
Réponse de 192.168.1.50 : octets=32 temps<1ms TTL=64
Réponse de 192.168.1.50 : octets=32 temps<1ms TTL=64
```

**[OK] Si les 2 tests fonctionnent :** La communication bidirectionnelle est OK !

**[BRAVO] TU PEUX PASSER À L'ÉTAPE 4**

---

## [OK] ÉTAPE 4 : FIXER L'IP DE LA VM (Fortement recommandé)

**Pourquoi fixer l'IP ?**

Actuellement, ta VM a reçu une IP automatiquement (DHCP).
**Problème :** Cette IP peut changer au redémarrage.

**Solution :** Lui donner une IP fixe (`192.168.1.100`)

### [LISTE] Informations nécessaires

Tu auras besoin de :
- [EDIT] IP que tu veux pour la VM : `192.168.1.100`
- [EDIT] Masque réseau : `255.255.255.0` (ou `/24`)
- [EDIT] Passerelle (Box) : `192.168.1.1`
- [EDIT] DNS pour Internet : `8.8.8.8`

**[ATTENTION] Vérifie que `192.168.1.100` est libre :**

```bash
ping 192.168.1.100 -c 4
```

**Si aucune réponse :** L'IP est libre [OK]  
**Si réponse :** Choisis une autre IP (ex: `192.168.1.101`)

---

### [OUTIL] Configuration (Netplan - Ubuntu/Debian récent)

```bash
sudo nano /etc/netplan/01-netcfg.yaml
```

**Contenu :**

```yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses:
          - 8.8.8.8
          - 8.8.4.4
```

**[ATTENTION] PERSONNALISE :**
- `192.168.1.100` -> L'IP que tu veux pour ta VM
- `192.168.1.1` -> L'IP de ta Box (trouvée à l'ÉTAPE 0)

**Appliquer :**
```bash
sudo netplan apply
```

**Vérifier :**
```bash
ip a | grep eth0
```

**Résultat attendu :**
```
inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0
```

---

## [OK] ÉTAPE 5 : VÉRIFIER QUE LE DNS FONCTIONNE SUR LA VM

**Avant de configurer ta machine physique**, assure-toi que ton serveur DNS fonctionne.

### Test depuis la VM elle-même

```bash
# Test avec DNSmasq
dig server1.local @localhost

# Test avec BIND9
dig server1.local @192.168.1.100
```

**Résultat attendu :**
```
;; ANSWER SECTION:
server1.local.    604800    IN    A    192.168.1.100
```

**[OK] Si ça fonctionne :** Ton serveur DNS est opérationnel

**[X] Si ça ne fonctionne pas :**

```bash
# Vérifier que le service tourne
sudo systemctl status dnsmasq    # ou bind9

# Vérifier le port 53
sudo netstat -tulpn | grep :53
```

---

## [OK] ÉTAPE 6 : CONFIGURER LE DNS SUR LA MACHINE PHYSIQUE

**MAINTENANT ET SEULEMENT MAINTENANT**, tu peux configurer ta machine physique.

### Sur Windows

**1. Ouvrir les paramètres réseau**

```
Win + R -> ncpa.cpl -> Entrée
```

**2. Configurer**

- Clique droit sur ta carte réseau -> **Propriétés**
- Double-clique sur **"Protocole Internet version 4 (TCP/IPv4)"**
- Sélectionne **"Utiliser l'adresse de serveur DNS suivante"**

**Remplis :**
```
Serveur DNS préféré:   192.168.1.100
Serveur DNS auxiliaire: 8.8.8.8
```

**3. Vider le cache DNS**

```cmd
ipconfig /flushdns
```

---

### Sur Mac

**1. Préférences Système -> Réseau**

**2. Sélectionne ta connexion -> Avancé**

**3. Onglet DNS**

**4. Clique sur le "+"**

Ajoute :
```
192.168.1.100
8.8.8.8
```

**5. Vider le cache**

```bash
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
```

---

## [OK] ÉTAPE 7 : TEST FINAL

### Test 1 : Avec nslookup (forcer le DNS de la VM)

```cmd
nslookup server1.local 192.168.1.100
```

**Résultat attendu :**
```
Serveur :   Unknown
Address:    192.168.1.100

Nom :    server1.local
Address:  192.168.1.100
```

[OK] **Si ça fonctionne :** Ton DNS répond correctement

---

### Test 2 : Ping avec le nom

```cmd
ping server1.local
```

**Résultat attendu :**
```
PING server1.local (192.168.1.100): 56 data bytes
64 bytes from 192.168.1.100: icmp_seq=0 ttl=64 time=0.5 ms
```

[OK] **Si ça fonctionne :** BRAVO ! Tout est opérationnel !

---

## [GRAPHIQUE] RÉCAPITULATIF COMPLET (Ordre correct)

| Étape | Action | Où ? | Requis pour passer à l'étape suivante |
|-------|--------|------|--------------------------------------|
| **0** | Noter IP machine physique, passerelle, masque | Machine physique | [OK] Tu connais ton réseau |
| **1** | Configurer VirtualBox en mode pont | VirtualBox | [OK] VM a une IP `192.168.1.X` |
| **2** | Vérifier l'IP de la VM | VM Linux | [OK] IP dans la bonne plage |
| **3** | Tester ping bidirectionnel | Les 2 | [OK] Les 2 machines communiquent |
| **4** | Fixer l'IP de la VM | VM Linux | [OK] IP stable (`192.168.1.100`) |
| **5** | Installer et configurer DNS | VM Linux | [OK] DNS répond sur la VM |
| **6** | Configurer DNS sur machine physique | Machine physique | [OK] Machine pointe vers `192.168.1.100` |
| **7** | Tester résolution DNS | Machine physique | [OK] `ping server1.local` fonctionne |

---

## [BRAVO] CONCLUSION

**Tu avais absolument raison !**

On ne peut PAS tester la communication DNS à l'étape 4 sans avoir :
1. [OK] Vérifié que les machines communiquent (ping)
2. [OK] Configuré le DNS sur la machine physique

**L'ordre correct est :**
1. Communication réseau (ping)
2. Configuration DNS sur la VM
3. **ENSUITE** configuration DNS sur la machine physique
4. **ENFIN** test de résolution DNS

Merci d'avoir posé cette excellente question ! [MERCI]


# [WEB] GUIDE COMPLET : Configurer un serveur web et y accéder via `http://web.local`

## [OBJECTIF] CE QUE TU VAS FAIRE

```
┌─────────────────────────────────────────────────┐
│  [CODE] MACHINE PHYSIQUE                            │
│                                                 │
│  Navigateur: http://web.local                   │
│              │                                  │
│              │ Requête DNS                      │
│              [BLACK_DOWN-POINTING_TRIANGLE]                                  │
│  DNS: "web.local = 192.168.1.100"              │
│              │                                  │
│              │ Connexion HTTP                   │
│              [BLACK_DOWN-POINTING_TRIANGLE]                                  │
└──────────────┼──────────────────────────────────┘
               │
               │ Réseau local
               [BLACK_DOWN-POINTING_TRIANGLE]
┌─────────────────────────────────────────────────┐
│  [LINUX] VM LINUX (192.168.1.100)                    │
│                                                 │
│  [OK] Serveur DNS (DNSmasq/BIND9)                │
│  [OK] Serveur WEB (Apache/Nginx)                 │
│  [OK] Page web accessible                        │
│                                                 │
└─────────────────────────────────────────────────┘
```

**Résultat final :** Tu tapes `http://web.local` dans ton navigateur -> La page s'affiche ! [BRAVO]

---

## [LISTE] PRÉREQUIS

Avant de commencer, assure-toi que :

- [ ] Ta VM est en mode **"Accès par pont"** (Bridge)
- [ ] Ta VM a une IP fixe (`192.168.1.100`)
- [ ] Le ping fonctionne : Machine physique <-> VM
- [ ] Ton serveur DNS (DNSmasq ou BIND9) fonctionne
- [ ] Ta machine physique utilise le DNS de la VM (`192.168.1.100`)

**Si tu n'as pas fait ces étapes, retourne à la réponse précédente ! ^**

---

## [RAPIDE] MÉTHODE 1 : AVEC APACHE (Le plus populaire)

### [PACKAGE] ÉTAPE 1 : Installation d'Apache

**Sur ta VM Linux**, ouvre un terminal :

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

**Explication :**
- `apt update` = Met à jour la liste des paquets disponibles
- `apt install apache2` = Installe le serveur web Apache
- `-y` = Répond "oui" automatiquement

**Durée :** ~1-2 minutes

---

### [OK] ÉTAPE 2 : Vérifier qu'Apache est démarré

```bash
sudo systemctl status apache2
```

**Résultat attendu :**
```
[BLACK_CIRCLE] apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled)
     Active: active (running) since...
              ^^^^^^
          C'EST BON ! [OK]
```

**Si "inactive" ou "failed" :**
```bash
sudo systemctl start apache2
sudo systemctl enable apache2
```

---

### [HOT] ÉTAPE 3 : Configurer le pare-feu (si UFW est actif)

**Vérifier si le pare-feu est actif :**
```bash
sudo ufw status
```

**Si "Status: active" :**
```bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
```

**Explication :**
- Port `80` = HTTP (web normal)
- Port `443` = HTTPS (web sécurisé)

---

### [TEST] ÉTAPE 4 : Premier test (avec l'IP)

**Sur ta machine physique**, ouvre un navigateur :

```
http://192.168.1.100
```

**[ATTENTION] REMPLACE `192.168.1.100` par l'IP de ta VM**

**Résultat attendu :**

Tu devrais voir la **page par défaut d'Apache** :

```
┌───────────────────────────────────────┐
│   Apache2 Default Page                │
│   It works!                           │
│                                       │
│   If you can see this, Apache is     │
│   working correctly.                  │
└───────────────────────────────────────┘
```

**[OK] Si tu vois cette page :** Apache fonctionne !

**[X] Si ça ne fonctionne pas :**

#### Dépannage immédiat

**1. Vérifier qu'Apache écoute sur le port 80 :**
```bash
sudo netstat -tulpn | grep :80
```

**Résultat attendu :**
```
tcp6  0  0 :::80  :::*  LISTEN  1234/apache2
```

**2. Vérifier les logs d'erreur :**
```bash
sudo tail -f /var/log/apache2/error.log
```

**3. Tester depuis la VM elle-même :**
```bash
curl localhost
```

---

## [LABEL] ÉTAPE 5 : Configurer le DNS pour `web.local`

Maintenant, on va faire en sorte que `web.local` pointe vers `192.168.1.100`.

---

### Avec DNSmasq

**Éditer le fichier hosts :**
```bash
sudo nano /etc/hosts.dnsmasq
```

**Ajouter cette ligne :**
```
192.168.1.100  web.local  web
```

**Structure complète du fichier :**
```
192.168.1.100  server1.local  server1
192.168.1.100  web.local      web
192.168.1.101  server2.local  server2
```

**[IDEE] Note :** `server1.local` et `web.local` pointent vers la **même IP** !

**Redémarrer DNSmasq :**
```bash
sudo systemctl restart dnsmasq
```

**Vérifier :**
```bash
dig web.local @localhost
```

**Résultat attendu :**
```
;; ANSWER SECTION:
web.local.    0    IN    A    192.168.1.100
```

---

### Avec BIND9

**Éditer le fichier de zone :**
```bash
sudo nano /etc/bind/db.local
```

**Ajouter cette ligne (avant la fin du fichier) :**
```
web     IN      A       192.168.1.100
```

**Structure complète :**
```
$TTL    604800
@       IN      SOA     ns1.local. admin.local. (
                              2024120601         ; Serial (INCRÉMENTER!)
                         604800
                          86400
                        2419200
                         604800 )
;
@       IN      NS      ns1.local.
ns1     IN      A       192.168.1.100
server1 IN      A       192.168.1.100
web     IN      A       192.168.1.100
server2 IN      A       192.168.1.101
```

**[ATTENTION] IMPORTANT :** Incrémenter le Serial (`2024120601` -> `2024120602`)

**Vérifier la syntaxe :**
```bash
sudo named-checkzone local /etc/bind/db.local
```

**Résultat attendu :**
```
zone local/IN: loaded serial 2024120602
OK
```

**Redémarrer BIND9 :**
```bash
sudo systemctl restart bind9
```

**Vérifier :**
```bash
dig web.local @192.168.1.100
```

---

## [TEST] ÉTAPE 6 : Tester la résolution DNS depuis la machine physique

**Sur ta machine physique :**

### Windows :
```cmd
nslookup web.local
```

### Mac/Linux :
```bash
dig web.local
```

**Résultat attendu :**
```
Name:    web.local
Address: 192.168.1.100
```

**[OK] Si ça fonctionne :** Parfait ! Le DNS résout `web.local`

**[X] Si ça ne fonctionne pas :**

```cmd
# Vider le cache DNS
ipconfig /flushdns    # Windows
sudo dscacheutil -flushcache  # Mac

# Tester en forçant le serveur DNS
nslookup web.local 192.168.1.100
```

---

## [WEB] ÉTAPE 7 : TEST FINAL - Accéder au site web

**Sur ta machine physique**, ouvre un navigateur :

```
http://web.local
```

**[BRAVO] RÉSULTAT ATTENDU :**

Tu devrais voir la **page par défaut d'Apache** !

```
┌───────────────────────────────────────┐
│   [OK] http://web.local                 │
├───────────────────────────────────────┤
│   Apache2 Default Page                │
│   It works!                           │
│                                       │
│   This is the default welcome page    │
└───────────────────────────────────────┘
```

**[OK] SI ÇA FONCTIONNE : FÉLICITATIONS !** [BRAVO]

Tu as réussi à :
- Installer un serveur web
- Configurer le DNS
- Accéder au site via un nom de domaine local

---

## [DESIGN] ÉTAPE 8 : Créer ta propre page web

Maintenant, remplaçons la page par défaut par ta propre page.

### [DOSSIER] Où sont les fichiers web ?

Apache stocke les fichiers dans :
```
/var/www/html/
```

**Voir les fichiers actuels :**
```bash
ls -la /var/www/html/
```

**Résultat :**
```
-rw-r--r-- 1 root root 10918 index.html
```

---

### [EDIT] Créer une page personnalisée

**Méthode 1 : Éditer directement**

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

**Remplacer le contenu par :**

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mon Serveur Web Local</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        .container {
            text-align: center;
            background: rgba(255, 255, 255, 0.1);
            padding: 50px;
            border-radius: 20px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
        }
        h1 {
            font-size: 3em;
            margin: 0;
        }
        p {
            font-size: 1.2em;
            margin-top: 20px;
        }
        .info {
            margin-top: 30px;
            background: rgba(255, 255, 255, 0.2);
            padding: 20px;
            border-radius: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>[BRAVO] Ça fonctionne !</h1>
        <p>Bienvenue sur mon serveur web local</p>
        <div class="info">
            <p><strong>Serveur:</strong> Apache sur Ubuntu</p>
            <p><strong>DNS:</strong> web.local</p>
            <p><strong>IP:</strong> 192.168.1.100</p>
        </div>
    </div>
</body>
</html>
```

**Sauvegarder :** `Ctrl + O` -> `Entrée` -> `Ctrl + X`

---

**Méthode 2 : Créer un fichier séparé**

```bash
# Sauvegarder l'ancien fichier
sudo mv /var/www/html/index.html /var/www/html/index.html.backup

# Créer le nouveau
sudo nano /var/www/html/index.html
```

(Coller le contenu HTML ci-dessus)

---

### [SYNC] Actualiser le navigateur

Retourne dans ton navigateur et actualise (`F5` ou `Ctrl + R`) :

```
http://web.local
```

**[DESIGN] Tu devrais voir ta nouvelle page avec un fond violet et un design moderne !**

---

## [RAPIDE] BONUS : Créer plusieurs pages

### [FICHIER] Créer une page "À propos"

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

**Contenu :**

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>À propos</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background: #1a1a2e;
            color: white;
            padding: 50px;
        }
        h1 { color: #16db93; }
        a { color: #16db93; text-decoration: none; }
    </style>
</head>
<body>
    <h1>À propos de ce serveur</h1>
    <p>Ceci est un serveur web local configuré avec Apache sur une VM Ubuntu.</p>
    <p><a href="index.html"><- Retour à l'accueil</a></p>
</body>
</html>
```

**Accéder à cette page :**
```
http://web.local/about.html
```

---

## [OUTIL] MÉTHODE 2 : AVEC NGINX (Alternative moderne)

Si tu préfères Nginx (plus rapide et léger) :

### [PACKAGE] Installation

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

### [OK] Vérifier le statut

```bash
sudo systemctl status nginx
```

### [HOT] Configurer le pare-feu

```bash
sudo ufw allow 'Nginx HTTP'
```

### [DOSSIER] Fichiers web

Nginx utilise le même répertoire :
```
/var/www/html/
```

**Tout le reste est identique à Apache !**

---

## [GRAPHIQUE] COMPARAISON Apache vs Nginx

| Critère | Apache | Nginx |
|---------|--------|-------|
| **Popularité** | ***** | **** |
| **Facilité** | **** Facile | *** Moyen |
| **Performance** | *** Bon | ***** Excellent |
| **Ressources** | Moyen | Léger |
| **Configuration** | `.htaccess` possible | Config centralisée |
| **Meilleur pour** | Débutants, CMS | Sites modernes, proxy |

**Recommandation pour débuter :** Apache (plus de documentation, plus simple)

---

## 🆘 DÉPANNAGE COMPLET

### [X] "Ce site est inaccessible" dans le navigateur

**Causes possibles :**

1. **Le DNS ne résout pas `web.local`**

**Test :**
```bash
nslookup web.local
```

**Si erreur "can't find web.local" :**
- Retourne à l'ÉTAPE 5 (Configuration DNS)
- Vérifie que ta machine physique utilise bien `192.168.1.100` comme DNS

---

2. **Apache/Nginx n'est pas démarré**

**Test :**
```bash
sudo systemctl status apache2
```

**Si "inactive" :**
```bash
sudo systemctl start apache2
sudo systemctl enable apache2
```

---

3. **Le pare-feu bloque le port 80**

**Sur la VM :**
```bash
sudo ufw status
sudo ufw allow 80/tcp
```

**Sur Windows (machine physique) :**
- Désactive temporairement le pare-feu pour tester
- Panneau de configuration -> Pare-feu Windows -> Désactiver

---

4. **Mauvaise IP dans le DNS**

**Vérifier :**
```bash
dig web.local @192.168.1.100
```

**Doit afficher :**
```
web.local.    0    IN    A    192.168.1.100
```

---

### [X] La page s'affiche avec l'IP mais pas avec `web.local`

**Cause :** Problème de DNS uniquement

**Solution :**

**1. Vérifier que ta machine physique utilise le bon DNS**

**Windows :**
```cmd
ipconfig /all
```

Cherche :
```
Serveurs DNS. . . . . . . . . . . . : 192.168.1.100
```

**Si ce n'est pas le cas :**
- Retourne à la configuration DNS de ta carte réseau
- Vérifie que `192.168.1.100` est en **premier**

**2. Vider le cache DNS**

```cmd
ipconfig /flushdns
```

**3. Tester en forçant le DNS**

```cmd
nslookup web.local 192.168.1.100
```

**Si ça fonctionne avec cette commande mais pas dans le navigateur :**
- Redémarre ton navigateur
- Essaye en navigation privée (`Ctrl + Shift + N`)

---

### [X] "403 Forbidden" dans le navigateur

**Cause :** Problème de permissions

**Solution :**

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

# Corriger si nécessaire
sudo chmod 755 /var/www/html
sudo chmod 644 /var/www/html/index.html
sudo chown -R www-data:www-data /var/www/html
```

---

### [X] "404 Not Found" pour une page

**Cause :** Le fichier n'existe pas ou mauvais nom

**Vérifier :**
```bash
ls -la /var/www/html/
```

**Exemple :**
- URL : `http://web.local/about.html`
- Fichier doit être : `/var/www/html/about.html`

---

## [COURS] COMMANDES UTILES À RETENIR

### Gestion Apache

```bash
# Démarrer
sudo systemctl start apache2

# Arrêter
sudo systemctl stop apache2

# Redémarrer
sudo systemctl restart apache2

# Voir le statut
sudo systemctl status apache2

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

---

### Gestion Nginx

```bash
# Démarrer
sudo systemctl start nginx

# Arrêter
sudo systemctl stop nginx

# Redémarrer
sudo systemctl restart nginx

# Recharger config (sans interrompre)
sudo nginx -s reload

# Tester la config
sudo nginx -t
```

---

### Gestion des fichiers web

```bash
# Aller dans le répertoire web
cd /var/www/html/

# Lister les fichiers
ls -la

# Éditer la page principale
sudo nano index.html

# Voir les permissions
ls -l

# Donner les bonnes permissions
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
sudo chmod 644 /var/www/html/*.html
```

---

## [BRAVO] CHECKLIST FINALE

- [ ] Apache/Nginx installé et démarré
- [ ] Page par défaut accessible via `http://192.168.1.100`
- [ ] DNS configuré (`web.local` -> `192.168.1.100`)
- [ ] Résolution DNS fonctionne (`nslookup web.local`)
- [ ] Site accessible via `http://web.local`
- [ ] Page personnalisée créée et affichée
- [ ] Pare-feu configuré (port 80 ouvert)

---

## [RAPIDE] PROCHAINES ÉTAPES POSSIBLES

### 1⃣ Installer PHP (pour sites dynamiques)

```bash
sudo apt install php libapache2-mod-php -y
sudo systemctl restart apache2
```

**Tester PHP :**
```bash
echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php
```

Accède à : `http://web.local/info.php`

---

### 2⃣ Installer un CMS (WordPress, etc.)

```bash
# Installer MySQL
sudo apt install mysql-server -y

# Installer phpmyadmin
sudo apt install phpmyadmin -y
```

---

### 3⃣ Configurer HTTPS (SSL)

```bash
# Créer un certificat auto-signé
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/web.local.key \
  -out /etc/ssl/certs/web.local.crt
```

---

### 4⃣ Créer plusieurs sites (Virtual Hosts)

```bash
# Créer un nouveau site
sudo mkdir -p /var/www/site2
sudo nano /etc/apache2/sites-available/site2.conf
```

---

## [GUIDE] RÉSUMÉ POUR RETENIR

**Ce que tu as appris :**

1. [OK] Installer un serveur web (Apache/Nginx)
2. [OK] Configurer le DNS pour un nom de domaine local
3. [OK] Créer et personnaliser des pages HTML
4. [OK] Gérer les services système avec `systemctl`
5. [OK] Dépanner les problèmes de connexion

**Architecture complète :**
```
Navigateur -> DNS (web.local) -> Serveur Web -> Page HTML
```

**Félicitations ! Tu as maintenant un serveur web local fonctionnel ! [BRAVO]**

# [OBJECTIF] EXCELLENTE QUESTION ! OUI, absolument !

## [OK] RÉPONSE COURTE

**OUI !** Juste après `sudo apt install apache2 -y`, **SANS toucher AUCUN fichier de configuration**, tu peux directement accéder à `http://192.168.1.100` depuis ta machine physique et voir la page par défaut d'Apache.

---

## [LOGIQUE] POURQUOI ÇA FONCTIONNE AUTOMATIQUEMENT ?

### [PACKAGE] Ce que fait `apt install apache2` automatiquement :

```
┌─────────────────────────────────────────────┐
│  apt install apache2                        │
└─────────────────┬───────────────────────────┘
                  │
                  ├─[BLACK_RIGHT-POINTING_POINTER] 1. Télécharge Apache
                  │
                  ├─[BLACK_RIGHT-POINTING_POINTER] 2. Installe Apache
                  │
                  ├─[BLACK_RIGHT-POINTING_POINTER] 3. Crée la configuration par défaut
                  │      /etc/apache2/apache2.conf
                  │      /etc/apache2/sites-available/000-default.conf
                  │
                  ├─[BLACK_RIGHT-POINTING_POINTER] 4. Crée la page par défaut
                  │      /var/www/html/index.html
                  │
                  ├─[BLACK_RIGHT-POINTING_POINTER] 5. DÉMARRE Apache automatiquement
                  │      (systemctl start apache2)
                  │
                  ├─[BLACK_RIGHT-POINTING_POINTER] 6. Active le démarrage au boot
                  │      (systemctl enable apache2)
                  │
                  └─[BLACK_RIGHT-POINTING_POINTER] 7. Configure Apache pour écouter sur :
                         - Port 80 (HTTP)
                         - Toutes les interfaces (0.0.0.0)
```

---

## [RECHERCHE] VÉRIFICATION ÉTAPE PAR ÉTAPE

### Test 1 : Apache est-il démarré ?

```bash
sudo systemctl status apache2
```

**Résultat attendu (juste après installation) :**

```
[BLACK_CIRCLE] apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2024-12-06 10:30:15 UTC; 2min ago
              ^^^^^^ ^^^^^^^
              DÉJÀ ACTIF ! [OK]
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 1234 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
   Main PID: 1235 (apache2)
      Tasks: 55 (limit: 2339)
     Memory: 5.2M
        CPU: 50ms
     CGroup: /system.slice/apache2.service
             ├─1235 /usr/sbin/apache2 -k start
             ├─1236 /usr/sbin/apache2 -k start
             └─1237 /usr/sbin/apache2 -k start
```

**[IDEE] Conclusion :** Apache est **déjà démarré** et **activé au boot** !

---

### Test 2 : Apache écoute-t-il sur le port 80 ?

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

**Résultat attendu :**

```
tcp6  0  0 :::80  :::*  LISTEN  1235/apache2
         ^^^
    ÉCOUTE SUR LE PORT 80 [OK]
```

**Explication :**
- `:::80` = Écoute sur **toutes les interfaces IPv6 ET IPv4**
- `LISTEN` = En attente de connexions
- `apache2` = C'est bien Apache qui écoute

---

### Test 3 : La page par défaut existe-t-elle ?

```bash
ls -la /var/www/html/
```

**Résultat attendu :**

```
total 12
drwxr-xr-x 2 root root 4096 Dec  6 10:30 .
drwxr-xr-x 3 root root 4096 Dec  6 10:30 ..
-rw-r--r-- 1 root root 10918 Dec  6 10:30 index.html
                                          ^^^^^^^^^^
                             FICHIER DÉJÀ CRÉÉ ! [OK]
```

**Voir le contenu :**

```bash
cat /var/www/html/index.html
```

**Extrait du contenu :**

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Apache2 Ubuntu Default Page: It works</title>
    ...
  </head>
  <body>
    <div class="main_page">
      <div class="page_header floating_element">
        <img src="/icons/ubuntu-logo.png" alt="Ubuntu Logo" />
      </div>
      <div class="content_section floating_element">
        <div class="section_header section_header_red">
          <div id="about"></div>
          It works!
        </div>
        <div class="content_section_text">
          <p>
            This is the default welcome page used to test the correct 
            operation of the Apache2 server after installation on Ubuntu systems.
          </p>
          ...
        </div>
      </div>
    </div>
  </body>
</html>
```

**[IDEE] Conclusion :** La page HTML par défaut est **déjà présente** !

---

### Test 4 : Apache répond-il localement (sur la VM) ?

**Sur la VM**, teste avec `curl` :

```bash
curl localhost
```

**ou**

```bash
curl 127.0.0.1
```

**Résultat attendu :**

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...>
<html xmlns="http://www.w3.org/1999/xhtml">
  ...
  It works!
  ...
</html>
```

**[IDEE] Conclusion :** Apache répond **localement** sur la VM ! [OK]

---

### Test 5 : Apache répond-il sur l'IP réseau ?

**Toujours sur la VM**, teste avec ton IP :

```bash
curl 192.168.1.100
```

**Résultat attendu :**

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...>
  ...
  It works!
  ...
</html>
```

**[IDEE] Conclusion :** Apache répond aussi sur l'**IP réseau** ! [OK]

---

## [WEB] TEST FINAL : Depuis ta machine physique

### Sur Windows

**Ouvre un navigateur (Chrome, Firefox, Edge, etc.)**

```
http://192.168.1.100
```

**OU teste en ligne de commande :**

```cmd
curl http://192.168.1.100
```

**Si `curl` n'existe pas sur Windows :**

```powershell
Invoke-WebRequest -Uri http://192.168.1.100
```

---

### Sur Mac/Linux

**Dans le navigateur :**

```
http://192.168.1.100
```

**En ligne de commande :**

```bash
curl http://192.168.1.100
```

---

## [OBJECTIF] RÉSULTAT ATTENDU DANS LE NAVIGATEUR

```
┌───────────────────────────────────────────────────┐
│  [WEB] http://192.168.1.100                          │
├───────────────────────────────────────────────────┤
│                                                   │
│   [Ubuntu Logo]                                   │
│                                                   │
│   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.           │
│                                                   │
│   If you can read this page, it means that the    │
│   Apache HTTP server installed at this site is    │
│   working properly.                               │
│                                                   │
│   Configuration Overview                          │
│   ────────────────────                           │
│                                                   │
│   Ubuntu's Apache2 default configuration is       │
│   different from the upstream default...          │
│                                                   │
└───────────────────────────────────────────────────┘
```

**[OK] Si tu vois cette page : C'EST BON !**

---

## [INTERDIT] SEULE EXCEPTION : Le pare-feu

### [ATTENTION] Si le pare-feu UFW est actif

**Vérifier :**

```bash
sudo ufw status
```

**Si "Status: active" :**

```
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
```

**[X] Problème :** Le port 80 n'est **PAS autorisé**

**Solution :**

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

**Résultat :**

```
Rule added
Rule added (v6)
```

**Vérifier à nouveau :**

```bash
sudo ufw status
```

**Maintenant :**

```
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere    <- AJOUTÉ [OK]
```

**Retester depuis ta machine physique :**

```
http://192.168.1.100
```

**[OK] Devrait fonctionner maintenant !**

---

## [GRAPHIQUE] RÉCAPITULATIF : Que se passe-t-il automatiquement ?

| Étape | Action | Automatique ? | Fichier/Service concerné |
|-------|--------|--------------|--------------------------|
| **1** | Installation des binaires Apache | [OK] OUI | `/usr/sbin/apache2` |
| **2** | Création de la configuration par défaut | [OK] OUI | `/etc/apache2/apache2.conf` |
| **3** | Activation du site par défaut | [OK] OUI | `/etc/apache2/sites-enabled/000-default.conf` |
| **4** | Création du répertoire web | [OK] OUI | `/var/www/html/` |
| **5** | Création de la page par défaut | [OK] OUI | `/var/www/html/index.html` |
| **6** | Démarrage du service | [OK] OUI | `systemctl start apache2` |
| **7** | Activation au boot | [OK] OUI | `systemctl enable apache2` |
| **8** | Écoute sur port 80 | [OK] OUI | Configuration par défaut |
| **9** | Écoute sur toutes les interfaces | [OK] OUI | `Listen 0.0.0.0:80` |
| **10** | Autorisation pare-feu | [X] **MANUEL** | `ufw allow 80/tcp` |

---

## [COURS] CONCLUSION

### [OK] OUI, tu peux accéder à `http://192.168.1.100` IMMÉDIATEMENT après installation

**Conditions :**
1. [OK] Ta VM a l'IP `192.168.1.100`
2. [OK] Ta VM et ta machine physique sont sur le même réseau (mode pont)
3. [OK] Le pare-feu UFW est désactivé OU le port 80 est autorisé

**SANS toucher :**
- [X] Aucun fichier de configuration Apache
- [X] Aucun fichier HTML
- [X] Aucun Virtual Host
- [X] Aucun module Apache

**Tout est déjà configuré et opérationnel par défaut !** [BRAVO]

---

## 🆘 SI ÇA NE FONCTIONNE PAS

### Checklist de dépannage

```bash
# 1. Apache est-il installé ?
dpkg -l | grep apache2

# 2. Apache est-il démarré ?
sudo systemctl status apache2

# 3. Apache écoute-t-il sur le port 80 ?
sudo netstat -tulpn | grep :80

# 4. La page existe-t-elle ?
ls -la /var/www/html/index.html

# 5. Pare-feu actif ?
sudo ufw status

# 6. Test local (sur la VM)
curl localhost

# 7. Test avec l'IP (sur la VM)
curl 192.168.1.100

# 8. Ping depuis la machine physique
ping 192.168.1.100

# 9. Test HTTP depuis la machine physique
curl http://192.168.1.100
```

**Si tous ces tests passent SAUF le dernier :**
- Problème de pare-feu sur la machine physique (Windows Defender)
- Problème de proxy/VPN

---

**[BRAVO] Voilà ! Maintenant tu sais EXACTEMENT pourquoi ça fonctionne immédiatement après installation !**


# [OBJECTIF] EXCELLENTE QUESTION TECHNIQUE !

## [OK] RÉPONSE DIRECTE

**Apache le fait AUTOMATIQUEMENT !** [BRAVO]

Tu n'as **RIEN à configurer manuellement**. Après `sudo apt install apache2`, Apache est déjà configuré pour écouter sur le port 80 et sur toutes les interfaces.

---

## [RECHERCHE] PREUVE : Regardons la configuration par défaut

### [FICHIER] Fichier 1 : `/etc/apache2/ports.conf`

Ce fichier est **créé automatiquement** lors de l'installation.

**Voir le contenu :**

```bash
cat /etc/apache2/ports.conf
```

**Contenu par défaut (SANS modification) :**

```apache
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 80
  ^^^^^^^
  DÉJÀ CONFIGURÉ AUTOMATIQUEMENT ! [OK]

<IfModule ssl_module>
        Listen 443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 443
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
```

**Explication :**

- `Listen 80` = **Écoute sur le port 80**
- Sans IP spécifiée = **Écoute sur TOUTES les interfaces** (équivalent à `0.0.0.0:80`)

---

### [FICHIER] Fichier 2 : `/etc/apache2/sites-available/000-default.conf`

Ce fichier définit le **Virtual Host par défaut**.

**Voir le contenu :**

```bash
cat /etc/apache2/sites-available/000-default.conf
```

**Contenu par défaut (SANS modification) :**

```apache
<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
                     ^^^^^^^^^^^^^
                     RÉPERTOIRE WEB PAR DÉFAUT [OK]

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
```

**Explication :**

- `<VirtualHost *:80>` = **Accepte les connexions sur toutes les interfaces (`*`) sur le port 80**
- `DocumentRoot /var/www/html` = **Répertoire où se trouvent les fichiers web**

---

## [TEST] VÉRIFICATION PRATIQUE

### Test 1 : Vérifier que Apache écoute sur le port 80

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

**Résultat (juste après installation, SANS config manuelle) :**

```
tcp6  0  0 :::80  :::*  LISTEN  1234/apache2
         ^^^^^
    PORT 80 [OK]
```

**Explication de `:::80` :**

- `::` = Adresse IPv6 "toutes les interfaces" (équivalent IPv6 de `0.0.0.0`)
- `:80` = Port 80
- Sur Linux, écouter sur `:::80` (IPv6) **inclut automatiquement IPv4** grâce à `IPV6_V6ONLY=0`

**Cela signifie qu'Apache écoute sur :**
- [OK] `0.0.0.0:80` (toutes interfaces IPv4)
- [OK] `[::]:80` (toutes interfaces IPv6)
- [OK] `127.0.0.1:80` (localhost IPv4)
- [OK] `192.168.1.100:80` (ton IP réseau)
- [OK] `[::1]:80` (localhost IPv6)

---

### Test 2 : Vérifier avec `ss` (alternative moderne à netstat)

```bash
sudo ss -tlnp | grep :80
```

**Résultat :**

```
LISTEN  0  511  *:80  *:*  users:(("apache2",pid=1234,fd=4))
            ^^^  ^^^
         PORT 80  TOUTES INTERFACES [OK]
```

---

### Test 3 : Vérifier avec `lsof`

```bash
sudo lsof -i :80
```

**Résultat :**

```
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
apache2  1234     root    4u  IPv6  12345      0t0  TCP *:http (LISTEN)
apache2  1235 www-data    4u  IPv6  12345      0t0  TCP *:http (LISTEN)
apache2  1236 www-data    4u  IPv6  12345      0t0  TCP *:http (LISTEN)
                                                       ^^^^^^^^^^
                                               *:http = 0.0.0.0:80 [OK]
```

---

## [DESIGN] SCHÉMA : Que signifie "écouter sur 0.0.0.0:80" ?

```
┌─────────────────────────────────────────────────┐
│           [ECRAN] VM LINUX (Apache)                  │
│                                                 │
│  Apache écoute sur 0.0.0.0:80                   │
│  (= toutes les interfaces)                      │
│                                                 │
│  ┌─────────────┐                                │
│  │   lo        │  127.0.0.1:80    <- Localhost   │
│  │  (loopback) │  [::1]:80                      │
│  └─────────────┘                                │
│         [BLACK_UP-POINTING_TRIANGLE]                                       │
│         │ Requêtes depuis la VM elle-même       │
│         │ (curl localhost)                      │
│                                                 │
│  ┌─────────────┐                                │
│  │   eth0      │  192.168.1.100:80 <- Réseau     │
│  │  (réseau)   │                                │
│  └─────────────┘                                │
│         [BLACK_UP-POINTING_TRIANGLE]                                       │
│         │ Requêtes depuis d'autres machines     │
│         │ (ta machine physique)                 │
│                                                 │
└─────────┼───────────────────────────────────────┘
          │
          │ Réseau local (192.168.1.0/24)
          │
          [BLACK_DOWN-POINTING_TRIANGLE]
┌─────────────────────────────────────────────────┐
│      [CODE] MACHINE PHYSIQUE                        │
│      (192.168.1.10)                             │
│                                                 │
│  Navigateur: http://192.168.1.100              │
│              ─────────────────────[BLACK_RIGHT-POINTING_POINTER]             │
│              Requête reçue par eth0:80 [OK]       │
└─────────────────────────────────────────────────┘
```

---

## [FACE_WITH_MONOCLE] COMPRENDRE : Pourquoi `0.0.0.0` et pas une IP spécifique ?

### Option 1 : Écouter sur une IP spécifique (RESTRICTIF)

**Si Apache était configuré comme ça :**

```apache
Listen 127.0.0.1:80
```

**Conséquence :**
- [OK] `curl localhost` -> **FONCTIONNE**
- [X] `curl 192.168.1.100` -> **NE FONCTIONNE PAS**
- [X] Depuis ta machine physique -> **NE FONCTIONNE PAS**

**Analogie :** C'est comme une maison qui n'a qu'une porte donnant sur le jardin intérieur. Les visiteurs de la rue ne peuvent pas entrer.

---

### Option 2 : Écouter sur toutes les interfaces (PERMISSIF) <- **C'EST ÇA PAR DÉFAUT**

**Configuration par défaut d'Apache :**

```apache
Listen 80
```

**ou explicitement :**

```apache
Listen 0.0.0.0:80
```

**Conséquence :**
- [OK] `curl localhost` -> **FONCTIONNE**
- [OK] `curl 127.0.0.1` -> **FONCTIONNE**
- [OK] `curl 192.168.1.100` -> **FONCTIONNE**
- [OK] Depuis ta machine physique -> **FONCTIONNE**
- [OK] Depuis n'importe quelle machine du réseau -> **FONCTIONNE**

**Analogie :** C'est comme une maison avec plusieurs portes : une sur rue, une sur jardin, une sur cour. Tout le monde peut entrer.

---

## [DOCS] COMPARAISON : Configurations possibles

| Configuration | Qui peut accéder ? | Cas d'usage |
|--------------|-------------------|-------------|
| `Listen 127.0.0.1:80` | [OK] Localhost uniquement<br>[X] Réseau | Développement local strict |
| `Listen 192.168.1.100:80` | [OK] Localhost<br>[OK] Réseau via cette IP<br>[X] Autres IPs de la VM | Serveur avec IP fixe |
| `Listen 80`<br>(= `0.0.0.0:80`) | [OK] Localhost<br>[OK] Toutes les IPs de la VM<br>[OK] Réseau | **DÉFAUT - Maximum de flexibilité** [OK] |

---

## [OUTIL] SI TU VOULAIS RESTREINDRE (optionnel, pas recommandé pour débuter)

### Exemple : Écouter uniquement sur l'IP réseau

**Éditer :**

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

**Modifier :**

```apache
# Avant (par défaut)
Listen 80

# Après (restrictif)
Listen 192.168.1.100:80
```

**Redémarrer :**

```bash
sudo systemctl restart apache2
```

**Conséquence :**
- [OK] `http://192.168.1.100` depuis ta machine physique -> **FONCTIONNE**
- [X] `curl localhost` sur la VM -> **NE FONCTIONNE PLUS**

**[ATTENTION] Pas recommandé pour débuter !**

---

## [COURS] RÉPONSE FINALE À TA QUESTION

### [?] "Doit-on configurer manuellement ou Apache le fait automatiquement ?"

```
┌────────────────────────────────────────────────┐
│  [PACKAGE] sudo apt install apache2                   │
└────────────────┬───────────────────────────────┘
                 │
                 [BLACK_DOWN-POINTING_TRIANGLE]
┌────────────────────────────────────────────────┐
│  [OK] AUTOMATIQUE (créé par l'installation)      │
├────────────────────────────────────────────────┤
│                                                │
│  1. Crée /etc/apache2/ports.conf               │
│     Contenu: Listen 80                         │
│                                                │
│  2. Crée /etc/apache2/sites-available/...     │
│     Contenu: <VirtualHost *:80>                │
│                                                │
│  3. Active le site par défaut                  │
│                                                │
│  4. Démarre Apache                             │
│                                                │
│  Résultat: Apache écoute sur 0.0.0.0:80 [OK]     │
│                                                │
└────────────────────────────────────────────────┘
                 │
                 [BLACK_DOWN-POINTING_TRIANGLE]
┌────────────────────────────────────────────────┐
│  [X] AUCUNE CONFIGURATION MANUELLE NÉCESSAIRE   │
└────────────────────────────────────────────────┘
```

---

## [GRAPHIQUE] RÉCAPITULATIF

| Question | Réponse |
|----------|---------|
| Apache écoute-t-il automatiquement sur le port 80 ? | [OK] **OUI** |
| Apache écoute-t-il automatiquement sur toutes les interfaces ? | [OK] **OUI** (`0.0.0.0` par défaut) |
| Dois-je éditer `/etc/apache2/ports.conf` ? | [X] **NON** (déjà configuré) |
| Dois-je créer un Virtual Host ? | [X] **NON** (000-default.conf existe déjà) |
| Dois-je redémarrer Apache après installation ? | [X] **NON** (déjà démarré automatiquement) |
| Puis-je accéder à `http://192.168.1.100` immédiatement ? | [OK] **OUI** (si pare-feu OK) |

---

## [BRAVO] CONCLUSION

**Apache configure TOUT automatiquement :**

1. [OK] Écoute sur le **port 80**
2. [OK] Écoute sur **toutes les interfaces** (`0.0.0.0`)
3. [OK] Crée un **Virtual Host par défaut**
4. [OK] Crée la **page par défaut** (`index.html`)
5. [OK] **Démarre le service**
6. [OK] **Active au boot**

**TU N'AS RIEN À FAIRE !** [BRAVO]

La seule chose à vérifier : le pare-feu (`sudo ufw allow 80/tcp` si nécessaire).


# Fichier: python_cheats/cheatsheets/configuration.txt (SUITE 2)

```
[OK] GESTION DES PROCESSUS & PERFORMANCES

# === QU'EST-CE QU'UN PROCESSUS? ===

# Processus = Programme en cours d'exécution
# Chaque app lancée = un ou plusieurs processus
# Exemples:
# - Navigateur web = processus
# - Serveur Nginx = processus
# - Script Python = processus

# === ÉTAPE 1: VOIR LES PROCESSUS ===

# Liste complète des processus:
ps aux

# Affiche:
# USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
# root         1  0.0  0.1 169564 13140 ?        Ss   Jan15   0:05 /sbin/init
# john      1234  2.5  1.2 456789 98765 ?        Sl   10:00   0:15 python app.py
# www-data  5678  0.1  0.5 123456 45678 ?        S    09:00   0:02 nginx: worker

# Explications des colonnes:
# USER: Utilisateur qui a lancé le processus
# PID: Process ID (numéro unique)
# %CPU: Utilisation CPU
# %MEM: Utilisation mémoire
# VSZ: Mémoire virtuelle (en Ko)
# RSS: Mémoire résidente (RAM réelle utilisée)
# TTY: Terminal (? = pas de terminal)
# STAT: État du processus
#   S: Sleeping (en attente)
#   R: Running (en cours)
#   Z: Zombie (terminé mais pas nettoyé)
#   D: Uninterruptible sleep (attente I/O)
#   T: Stopped (arrêté)
# START: Heure de démarrage
# TIME: Temps CPU cumulé
# COMMAND: Commande exécutée

# Voir seulement vos processus:
ps u

# Voir les processus en arborescence:
ps auxf

# ou:
pstree

# Affiche:
# systemd─┬─accounts-daemon───2*[{accounts-daemon}]
#         ├─cron
#         ├─dbus-daemon
#         ├─nginx───4*[nginx]
#         ├─sshd───sshd───sshd───bash───pstree

# Voir les processus d'un utilisateur:
ps -u john

# Chercher un processus par nom:
ps aux | grep nginx

# Affiche:
# root      1234  0.0  0.1 123456  7890 ?  Ss   09:00   0:00 nginx: master
# www-data  5678  0.0  0.2 123456  9876 ?  S    09:00   0:00 nginx: worker


# === ÉTAPE 2: COMMANDE TOP (MONITORING TEMPS RÉEL) ===

# Lancer top:
top

# Affiche (mis à jour toutes les 3 secondes):
# top - 10:30:00 up 5 days, 14:23,  2 users,  load average: 0.15, 0.20, 0.18
# Tasks: 120 total,   1 running, 119 sleeping,   0 stopped,   0 zombie
# %Cpu(s):  5.2 us,  2.1 sy,  0.0 ni, 92.5 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
# MiB Mem :   1987.7 total,    256.3 free,    830.2 used,    901.2 buff/cache
# MiB Swap:   1024.0 total,   1024.0 free,      0.0 used.    987.4 avail Mem

# Explications ligne load average:
# load average: 0.15, 0.20, 0.18
# = Charge système sur 1 min, 5 min, 15 min
# Valeur idéale < nombre de CPUs
# Si 4 CPUs: load < 4.00 = OK

# Explications ligne CPU:
# us: user space (programmes utilisateur)
# sy: system (kernel)
# ni: nice (processus avec priorité modifiée)
# id: idle (CPU inactif)
# wa: wait (attente I/O disque)
# hi: hardware interrupts
# si: software interrupts
# st: steal (VM, temps volé par l'hyperviseur)

# Commandes dans top:
# M: Trier par mémoire
# P: Trier par CPU
# k: Kill un processus (demande le PID)
# r: Renice (changer la priorité)
# 1: Afficher tous les CPUs individuellement
# h: Aide
# q: Quitter

# Options au lancement:
top -d 1        # Mise à jour toutes les 1 seconde
top -u john     # Seulement les processus de john
top -p 1234     # Seulement le processus PID 1234


# === ÉTAPE 3: HTOP (VERSION AMÉLIORÉE) ===

# Installer:
sudo apt install htop

# Lancer:
htop

# Avantages de htop:
# - Interface colorée et graphique
# - Barres de progression pour CPU/RAM
# - Défilement horizontal et vertical
# - Recherche facile
# - Kill/Nice avec souris

# Raccourcis clavier:
# F1: Aide
# F2: Setup (configuration)
# F3: Recherche
# F4: Filtre
# F5: Arborescence
# F6: Trier
# F9: Kill
# F10: Quitter
# Space: Tag/Untag un processus
# U: Filtrer par utilisateur
# t: Arborescence on/off
# H: Cacher/Afficher les threads


# === ÉTAPE 4: TUER UN PROCESSUS ===

# Tuer par PID:
kill 1234

# Tuer avec force (si ne répond pas):
kill -9 1234

# Explications des signaux:
# kill = envoyer un signal
# Par défaut: SIGTERM (15) = demande gentille d'arrêt
# -9 = SIGKILL = tuer immédiatement (brutal!)

# Autres signaux utiles:
# -1 (SIGHUP): Recharger la config
# -15 (SIGTERM): Arrêt normal (défaut)
# -9 (SIGKILL): Tuer de force
# -STOP: Suspendre
# -CONT: Reprendre

# Exemples:
kill -HUP 1234      # Recharger la config
kill -TERM 1234     # Arrêt normal
kill -KILL 1234     # Tuer de force

# Tuer par nom:
killall nginx

# Tuer tous les processus d'un utilisateur:
killall -u john

# Tuer avec force:
killall -9 python

# Tuer avec pattern (plus flexible):
pkill -f "python app.py"

# Explications:
# pkill: Kill par pattern
# -f: Chercher dans la ligne de commande complète

# Exemples:
pkill -u john           # Tous les processus de john
pkill -9 nginx          # Tuer nginx avec force
pkill -HUP php-fpm      # Recharger PHP-FPM


# === ÉTAPE 5: PRIORITÉ DES PROCESSUS (NICE) ===

# Nice = Priorité d'un processus
# Valeurs: -20 (priorité maximale) à 19 (priorité minimale)
# Défaut: 0

# Lancer avec une priorité basse:
nice -n 10 command

# Exemple:
nice -n 15 tar -czvf backup.tar.gz /var/www

# Explications:
# -n 15: Nice value de 15 (priorité basse)
# Le backup n'impactera pas les autres processus

# Changer la priorité d'un processus en cours:
renice -n 10 -p 1234

# Explications:
# -n 10: Nouvelle priorité
# -p 1234: PID du processus

# Changer pour tous les processus d'un utilisateur:
renice -n 10 -u john

# Voir la priorité:
ps -eo pid,nice,comm

# Affiche:
#   PID  NI COMMAND
#     1   0 systemd
#  1234  10 python
#  5678   0 nginx


# === ÉTAPE 6: PROCESSUS EN ARRIÈRE-PLAN ===

# Lancer en arrière-plan:
command &

# Exemple:
python app.py &

# Affiche:
# [1] 12345

# Explications:
# [1]: Job number
# 12345: PID

# Voir les jobs en arrière-plan:
jobs

# Affiche:
# [1]+  Running                 python app.py &

# Ramener en avant-plan:
fg %1

# Explications:
# fg: Foreground
# %1: Job number 1

# Envoyer en arrière-plan:
# Ctrl+Z (suspend)
bg %1

# Détacher un processus du terminal (nohup):
nohup python app.py &

# Explications:
# nohup: No hangup
# Le processus continue même si tu fermes le terminal
# Sortie redirigée vers nohup.out

# Voir la sortie:
tail -f nohup.out


# === ÉTAPE 7: SCREEN & TMUX (SESSIONS PERSISTANTES) ===

# === SCREEN ===

# Installer:
sudo apt install screen

# Créer une session:
screen

# Créer avec un nom:
screen -S mysession

# Détacher de la session:
# Ctrl+A puis D

# Lister les sessions:
screen -ls

# Affiche:
# There is a screen on:
#     12345.mysession    (01/15/24 10:00:00)    (Detached)

# Rattacher à une session:
screen -r mysession

# Tuer une session:
screen -X -S mysession quit

# Commandes dans screen:
# Ctrl+A puis C: Nouvelle fenêtre
# Ctrl+A puis N: Fenêtre suivante
# Ctrl+A puis P: Fenêtre précédente
# Ctrl+A puis K: Tuer la fenêtre
# Ctrl+A puis ": Liste des fenêtres


# === TMUX (PLUS MODERNE) ===

# Installer:
sudo apt install tmux

# Créer une session:
tmux

# Créer avec un nom:
tmux new -s mysession

# Détacher:
# Ctrl+B puis D

# Lister:
tmux ls

# Rattacher:
tmux attach -t mysession

# Tuer:
tmux kill-session -t mysession

# Commandes dans tmux:
# Ctrl+B puis C: Nouvelle fenêtre
# Ctrl+B puis N: Fenêtre suivante
# Ctrl+B puis P: Fenêtre précédente
# Ctrl+B puis %: Split vertical
# Ctrl+B puis ": Split horizontal
# Ctrl+B puis flèches: Naviguer entre splits
# Ctrl+B puis X: Tuer le panel actuel


[OK] CONFIGURATION RÉSEAU AVANCÉE

# === BONDING (AGRÉGATION DE LIENS) ===

# Bonding = Combiner plusieurs interfaces réseau
# Avantages:
# - Redondance (si une interface tombe, l'autre prend le relais)
# - Bande passante augmentée

# Installer:
sudo apt install ifenslave

# Charger le module kernel:
sudo modprobe bonding

# Éditer la config:
sudo nano /etc/netplan/01-netcfg.yaml

# Contenu:
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
    eth1:
      dhcp4: no
  bonds:
    bond0:
      interfaces: [eth0, eth1]
      addresses: [192.168.1.100/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
      parameters:
        mode: active-backup
        primary: eth0
        mii-monitor-interval: 100

# Modes de bonding:
# - mode 0 (balance-rr): Round-robin (charge équilibrée)
# - mode 1 (active-backup): Redondance (un actif, autres backup)
# - mode 2 (balance-xor): XOR hash
# - mode 4 (802.3ad): LACP (switch doit supporter)
# - mode 5 (balance-tlb): Transmission load balancing
# - mode 6 (balance-alb): Adaptive load balancing

# Appliquer:
sudo netplan apply


# === VLAN (VIRTUAL LAN) ===

# VLAN = Segmentation logique du réseau

# Installer:
sudo apt install vlan

# Charger le module:
sudo modprobe 8021q

# Rendre permanent:
echo "8021q" | sudo tee -a /etc/modules

# Configuration Netplan:
sudo nano /etc/netplan/01-netcfg.yaml

# Contenu:
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
  vlans:
    vlan10:
      id: 10
      link: eth0
      addresses: [192.168.10.100/24]
    vlan20:
      id: 20
      link: eth0
      addresses: [192.168.20.100/24]

# Appliquer:
sudo netplan apply

# Vérifier:
ip addr show


# === BRIDGE (PONT RÉSEAU) ===

# Bridge = Connecter plusieurs réseaux
# Utilisé pour: VMs, conteneurs

# Installer:
sudo apt install bridge-utils

# Créer un bridge:
sudo brctl addbr br0

# Ajouter une interface:
sudo brctl addif br0 eth0

# Configuration permanente:
sudo nano /etc/netplan/01-netcfg.yaml

# Contenu:
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
  bridges:
    br0:
      interfaces: [eth0]
      dhcp4: no
      addresses: [192.168.1.100/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [8.8.8.8]

# Appliquer:
sudo netplan apply

# Voir les bridges:
brctl show


# === TRAFFIC SHAPING (LIMITATION BANDE PASSANTE) ===

# TC = Traffic Control
# Limiter la bande passante d'une interface

# Limiter à 1 Mbit/s:
sudo tc qdisc add dev eth0 root tbf rate 1mbit burst 32kbit latency 400ms

# Explications:
# qdisc: Queuing discipline
# tbf: Token Bucket Filter
# rate: Débit maximum
# burst: Taille du burst
# latency: Latence maximale

# Voir la config:
tc qdisc show dev eth0

# Supprimer la limitation:
sudo tc qdisc del dev eth0 root

# Limiter pour une IP spécifique (avec iptables):
sudo iptables -A FORWARD -s 192.168.1.50 -j DROP
sudo iptables -A FORWARD -s 192.168.1.50 -m limit --limit 1/s -j ACCEPT


[OK] CONFIGURATION NTP (SYNCHRONISATION HORAIRE)

# === POURQUOI NTP? ===

# NTP = Network Time Protocol
# Synchronise l'heure avec des serveurs de temps
# Important pour:
# - Logs horodatés correctement
# - Certificats SSL (validité basée sur l'heure)
# - Authentification (Kerberos, etc.)
# - Bases de données distribuées

# === INSTALLER NTP ===

# Méthode moderne (systemd-timesyncd):

# Vérifier le statut:
timedatectl status

# Affiche:
#                Local time: Mon 2024-01-15 10:30:00 UTC
#            Universal time: Mon 2024-01-15 10:30:00 UTC
#                  RTC time: Mon 2024-01-15 10:30:00
#                 Time zone: UTC (UTC, +0000)
# System clock synchronized: yes
#               NTP service: active
#           RTC in local TZ: no

# Activer la synchronisation:
sudo timedatectl set-ntp true

# Configurer les serveurs NTP:
sudo nano /etc/systemd/timesyncd.conf

# Contenu:
[Time]
NTP=0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org
FallbackNTP=2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org

# Redémarrer:
sudo systemctl restart systemd-timesyncd

# Vérifier:
timedatectl timesync-status

# Affiche:
#        Server: 91.189.91.157 (0.ubuntu.pool.ntp.org)
# Poll interval: 34min 8s (min: 32s; max 34min 8s)
#          Leap: normal
#       Version: 4
#       Stratum: 2


# === MÉTHODE CLASSIQUE (NTPD) ===

# Installer:
sudo apt install ntp

# Configuration:
sudo nano /etc/ntp.conf

# Ajouter/modifier:
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
server 3.pool.ntp.org iburst

# Redémarrer:
sudo systemctl restart ntp

# Vérifier:
ntpq -p

# Affiche:
#      remote           refid      st t when poll reach   delay   offset  jitter
# ==============================================================================
# *time.cloudflare 10.21.8.251      3 u   64   64  377    8.234    0.123   0.456


# === CHANGER LE FUSEAU HORAIRE ===

# Voir le fuseau actuel:
timedatectl

# Lister les fuseaux disponibles:
timedatectl list-timezones

# Chercher un fuseau:
timedatectl list-timezones | grep Paris

# Changer le fuseau:
sudo timedatectl set-timezone Europe/Paris

# Vérifier:
date

# Affiche:
# Mon Jan 15 11:30:00 CET 2024


[OK] CONFIGURATION SWAP

# === QU'EST-CE QUE LE SWAP? ===

# Swap = Espace disque utilisé comme RAM virtuelle
# Quand la RAM est pleine, le système utilise le swap
# Plus lent que la RAM mais évite les crashes

# === VOIR LE SWAP ACTUEL ===

# Voir l'utilisation:
free -h

# Affiche:
#               total        used        free      shared  buff/cache   available
# Mem:          1.9Gi       810Mi       250Mi       5.0Mi       900Mi       980Mi
# Swap:         1.0Gi          0B       1.0Gi

# Voir les partitions swap:
sudo swapon --show

# Affiche:
# NAME      TYPE      SIZE USED PRIO
# /dev/sda2 partition 1.0G   0B   -2

# Ou:
cat /proc/swaps


# === CRÉER UN FICHIER SWAP ===

# Créer un fichier de 2 Go:
sudo fallocate -l 2G /swapfile

# Alternative si fallocate ne marche pas:
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048

# Définir les permissions (IMPORTANT!):
sudo chmod 600 /swapfile

# Formater en swap:
sudo mkswap /swapfile

# Affiche:
# Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
# no label, UUID=abc123-def456

# Activer:
sudo swapon /swapfile

# Vérifier:
sudo swapon --show

# Affiche:
# NAME      TYPE SIZE USED PRIO
# /swapfile file   2G   0B   -2

# Rendre permanent:
sudo nano /etc/fstab

# Ajouter:
/swapfile none swap sw 0 0


# === AJUSTER LA SWAPPINESS ===

# Swappiness = Tendance du système à utiliser le swap
# Valeurs: 0-100
# - 0: Utiliser le swap seulement en dernier recours
# - 100: Utiliser le swap agressivement
# Défaut: 60

# Voir la valeur actuelle:
cat /proc/sys/vm/swappiness

# Affiche:
# 60

# Changer temporairement:
sudo sysctl vm.swappiness=10

# Rendre permanent:
sudo nano /etc/sysctl.conf

# Ajouter:
vm.swappiness=10

# Appliquer:
sudo sysctl -p

# Recommandations:
# - Serveur web: 10-20
# - Desktop: 60 (défaut)
# - Base de données: 1-10


# === SUPPRIMER LE SWAP ===

# Désactiver:
sudo swapoff /swapfile

# Supprimer le fichier:
sudo rm /swapfile

# Retirer de fstab:
sudo nano /etc/fstab
# Supprimer la ligne avec /swapfile


[OK] CONFIGURATION SELINUX (CENTOS/RHEL)

# === QU'EST-CE QUE SELINUX? ===

# SELinux = Security-Enhanced Linux
# Système de sécurité par le kernel
# Contrôle d'accès obligatoire (MAC)
# Présent par défaut sur CentOS/RHEL

# 3 modes:
# - Enforcing: Actif, bloque les violations
# - Permissive: Actif, log mais ne bloque pas
# - Disabled: Désactivé

# === VOIR LE STATUT ===

# Statut actuel:
getenforce

# Affiche:
# Enforcing

# Statut détaillé:
sestatus

# Affiche:
# SELinux status:                 enabled
# SELinuxfs mount:                /sys/fs/selinux
# SELinux root directory:         /etc/selinux
# Loaded policy name:             targeted
# Current mode:                   enforcing
# Mode from config file:          enforcing
# Policy MLS status:              enabled
# Policy deny_unknown status:     allowed


# === CHANGER LE MODE ===

# Temporairement (jusqu'au reboot):
sudo setenforce 0        # Permissive
sudo setenforce 1        # Enforcing

# Permanent:
sudo nano /etc/selinux/config

# Changer:
SELINUX=enforcing

# À:
SELINUX=permissive
# ou:
SELINUX=disabled

# Redémarrer:
sudo reboot


# === GÉRER LES CONTEXTES ===

# Voir le contexte d'un fichier:
ls -Z /var/www/html/index.html

# Affiche:
# -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

# Changer le contexte:
sudo chcon -t httpd_sys_content_t /var/www/html/newfile.html

# Restaurer le contexte par défaut:
sudo restorecon -v /var/www/html/newfile.html

# Restaurer récursivement:
sudo restorecon -Rv /var/www/html/


# === GÉRER LES BOOLÉENS ===

# Voir tous les booléens:
getsebool -a

# Voir un booléen spécifique:
getsebool httpd_can_network_connect

# Affiche:
# httpd_can_network_connect --> off

# Activer un booléen:
sudo setsebool httpd_can_network_connect on

# Rendre permanent:
sudo setsebool -P httpd_can_network_connect on


# === LOGS SELINUX ===

# Voir les violations:
sudo ausearch -m avc -ts recent

# Ou:
sudo grep "avc:" /var/log/audit/audit.log

# Analyser et proposer des solutions:
sudo ausearch -m avc -ts recent | audit2why


[OK] CONFIGURATION APPARMOR (UBUNTU)

# === QU'EST-CE QU'APPARMOR? ===

# AppArmor = Application Armor
# Alternative à SELinux (plus simple)
# Utilisé par défaut sur Ubuntu/Debian

# === VOIR LE STATUT ===

# Statut:
sudo aa-status

# Affiche:
# apparmor module is loaded.
# 18 profiles are loaded.
# 18 profiles are in enforce mode.
#    /sbin/dhclient
#    /usr/bin/lxc-start
#    /usr/lib/NetworkManager/nm-dhcp-client.action
#    ...

# === MODES ===

# - Enforce: Actif, bloque les violations
# - Complain: Actif, log mais ne bloque pas
# - Disabled: Désactivé

# === GÉRER LES PROFILS ===

# Mettre en mode complain:
sudo aa-complain /usr/sbin/nginx

# Mettre en mode enforce:
sudo aa-enforce /usr/sbin/nginx

# Désactiver un profil:
sudo ln -s /etc/apparmor.d/usr.sbin.nginx /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.nginx

# Activer un profil:
sudo rm /etc/apparmor.d/disable/usr.sbin.nginx
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx

# Recharger tous les profils:
sudo systemctl reload apparmor


# === LOGS APPARMOR ===

# Voir les violations:
sudo journalctl -xe | grep apparmor

# Ou:
sudo dmesg | grep apparmor


[OK] CONFIGURATION SYSCTL (OPTIMISATION KERNEL)

# === QU'EST-CE QUE SYSCTL? ===

# sysctl = Configurer les paramètres du kernel Linux
# Permet d'optimiser:
# - Réseau
# - Mémoire
# - Sécurité
# - Performances

# === VOIR LES PARAMÈTRES ===

# Tous les paramètres:
sysctl -a

# Chercher un paramètre:
sysctl -a | grep tcp

# Voir un paramètre spécifique:
sysctl net.ipv4.ip_forward

# Affiche:
# net.ipv4.ip_forward = 0


# === MODIFIER UN PARAMÈTRE ===

# Temporaire (jusqu'au reboot):
sudo sysctl -w net.ipv4.ip_forward=1

# Permanent:
sudo nano /etc/sysctl.conf

# Ajouter/modifier:
net.ipv4.ip_forward = 1

# Appliquer:
sudo sysctl -p

# Ou créer un fichier dédié:
sudo nano /etc/sysctl.d/99-custom.conf


# === OPTIMISATIONS RÉSEAU ===

# Augmenter les buffers réseau:
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864

# Activer TCP Fast Open:
net.ipv4.tcp_fastopen = 3

# Augmenter les connexions:
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192

# BBR (meilleur algorithme de congestion):
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# Réutilisation rapide des sockets:
net.ipv4.tcp_tw_reuse = 1

# Protection SYN flood:
net.ipv4.tcp_syncookies = 1


# === OPTIMISATIONS MÉMOIRE ===

# Swappiness (déjà vu):
vm.swappiness = 10

# Cache de dentries et inodes:
vm.vfs_cache_pressure = 50

# Dirty ratio (écriture disque):
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5


# === SÉCURITÉ ===

# Désactiver le forwarding IP (si pas routeur):
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# Protection contre IP spoofing:
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignorer ICMP redirects:
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# Ignorer les pings (optionnel):
net.ipv4.icmp_echo_ignore_all = 1

# Logs des paquets suspects:
net.ipv4.conf.all.log_martians = 1


# === PERFORMANCES FICHIERS ===

# Augmenter le nombre de fichiers ouverts:
fs.file-max = 2097152

# Augmenter les inodes:
fs.inotify.max_user_watches = 524288


[OK] CONFIGURATION ULIMIT (LIMITES RESSOURCES)

# === QU'EST-CE QU'ULIMIT? ===

# ulimit = Limites de ressources par processus/utilisateur
# Contrôle:
# - Nombre de fichiers ouverts
# - Taille des fichiers
# - Nombre de processus
# - Mémoire

# === VOIR LES LIMITES ===

# Limites actuelles:
ulimit -a

# Affiche:
# core file size          (blocks, -c) 0
# data seg size           (kbytes, -d) unlimited
# scheduling priority             (-e) 0
# file size               (blocks, -f) unlimited
# max locked memory       (kbytes, -l) 65536
# max memory size         (kbytes, -m) unlimited
# open files                      (-n) 1024
# max user processes              (-u) 7680

# Limite spécifique:
ulimit -n        # Nombre de fichiers ouverts

# Affiche:
# 1024


# === MODIFIER LES LIMITES ===

# Temporaire (session actuelle):
ulimit -n 65536

# Permanent:
su


[OK] RÉSUMÉ & CHECKLIST FINALE

# === CHECKLIST SÉCURITÉ ===

[ ] Utilisateur non-root créé avec sudo
[ ] SSH configuré (port changé, clés SSH, PasswordAuth=no)
[ ] Fail2Ban installé et configuré
[ ] Firewall activé (ufw/firewalld)
[ ] Mises à jour système régulières
[ ] Permissions correctes (pas de 777!)
[ ] Logs surveillés

# === CHECKLIST RÉSEAU ===

[ ] IP statique configurée (si nécessaire)
[ ] DNS configuré (/etc/resolv.conf)
[ ] Hostname défini
[ ] Ports nécessaires ouverts dans le firewall
[ ] SSH accessible

# === CHECKLIST SERVICES ===

[ ] Services démarrés (systemctl start)
[ ] Services activés au boot (systemctl enable)
[ ] Logs vérifiés (journalctl -u service)
[ ] Pas d'erreurs dans systemctl status

# === CHECKLIST STOCKAGE ===

[ ] Partitions montées (/etc/fstab)
[ ] Espace disque surveillé (df -h)
[ ] Backups configurés et testés
[ ] Logrotate configuré

# === CHECKLIST WEB (si applicable) ===

[ ] Nginx/Apache installé
[ ] Sites configurés
[ ] HTTPS avec Let's Encrypt
[ ] Reverse proxy fonctionnel (si applicable)
[ ] Logs accessibles

# === CHECKLIST MONITORING ===

[ ] Cron jobs configurés (backups, nettoyage)
[ ] Monitoring de base (htop, free, df)
[ ] Logs régulièrement vérifiés

# === COMMANDES ESSENTIELLES À RETENIR ===

# Système:
sudo apt update && sudo apt upgrade -y  # Mises à jour
sudo systemctl status service           # Statut service
sudo journalctl -u service -f           # Logs en temps réel
df -h                                   # Espace disque
free -h                                 # Mémoire

# Réseau:
ip addr show                            # IPs
ping 8.8.8.8                            # Test connectivité
sudo ss -tuln                           # Ports ouverts

# Utilisateurs:
sudo adduser user                       # Créer utilisateur
sudo usermod -aG sudo user              # Donner sudo
chmod 755 file                          # Permissions

# SSH:
ssh user@server                         # Connexion
ssh-keygen -t rsa -b 4096               # Générer clé
ssh-copy-id user@server                 # Copier clé

# Firewall:
sudo ufw allow 22/tcp                   # Autoriser SSH
sudo ufw enable                         # Activer firewall
sudo ufw status                         # Voir règles

# Services:
sudo systemctl start nginx              # Démarrer
sudo systemctl enable nginx             # Activer au boot
sudo systemctl restart nginx            # Redémarrer

# Fichiers:
ls -la                                  # Lister fichiers
cat /etc/file                           # Voir contenu
sudo nano /etc/file                     # Éditer
tail -f /var/log/file                   # Suivre log


[OK] RESSOURCES & DOCUMENTATION

# Documentation officielle:
# Ubuntu: https://ubuntu.com/server/docs
# CentOS: https://docs.centos.org/
# Nginx: https://nginx.org/en/docs/
# Systemd: https://www.freedesktop.org/software/systemd/man/

# Tutoriels recommandés:
# DigitalOcean Tutorials: https://www.digitalocean.com/community/tutorials
# Linux Journey: https://linuxjourney.com/
# The Linux Documentation Project: https://tldp.org/

# Forums d'aide:
# Ask Ubuntu: https://askubuntu.com/
# Unix & Linux Stack Exchange: https://unix.stackexchange.com/
# Reddit r/linuxadmin: https://reddit.com/r/linuxadmin

# Livres recommandés:
# - "The Linux Command Line" par William Shotts
# - "UNIX and Linux System Administration Handbook"
# - "How Linux Works" par Brian Ward

# === FIN DU GUIDE ===

# Félicitations! Tu as maintenant les bases solides pour administrer un serveur Linux!
# Continue à pratiquer et à explorer. Chaque serveur est différent et tu apprendras en faisant.
# N'oublie jamais: TOUJOURS faire des backups avant de modifier quoi que ce soit!
```