Réorganiser les guides et ajouter architecture filesystem
- Nouvelle structure : linux-essentials/ et forgejo/ - Nouveau guide : architecture-filesystem.md (comprendre /etc, /var, etc.) - Déplacement et renommage des guides existants - README pour chaque dossier - Suppression des sections auteurs Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4e99c5025c
commit
e33395dc35
10 changed files with 2811 additions and 17 deletions
98
serveur/linux-essentials/README.md
Normal file
98
serveur/linux-essentials/README.md
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
# Guides Linux Essentiels
|
||||
|
||||
Guides généralistes pour comprendre et administrer un système Linux.
|
||||
|
||||
## 📚 Guides disponibles
|
||||
|
||||
### 🏗️ Comprendre Linux
|
||||
|
||||
**[architecture-filesystem.md](architecture-filesystem.md)**
|
||||
- **Objectif :** Comprendre l'organisation des dossiers Linux (/etc, /var, /lib, etc.)
|
||||
- **Contenu :** FHS, rôle de chaque dossier, cas pratiques
|
||||
- **Niveau :** Débutant
|
||||
- **Temps :** 30-45 min de lecture
|
||||
|
||||
### 🔍 Diagnostic
|
||||
|
||||
**[diagnostic-espace-disque.md](diagnostic-espace-disque.md)**
|
||||
- **Objectif :** Identifier ce qui remplit le disque et comment le nettoyer
|
||||
- **Contenu :** Commandes `df`, `du`, `find`, cas pratiques (Docker, logs, caches)
|
||||
- **Niveau :** Débutant à intermédiaire
|
||||
- **Temps :** 15-30 min selon le problème
|
||||
|
||||
**[analyse-logs-detection-bots.md](analyse-logs-detection-bots.md)**
|
||||
- **Objectif :** Analyser les logs pour identifier les IP problématiques et les bloquer
|
||||
- **Contenu :** Docker logs, extraction d'IP, Fail2ban, whois, rate limiting
|
||||
- **Niveau :** Intermédiaire
|
||||
- **Temps :** 20-40 min
|
||||
|
||||
### 📖 Apprendre les commandes
|
||||
|
||||
**[comprendre-commandes-find-du.md](comprendre-commandes-find-du.md)**
|
||||
- **Objectif :** Maîtriser les commandes `find`, `du`, pipes et grep
|
||||
- **Contenu :** Explications détaillées, exemples progressifs, cas pratiques
|
||||
- **Niveau :** Débutant (pédagogique)
|
||||
- **Temps :** 1h de lecture active
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Par besoin
|
||||
|
||||
### Je débute sur Linux
|
||||
1. Lire : [architecture-filesystem.md](architecture-filesystem.md)
|
||||
2. Pratiquer avec : [comprendre-commandes-find-du.md](comprendre-commandes-find-du.md)
|
||||
|
||||
### Mon disque est plein
|
||||
1. Diagnostiquer : [diagnostic-espace-disque.md](diagnostic-espace-disque.md)
|
||||
2. Si besoin d'approfondir les commandes : [comprendre-commandes-find-du.md](comprendre-commandes-find-du.md)
|
||||
|
||||
### Je veux analyser les logs
|
||||
1. Lire : [analyse-logs-detection-bots.md](analyse-logs-detection-bots.md)
|
||||
2. Pour les commandes : [comprendre-commandes-find-du.md](comprendre-commandes-find-du.md)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Commandes essentielles
|
||||
|
||||
### Espace disque
|
||||
```bash
|
||||
df -h # Vue globale
|
||||
sudo du -sh /* | sort -h | tail -10 # Top 10 dossiers racine
|
||||
ncdu / # Navigateur interactif
|
||||
```
|
||||
|
||||
### Fichiers
|
||||
```bash
|
||||
find /path -type f -size +100M # Gros fichiers
|
||||
find /path -type f -mmin +360 # Fichiers de +6h
|
||||
```
|
||||
|
||||
### Logs
|
||||
```bash
|
||||
sudo journalctl -u service -n 50 # Logs d'un service
|
||||
sudo tail -f /var/log/syslog # Logs en temps réel
|
||||
```
|
||||
|
||||
### Système
|
||||
```bash
|
||||
ls -la /etc/ # Configurations
|
||||
ls -la /var/log/ # Logs
|
||||
du -sh /var/lib/docker # Données Docker
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tableau de référence rapide
|
||||
|
||||
| Dossier | Rôle | Exemple |
|
||||
|---------|------|---------|
|
||||
| `/etc` | Configurations | `/etc/nginx/nginx.conf` |
|
||||
| `/var/log` | Logs | `/var/log/syslog` |
|
||||
| `/var/lib` | Données d'état | `/var/lib/docker/` |
|
||||
| `/home` | Utilisateurs | `/home/debian/` |
|
||||
| `/tmp` | Temporaire | `/tmp/fichier` |
|
||||
| `/usr/bin` | Commandes | `/usr/bin/python3` |
|
||||
|
||||
---
|
||||
|
||||
[← Retour à l'index principal](../README.md)
|
||||
729
serveur/linux-essentials/analyse-logs-detection-bots.md
Normal file
729
serveur/linux-essentials/analyse-logs-detection-bots.md
Normal file
|
|
@ -0,0 +1,729 @@
|
|||
# Guide d'analyse des logs et détection de bots abusifs
|
||||
|
||||
Guide complet pour analyser les logs d'un serveur, identifier les IP problématiques, détecter les bots malveillants et mettre en place des protections automatiques.
|
||||
|
||||
## Table des matières
|
||||
|
||||
1. [Comprendre les logs](#1-comprendre-les-logs)
|
||||
2. [Analyser les logs Docker](#2-analyser-les-logs-docker)
|
||||
3. [Identifier les IP problématiques](#3-identifier-les-ip-problématiques)
|
||||
4. [Analyser le comportement d'une IP](#4-analyser-le-comportement-dune-ip)
|
||||
5. [Déterminer le type de bot](#5-déterminer-le-type-de-bot)
|
||||
6. [Bloquer manuellement une IP](#6-bloquer-manuellement-une-ip)
|
||||
7. [Automatiser avec Fail2ban](#7-automatiser-avec-fail2ban)
|
||||
8. [Rate limiting](#8-rate-limiting)
|
||||
9. [Monitoring continu](#9-monitoring-continu)
|
||||
10. [Mémo rapide](#10-mémo-rapide)
|
||||
|
||||
---
|
||||
|
||||
## 1. Comprendre les logs
|
||||
|
||||
### Types de logs sous Linux
|
||||
|
||||
| Type | Emplacement | Contenu |
|
||||
|------|-------------|---------|
|
||||
| **Logs système** | `/var/log/syslog` | Messages généraux du système |
|
||||
| **Logs d'authentification** | `/var/log/auth.log` | Connexions SSH, sudo, etc. |
|
||||
| **Logs Docker** | `/var/lib/docker/containers/.../*.log` | Logs des conteneurs |
|
||||
| **Journald** | `journalctl` | Logs systemd (moderne) |
|
||||
| **Logs d'applications** | Variable | Nginx, Apache, bases de données... |
|
||||
|
||||
### Format typique d'une ligne de log
|
||||
|
||||
```
|
||||
2026/02/02 08:17:57 [I] router: completed GET /repo/archive/main.zip for 216.73.216.118:0, 200 OK in 10.8ms
|
||||
│ │ │ │ │
|
||||
│ │ │ └─ IP source └─ Code HTTP
|
||||
│ │ └─ Action (GET, POST...)
|
||||
│ └─ Niveau (I=Info, E=Error, W=Warning)
|
||||
└─ Timestamp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Analyser les logs Docker
|
||||
|
||||
### Voir les logs d'un conteneur
|
||||
|
||||
**Logs complets :**
|
||||
```bash
|
||||
docker logs nom_conteneur
|
||||
```
|
||||
|
||||
**Dernières lignes :**
|
||||
```bash
|
||||
docker logs nom_conteneur --tail 50
|
||||
```
|
||||
|
||||
**Logs en temps réel (suivi) :**
|
||||
```bash
|
||||
docker logs nom_conteneur -f
|
||||
```
|
||||
|
||||
**Logs depuis un moment spécifique :**
|
||||
```bash
|
||||
# Dernières 24 heures
|
||||
docker logs nom_conteneur --since 24h
|
||||
|
||||
# Dernières 2 heures
|
||||
docker logs nom_conteneur --since 2h
|
||||
|
||||
# Depuis une date précise
|
||||
docker logs nom_conteneur --since 2026-02-01T00:00:00
|
||||
```
|
||||
|
||||
### Filtrer les logs
|
||||
|
||||
**Chercher un pattern spécifique :**
|
||||
```bash
|
||||
docker logs nom_conteneur | grep "erreur"
|
||||
docker logs nom_conteneur | grep "404"
|
||||
docker logs nom_conteneur | grep -i "archive" # -i = insensible à la casse
|
||||
```
|
||||
|
||||
**Exclure certaines lignes :**
|
||||
```bash
|
||||
docker logs nom_conteneur | grep -v "health check" # -v = inverse
|
||||
```
|
||||
|
||||
**Sauvegarder dans un fichier :**
|
||||
```bash
|
||||
docker logs nom_conteneur --since 24h > /tmp/logs.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Identifier les IP problématiques
|
||||
|
||||
### Compter toutes les requêtes par IP
|
||||
|
||||
**Méthode générale (si les IP sont dans les logs) :**
|
||||
```bash
|
||||
docker logs conteneur --since 24h | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -20
|
||||
```
|
||||
|
||||
**Explication :**
|
||||
- `grep -oP '\d+\.\d+\.\d+\.\d+'` : Extrait toutes les adresses IP (regex)
|
||||
- `sort` : Trie les IP
|
||||
- `uniq -c` : Compte les occurrences uniques
|
||||
- `sort -rn` : Trie par nombre décroissant
|
||||
- `head -20` : Garde les 20 premières
|
||||
|
||||
**Exemple de résultat :**
|
||||
```
|
||||
2144 216.73.216.118 ← SUSPECT (trop de requêtes)
|
||||
42 192.168.1.100
|
||||
12 10.0.0.5
|
||||
3 172.18.0.1
|
||||
```
|
||||
|
||||
### Filtrer par type de requête
|
||||
|
||||
**Requêtes d'archives uniquement :**
|
||||
```bash
|
||||
docker logs forgejo --since 24h | grep "archive" > /tmp/archives.log
|
||||
grep -oP '\d+\.\d+\.\d+\.\d+' /tmp/archives.log | sort | uniq -c | sort -rn
|
||||
```
|
||||
|
||||
**Requêtes avec erreur 500 :**
|
||||
```bash
|
||||
docker logs forgejo --since 24h | grep "500 Internal" | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn
|
||||
```
|
||||
|
||||
**Requêtes POST (modifications) :**
|
||||
```bash
|
||||
docker logs forgejo --since 24h | grep "POST" | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn
|
||||
```
|
||||
|
||||
### Statistiques par heure
|
||||
|
||||
**Voir l'activité par heure :**
|
||||
```bash
|
||||
docker logs forgejo --since 24h | grep "archive" | grep -oP '^\d{4}/\d{2}/\d{2} \d{2}' | uniq -c
|
||||
```
|
||||
|
||||
**Exemple :**
|
||||
```
|
||||
12 2026/02/02 08 ← 12 requêtes à 8h
|
||||
145 2026/02/02 09 ← 145 requêtes à 9h (SUSPECT)
|
||||
18 2026/02/02 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Analyser le comportement d'une IP
|
||||
|
||||
Une fois une IP suspecte identifiée (ex: `216.73.216.118`), analysons son comportement.
|
||||
|
||||
### Voir toutes ses requêtes
|
||||
|
||||
```bash
|
||||
docker logs forgejo --since 24h | grep "216.73.216.118" > /tmp/ip_suspect.log
|
||||
```
|
||||
|
||||
### Compter ses requêtes
|
||||
|
||||
```bash
|
||||
wc -l /tmp/ip_suspect.log
|
||||
```
|
||||
|
||||
**Exemple :** `2144` requêtes en 24h = ~90 requêtes/heure = suspect
|
||||
|
||||
### Voir ce qu'elle télécharge
|
||||
|
||||
```bash
|
||||
grep "216.73.216.118" /tmp/ip_suspect.log | head -20
|
||||
```
|
||||
|
||||
**Patterns suspects :**
|
||||
|
||||
| Pattern | Signification |
|
||||
|---------|---------------|
|
||||
| `/archive/main:vendor/...` | Scanne les dépendances (recherche de vulnérabilités) |
|
||||
| `/archive/commit123.zip` répété | Télécharge tous les commits (crawler) |
|
||||
| Requêtes très rapprochées | Bot automatisé |
|
||||
| 500 Internal Server Error | Tentatives qui échouent (disque plein, etc.) |
|
||||
|
||||
### Identifier les repos ciblés
|
||||
|
||||
```bash
|
||||
grep "216.73.216.118" /tmp/ip_suspect.log | grep -oP '/[^/]+/[^/]+/archive' | sort | uniq -c | sort -rn
|
||||
```
|
||||
|
||||
**Exemple :**
|
||||
```
|
||||
1350 /studio-variable/designtopack/archive ← Cible principale
|
||||
232 /studio-variable/index-shop/archive
|
||||
86 /studio-variable/world-game/archive
|
||||
```
|
||||
|
||||
### Analyser la fréquence
|
||||
|
||||
**Temps entre chaque requête :**
|
||||
```bash
|
||||
grep "216.73.216.118" /tmp/ip_suspect.log | grep -oP '^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}' | head -20
|
||||
```
|
||||
|
||||
**Si les timestamps sont très rapprochés (< 1 seconde) :** C'est un bot automatisé.
|
||||
|
||||
---
|
||||
|
||||
## 5. Déterminer le type de bot
|
||||
|
||||
### Identifier le User-Agent
|
||||
|
||||
```bash
|
||||
docker logs forgejo --since 24h | grep "216.73.216.118" | grep -oP 'User-Agent: [^"]*' | sort | uniq -c
|
||||
```
|
||||
|
||||
**User-Agents courants :**
|
||||
|
||||
| User-Agent | Type | Légitime ? |
|
||||
|------------|------|------------|
|
||||
| `Googlebot` | Crawler Google | ✅ Oui |
|
||||
| `bingbot` | Crawler Bing | ✅ Oui |
|
||||
| `curl/7.x` | Script automatisé | ⚠️ Dépend |
|
||||
| `python-requests/2.x` | Script Python | ⚠️ Dépend |
|
||||
| `Go-http-client` | Script Go | ⚠️ Dépend |
|
||||
| Aucun ou vide | Bot basique | ❌ Suspect |
|
||||
|
||||
### Identifier le propriétaire de l'IP (whois)
|
||||
|
||||
```bash
|
||||
whois 216.73.216.118 | head -30
|
||||
```
|
||||
|
||||
**Cherche :**
|
||||
- `OrgName:` → Propriétaire (AWS, Google, hébergeur...)
|
||||
- `NetName:` → Type de réseau
|
||||
- `Country:` → Pays
|
||||
|
||||
**Exemples :**
|
||||
```
|
||||
OrgName: Amazon.com, Inc. → Hébergé sur AWS
|
||||
OrgName: Google LLC → Infrastructure Google
|
||||
OrgName: OVH SAS → Hébergeur français
|
||||
```
|
||||
|
||||
### Vérifier la réputation de l'IP
|
||||
|
||||
**Services en ligne :**
|
||||
- https://www.abuseipdb.com/check/IP
|
||||
- https://www.virustotal.com/gui/ip-address/IP
|
||||
- https://mxtoolbox.com/SuperTool.aspx?action=blacklist:IP
|
||||
|
||||
---
|
||||
|
||||
## 6. Bloquer manuellement une IP
|
||||
|
||||
### Dans Forgejo/Gitea
|
||||
|
||||
**Éditer la configuration :**
|
||||
```bash
|
||||
sudo nano /path/to/forgejo/data/gitea/conf/app.ini
|
||||
```
|
||||
|
||||
**Ajouter la section `[security]` :**
|
||||
```ini
|
||||
[security]
|
||||
BANNED_IP_ADDRESSES = 216.73.216.118,192.168.1.50
|
||||
```
|
||||
|
||||
**Redémarrer :**
|
||||
```bash
|
||||
docker restart forgejo
|
||||
```
|
||||
|
||||
### Avec iptables (niveau firewall)
|
||||
|
||||
**Bloquer une IP :**
|
||||
```bash
|
||||
sudo iptables -A INPUT -s 216.73.216.118 -j DROP
|
||||
```
|
||||
|
||||
**Voir les règles :**
|
||||
```bash
|
||||
sudo iptables -L -n
|
||||
```
|
||||
|
||||
**Sauvegarder (pour que ça persiste au reboot) :**
|
||||
```bash
|
||||
sudo iptables-save > /etc/iptables/rules.v4
|
||||
```
|
||||
|
||||
**Débloquer une IP :**
|
||||
```bash
|
||||
sudo iptables -D INPUT -s 216.73.216.118 -j DROP
|
||||
```
|
||||
|
||||
### Avec UFW (plus simple)
|
||||
|
||||
**Bloquer une IP :**
|
||||
```bash
|
||||
sudo ufw deny from 216.73.216.118
|
||||
```
|
||||
|
||||
**Voir les règles :**
|
||||
```bash
|
||||
sudo ufw status numbered
|
||||
```
|
||||
|
||||
**Supprimer une règle :**
|
||||
```bash
|
||||
sudo ufw delete NUMÉRO
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Automatiser avec Fail2ban
|
||||
|
||||
Fail2ban surveille les logs et bannit automatiquement les IP abusives.
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install fail2ban
|
||||
sudo systemctl enable fail2ban
|
||||
sudo systemctl start fail2ban
|
||||
```
|
||||
|
||||
### Configuration pour détecter les requêtes d'archives excessives
|
||||
|
||||
**Créer un filtre :**
|
||||
```bash
|
||||
sudo nano /etc/fail2ban/filter.d/forgejo-archive.conf
|
||||
```
|
||||
|
||||
**Contenu :**
|
||||
```ini
|
||||
[Definition]
|
||||
failregex = completed GET .*/archive/.* for <HOST>
|
||||
ignoreregex =
|
||||
```
|
||||
|
||||
**Créer une jail :**
|
||||
```bash
|
||||
sudo nano /etc/fail2ban/jail.d/forgejo.conf
|
||||
```
|
||||
|
||||
**Contenu :**
|
||||
```ini
|
||||
[forgejo-archive]
|
||||
enabled = true
|
||||
filter = forgejo-archive
|
||||
logpath = /var/lib/docker/containers/CONTAINER_ID/CONTAINER_ID-json.log
|
||||
maxretry = 50
|
||||
findtime = 600
|
||||
bantime = 3600
|
||||
```
|
||||
|
||||
**Remplace `CONTAINER_ID` par le vrai ID :**
|
||||
```bash
|
||||
docker inspect forgejo --format='{{.LogPath}}'
|
||||
```
|
||||
|
||||
**Redémarrer Fail2ban :**
|
||||
```bash
|
||||
sudo systemctl restart fail2ban
|
||||
```
|
||||
|
||||
### Vérifier le statut
|
||||
|
||||
```bash
|
||||
# Statut général
|
||||
sudo fail2ban-client status
|
||||
|
||||
# Statut d'une jail spécifique
|
||||
sudo fail2ban-client status forgejo-archive
|
||||
```
|
||||
|
||||
**Exemple de sortie :**
|
||||
```
|
||||
Status for the jail: forgejo-archive
|
||||
|- Filter
|
||||
| |- Currently failed: 2
|
||||
| |- Total failed: 145
|
||||
| `- File list: /var/lib/docker/containers/.../...json.log
|
||||
`- Actions
|
||||
|- Currently banned: 1
|
||||
|- Total banned: 3
|
||||
`- Banned IP list: 216.73.216.118
|
||||
```
|
||||
|
||||
### Commandes utiles
|
||||
|
||||
```bash
|
||||
# Voir les IP bannies
|
||||
sudo fail2ban-client get forgejo-archive banip
|
||||
|
||||
# Bannir manuellement une IP
|
||||
sudo fail2ban-client set forgejo-archive banip 192.168.1.50
|
||||
|
||||
# Débannir une IP
|
||||
sudo fail2ban-client set forgejo-archive unbanip 192.168.1.50
|
||||
|
||||
# Voir les logs de Fail2ban
|
||||
sudo tail -f /var/log/fail2ban.log
|
||||
```
|
||||
|
||||
### Ajuster les paramètres
|
||||
|
||||
Dans `/etc/fail2ban/jail.d/forgejo.conf` :
|
||||
|
||||
| Paramètre | Signification | Exemple |
|
||||
|-----------|---------------|---------|
|
||||
| `maxretry` | Nombre de tentatives avant ban | `50` = bannir après 50 requêtes |
|
||||
| `findtime` | Fenêtre de temps (secondes) | `600` = dans les 10 dernières minutes |
|
||||
| `bantime` | Durée du ban (secondes) | `3600` = bannir pour 1 heure |
|
||||
|
||||
**Exemples de configurations :**
|
||||
|
||||
```ini
|
||||
# Tolérant (serveur public)
|
||||
maxretry = 100
|
||||
findtime = 600
|
||||
bantime = 3600
|
||||
|
||||
# Strict (serveur privé)
|
||||
maxretry = 20
|
||||
findtime = 300
|
||||
bantime = 86400 # 24 heures
|
||||
|
||||
# Permanent
|
||||
bantime = -1 # Ban permanent
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Rate limiting
|
||||
|
||||
Limite le nombre de requêtes par IP directement dans l'application.
|
||||
|
||||
### Dans Forgejo/Gitea
|
||||
|
||||
**Éditer `app.ini` :**
|
||||
```bash
|
||||
sudo nano /path/to/forgejo/data/gitea/conf/app.ini
|
||||
```
|
||||
|
||||
**Ajouter :**
|
||||
```ini
|
||||
[api]
|
||||
ENABLE_RATE_LIMIT = true
|
||||
RATE_LIMIT_BURST = 100
|
||||
|
||||
[repository]
|
||||
DOWNLOAD_OR_CLONE_METHODS = http,https,ssh
|
||||
DOWNLOAD_EXPIRY_TIME = 60
|
||||
```
|
||||
|
||||
**Redémarrer :**
|
||||
```bash
|
||||
docker restart forgejo
|
||||
```
|
||||
|
||||
### Avec Nginx (si reverse proxy)
|
||||
|
||||
**Dans la config Nginx :**
|
||||
```nginx
|
||||
http {
|
||||
# Définir une zone de rate limiting
|
||||
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
|
||||
|
||||
server {
|
||||
location / {
|
||||
# Appliquer la limite
|
||||
limit_req zone=mylimit burst=20 nodelay;
|
||||
proxy_pass http://localhost:3000;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Tester la config :**
|
||||
```bash
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Monitoring continu
|
||||
|
||||
### Script de surveillance quotidien
|
||||
|
||||
**Créer un script :**
|
||||
```bash
|
||||
sudo nano /usr/local/bin/check-suspicious-ips.sh
|
||||
```
|
||||
|
||||
**Contenu :**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
LOG_FILE="/tmp/suspicious_ips_$(date +%Y%m%d).log"
|
||||
THRESHOLD=100
|
||||
|
||||
echo "=== Suspicious IP Report - $(date) ===" > "$LOG_FILE"
|
||||
echo "" >> "$LOG_FILE"
|
||||
|
||||
# Top 20 IP des dernières 24h
|
||||
echo "Top 20 IPs (last 24h):" >> "$LOG_FILE"
|
||||
docker logs forgejo --since 24h | grep -oP '\d+\.\d+\.\d+\.\d+' | \
|
||||
sort | uniq -c | sort -rn | head -20 >> "$LOG_FILE"
|
||||
|
||||
echo "" >> "$LOG_FILE"
|
||||
|
||||
# IP dépassant le seuil
|
||||
echo "IPs with more than $THRESHOLD requests:" >> "$LOG_FILE"
|
||||
docker logs forgejo --since 24h | grep -oP '\d+\.\d+\.\d+\.\d+' | \
|
||||
sort | uniq -c | sort -rn | awk -v threshold="$THRESHOLD" '$1 > threshold' >> "$LOG_FILE"
|
||||
|
||||
# Envoyer par email (optionnel)
|
||||
# mail -s "Suspicious IPs Report" admin@example.com < "$LOG_FILE"
|
||||
|
||||
echo "Report saved to $LOG_FILE"
|
||||
```
|
||||
|
||||
**Rendre exécutable :**
|
||||
```bash
|
||||
sudo chmod +x /usr/local/bin/check-suspicious-ips.sh
|
||||
```
|
||||
|
||||
**Ajouter au cron (tous les jours à 8h) :**
|
||||
```bash
|
||||
sudo crontab -e
|
||||
```
|
||||
|
||||
Ajouter :
|
||||
```
|
||||
0 8 * * * /usr/local/bin/check-suspicious-ips.sh
|
||||
```
|
||||
|
||||
### Dashboard temps réel
|
||||
|
||||
**Surveiller les requêtes d'archives en temps réel :**
|
||||
```bash
|
||||
watch -n 5 'docker logs forgejo --since 5m | grep "archive" | wc -l'
|
||||
```
|
||||
|
||||
**Voir les nouvelles IP actives :**
|
||||
```bash
|
||||
watch -n 10 'docker logs forgejo --since 10m | grep -oP "\d+\.\d+\.\d+\.\d+" | sort -u'
|
||||
```
|
||||
|
||||
### Alertes par email
|
||||
|
||||
**Installer mailutils :**
|
||||
```bash
|
||||
sudo apt install mailutils
|
||||
```
|
||||
|
||||
**Script d'alerte :**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
COUNT=$(docker logs forgejo --since 1h | grep "archive" | wc -l)
|
||||
|
||||
if [ "$COUNT" -gt 500 ]; then
|
||||
echo "ALERTE: $COUNT requêtes d'archives dans la dernière heure!" | \
|
||||
mail -s "Alerte serveur Forgejo" admin@example.com
|
||||
fi
|
||||
```
|
||||
|
||||
**Ajouter au cron (toutes les heures) :**
|
||||
```
|
||||
0 * * * * /path/to/alert-script.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Mémo rapide (cheat sheet)
|
||||
|
||||
### Analyse basique
|
||||
|
||||
```bash
|
||||
# Top 20 IP des dernières 24h
|
||||
docker logs conteneur --since 24h | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -20
|
||||
|
||||
# Requêtes d'une IP spécifique
|
||||
docker logs conteneur --since 24h | grep "IP_ADRESSE"
|
||||
|
||||
# Compter les requêtes d'archives
|
||||
docker logs conteneur --since 24h | grep "archive" | wc -l
|
||||
|
||||
# Repos les plus ciblés
|
||||
docker logs conteneur --since 24h | grep "archive" | grep -oP '/[^/]+/[^/]+/archive' | sort | uniq -c | sort -rn | head -10
|
||||
|
||||
# Whois d'une IP
|
||||
whois IP_ADRESSE | head -30
|
||||
```
|
||||
|
||||
### Fail2ban
|
||||
|
||||
```bash
|
||||
# Statut général
|
||||
sudo fail2ban-client status
|
||||
|
||||
# Statut d'une jail
|
||||
sudo fail2ban-client status nom_jail
|
||||
|
||||
# IP bannies
|
||||
sudo fail2ban-client get nom_jail banip
|
||||
|
||||
# Bannir manuellement
|
||||
sudo fail2ban-client set nom_jail banip IP
|
||||
|
||||
# Débannir
|
||||
sudo fail2ban-client set nom_jail unbanip IP
|
||||
|
||||
# Logs Fail2ban
|
||||
sudo tail -f /var/log/fail2ban.log
|
||||
```
|
||||
|
||||
### Blocage manuel
|
||||
|
||||
```bash
|
||||
# Dans Forgejo (app.ini)
|
||||
[security]
|
||||
BANNED_IP_ADDRESSES = IP1,IP2,IP3
|
||||
|
||||
# Avec UFW
|
||||
sudo ufw deny from IP_ADRESSE
|
||||
sudo ufw status numbered
|
||||
sudo ufw delete NUMERO
|
||||
|
||||
# Avec iptables
|
||||
sudo iptables -A INPUT -s IP_ADRESSE -j DROP
|
||||
sudo iptables -L -n
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cas pratiques
|
||||
|
||||
### Cas 1 : Bot qui télécharge massivement des archives
|
||||
|
||||
**Symptômes :**
|
||||
- 2000+ requêtes d'archives en 24h
|
||||
- Disque qui se remplit rapidement
|
||||
- Cache repo-archive qui grossit
|
||||
|
||||
**Diagnostic :**
|
||||
```bash
|
||||
# Identifier l'IP
|
||||
docker logs forgejo --since 24h | grep "archive" | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -5
|
||||
|
||||
# Analyser son comportement
|
||||
docker logs forgejo --since 24h | grep "IP_SUSPECTE" | head -20
|
||||
|
||||
# Whois
|
||||
whois IP_SUSPECTE
|
||||
```
|
||||
|
||||
**Solution :**
|
||||
1. Bloquer l'IP dans Forgejo (app.ini)
|
||||
2. Configurer Fail2ban pour détecter automatiquement
|
||||
3. Ajouter rate limiting
|
||||
4. Mettre en place un cron de nettoyage du cache
|
||||
|
||||
### Cas 2 : Scan de vulnérabilités
|
||||
|
||||
**Symptômes :**
|
||||
- Requêtes ciblant `/vendor`, `/node_modules`, `.env`
|
||||
- Beaucoup d'erreurs 404
|
||||
- User-Agent = `curl` ou `python-requests`
|
||||
|
||||
**Diagnostic :**
|
||||
```bash
|
||||
# Voir les URLs demandées
|
||||
docker logs forgejo --since 24h | grep "IP_SUSPECTE" | grep -oP 'GET [^ ]*' | sort | uniq -c
|
||||
```
|
||||
|
||||
**Solution :**
|
||||
1. Bloquer l'IP
|
||||
2. Vérifier qu'aucun fichier sensible n'est exposé
|
||||
3. Configurer Fail2ban pour bannir après 10 erreurs 404
|
||||
|
||||
### Cas 3 : Attaque DDoS
|
||||
|
||||
**Symptômes :**
|
||||
- Centaines d'IP différentes
|
||||
- Requêtes très rapprochées
|
||||
- Serveur lent/inaccessible
|
||||
|
||||
**Diagnostic :**
|
||||
```bash
|
||||
# Nombre d'IP uniques
|
||||
docker logs forgejo --since 10m | grep -oP '\d+\.\d+\.\d+\.\d+' | sort -u | wc -l
|
||||
|
||||
# Si > 100 IP en 10 min = DDoS potentiel
|
||||
```
|
||||
|
||||
**Solution :**
|
||||
1. Mettre le service derrière Cloudflare
|
||||
2. Activer le mode "Under Attack" temporairement
|
||||
3. Réduire drastiquement le rate limiting
|
||||
|
||||
---
|
||||
|
||||
## Ressources complémentaires
|
||||
|
||||
**Documentation :**
|
||||
- Fail2ban : https://www.fail2ban.org/wiki/index.php/Main_Page
|
||||
- iptables : `man iptables`
|
||||
- UFW : `man ufw`
|
||||
- grep : `man grep`
|
||||
|
||||
**Outils utiles :**
|
||||
- `goaccess` : Analyseur de logs web en temps réel
|
||||
- `geoiplookup` : Géolocalisation d'IP
|
||||
- `tcpdump` : Capture du trafic réseau
|
||||
- `netstat` / `ss` : Connexions actives
|
||||
|
||||
**Regex IP :**
|
||||
```regex
|
||||
\d+\.\d+\.\d+\.\d+ # IPv4 basique
|
||||
\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b # IPv4 plus précis
|
||||
```
|
||||
609
serveur/linux-essentials/architecture-filesystem.md
Normal file
609
serveur/linux-essentials/architecture-filesystem.md
Normal file
|
|
@ -0,0 +1,609 @@
|
|||
# Architecture du système de fichiers Linux
|
||||
|
||||
Guide complet pour comprendre l'organisation des dossiers sur un système Linux (Debian, Ubuntu, etc.).
|
||||
|
||||
## Table des matières
|
||||
|
||||
1. [Vue d'ensemble](#1-vue-densemble)
|
||||
2. [Arborescence de base](#2-arborescence-de-base)
|
||||
3. [Dossiers systèmes essentiels](#3-dossiers-systèmes-essentiels)
|
||||
4. [Dossiers de données](#4-dossiers-de-données)
|
||||
5. [Dossiers temporaires](#5-dossiers-temporaires)
|
||||
6. [Cas pratiques](#6-cas-pratiques)
|
||||
7. [Mémo rapide](#7-mémo-rapide)
|
||||
|
||||
---
|
||||
|
||||
## 1. Vue d'ensemble
|
||||
|
||||
### Le principe UNIX : "Tout est fichier"
|
||||
|
||||
Sous Linux, **tout est représenté comme un fichier** :
|
||||
- Les vrais fichiers (documents, images)
|
||||
- Les dossiers (fichiers spéciaux)
|
||||
- Les périphériques (disques, clavier, souris)
|
||||
- Les processus en cours
|
||||
- Les connexions réseau
|
||||
|
||||
### Hiérarchie FHS (Filesystem Hierarchy Standard)
|
||||
|
||||
Linux suit une convention appelée **FHS** qui définit où mettre quoi.
|
||||
|
||||
**Analogie avec une maison :**
|
||||
- `/` → La maison entière (racine)
|
||||
- `/home` → Les chambres des habitants
|
||||
- `/etc` → Le tableau électrique et les plans
|
||||
- `/var` → Le garage et la cave (stockage variable)
|
||||
- `/tmp` → La corbeille (temporaire)
|
||||
- `/usr` → Les communs (salon, cuisine)
|
||||
|
||||
---
|
||||
|
||||
## 2. Arborescence de base
|
||||
|
||||
```
|
||||
/ ← Racine (root) du système
|
||||
├── bin/ → Commandes de base (ls, cp, cat)
|
||||
├── boot/ → Fichiers de démarrage (kernel)
|
||||
├── dev/ → Périphériques (disques, USB)
|
||||
├── etc/ → Fichiers de configuration
|
||||
├── home/ → Dossiers personnels des utilisateurs
|
||||
│ ├── alice/
|
||||
│ ├── bob/
|
||||
│ └── debian/
|
||||
├── lib/ → Bibliothèques système
|
||||
├── media/ → Points de montage auto (USB, CD)
|
||||
├── mnt/ → Points de montage manuels
|
||||
├── opt/ → Logiciels optionnels (tiers)
|
||||
├── proc/ → Informations sur les processus (virtuel)
|
||||
├── root/ → Dossier personnel de l'utilisateur root
|
||||
├── run/ → Données runtime (PID, sockets)
|
||||
├── sbin/ → Commandes d'administration système
|
||||
├── srv/ → Données des services (web, ftp)
|
||||
├── sys/ → Informations système (virtuel)
|
||||
├── tmp/ → Fichiers temporaires
|
||||
├── usr/ → Applications et utilitaires utilisateur
|
||||
│ ├── bin/ → Commandes utilisateur
|
||||
│ ├── lib/ → Bibliothèques
|
||||
│ ├── local/ → Logiciels installés localement
|
||||
│ └── share/ → Données partagées (docs, icônes)
|
||||
└── var/ → Données variables (logs, caches)
|
||||
├── cache/ → Caches applicatifs
|
||||
├── lib/ → Données d'état (bases de données)
|
||||
├── log/ → Logs système et applicatifs
|
||||
├── mail/ → Boîtes mail
|
||||
├── spool/ → Files d'attente (impression, mail)
|
||||
└── tmp/ → Temporaire persistant entre reboots
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Dossiers systèmes essentiels
|
||||
|
||||
### `/etc` - Configuration
|
||||
|
||||
**Rôle :** Contient **tous** les fichiers de configuration du système et des applications.
|
||||
|
||||
**Exemples importants :**
|
||||
|
||||
| Fichier/Dossier | Rôle |
|
||||
|----------------|------|
|
||||
| `/etc/passwd` | Liste des utilisateurs du système |
|
||||
| `/etc/group` | Liste des groupes d'utilisateurs |
|
||||
| `/etc/hostname` | Nom de la machine |
|
||||
| `/etc/hosts` | Résolution DNS locale |
|
||||
| `/etc/fstab` | Points de montage des disques |
|
||||
| `/etc/crontab` | Tâches planifiées système |
|
||||
| `/etc/ssh/` | Configuration du serveur SSH |
|
||||
| `/etc/nginx/` | Configuration Nginx |
|
||||
| `/etc/fail2ban/` | Configuration Fail2ban |
|
||||
| `/etc/systemd/` | Services systemd |
|
||||
|
||||
**Commande utile :**
|
||||
```bash
|
||||
# Trouver tous les fichiers de config modifiés récemment
|
||||
find /etc -type f -mtime -7
|
||||
```
|
||||
|
||||
**⚠️ Attention :**
|
||||
- Toujours faire une backup avant modification
|
||||
- Les droits sont stricts (souvent root uniquement)
|
||||
|
||||
---
|
||||
|
||||
### `/var` - Données variables
|
||||
|
||||
**Rôle :** Contient les données qui **changent fréquemment** pendant le fonctionnement du système.
|
||||
|
||||
**Sous-dossiers importants :**
|
||||
|
||||
#### `/var/log` - Logs
|
||||
|
||||
**Les plus courants :**
|
||||
|
||||
| Fichier | Contenu |
|
||||
|---------|---------|
|
||||
| `/var/log/syslog` | Logs système généraux (Debian/Ubuntu) |
|
||||
| `/var/log/auth.log` | Authentifications (SSH, sudo) |
|
||||
| `/var/log/kern.log` | Messages du kernel |
|
||||
| `/var/log/fail2ban.log` | Logs Fail2ban |
|
||||
| `/var/log/nginx/` | Logs Nginx (access.log, error.log) |
|
||||
| `/var/log/apache2/` | Logs Apache |
|
||||
|
||||
**Commandes utiles :**
|
||||
```bash
|
||||
# Voir les logs système
|
||||
sudo tail -f /var/log/syslog
|
||||
|
||||
# Voir les tentatives SSH
|
||||
sudo grep "Failed password" /var/log/auth.log
|
||||
|
||||
# Taille des logs
|
||||
sudo du -sh /var/log
|
||||
```
|
||||
|
||||
#### `/var/lib` - Données d'état des applications
|
||||
|
||||
**Exemples :**
|
||||
|
||||
| Dossier | Contenu |
|
||||
|---------|---------|
|
||||
| `/var/lib/docker/` | Images, conteneurs, volumes Docker |
|
||||
| `/var/lib/mysql/` | Bases de données MySQL |
|
||||
| `/var/lib/postgresql/` | Bases de données PostgreSQL |
|
||||
| `/var/lib/apt/` | État des paquets APT |
|
||||
|
||||
**Commande utile :**
|
||||
```bash
|
||||
# Voir ce qui prend de la place dans /var/lib
|
||||
sudo du -sh /var/lib/* | sort -h | tail -10
|
||||
```
|
||||
|
||||
#### `/var/cache` - Caches
|
||||
|
||||
**Exemples :**
|
||||
|
||||
| Dossier | Contenu |
|
||||
|---------|---------|
|
||||
| `/var/cache/apt/` | Paquets .deb téléchargés |
|
||||
| `/var/cache/nginx/` | Cache Nginx |
|
||||
|
||||
**Nettoyage :**
|
||||
```bash
|
||||
# Nettoyer le cache APT
|
||||
sudo apt clean
|
||||
|
||||
# Voir la taille
|
||||
sudo du -sh /var/cache/apt
|
||||
```
|
||||
|
||||
#### `/var/spool` - Files d'attente
|
||||
|
||||
**Exemples :**
|
||||
|
||||
| Dossier | Contenu |
|
||||
|---------|---------|
|
||||
| `/var/spool/cron/` | Tâches cron des utilisateurs |
|
||||
| `/var/spool/mail/` | Mails en attente |
|
||||
|
||||
---
|
||||
|
||||
### `/home` - Dossiers personnels
|
||||
|
||||
**Rôle :** Un sous-dossier par utilisateur pour ses fichiers personnels.
|
||||
|
||||
**Structure typique :**
|
||||
```
|
||||
/home/debian/
|
||||
├── .bashrc → Config du shell bash
|
||||
├── .ssh/ → Clés SSH
|
||||
│ ├── id_rsa
|
||||
│ ├── id_rsa.pub
|
||||
│ └── authorized_keys
|
||||
├── Documents/
|
||||
├── Downloads/
|
||||
└── projects/
|
||||
```
|
||||
|
||||
**Commandes utiles :**
|
||||
```bash
|
||||
# Aller dans votre home
|
||||
cd ~
|
||||
# ou
|
||||
cd $HOME
|
||||
|
||||
# Voir tous les fichiers cachés (commencent par .)
|
||||
ls -la ~
|
||||
|
||||
# Taille de votre home
|
||||
du -sh ~
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `/tmp` - Fichiers temporaires
|
||||
|
||||
**Rôle :** Stockage temporaire, **vidé au redémarrage** (sur la plupart des systèmes).
|
||||
|
||||
**Caractéristiques :**
|
||||
- Accessible en écriture par tous les utilisateurs
|
||||
- Nettoyé automatiquement
|
||||
- Parfois monté en RAM (tmpfs) pour plus de rapidité
|
||||
|
||||
**Commandes utiles :**
|
||||
```bash
|
||||
# Créer un fichier temporaire
|
||||
mktemp
|
||||
|
||||
# Voir la taille de /tmp
|
||||
df -h /tmp
|
||||
|
||||
# Nettoyer manuellement (⚠️ peut casser des apps en cours)
|
||||
sudo rm -rf /tmp/*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `/usr` - Applications utilisateur
|
||||
|
||||
**Rôle :** Contient les programmes et bibliothèques installés par le système de paquets.
|
||||
|
||||
**Sous-dossiers :**
|
||||
|
||||
| Dossier | Contenu |
|
||||
|---------|---------|
|
||||
| `/usr/bin/` | Commandes utilisateur (git, python, vim) |
|
||||
| `/usr/sbin/` | Commandes admin (iptables, systemctl) |
|
||||
| `/usr/lib/` | Bibliothèques partagées (.so) |
|
||||
| `/usr/share/` | Données partagées (docs, man pages, icônes) |
|
||||
| `/usr/local/` | Logiciels installés manuellement (hors paquets) |
|
||||
|
||||
**Commandes utiles :**
|
||||
```bash
|
||||
# Où se trouve une commande ?
|
||||
which python3
|
||||
# → /usr/bin/python3
|
||||
|
||||
# Taille de /usr
|
||||
du -sh /usr
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `/opt` - Logiciels optionnels
|
||||
|
||||
**Rôle :** Logiciels tiers installés manuellement (pas via apt/yum).
|
||||
|
||||
**Exemples :**
|
||||
- `/opt/google/chrome/`
|
||||
- `/opt/nodejs/`
|
||||
- `/opt/myapp/`
|
||||
|
||||
**Convention :** Chaque logiciel dans son propre dossier.
|
||||
|
||||
---
|
||||
|
||||
### `/srv` - Données des services
|
||||
|
||||
**Rôle :** Données servies par le système (sites web, FTP, etc.).
|
||||
|
||||
**Exemples :**
|
||||
- `/srv/www/` → Sites web
|
||||
- `/srv/ftp/` → Serveur FTP
|
||||
- `/srv/git/` → Dépôts Git
|
||||
|
||||
**Note :** Peu utilisé en pratique, beaucoup préfèrent `/var/www/` ou `/home/user/`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dossiers de données
|
||||
|
||||
### `/root` - Dossier de l'admin
|
||||
|
||||
**Rôle :** Dossier personnel de l'utilisateur `root` (super-admin).
|
||||
|
||||
**⚠️ Important :**
|
||||
- Séparé de `/home` pour raisons de sécurité
|
||||
- Accessible uniquement par root
|
||||
- Contient souvent des scripts d'admin
|
||||
|
||||
```bash
|
||||
# Passer en root
|
||||
sudo su -
|
||||
|
||||
# Voir où vous êtes
|
||||
pwd
|
||||
# → /root
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `/boot` - Démarrage système
|
||||
|
||||
**Rôle :** Fichiers nécessaires au démarrage (kernel, initramfs).
|
||||
|
||||
**Contenu typique :**
|
||||
```
|
||||
/boot/
|
||||
├── vmlinuz-5.10.0-21-amd64 → Kernel Linux
|
||||
├── initrd.img-5.10.0-21-amd64 → RAM disk initial
|
||||
└── grub/ → Bootloader GRUB
|
||||
```
|
||||
|
||||
**⚠️ Attention :**
|
||||
- Souvent une petite partition (200-500 MB)
|
||||
- Peut se remplir avec de vieux kernels
|
||||
|
||||
**Nettoyage :**
|
||||
```bash
|
||||
# Voir les kernels installés
|
||||
dpkg --list | grep linux-image
|
||||
|
||||
# Supprimer les anciens (apt le fait automatiquement)
|
||||
sudo apt autoremove
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Dossiers temporaires
|
||||
|
||||
### `/run` - Runtime
|
||||
|
||||
**Rôle :** Informations **runtime** du système (PID, sockets).
|
||||
|
||||
**Caractéristiques :**
|
||||
- Créé au démarrage, vidé au reboot
|
||||
- Monté en RAM (tmpfs)
|
||||
- Remplace l'ancien `/var/run`
|
||||
|
||||
**Exemples :**
|
||||
```
|
||||
/run/
|
||||
├── systemd/ → État systemd
|
||||
├── docker.sock → Socket Docker
|
||||
├── user/1000/ → Session utilisateur ID 1000
|
||||
└── lock/ → Fichiers de verrou
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `/proc` et `/sys` - Systèmes de fichiers virtuels
|
||||
|
||||
**Rôle :** Interfaces vers le kernel (pas de vrais fichiers sur disque).
|
||||
|
||||
#### `/proc` - Informations sur les processus
|
||||
|
||||
**Exemples :**
|
||||
```bash
|
||||
# Infos CPU
|
||||
cat /proc/cpuinfo
|
||||
|
||||
# Infos mémoire
|
||||
cat /proc/meminfo
|
||||
|
||||
# Processus en cours
|
||||
ls /proc
|
||||
# → 1/ 2/ 3/ ... (PIDs)
|
||||
|
||||
# Infos sur un processus
|
||||
cat /proc/1234/cmdline
|
||||
```
|
||||
|
||||
#### `/sys` - Informations hardware
|
||||
|
||||
**Exemples :**
|
||||
```bash
|
||||
# Infos réseau
|
||||
ls /sys/class/net/
|
||||
# → eth0 lo wlan0
|
||||
|
||||
# Température CPU (si disponible)
|
||||
cat /sys/class/thermal/thermal_zone0/temp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Cas pratiques
|
||||
|
||||
### Cas 1 : Chercher un fichier de configuration
|
||||
|
||||
**Problème :** Vous voulez modifier la config de SSH.
|
||||
|
||||
**Solution :**
|
||||
```bash
|
||||
# Chercher dans /etc
|
||||
find /etc -name "*ssh*"
|
||||
# → /etc/ssh/sshd_config
|
||||
|
||||
# Éditer
|
||||
sudo nano /etc/ssh/sshd_config
|
||||
|
||||
# Redémarrer le service
|
||||
sudo systemctl restart ssh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cas 2 : Analyser les logs d'une application
|
||||
|
||||
**Problème :** Votre application web plante.
|
||||
|
||||
**Solution :**
|
||||
```bash
|
||||
# Logs Nginx
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
|
||||
# Logs système
|
||||
sudo journalctl -u nginx -n 50
|
||||
|
||||
# Logs applicatifs (selon l'app)
|
||||
sudo tail -f /var/log/myapp/error.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cas 3 : Le disque est plein
|
||||
|
||||
**Diagnostic :**
|
||||
```bash
|
||||
# 1. Identifier le disque plein
|
||||
df -h
|
||||
|
||||
# 2. Trouver les gros dossiers à la racine
|
||||
sudo du -sh /* | sort -h | tail -10
|
||||
|
||||
# 3. Si c'est /var (courant)
|
||||
sudo du -sh /var/* | sort -h | tail -10
|
||||
|
||||
# 4. Si c'est /var/log
|
||||
sudo du -sh /var/log/* | sort -h | tail -10
|
||||
|
||||
# 5. Nettoyer les vieux logs
|
||||
sudo journalctl --vacuum-size=500M
|
||||
```
|
||||
|
||||
**Coupables courants :**
|
||||
- `/var/log/` → Logs trop volumineux
|
||||
- `/var/lib/docker/` → Images Docker
|
||||
- `/var/cache/apt/` → Cache de paquets
|
||||
- `/tmp/` → Fichiers temporaires oubliés
|
||||
|
||||
---
|
||||
|
||||
### Cas 4 : Où installer un logiciel manuel ?
|
||||
|
||||
**Options :**
|
||||
|
||||
| Emplacement | Quand l'utiliser |
|
||||
|-------------|------------------|
|
||||
| `/usr/local/bin/` | Binaires manuels (disponibles globalement) |
|
||||
| `/opt/myapp/` | Application complète avec ses dépendances |
|
||||
| `~/bin/` ou `~/.local/bin/` | Scripts personnels (utilisateur uniquement) |
|
||||
|
||||
**Exemple :**
|
||||
```bash
|
||||
# Installer un script global
|
||||
sudo cp mon-script.sh /usr/local/bin/mon-script
|
||||
sudo chmod +x /usr/local/bin/mon-script
|
||||
|
||||
# Installer une app complète
|
||||
sudo mkdir -p /opt/myapp
|
||||
sudo cp -r myapp/* /opt/myapp/
|
||||
sudo ln -s /opt/myapp/bin/myapp /usr/local/bin/myapp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cas 5 : Trouver où une application stocke ses données
|
||||
|
||||
**Pistes :**
|
||||
|
||||
1. **Configuration :** `/etc/[nom-app]/`
|
||||
2. **Données :** `/var/lib/[nom-app]/`
|
||||
3. **Logs :** `/var/log/[nom-app]/`
|
||||
4. **Cache :** `/var/cache/[nom-app]/`
|
||||
|
||||
**Exemple avec Docker :**
|
||||
```bash
|
||||
# Config (rare, Docker utilise peu /etc)
|
||||
ls /etc/docker/
|
||||
|
||||
# Données (images, conteneurs)
|
||||
sudo du -sh /var/lib/docker
|
||||
|
||||
# Logs des conteneurs
|
||||
sudo ls /var/lib/docker/containers/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Mémo rapide
|
||||
|
||||
### Tableau récapitulatif
|
||||
|
||||
| Dossier | Rôle | Exemple |
|
||||
|---------|------|---------|
|
||||
| `/` | Racine du système | Point de départ de tout |
|
||||
| `/etc` | **Config**urations | `/etc/nginx/nginx.conf` |
|
||||
| `/var` | Données **var**iables | `/var/log/syslog` |
|
||||
| `/var/log` | **Logs** système/apps | `/var/log/auth.log` |
|
||||
| `/var/lib` | **État** des apps | `/var/lib/docker/` |
|
||||
| `/home` | Dossiers **utilisateurs** | `/home/debian/` |
|
||||
| `/tmp` | **Temporaire** (vidé au reboot) | `/tmp/fichier-temp` |
|
||||
| `/usr` | **Applications** système | `/usr/bin/python3` |
|
||||
| `/usr/local` | Apps installées **manuellement** | `/usr/local/bin/mon-script` |
|
||||
| `/opt` | Apps **tierces** | `/opt/google/chrome/` |
|
||||
| `/root` | Dossier de **root** (admin) | `/root/.bashrc` |
|
||||
| `/boot` | Fichiers de **démarrage** | `/boot/vmlinuz` |
|
||||
| `/srv` | Données **servies** | `/srv/www/` |
|
||||
| `/run` | Infos **runtime** (RAM) | `/run/docker.sock` |
|
||||
| `/proc` | Infos **processus** (virtuel) | `/proc/cpuinfo` |
|
||||
| `/sys` | Infos **hardware** (virtuel) | `/sys/class/net/` |
|
||||
|
||||
---
|
||||
|
||||
### Commandes essentielles
|
||||
|
||||
```bash
|
||||
# Naviguer
|
||||
cd /var/log # Aller dans un dossier
|
||||
pwd # Voir où je suis
|
||||
ls -la # Lister avec fichiers cachés
|
||||
|
||||
# Explorer
|
||||
tree /etc -L 2 # Arborescence (2 niveaux)
|
||||
find /etc -name "*.conf" # Trouver des fichiers
|
||||
|
||||
# Analyser l'espace
|
||||
df -h # Espace des disques
|
||||
du -sh /var/* # Taille des dossiers
|
||||
ncdu /var # Navigateur interactif
|
||||
|
||||
# Permissions
|
||||
ls -l fichier # Voir les permissions
|
||||
sudo chown user:group fichier # Changer propriétaire
|
||||
sudo chmod 644 fichier # Changer permissions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Checklist : "Où mettre mes fichiers ?"
|
||||
|
||||
| Type de fichier | Emplacement |
|
||||
|----------------|-------------|
|
||||
| Configuration d'une app | `/etc/[app]/` |
|
||||
| Script personnel | `~/bin/` ou `~/.local/bin/` |
|
||||
| Script global | `/usr/local/bin/` |
|
||||
| Application manuelle | `/opt/[app]/` |
|
||||
| Site web | `/var/www/` ou `/srv/www/` |
|
||||
| Base de données | `/var/lib/[db]/` |
|
||||
| Logs applicatifs | `/var/log/[app]/` |
|
||||
| Cache applicatif | `/var/cache/[app]/` |
|
||||
| Fichier temporaire | `/tmp/` |
|
||||
| Backup | `/var/backups/` ou `/home/[user]/backups/` |
|
||||
|
||||
---
|
||||
|
||||
## Ressources complémentaires
|
||||
|
||||
**Standards officiels :**
|
||||
- [FHS (Filesystem Hierarchy Standard)](https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.pdf)
|
||||
|
||||
**Commandes utiles :**
|
||||
```bash
|
||||
# Arbre complet du système (attention, très long)
|
||||
tree / -L 2
|
||||
|
||||
# Pages de manuel
|
||||
man hier # Hiérarchie du filesystem
|
||||
man file # Types de fichiers
|
||||
|
||||
# Infos disque
|
||||
lsblk # Liste des disques et partitions
|
||||
mount # Points de montage actifs
|
||||
```
|
||||
|
||||
**Outils recommandés :**
|
||||
- `ncdu` : Navigateur d'espace disque interactif
|
||||
- `tree` : Affichage en arbre
|
||||
- `htop` : Monitoring incluant infos filesystem
|
||||
566
serveur/linux-essentials/comprendre-commandes-find-du.md
Normal file
566
serveur/linux-essentials/comprendre-commandes-find-du.md
Normal file
|
|
@ -0,0 +1,566 @@
|
|||
# Comprendre les commandes de diagnostic (find, du, grep)
|
||||
|
||||
Guide pédagogique pour comprendre les commandes utilisées dans le diagnostic du cache Forgejo.
|
||||
|
||||
---
|
||||
|
||||
## 1. La commande `find` : Chercher des fichiers
|
||||
|
||||
### Syntaxe de base
|
||||
|
||||
```bash
|
||||
find [où chercher] [critères] [action]
|
||||
```
|
||||
|
||||
### Exemples progressifs
|
||||
|
||||
**Exemple 1 : Lister tous les fichiers d'un dossier**
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive
|
||||
```
|
||||
|
||||
**Ce que ça fait :**
|
||||
- Parcourt récursivement tout le dossier `repo-archive`
|
||||
- Affiche tous les fichiers ET dossiers trouvés
|
||||
|
||||
---
|
||||
|
||||
**Exemple 2 : Seulement les fichiers (pas les dossiers)**
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive -type f
|
||||
```
|
||||
|
||||
**Nouveau paramètre :**
|
||||
- `-type f` : Filtre pour garder seulement les **f**ichiers (file)
|
||||
- `-type d` : Pour les **d**ossiers (directory)
|
||||
|
||||
---
|
||||
|
||||
**Exemple 3 : Compter les fichiers**
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive -type f | wc -l
|
||||
```
|
||||
|
||||
**Décortiquons :**
|
||||
- `find ... -type f` : Trouve tous les fichiers
|
||||
- `|` : "Pipe" = envoie le résultat à la commande suivante
|
||||
- `wc -l` : **W**ord **C**ount avec `-l` (line) = compte les lignes
|
||||
|
||||
**Résultat :** Le nombre de fichiers trouvés (ex: `1189`)
|
||||
|
||||
---
|
||||
|
||||
### Filtres par date : `-mtime`, `-mmin`
|
||||
|
||||
**Les 3 formes :**
|
||||
|
||||
| Syntaxe | Signification | Exemple |
|
||||
|---------|---------------|---------|
|
||||
| `-mtime -1` | Modifié **moins de** 24h | Fichiers créés aujourd'hui |
|
||||
| `-mtime 0` | Modifié **il y a exactement** 24h | Fichiers d'hier |
|
||||
| `-mtime +1` | Modifié **plus de** 48h | Fichiers d'avant-hier ou plus |
|
||||
|
||||
**Note importante :**
|
||||
- `-mtime` compte en **jours entiers** (multiples de 24h)
|
||||
- `-mtime +1` signifie "plus de 1 jour complet" donc **≥ 2 jours** (48h)
|
||||
|
||||
**Pour plus de précision, utilisez `-mmin` (minutes) :**
|
||||
|
||||
| Syntaxe | Signification |
|
||||
|---------|---------------|
|
||||
| `-mmin -60` | Modifié dans les 60 dernières minutes (< 1h) |
|
||||
| `-mmin +360` | Modifié il y a plus de 360 minutes (> 6h) |
|
||||
|
||||
**Exemple pratique :**
|
||||
```bash
|
||||
# Fichiers de moins de 6 heures
|
||||
find repo-archive -type f -mmin -360
|
||||
|
||||
# Fichiers de plus de 6 heures
|
||||
find repo-archive -type f -mmin +360
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### L'opérateur `!` (NOT)
|
||||
|
||||
**Inverser une condition :**
|
||||
|
||||
```bash
|
||||
find repo-archive -type f ! -mtime -1
|
||||
```
|
||||
|
||||
**Signification :**
|
||||
- `-mtime -1` : Fichiers de moins de 24h
|
||||
- `!` : **NOT** (inverse la condition)
|
||||
- Résultat : Fichiers de **PLUS de 24h**
|
||||
|
||||
**Équivalent :**
|
||||
- `! -mtime -1` = `-mtime 0 -o -mtime +1` (24h-48h OU plus de 48h)
|
||||
|
||||
---
|
||||
|
||||
### La commande `-exec` : Exécuter une action sur chaque fichier
|
||||
|
||||
**Syntaxe :**
|
||||
```bash
|
||||
find [critères] -exec commande {} \;
|
||||
```
|
||||
|
||||
**Composants :**
|
||||
- `-exec` : Exécute une commande sur chaque fichier trouvé
|
||||
- `commande` : La commande à exécuter (ex: `ls`, `du`, `rm`)
|
||||
- `{}` : Remplacé par le chemin du fichier trouvé
|
||||
- `\;` : Marque la fin de la commande (obligatoire)
|
||||
|
||||
**Exemple 1 : Afficher les détails de chaque fichier**
|
||||
```bash
|
||||
find repo-archive -type f -exec ls -lh {} \;
|
||||
```
|
||||
|
||||
**Ce qui se passe :**
|
||||
1. `find` trouve le fichier `/path/to/file1.zip`
|
||||
2. Exécute : `ls -lh /path/to/file1.zip`
|
||||
3. Trouve le fichier `/path/to/file2.zip`
|
||||
4. Exécute : `ls -lh /path/to/file2.zip`
|
||||
5. Etc.
|
||||
|
||||
---
|
||||
|
||||
**Exemple 2 : Supprimer tous les fichiers trouvés**
|
||||
```bash
|
||||
find repo-archive -type f -mmin +360 -exec rm {} \;
|
||||
```
|
||||
|
||||
**⚠️ Attention :** Cette commande **supprime définitivement** les fichiers.
|
||||
|
||||
**Équivalent plus simple :**
|
||||
```bash
|
||||
find repo-archive -type f -mmin +360 -delete
|
||||
```
|
||||
|
||||
L'option `-delete` est plus rapide et sûre que `-exec rm`.
|
||||
|
||||
---
|
||||
|
||||
### Différence entre `\;` et `+`
|
||||
|
||||
```bash
|
||||
# Avec \; : Exécute la commande UNE FOIS par fichier (lent)
|
||||
find repo-archive -type f -exec du -h {} \;
|
||||
# → du -h file1.zip
|
||||
# → du -h file2.zip
|
||||
# → du -h file3.zip
|
||||
|
||||
# Avec + : Exécute la commande UNE FOIS avec TOUS les fichiers (rapide)
|
||||
find repo-archive -type f -exec du -h {} +
|
||||
# → du -h file1.zip file2.zip file3.zip
|
||||
```
|
||||
|
||||
**Utilisez `+` quand possible, c'est beaucoup plus rapide.**
|
||||
|
||||
---
|
||||
|
||||
### La commande `-printf` : Format personnalisé
|
||||
|
||||
**Afficher des informations personnalisées :**
|
||||
|
||||
```bash
|
||||
find repo-archive -type f -printf '%TY-%Tm-%Td\n'
|
||||
```
|
||||
|
||||
**Composants :**
|
||||
- `-printf` : Affiche un format personnalisé (au lieu du nom du fichier)
|
||||
- `%T` : Date de modification du fichier
|
||||
- `%TY` : Année (2026)
|
||||
- `%Tm` : Mois (02)
|
||||
- `%Td` : Jour (05)
|
||||
- `\n` : Saut de ligne
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
2026-02-03
|
||||
2026-02-03
|
||||
2026-02-04
|
||||
2026-02-04
|
||||
...
|
||||
```
|
||||
|
||||
**Formater avec l'heure :**
|
||||
```bash
|
||||
find repo-archive -type f -printf '%TY-%Tm-%Td %TH:%TM\n'
|
||||
```
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
2026-02-03 14:23
|
||||
2026-02-03 14:45
|
||||
2026-02-04 08:12
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. La commande `du` : Disk Usage (taille des fichiers)
|
||||
|
||||
### Syntaxe de base
|
||||
|
||||
```bash
|
||||
du [options] [chemin]
|
||||
```
|
||||
|
||||
### Options courantes
|
||||
|
||||
| Option | Signification | Exemple |
|
||||
|--------|---------------|---------|
|
||||
| `-s` | **S**ummary (résumé total) | Affiche seulement le total |
|
||||
| `-h` | **H**uman-readable (Go, Mo) | `5.2G` au lieu de `5242880` |
|
||||
| `-b` | **B**ytes (octets exacts) | Pour des calculs précis |
|
||||
| `-c` | **C**umulé (total à la fin) | Ajoute une ligne de total |
|
||||
|
||||
### Exemples
|
||||
|
||||
**Voir la taille d'un dossier :**
|
||||
```bash
|
||||
du -sh /home/debian/forgejo/data/gitea/repo-archive
|
||||
```
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
47G /home/debian/forgejo/data/gitea/repo-archive
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Voir la taille de chaque sous-dossier :**
|
||||
```bash
|
||||
du -sh /home/debian/forgejo/data/gitea/*
|
||||
```
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
4.0K /home/debian/forgejo/data/gitea/actions_artifacts
|
||||
8.0K /home/debian/forgejo/data/gitea/conf
|
||||
47G /home/debian/forgejo/data/gitea/repo-archive
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Taille en octets (pour des comparaisons) :**
|
||||
```bash
|
||||
du -sb /home/debian/forgejo/data/gitea/repo-archive
|
||||
```
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
50465865728 /home/debian/forgejo/data/gitea/repo-archive
|
||||
```
|
||||
|
||||
**Utilité :** Pour comparer avec un seuil (ex: 10G = 10737418240 octets)
|
||||
|
||||
---
|
||||
|
||||
### Utiliser `du` avec `find`
|
||||
|
||||
**Calculer la taille totale des fichiers trouvés :**
|
||||
|
||||
```bash
|
||||
find repo-archive -type f -exec du -ch {} + | tail -1
|
||||
```
|
||||
|
||||
**Décortiquons :**
|
||||
1. `find repo-archive -type f` : Trouve tous les fichiers
|
||||
2. `-exec du -ch {} +` : Calcule la taille de chaque fichier
|
||||
- `-c` : Affiche un total à la fin
|
||||
- `-h` : Format lisible (Go, Mo)
|
||||
- `+` : Passe tous les fichiers en une fois (rapide)
|
||||
3. `| tail -1` : Garde seulement la dernière ligne (le total)
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
47G total
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Pipeline de commandes avec `|`
|
||||
|
||||
### Concept du pipe `|`
|
||||
|
||||
Le pipe `|` envoie le **résultat** d'une commande à l'**entrée** de la suivante.
|
||||
|
||||
```bash
|
||||
commande1 | commande2 | commande3
|
||||
```
|
||||
|
||||
**Exemple concret :**
|
||||
```bash
|
||||
find repo-archive -type f | wc -l
|
||||
```
|
||||
|
||||
**Ce qui se passe :**
|
||||
1. `find` affiche tous les fichiers (un par ligne)
|
||||
2. `|` envoie cette liste à `wc`
|
||||
3. `wc -l` compte le nombre de lignes
|
||||
|
||||
---
|
||||
|
||||
### Chaînes courantes
|
||||
|
||||
**Compter + Trier :**
|
||||
```bash
|
||||
docker logs forgejo --since 24h | grep "archive" | wc -l
|
||||
```
|
||||
|
||||
**Étapes :**
|
||||
1. `docker logs forgejo --since 24h` : Affiche les logs des 24 dernières heures
|
||||
2. `grep "archive"` : Garde seulement les lignes contenant "archive"
|
||||
3. `wc -l` : Compte combien de lignes
|
||||
|
||||
---
|
||||
|
||||
**Extraire + Compter + Trier :**
|
||||
```bash
|
||||
docker logs forgejo --since 24h | grep "archive" | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -5
|
||||
```
|
||||
|
||||
**Étapes détaillées :**
|
||||
1. `docker logs forgejo --since 24h` : Logs des 24h
|
||||
2. `grep "archive"` : Lignes avec "archive"
|
||||
3. `grep -oP '\d+\.\d+\.\d+\.\d+'` : Extrait les adresses IP (regex)
|
||||
4. `sort` : Trie les IP alphabétiquement
|
||||
5. `uniq -c` : Compte les occurrences de chaque IP unique
|
||||
6. `sort -rn` : Trie par nombre décroissant
|
||||
7. `head -5` : Garde les 5 premières
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
2144 216.73.216.118
|
||||
42 192.168.1.100
|
||||
12 10.0.0.5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Commandes complémentaires
|
||||
|
||||
### `sort` : Trier
|
||||
|
||||
| Option | Signification |
|
||||
|--------|---------------|
|
||||
| `-h` | Trie en mode "humain" (comprend 10G > 2G) |
|
||||
| `-r` | **R**everse (ordre décroissant) |
|
||||
| `-n` | **N**umérique (trie les nombres correctement) |
|
||||
| `-rn` | Numérique décroissant |
|
||||
|
||||
**Exemple :**
|
||||
```bash
|
||||
du -sh /var/* | sort -h
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `uniq` : Dédoublonner
|
||||
|
||||
| Option | Signification |
|
||||
|--------|---------------|
|
||||
| `-c` | **C**ount (compte les occurrences) |
|
||||
|
||||
**Important :** `uniq` ne fonctionne que sur des données **triées**.
|
||||
|
||||
```bash
|
||||
# ❌ Mauvais (données non triées)
|
||||
echo -e "a\nb\na" | uniq -c
|
||||
|
||||
# ✅ Bon (trier d'abord)
|
||||
echo -e "a\nb\na" | sort | uniq -c
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `head` / `tail` : Garder les premières/dernières lignes
|
||||
|
||||
```bash
|
||||
# Garder les 10 premières lignes
|
||||
command | head -10
|
||||
|
||||
# Garder les 10 dernières lignes
|
||||
command | tail -10
|
||||
|
||||
# Garder seulement la dernière ligne
|
||||
command | tail -1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Exemples complets avec explications
|
||||
|
||||
### Exemple 1 : Trouver les gros fichiers
|
||||
|
||||
**Commande :**
|
||||
```bash
|
||||
find /home -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -h | tail -20
|
||||
```
|
||||
|
||||
**Décortiquons pas à pas :**
|
||||
|
||||
| Partie | Rôle |
|
||||
|--------|------|
|
||||
| `find /home` | Cherche dans /home |
|
||||
| `-type f` | Seulement les fichiers |
|
||||
| `-size +100M` | Plus de 100 MB |
|
||||
| `-exec ls -lh {} \;` | Affiche les détails de chaque fichier trouvé |
|
||||
| `2>/dev/null` | Masque les erreurs (permissions refusées) |
|
||||
| `sort -k5 -h` | Trie par la 5ème colonne (taille) en mode humain |
|
||||
| `tail -20` | Garde les 20 derniers = les plus gros |
|
||||
|
||||
---
|
||||
|
||||
### Exemple 2 : Distribution des fichiers par date
|
||||
|
||||
**Commande :**
|
||||
```bash
|
||||
find repo-archive -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c
|
||||
```
|
||||
|
||||
**Décortiquons :**
|
||||
|
||||
| Partie | Rôle |
|
||||
|--------|------|
|
||||
| `find repo-archive -type f` | Trouve tous les fichiers |
|
||||
| `-printf '%TY-%Tm-%Td\n'` | Affiche la date de chaque fichier (format YYYY-MM-DD) |
|
||||
| `sort` | Trie les dates |
|
||||
| `uniq -c` | Compte combien de fichiers par date |
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
676 2026-02-03
|
||||
513 2026-02-04
|
||||
```
|
||||
|
||||
**Interprétation :** 676 fichiers créés le 3 février, 513 le 4 février.
|
||||
|
||||
---
|
||||
|
||||
### Exemple 3 : Taille totale des fichiers récents
|
||||
|
||||
**Commande :**
|
||||
```bash
|
||||
find repo-archive -type f -mtime -1 -exec du -ch {} + | tail -1
|
||||
```
|
||||
|
||||
**Décortiquons :**
|
||||
|
||||
| Partie | Rôle |
|
||||
|--------|------|
|
||||
| `find repo-archive -type f` | Trouve tous les fichiers |
|
||||
| `-mtime -1` | Modifiés dans les dernières 24h |
|
||||
| `-exec du -ch {} +` | Calcule la taille avec total à la fin |
|
||||
| `tail -1` | Garde la dernière ligne (le total) |
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
5.9G total
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Cas pratique : Diagnostic du cache Forgejo
|
||||
|
||||
**Objectif :** Comprendre pourquoi le cache fait 47G.
|
||||
|
||||
### Étape 1 : Taille totale
|
||||
|
||||
```bash
|
||||
du -sh /home/debian/forgejo/data/gitea/repo-archive
|
||||
```
|
||||
|
||||
**Résultat :** `47G`
|
||||
|
||||
---
|
||||
|
||||
### Étape 2 : Nombre de fichiers
|
||||
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive -type f | wc -l
|
||||
```
|
||||
|
||||
**Résultat :** `1189 fichiers`
|
||||
|
||||
---
|
||||
|
||||
### Étape 3 : Distribution par date
|
||||
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c
|
||||
```
|
||||
|
||||
**Résultat :**
|
||||
```
|
||||
676 2026-02-03
|
||||
513 2026-02-04
|
||||
```
|
||||
|
||||
**Interprétation :** Tous les fichiers datent de 2-3 jours. Le cron n'a pas nettoyé ou les bots régénèrent constamment.
|
||||
|
||||
---
|
||||
|
||||
### Étape 4 : Taille des fichiers récents vs anciens
|
||||
|
||||
**Fichiers de moins de 24h :**
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive -type f -mtime -1 | wc -l
|
||||
```
|
||||
**Résultat :** `239 fichiers`
|
||||
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive -type f -mtime -1 -exec du -ch {} + | tail -1
|
||||
```
|
||||
**Résultat :** `5.9G`
|
||||
|
||||
---
|
||||
|
||||
**Fichiers de plus de 24h :**
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive -type f ! -mtime -1 | wc -l
|
||||
```
|
||||
**Résultat :** `957 fichiers`
|
||||
|
||||
```bash
|
||||
find /home/debian/forgejo/data/gitea/repo-archive -type f ! -mtime -1 -exec du -ch {} + | tail -1
|
||||
```
|
||||
**Résultat :** `42G`
|
||||
|
||||
---
|
||||
|
||||
**Conclusion :**
|
||||
- 239 fichiers récents (24h) = 5.9G → **Normal**
|
||||
- 957 fichiers anciens (24h+) = 42G → **PROBLÈME** (auraient dû être supprimés)
|
||||
|
||||
**Cause :** Le cron ne s'est pas exécuté OU Fail2ban n'a pas banni les bots assez vite.
|
||||
|
||||
---
|
||||
|
||||
## Résumé des commandes essentielles
|
||||
|
||||
```bash
|
||||
# Taille d'un dossier
|
||||
du -sh /path/to/folder
|
||||
|
||||
# Nombre de fichiers
|
||||
find /path -type f | wc -l
|
||||
|
||||
# Taille totale des fichiers
|
||||
find /path -type f -exec du -ch {} + | tail -1
|
||||
|
||||
# Fichiers de plus de 6h
|
||||
find /path -type f -mmin +360
|
||||
|
||||
# Supprimer fichiers de plus de 6h
|
||||
find /path -type f -mmin +360 -delete
|
||||
|
||||
# Distribution par date
|
||||
find /path -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c
|
||||
|
||||
# Top 20 gros fichiers
|
||||
find /path -type f -size +100M -exec ls -lh {} \; | sort -k5 -h | tail -20
|
||||
```
|
||||
451
serveur/linux-essentials/diagnostic-espace-disque.md
Normal file
451
serveur/linux-essentials/diagnostic-espace-disque.md
Normal file
|
|
@ -0,0 +1,451 @@
|
|||
# Guide de diagnostic d'espace disque Linux
|
||||
|
||||
Guide complet pour identifier et résoudre les problèmes d'espace disque sur un serveur Linux.
|
||||
|
||||
## 1. Vue d'ensemble : quel disque est plein ?
|
||||
|
||||
```bash
|
||||
df -h
|
||||
```
|
||||
|
||||
**Cherche :**
|
||||
- La ligne `/dev/sda1` (ou `/dev/nvme0n1p1`, `/dev/vda1`) montée sur `/`
|
||||
- Si `Use%` > 80% → Problème
|
||||
|
||||
**Exemple :**
|
||||
```
|
||||
/dev/sda1 59G 57G 171M 100% / ← PROBLÈME ICI
|
||||
```
|
||||
|
||||
**Comprendre la sortie :**
|
||||
|
||||
| Colonne | Signification |
|
||||
|---------|---------------|
|
||||
| Filesystem | Nom du disque/partition |
|
||||
| Size | Capacité totale |
|
||||
| Used | Espace utilisé |
|
||||
| Avail | Espace disponible |
|
||||
| Use% | Pourcentage d'utilisation |
|
||||
| Mounted on | Point de montage (où le disque est accessible) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Niveau 1 : Identifier les gros dossiers à la racine
|
||||
|
||||
```bash
|
||||
sudo du -sh /* 2>/dev/null | sort -h
|
||||
```
|
||||
|
||||
**Explication :**
|
||||
- `du` : **D**isk **U**sage (utilisation disque)
|
||||
- `-s` : **S**ummary (résumé total)
|
||||
- `-h` : **H**uman-readable (Go, Mo au lieu d'octets)
|
||||
- `/*` : Tous les dossiers à la racine
|
||||
- `2>/dev/null` : Masque les erreurs de permission
|
||||
- `sort -h` : Trie par taille humaine (comprend que 10G > 2G)
|
||||
|
||||
**Résultat typique :**
|
||||
```
|
||||
4.0K /mnt
|
||||
128M /boot
|
||||
2.1G /usr
|
||||
15G /var
|
||||
40G /home ← SUSPECT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Niveau 2 : Descendre dans le dossier suspect
|
||||
|
||||
**Si `/home` est gros :**
|
||||
|
||||
```bash
|
||||
sudo du -sh /home/* | sort -h
|
||||
```
|
||||
|
||||
**Si `/var` est gros :**
|
||||
|
||||
```bash
|
||||
sudo du -sh /var/* | sort -h
|
||||
```
|
||||
|
||||
**Continue à descendre dans l'arborescence :**
|
||||
|
||||
```bash
|
||||
# Exemple : /var/lib est gros
|
||||
sudo du -sh /var/lib/* | sort -h
|
||||
|
||||
# Puis /var/lib/docker est gros
|
||||
sudo du -sh /var/lib/docker/* | sort -h
|
||||
```
|
||||
|
||||
**Astuce :** Garde seulement les 10 plus gros avec `tail -10` :
|
||||
|
||||
```bash
|
||||
sudo du -sh /var/* | sort -h | tail -10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Trouver les plus gros fichiers (top 20)
|
||||
|
||||
```bash
|
||||
sudo find /home -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -h | tail -20
|
||||
```
|
||||
|
||||
**Explication :**
|
||||
- `find /home` : Cherche dans /home (change le path selon besoin)
|
||||
- `-type f` : Seulement les fichiers (pas les dossiers)
|
||||
- `-size +100M` : Fichiers de plus de 100 MB
|
||||
- `-exec ls -lh {} \;` : Affiche les détails de chaque fichier trouvé
|
||||
- `sort -k5 -h` : Trie par la 5ème colonne (taille) en mode humain
|
||||
- `tail -20` : Garde les 20 derniers (= les plus gros)
|
||||
|
||||
**Variantes :**
|
||||
|
||||
| Taille | Option |
|
||||
|--------|--------|
|
||||
| Plus de 100 MB | `-size +100M` |
|
||||
| Plus de 500 MB | `-size +500M` |
|
||||
| Plus de 1 GB | `-size +1G` |
|
||||
| Plus de 10 GB | `-size +10G` |
|
||||
|
||||
---
|
||||
|
||||
## 5. Cas particuliers
|
||||
|
||||
### A. Fichiers supprimés mais encore ouverts (fantômes)
|
||||
|
||||
Les fichiers supprimés mais encore ouverts par un processus continuent d'occuper l'espace disque jusqu'à ce que le processus se termine.
|
||||
|
||||
**Identifier les fichiers fantômes :**
|
||||
|
||||
```bash
|
||||
sudo lsof +L1 | grep deleted
|
||||
```
|
||||
|
||||
**Calculer l'espace total occupé :**
|
||||
|
||||
```bash
|
||||
sudo lsof +L1 | grep deleted | awk '{sum+=$7} END {print "Space: " sum/1024/1024/1024 " GB"}'
|
||||
```
|
||||
|
||||
**Solution :** Redémarre le service qui garde les fichiers ouverts :
|
||||
|
||||
```bash
|
||||
# Identifier le processus
|
||||
sudo lsof +L1 | grep deleted
|
||||
|
||||
# Redémarrer le service (exemple avec Docker)
|
||||
docker restart container_name
|
||||
|
||||
# Ou redémarrer un service système
|
||||
sudo systemctl restart service_name
|
||||
```
|
||||
|
||||
### B. Logs système volumineux
|
||||
|
||||
Les logs système peuvent grossir indéfiniment et remplir le disque.
|
||||
|
||||
**Vérifier la taille des logs :**
|
||||
|
||||
```bash
|
||||
sudo journalctl --disk-usage
|
||||
```
|
||||
|
||||
**Nettoyer les logs (garder seulement 500M) :**
|
||||
|
||||
```bash
|
||||
sudo journalctl --vacuum-size=500M
|
||||
```
|
||||
|
||||
**Nettoyer les logs de plus de 7 jours :**
|
||||
|
||||
```bash
|
||||
sudo journalctl --vacuum-time=7d
|
||||
```
|
||||
|
||||
### C. Docker qui prend trop de place
|
||||
|
||||
Docker accumule des images, conteneurs, volumes et cache de build.
|
||||
|
||||
**Voir l'utilisation Docker :**
|
||||
|
||||
```bash
|
||||
docker system df
|
||||
```
|
||||
|
||||
**Exemple de sortie :**
|
||||
```
|
||||
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
|
||||
Images 10 3 2.935GB 2.719GB (92%)
|
||||
Containers 3 2 110.1MB 0B (0%)
|
||||
Local Volumes 1 0 0B 0B
|
||||
Build Cache 35 0 108.7MB 108.7MB
|
||||
```
|
||||
|
||||
**Nettoyer Docker :**
|
||||
|
||||
⚠️ **ATTENTION :** Cette commande supprime :
|
||||
- Toutes les images non utilisées
|
||||
- Tous les conteneurs arrêtés
|
||||
- Tous les volumes non utilisés
|
||||
- Tout le cache de build
|
||||
|
||||
```bash
|
||||
docker system prune -a --volumes
|
||||
```
|
||||
|
||||
**Nettoyage conservateur (seulement les ressources danglings) :**
|
||||
|
||||
```bash
|
||||
docker system prune
|
||||
```
|
||||
|
||||
### D. Cache APT (paquets téléchargés)
|
||||
|
||||
Les paquets `.deb` téléchargés par APT sont conservés dans le cache.
|
||||
|
||||
**Taille du cache :**
|
||||
|
||||
```bash
|
||||
sudo du -sh /var/cache/apt
|
||||
```
|
||||
|
||||
**Nettoyer :**
|
||||
|
||||
```bash
|
||||
sudo apt clean
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Méthodologie complète (étape par étape)
|
||||
|
||||
Voici la séquence complète pour diagnostiquer un problème d'espace disque :
|
||||
|
||||
```bash
|
||||
# 1. Vue globale - quel disque est plein ?
|
||||
df -h
|
||||
|
||||
# 2. Identifier les gros dossiers à la racine
|
||||
sudo du -sh /* 2>/dev/null | sort -h | tail -10
|
||||
|
||||
# 3. Descendre dans le dossier suspect (exemple : /home)
|
||||
sudo du -sh /home/* | sort -h | tail -10
|
||||
|
||||
# 4. Descendre encore plus profond (exemple : /home/debian)
|
||||
sudo du -sh /home/debian/* | sort -h | tail -10
|
||||
|
||||
# 5. Trouver les gros fichiers individuels
|
||||
sudo find /home/debian -type f -size +100M -exec ls -lh {} \; 2>/dev/null
|
||||
|
||||
# 6. Vérifier les fichiers fantômes (supprimés mais ouverts)
|
||||
sudo lsof +L1 | grep deleted
|
||||
|
||||
# 7. Vérifier les logs système
|
||||
sudo journalctl --disk-usage
|
||||
|
||||
# 8. Vérifier Docker
|
||||
docker system df
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Outil interactif : ncdu (recommandé)
|
||||
|
||||
`ncdu` est un outil interactif qui permet d'explorer visuellement l'espace disque, comme un explorateur de fichiers en mode texte.
|
||||
|
||||
**Installation :**
|
||||
|
||||
```bash
|
||||
sudo apt install ncdu
|
||||
```
|
||||
|
||||
**Utilisation :**
|
||||
|
||||
```bash
|
||||
# Scanner un dossier
|
||||
sudo ncdu /home
|
||||
|
||||
# Scanner depuis la racine (lent sur gros disques)
|
||||
sudo ncdu /
|
||||
```
|
||||
|
||||
**Navigation :**
|
||||
- `↑` `↓` : Se déplacer dans la liste
|
||||
- `Entrée` : Entrer dans un dossier
|
||||
- `←` : Remonter au dossier parent
|
||||
- `d` : Supprimer le fichier/dossier (⚠️ ATTENTION !)
|
||||
- `g` : Afficher en graphique
|
||||
- `?` : Aide
|
||||
- `q` : Quitter
|
||||
|
||||
---
|
||||
|
||||
## 8. Mémo rapide (cheat sheet)
|
||||
|
||||
À garder sous la main pour un diagnostic rapide :
|
||||
|
||||
```bash
|
||||
# Vue globale
|
||||
df -h
|
||||
|
||||
# Top 10 gros dossiers dans un path
|
||||
sudo du -sh /path/* | sort -h | tail -10
|
||||
|
||||
# Top 20 gros fichiers dans un path
|
||||
sudo find /path -type f -size +100M -exec ls -lh {} \; 2>/dev/null | tail -20
|
||||
|
||||
# Fichiers fantômes (supprimés mais ouverts)
|
||||
sudo lsof +L1 | grep deleted
|
||||
|
||||
# Logs système
|
||||
sudo journalctl --disk-usage
|
||||
sudo journalctl --vacuum-size=500M
|
||||
|
||||
# Docker
|
||||
docker system df
|
||||
docker system prune -a --volumes
|
||||
|
||||
# Cache APT
|
||||
sudo apt clean
|
||||
|
||||
# Outil interactif
|
||||
sudo ncdu /
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Exemples de problèmes courants
|
||||
|
||||
### Problème 1 : Cache d'archives Git (Forgejo/GitLab)
|
||||
|
||||
**Symptôme :**
|
||||
```
|
||||
/home/user/forgejo/data/gitea/repo-archive → 48G
|
||||
```
|
||||
|
||||
**Cause :** Des bots téléchargent massivement des archives Git via `/repo/archive/main.zip`.
|
||||
|
||||
**Diagnostic :**
|
||||
```bash
|
||||
# Nombre total de fichiers et taille
|
||||
find /path/to/repo-archive -type f | wc -l
|
||||
du -sh /path/to/repo-archive
|
||||
|
||||
# Distribution par date de création
|
||||
find /path/to/repo-archive -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c
|
||||
|
||||
# Identifier les IP qui téléchargent le plus
|
||||
docker logs forgejo --since 24h | grep "archive" | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -10
|
||||
```
|
||||
|
||||
**Solution immédiate : Nettoyage d'urgence**
|
||||
```bash
|
||||
find /home/user/forgejo/data/gitea/repo-archive -type f -delete
|
||||
```
|
||||
|
||||
**Solution pérenne : Bloquer à la source (RECOMMANDÉ)**
|
||||
|
||||
Au lieu de nettoyer en boucle, bloquez les téléchargements abusifs :
|
||||
- Durcir Fail2ban pour bannir plus vite
|
||||
- Rate limiting dans Forgejo
|
||||
- Expiration rapide des archives
|
||||
- Optionnel : désactiver les archives publiques
|
||||
|
||||
→ Voir le guide complet : `bloquer-telechargements-abusifs-forgejo.md`
|
||||
|
||||
### Problème 2 : Logs Docker volumineux
|
||||
|
||||
**Symptôme :**
|
||||
```
|
||||
/var/lib/docker/containers/.../container-json.log → 10G
|
||||
```
|
||||
|
||||
**Solution :**
|
||||
```bash
|
||||
# Limiter la taille des logs Docker
|
||||
sudo nano /etc/docker/daemon.json
|
||||
```
|
||||
|
||||
Ajouter :
|
||||
```json
|
||||
{
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "10m",
|
||||
"max-file": "3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Redémarrer Docker
|
||||
sudo systemctl restart docker
|
||||
```
|
||||
|
||||
### Problème 3 : Base de données SQLite gonflée
|
||||
|
||||
**Symptôme :**
|
||||
```
|
||||
/var/lib/app/database.db → 5G
|
||||
```
|
||||
|
||||
**Solution :**
|
||||
```bash
|
||||
# Vacuum (compacter) la base de données
|
||||
sqlite3 /var/lib/app/database.db "VACUUM;"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Prévention
|
||||
|
||||
**Meilleures pratiques pour éviter les disques pleins :**
|
||||
|
||||
1. **Rotation des logs**
|
||||
- Configurer `logrotate` pour limiter la taille des logs
|
||||
- Utiliser `journalctl --vacuum-size=500M`
|
||||
|
||||
2. **Nettoyage automatique**
|
||||
- Ajouter des crons pour nettoyer les caches/tmp
|
||||
- Docker auto-prune régulier
|
||||
|
||||
3. **Monitoring**
|
||||
- Alertes quand le disque dépasse 80%
|
||||
- Vérifier régulièrement `df -h`
|
||||
|
||||
4. **Limites de taille**
|
||||
- Configurer `max-size` pour les logs Docker
|
||||
- Limiter les caches applicatifs
|
||||
|
||||
5. **Stockage externe**
|
||||
- Monter les gros volumes sur des disques séparés
|
||||
- Utiliser du stockage objet (S3) pour les archives
|
||||
|
||||
---
|
||||
|
||||
## Ressources complémentaires
|
||||
|
||||
**Commandes utiles :**
|
||||
|
||||
```bash
|
||||
# Voir les inodes (nombre de fichiers)
|
||||
df -i
|
||||
|
||||
# Trouver les dossiers avec beaucoup de petits fichiers
|
||||
sudo find / -type d -exec sh -c 'echo "$(find "$1" -maxdepth 1 | wc -l) $1"' _ {} \; 2>/dev/null | sort -n | tail -20
|
||||
|
||||
# Voir l'espace utilisé par utilisateur
|
||||
sudo du -sh /home/* | sort -h
|
||||
|
||||
# Monitoring en temps réel
|
||||
watch -n 5 'df -h'
|
||||
```
|
||||
|
||||
**Pages man utiles :**
|
||||
- `man df` - Afficher l'espace disque
|
||||
- `man du` - Calculer l'utilisation disque
|
||||
- `man find` - Rechercher des fichiers
|
||||
- `man lsof` - Lister les fichiers ouverts
|
||||
Loading…
Add table
Add a link
Reference in a new issue