# SECURITY-05 — Durcissement réseau & exposition (4 trous rouges)

**Date** : 2026-06-25
**Contexte** : audit post-remédiation. Snapshots dans `snapshots/security/`
(ufw, fail2ban, wordpress-security). 4 points faibles ouverts identifiés.
**Contrainte** : debug, aucune action serveur sans consentement explicite.

## État audité (2026-06-25)
- UFW : actif, deny incoming, ports 22/80/443. OK (manque `ufw limit` 22 = mineur).
- SSH : root sans mot de passe, password auth off, clé only. OK.
- wp-config : DISALLOW_FILE_MODS=true, salts rotés, WP_DEBUG=false. OK. (révisé le 2026-06-30 — cf. note en bas.)
- uploads/.htaccess : deny exécution PHP (TLO-HARDENING). OK.
- unattended-upgrades : actif. OK.

## Les 4 trous rouges

### #3 — Énumération des comptes (REST + ?author=)  ✅ TRAITÉ EN PREMIER
- `/wp-json/wp/v2/users` -> 200, fuite id/slug des comptes.
- Correctif : mu-plugin `wp-content/mu-plugins/tlo-hardening.php`
  (copie versionnée : `snapshots/security/tlo-hardening.mu.php`).
  - filtre `rest_endpoints` : users masqué si non connecté.
  - `?author=N` : redirection 301 home si non connecté.
  - `xmlrpc_methods` : retire pingback (defense-in-depth, complète #2).
- Contourne DISALLOW_FILE_MODS (mu-plugin = dépôt fichier, pas install admin).
- Rollback : supprimer le fichier.
- Vigilance : vérifier sitemap auteurs Rank Math après dépôt.

### #2 — XML-RPC ouvert  ✅ FAIT (2026-06-25)
- WPML retiré => plus de translationproxy => blocage total sans risque (la raison de la pause a disparu).
- Bloc ajouté au vhost 443 (`/etc/apache2/sites-available/toulouse.conf`) :
  `<Files "xmlrpc.php"> Require all denied </Files>`. configtest OK + reload.
- Vérifié : GET et POST /xmlrpc.php -> **403**, site 200.
- Snapshots : `snapshots/apache/toulouse.conf.before-xmlrpc` / `.after-xmlrpc`. Rollback : retirer le bloc + reload.

### #1 — Fail2ban  ✅ FAIT (2026-06-25)
- fail2ban v1.0.2, banaction=ufw. Confs versionnées dans snapshots/security/.
- [sshd] backend systemd, maxretry 4, ban 1h.
- [wordpress-auth] logpath /var/log/apache2/toulouse.access.log,
  failregex POST wp-login.php " 200 (échec = 200, succès = 302), maxretry 5/5min, ban 2h.
- ignoreip = 127.0.0.1/8 ::1 51.158.96.239.
- xmlrpc EXCLU (cohérence pause #2). Validé : 2 IP SSH bannies (REJECT IN ufw) au démarrage.
- Rollback : systemctl stop fail2ban + apt remove, ou retirer jail.local.

### #4 — WPML pas à jour (CVE-2024-6386, SSTI)  ✅ FERMÉ (2026-06-25)
- Résolu **autrement que par la MAJ** : WPML **retiré** (site mono-langue, 0 traduction EN). Cf SECURITY-06.
- Code vulnérable supprimé du disque → faille éliminée, **sans dépendre de la licence OTGS**.
- SEO vérifié intact (sitemap/canonical/title inchangés). Résidu menu (switcher Twig codé en dur) nettoyé.

## BONUS — Hardening SSH  ✅ APPLIQUÉ (2026-06-25)
Drop-in `/etc/ssh/sshd_config.d/99-tlo-hardening.conf`
(copie versionnée : `snapshots/security/99-tlo-hardening.sshd.conf`).
- MaxAuthTries 6->3, LoginGraceTime 120->30, ClientAliveInterval 0->300 (déco idle).
- X11Forwarding no, AllowTcpForwarding no, MaxSessions 4.
- AllowUsers root ubuntu (jerome exclu : aucune clé, jamais en SSH).
- PermitRootLogin prohibit-password (clé only). NB: idéal=`no`, à basculer après validation workflow ubuntu+sudo.
- Algos modernes only : Ciphers chacha20/aes-gcm, MACs sha2-512/256-etm, Kex curve25519/sntrup761/dh-group16-18.
- Appliqué avec filet auto-rollback (90s, annulé par /tmp/ssh-harden-confirmed). Connexion neuve testée OK.
- Backup conf : /root/sshd_config.bak-20260625.
- Accès SSH réels : root (1 clé ED25519), ubuntu (3 clés, groupe sudo). jerome = web only, pas de clé.
- Rollback : rm le drop-in + reload ssh.

## Ordre d'exécution
1. #3 mu-plugin ✅ — SSH hardening ✅ — 2. #2 xmlrpc (après réponse WPML) — 3. #1 fail2ban — 4. #4 WPML (clé OTGS).

## Révision wp-config (2026-06-30) — réouverture installs + verrou éditeur de code
**Contexte** : l'équipe (`bastienhkt747`, admin) doit pouvoir installer des plugins ; `DISALLOW_FILE_MODS=true` bloquait l'installateur/uploader **pour tous les rôles**. Demande explicite de laisser ouvert.
- `DISALLOW_FILE_MODS` : `true` → **`false`** (L67). Réactive install/màj/suppression plugins+thèmes **+ màj auto de sécurité** (qui étaient aussi bloquées).
- `DISALLOW_FILE_EDIT` : `false` → **`true`** (L185). Désactive l'éditeur de code Plugins/Thèmes en admin = ferme la surface « coller du PHP en un clic » (vecteur de persistance type webshell `aioseo.php`). **Net : installs ON, éditeur de code OFF** — pattern WordPress recommandé.
- Backup : `/root/wp-config.php.bak-20260630`. `php -l` OK. Rollback : restaurer le backup.
- ⚠️ Compromis assumé : l'admin reste une surface d'install ; mitigations en place = comptes admin limités, fail2ban wp-login, mu-plugin anti-énum, deny exécution PHP dans uploads.

## Statut : #1 fail2ban ✅ + #2 xmlrpc ✅ + #3 mu-plugin ✅ + SSH ✅ + #4 WPML retiré ✅ — TOUS les trous rouges fermés
