← Contextes /
optimisation-reseau-linux.md 329 lignes · 9.8 KB
Personnaliser Télécharger
# CLAUDE.md — Optimisation réseau Linux (TCP BBR, NIC, Apache, ProFTPD)

Contexte de référence pour le tuning réseau sur Debian/Ubuntu : BBR, ring buffers NIC,
socket buffers ProFTPD/Apache, TLS session cache et OCSP Stapling.

---

## Section 1 : Diagnostic débit

Avant de toucher quoi que ce soit, mesurer et localiser le goulot.

```bash
# Identifier l'interface réseau
ip link show
# ou
ip -brief link show

# Vitesse négociée et état de la liaison
ethtool eth0   # ou enp2s0f0, ens3, etc.
# Speed: 1000Mb/s
# Duplex: Full
# Link detected: yes

# Statistiques NIC : drops ring buffer
ethtool -S eth0 | grep -i -E "drop|miss|error|overflow"
# rx_missed_errors, rx_fifo_errors, rx_over_errors → drops ring buffer
# tx_fifo_errors → drops ring buffer TX

# Statistiques TCP kernel
ss -s
# Retransmissions, connexions en attente

# Compteurs TCP détaillés (pertes, retrans, cwnd drops)
netstat -s | grep -i -E "retransmit|failed|reset|timeout"

# Quel algorithme de congestion est actif
sysctl net.ipv4.tcp_congestion_control
# → cubic (mauvais) ou bbr (bon)

# Modules disponibles
sysctl net.ipv4.tcp_available_congestion_control
# → reno cubic bbr

# Test débit SFTP simple (nécessite un fichier de test)
dd if=/dev/zero of=/tmp/testfile bs=1M count=1024
time sftp user@serveur <<< $'put /tmp/testfile /tmp/testfile'

# Test débit HTTP avec curl
curl -o /dev/null -w "%{speed_download}\n" https://votre-domaine.com/gros-fichier.bin

# Observer les connexions TCP actives et leur état cwnd
ss -tin sport = :22   # SFTP (passe par SSH)
# cwnd: valeur courante de la fenêtre de congestion
```

---

## Section 2 : TCP BBR et sysctl

Fichier `/etc/sysctl.d/99-bbr.conf` — configuration complète :

```bash
# Algorithme de contrôle de congestion
# BBR (Google, 2016) : basé sur mesure de débit + RTT, ne réagit pas aux pertes
# CUBIC (défaut) : réduit cwnd de 50% à chaque perte détectée → mauvais sur liens modernes
net.ipv4.tcp_congestion_control = bbr

# Désactiver le slow start après inactivité
# Par défaut : Linux remet cwnd à 10 après idle. Pénalise les sessions SFTP interactives
# (chaque nouveau transfert après navigation repart en slow start)
net.ipv4.tcp_slow_start_after_idle = 0

# Ne pas réutiliser les métriques TCP des sessions précédentes
# Évite d'hériter d'une cwnd dégradée d'une session antérieure problématique
net.ipv4.tcp_no_metrics_save = 1

# TCP Fast Open client + serveur
# Économise 1 RTT sur les reconnexions en incluant des données dans le SYN
# 1 = client, 2 = serveur, 3 = les deux
net.ipv4.tcp_fastopen = 3

# MTU Path Discovery si ICMP bloqué
# Certains pare-feux bloquent les messages ICMP "fragmentation needed"
# → TCP ne sait pas que les paquets sont trop grands → stalls
# tcp_mtu_probing = 1 active la découverte MTU par TCP lui-même
net.ipv4.tcp_mtu_probing = 1

# Buffer d'écriture TCP [min, default, max] en octets
# min : 4 KB (valeur minimale garantie par socket)
# default : 256 KB (taille initiale du buffer send)
# max : 16 MB (plafond — kernel ajuste dynamiquement entre default et max)
net.ipv4.tcp_wmem = 4096 262144 16777216

# Queue de paquets NIC avant traitement kernel
# À 1 Gbit/s : ~83 000 paquets/s → queue de 5000 entrées évite les drops
# si le kernel est temporairement occupé (interruptions, scheduling)
net.core.netdev_max_backlog = 5000

# Paquets traités par cycle NAPI (New API)
# NAPI = mécanisme d'interruption différée pour les NIC haute performance
# budget = 600 : traiter jusqu'à 600 paquets avant de rendre la main
net.core.netdev_budget = 600
```

Appliquer et vérifier :

```bash
# Charger immédiatement (persistant via le fichier .conf)
sysctl -p /etc/sysctl.d/99-bbr.conf

# Vérifications
sysctl net.ipv4.tcp_congestion_control
# → net.ipv4.tcp_congestion_control = bbr

sysctl net.ipv4.tcp_wmem
# → net.ipv4.tcp_wmem = 4096 262144 16777216

# Si BBR n'est pas disponible : charger le module
lsmod | grep bbr
modprobe tcp_bbr
echo "tcp_bbr" >> /etc/modules-load.d/bbr.conf
```

---

## Section 3 : NIC ring buffers

Le ring buffer NIC est la zone mémoire entre la carte réseau et le kernel.
Si elle sature, les paquets sont dropped silencieusement — CUBIC s'effondre, BBR sous-performe.

```bash
# Vérifier l'état actuel
ethtool -g enp2s0f0
# Ring parameters for enp2s0f0:
# Pre-set maximums:
# RX:     4096
# TX:     4096
# Current hardware settings:
# RX:     256    ← trop petit pour 1 Gbit/s
# TX:     256

# Appliquer (immédiat, non persistant)
ethtool -G enp2s0f0 rx 4096 tx 4096

# Vérifier
ethtool -g enp2s0f0 | grep -A5 "Current hardware"
# RX:     4096
# TX:     4096

# Observer les drops en temps réel
watch -n1 "ethtool -S enp2s0f0 | grep -i -E 'drop|miss|fifo'"
```

Persistance dans `/etc/network/interfaces` :

```
# Exemple de bloc iface complet
auto enp2s0f0
iface enp2s0f0 inet static
    address 192.168.1.10/24
    gateway 192.168.1.1
    dns-nameservers 8.8.8.8
    dns-search example.com
    post-up ethtool -G enp2s0f0 rx 4096 tx 4096
```

Remarques :
- Le nom d'interface varie : `eth0`, `enp2s0f0`, `ens3`... vérifier avec `ip link show`
- Les maximums NIC dépendent du hardware — `ethtool -g` affiche les limites réelles
- Sur les VPS/cloud, les ring buffers sont souvent virtualisés et peuvent ne pas être configurables

---

## Section 4 : ProFTPD socket buffers

Les socket buffers contrôlent la quantité de données que le kernel peut tenir en transit
par connexion TCP, côté applicatif. ProFTPD utilise les défauts système (~87 KB) sauf configuration explicite.

Dans `/etc/proftpd/proftpd.conf`, après `UseSendFile on` :

```apacheconf
# rcvbuf : buffer de réception (données entrantes — uploads)
# sndbuf : buffer d'envoi (données sortantes — downloads)
# 1048576 = 1 MB
SocketOptions rcvbuf 1048576 sndbuf 1048576
```

```bash
# Tester la config avant rechargement
proftpd --configtest

# Recharger
systemctl reload proftpd

# Vérifier que ProFTPD applique bien les valeurs socket
# (nécessite une session SFTP active)
ss -tn dst <ip-client> | grep :22
# sndbuf et rcvbuf visibles dans ss -tm (man ss)
```

---

## Section 5 : Apache SendBufferSize + TLS session cache + OCSP Stapling

### Apache SendBufferSize

Dans `/etc/apache2/apache2.conf` (niveau global, hors VirtualHost) :

```apacheconf
# Buffer d'envoi TCP pour les connexions HTTP
# Sans ce paramètre : valeur système (~87 KB)
# 1048576 = 1 MB
SendBufferSize 1048576
```

### TLS session cache

Dans `/etc/apache2/mods-enabled/ssl.conf` :

```apacheconf
# Cache de sessions TLS en mémoire partagée
# shmcb = shared memory circular buffer
# ${APACHE_RUN_DIR}/ssl_scache = chemin du fichier mémoire partagée
# (10485760) = 10 MB → environ 40 000 sessions simultanées
SSLSessionCache         shmcb:${APACHE_RUN_DIR}/ssl_scache(10485760)
# Durée de vie d'une session en cache : 3600 secondes (1 heure)
SSLSessionCacheTimeout  3600
```

### OCSP Stapling

```apacheconf
# Activer le stapling OCSP
# Apache précharge et met en cache la réponse OCSP de l'AC
# → incluse dans le handshake TLS, le client n'a pas besoin de contacter l'AC
SSLUseStapling          on

# Cache OCSP en mémoire partagée : 2 MB
SSLStaplingCache        shmcb:/var/run/apache2/ssl_stapling(2097152)

# Ne pas renvoyer les erreurs OCSP upstream au client
# Si l'AC est temporairement injoignable, Apache continue sans stapling
# (comportement sécurisé en production)
SSLStaplingReturnResponderErrors off
```

```bash
# Tester la config
apache2ctl configtest

# Recharger
systemctl reload apache2

# Vérifier le stapling
openssl s_client -connect votre-domaine.com:443 -status < /dev/null 2>&1 | grep -A3 "OCSP"
# → OCSP Response Status: successful (0x0)

# Vérifier la reprise de session TLS
openssl s_client -connect votre-domaine.com:443 -reconnect 2>&1 | grep "Reused"
# → Reused, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
```

---

## Section 6 : Vérifications post-déploiement

Checklist complète après application de l'ensemble des optimisations.

```bash
# === BBR ===
sysctl net.ipv4.tcp_congestion_control
# attendu → bbr

sysctl net.ipv4.tcp_slow_start_after_idle
# attendu → 0

sysctl net.ipv4.tcp_wmem
# attendu → 4096 262144 16777216

# === Ring buffers NIC ===
ethtool -g enp2s0f0 | grep -A5 "Current hardware settings"
# attendu → RX: 4096, TX: 4096

# Pas de drops actifs
ethtool -S enp2s0f0 | grep -i -E "drop|miss|fifo" | grep -v " 0$"
# attendu → vide (ou compteurs stables)

# === Statistiques TCP ===
ss -s
# Observer : retransmissions, established, time-wait

# Compteurs de retransmissions
netstat -s | grep -i retransmit
# Idéalement faible par rapport au trafic total

# === ProFTPD ===
proftpd --configtest 2>&1 | grep -i "socket\|error"
systemctl is-active proftpd
# → active

# === Apache ===
apache2ctl configtest
# → Syntax OK

apache2ctl -t -D DUMP_RUN_CFG 2>&1 | grep -i "sendbuffer\|sslsession"

# === TLS ===
# OCSP Stapling
openssl s_client -connect votre-domaine.com:443 -status < /dev/null 2>&1 | \
  grep -E "OCSP Response Status|nextUpdate"
# → OCSP Response Status: successful (0x0)

# Session resumption (reconnect 5 fois)
openssl s_client -connect votre-domaine.com:443 -reconnect 2>&1 | grep -c "Reused"
# → 4 (4 reconnexions sur 5 ont repris la session)

# === Test débit SFTP ===
dd if=/dev/zero of=/tmp/testfile bs=1M count=512
time sftp user@serveur <<< $'put /tmp/testfile /tmp/testfile'
# Comparer avec la valeur avant optimisation

# === Monitoring ongoing ===
# Drops NIC toutes les 10 secondes
watch -n10 "ethtool -S enp2s0f0 | grep -i -E 'drop|miss' | awk '\$2>0'"

# Connexions TCP actives avec cwnd
ss -tin | grep -E "cwnd|rto|rtt"
```