Durcir Apache2 pour WordPress : en-têtes de sécurité, CSP pragmatique, IP réelle derrière Cloudflare/Reverse proxy, règles .htaccess et bonnes pratiques 2025.
Prérequis & principes
- Ubuntu 22.04/24.04 avec Apache2, WordPress installé (
/var/www/html/wordpressà adapter). - Accès sudo/root.
- Objectif : sécurité pragmatique (ne pas casser l’admin WP), durcissement incrémental.
Modules requis : headers, rewrite, ssl, remoteip (si proxy/CDN).
sudo a2enmod headers rewrite ssl remoteip
sudo systemctl reload apache2
En-têtes HTTP de sécurité (Apache)
Créez une configuration dédiée aux en-têtes. Cette baseline est prudente et compatible WordPress par défaut (front et admin). Ajustez-la selon vos extensions/CDN.
# /etc/apache2/conf-available/security-headers.conf
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "accelerometer=(), geolocation=(), microphone=(), camera=()"
Header always set X-XSS-Protection "1; mode=block"
</IfModule>
sudo a2enconf security-headers
sudo systemctl reload apache2
Réduisez la verbosité serveur :
# /etc/apache2/conf-available/security-tuning.conf
ServerTokens Prod
ServerSignature Off
sudo a2enconf security-tuning
sudo systemctl reload apache2
CSP (Content-Security-Policy) : baseline front & admin
Une CSP stricte casse facilement l’admin WP. On propose donc deux politiques : front (plus stricte) et admin (plus permissive). Commencez en mode Report-Only si besoin.
Front (pages publiques)
# /etc/apache2/conf-available/csp-front.conf
<IfModule mod_headers.c>
<LocationMatch "^/(?!wp-admin|wp-login\.php)">
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline' https:; script-src 'self' 'unsafe-inline' https:; font-src 'self' data: https:; frame-ancestors 'self';"
</LocationMatch>
</IfModule>
Admin (wp-admin)
# /etc/apache2/conf-available/csp-admin.conf
<IfModule mod_headers.c>
<Location /wp-admin>
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline' https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; font-src 'self' data: https:; frame-ancestors 'self';"
</Location>
</IfModule>
Activez puis testez (si votre thème/plug-ins chargent des ressources externes, ajoutez leurs domaines aux directives img-src, script-src, style-src, etc.).
sudo a2enconf csp-front csp-admin
sudo systemctl reload apache2
IP réelle client (Cloudflare / reverse proxy)
Derrière Cloudflare/proxy, Apache voit l’IP du proxy. Activez mod_remoteip pour consigner l’IP client réelle et fiabiliser vos règles (WAF/ban, logs, analytics).
# /etc/apache2/conf-available/remoteip-cloudflare.conf
RemoteIPHeader CF-Connecting-IP
# Ajoutez les ranges Cloudflare v4 / v6 (extrait)
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
RemoteIPTrustedProxy 103.22.200.0/22
RemoteIPTrustedProxy 103.31.4.0/22
# ... (complétez avec toutes les plages officielles CF)
Optionnel : remplacez %h par %a pour que les logs utilisent l’IP client réelle :
sudo sed -i 's/LogFormat "%h %l %u/LogFormat "%a %l %u/' /etc/apache2/apache2.conf
sudo a2enconf remoteip-cloudflare
sudo systemctl reload apache2
.htaccess : protections utiles pour WordPress
Conservez d’abord le bloc WordPress, puis ajoutez des règles de protection. Évitez de surcharger : le gros des règles doit vivre en /etc/apache2/ côté vhost/conf.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# Bloquer fichiers sensibles
<FilesMatch "(^\.|wp-config\.php|readme\.html|license\.txt|composer\.(json|lock))">
Require all denied
</FilesMatch>
# Interdire exécution PHP dans uploads (créez aussi .htaccess sous /uploads)
# (double filet : utile si AllowOverride)
<Directory "wp-content/uploads">
<FilesMatch "\.php$"> Require all denied </FilesMatch>
</Directory>
# Limiter XML-RPC (si non utilisé). Préférez règles WAF CF si possible.
<Files xmlrpc.php>
Require all denied
</Files>
HTTPS / HSTS (rappel rapide)
Forcez le HTTPS et activez HSTS uniquement si tout le site est servi en HTTPS sans contenu mixte.
# VHost 80 > redirection HTTPS
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
# VHost 443 (Let’s Encrypt)
<IfModule mod_headers.c>
# Activez HSTS quand vous êtes prêt (testez avant preload)
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
</IfModule>
Validation & debug
- Vérifier en-têtes :
curl -sI https://example.com | less - Tester la CSP : passez d’abord en Report-Only, analysez la console navigateur, ajustez les domaines autorisés.
- Confirmer IP réelle : regardez vos logs Apache (le premier champ doit afficher l’IP client réelle, pas celle de Cloudflare).
Maillage interne
FAQ
Puis-je activer une CSP très stricte sans casser WordPress ?
WordPress et certains thèmes/plug-ins utilisent des scripts et styles inline. Une CSP trop stricte (sans 'unsafe-inline' ni nonces) casse souvent l’admin. Commencez avec une politique pragmatique, puis durcissez progressivement en listant précisément les domaines de confiance.
Faut-il bloquer totalement xmlrpc.php ?
Si vous n’utilisez pas de services qui en dépendent (ex. anciennes apps mobiles), oui : bloquez-le côté Apache ou via Cloudflare (règle WAF). Sinon, limitez par IP et surveillez via un IDS comme CrowdSec.
Comment vérifier que l’IP réelle client est bien consignée ?
Après configuration de mod_remoteip, vérifiez les logs d’accès Apache : la première colonne doit afficher l’IP publique du visiteur (pas l’IP Cloudflare). Vous pouvez tester en visitant le site depuis une connexion 4G/5G et en consultant la dernière entrée de log.
HSTS peut-il casser mon site ?
HSTS force le navigateur à utiliser HTTPS. Si une partie du site n’est pas prête (contenu mixte, sous-domaines non SSL), vous risquez des erreurs. Activez-le uniquement lorsque tout est en HTTPS correct, puis augmentez progressivement la durée (max-age).
Conclusion
Le durcissement Apache2 pour WordPress repose sur des en-têtes solides, une CSP progressive, la bonne IP client quand on est derrière Cloudflare, et des règles .htaccess simples mais efficaces. Appliquez, testez, itérez : la sécurité est un processus continu.










