Placer Cloudflare devant un site WordPress apporte un cache, un pare-feu et une protection contre les attaques par saturation. Mais WordPress ne voit plus vos visiteurs : il voit les serveurs de Cloudflare. Mal corrigé, ce détail désactive la limitation des connexions ou permet à un attaquant de choisir sa propre adresse IP. Voici comment restaurer la vraie IP au bon endroit, protéger l’origine et écrire quelques règles de pare-feu utiles.
Pourquoi WordPress voit l’adresse de Cloudflare
Cloudflare fonctionne en proxy inverse : le visiteur se connecte à Cloudflare, puis Cloudflare ouvre sa propre connexion vers votre serveur. Pour PHP, la variable $_SERVER['REMOTE_ADDR'] contient donc l’adresse du nœud Cloudflare. Tant que rien n’est corrigé :
- la limitation des tentatives de connexion compte les échecs de milliers de visiteurs sur quelques adresses Cloudflare, et finit par bloquer des innocents ou par ne plus rien bloquer ;
- les journaux du serveur et des extensions de sécurité deviennent inexploitables lors d’un incident ;
- les outils antispam des commentaires et les contrôles anti-fraude d’une boutique perdent leur principal indice.

Les en-têtes que Cloudflare transmet
| En-tête | Contenu | Disponibilité |
|---|---|---|
CF-Connecting-IP | Une seule adresse : celle du client connecté à Cloudflare | Toutes les offres |
True-Client-IP | Même valeur, sous le nom utilisé par d’autres CDN | Offre Enterprise, via une transformation gérée |
X-Forwarded-For | Une liste : si la requête en contenait déjà un, Cloudflare y ajoute l’adresse qui s’est connectée | Toutes les offres |
CF-IPCountry | Code pays à deux lettres (XX inconnu, T1 réseau Tor) | Via la transformation gérée des en-têtes de localisation |
CF-Ray | Identifiant de la requête, utile pour le support | Toutes les offres |
X-Forwarded-For est le plus trompeur : sa première valeur peut avoir été écrite par le client lui-même. Une extension qui en prend le premier élément croit n’importe quelle adresse inventée.
Le piège : un en-tête se falsifie en une ligne
Un en-tête HTTP n’est qu’un texte envoyé par le client. Si votre serveur répond aussi en direct, sans passer par Cloudflare, un attaquant peut l’appeler avec CF-Connecting-IP rempli à sa guise. La documentation d’Apache le rappelle pour mod_remoteip : il est trivial pour un client de se faire passer pour un autre, il ne faut faire confiance qu’aux proxys intermédiaires connus.

Les conséquences d’une confiance aveugle sont concrètes : l’attaquant change d’adresse à chaque essai de mot de passe et contourne la limitation, fait bannir l’adresse d’un client légitime, ou brouille vos journaux.
Restaurer la vraie IP au niveau du serveur
Le bon endroit est le serveur web, avant PHP : WordPress et toutes les extensions reçoivent alors la bonne valeur dans REMOTE_ADDR, sans configuration propre à chacune. Cloudflare publie ses plages d’adresses en texte brut sur https://www.cloudflare.com/ips-v4/ et https://www.cloudflare.com/ips-v6/, et via son API https://api.cloudflare.com/client/v4/ips. En octobre 2026, la liste compte 15 plages IPv4 et 7 plages IPv6. Elle évolue rarement, mais elle évolue : automatisez la mise à jour plutôt que de la recopier une fois pour toutes.
Apache : mod_remoteip
Activez le module (a2enmod remoteip sur Debian et Ubuntu), puis déclarez chaque plage. RemoteIPTrustedProxy limite la confiance aux adresses listées : sans directive de ce type, le module fait confiance à tout hôte qui envoie l’en-tête.
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
# ... une ligne par plage IPv4 et IPv6 publiée par Cloudflare
RemoteIPTrustedProxy 2400:cb00::/32
# Journaux : %a (adresse restaurée) au lieu de %h
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Nginx : ngx_http_realip_module
Le module n’est pas compilé par défaut dans Nginx (option --with-http_realip_module) ; vérifiez sa présence avec nginx -V. set_real_ip_from définit les adresses de confiance.
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
# ... une ligne par plage publiée par Cloudflare
set_real_ip_from 2400:cb00::/32;
real_ip_header CF-Connecting-IP;
LiteSpeed et hébergement mutualisé
Sur LiteSpeed, Cloudflare indique que l’option Use Client IP in Header fait apparaître l’adresse du client dans REMOTE_ADDR. Sur un mutualisé sans accès à la configuration, demandez à l’hébergeur s’il restaure déjà l’adresse pour Cloudflare. Méfiez-vous des extraits PHP qui copient HTTP_CF_CONNECTING_IP dans REMOTE_ADDR sans vérifier l’adresse d’origine : ils créent exactement la faille décrite plus haut.
Pour vérifier : connectez-vous en navigation privée, puis comparez l’adresse enregistrée par le serveur ou par votre extension de sécurité avec votre adresse publique.
Fermer l’accès direct à l’origine
Restaurer l’IP ne suffit pas si l’origine reste joignable en direct : l’attaquant contourne alors le pare-feu de Cloudflare. La documentation de Cloudflare compare plusieurs méthodes :
| Méthode | Niveau selon Cloudflare | Offres | Remarque |
|---|---|---|---|
Cloudflare Tunnel (cloudflared) | Le plus sûr | Toutes | L’origine n’a plus d’adresse publique à attaquer |
| Authenticated Origin Pulls | Très sûr | Toutes | Mode SSL Full ou Full (strict) requis ; certificat personnel conseillé |
| Liste blanche des IP Cloudflare | Moyen | Toutes | Plages à tenir à jour ; à combiner avec une autre mesure |
| En-tête secret vérifié par l’origine | Moyen | Toutes | Exposé au rejeu si le secret fuit |
Pensez aussi à l’historique : si l’adresse de votre serveur a été publique avant Cloudflare, des services d’historique DNS l’ont conservée. Cloudflare conseille de proxifier tous les enregistrements DNS concernés et, si possible, de changer l’adresse de l’origine.
Règles de pare-feu utiles pour WordPress
Le pare-feu de Cloudflare n’offre pas les mêmes moyens selon l’offre. Avant d’écrire des règles, vérifiez ce dont vous disposez :
| Fonction | Free | Pro | Business | Enterprise |
|---|---|---|---|---|
| Règles personnalisées | 5 | 20 | 100 | 1 000 |
| Expressions régulières | Non | Non | Oui | Oui |
| Jeu de règles gérées gratuit | Oui | Oui | Oui | Oui |
| Jeu géré Cloudflare et OWASP Core Ruleset | Non | Oui | Oui | Oui |
| Règles de limitation de débit | 1 (par IP, période de 10 s) | Selon l’offre | Selon l’offre | Selon l’offre |
Avec cinq règles gratuites, privilégiez celles qui ciblent les attaques les plus fréquentes sur WordPress. Exemples d’expressions à saisir dans l’éditeur de règles :
# 1. Bloquer XML-RPC si vous ne l'utilisez pas (Jetpack et certaines applis en ont besoin)
(http.request.uri.path eq "/xmlrpc.php")
# 2. Défi géré sur la connexion pour les pays où vous n'avez pas d'utilisateurs
(http.request.uri.path eq "/wp-login.php" and ip.src.country ne "FR")
# 3. Bloquer l'exécution de PHP dans les médias
(http.request.uri.path contains "/wp-content/uploads/" and http.request.uri.path contains ".php")
- Utilisez l’action Managed Challenge plutôt que le blocage sur la page de connexion : un humain passe, un script échoue le plus souvent.
- N’appliquez pas de défi à tout
/wp-admin/:admin-ajax.phpsert aussi aux visiteurs (formulaires, paniers, filtres). - Le champ
ip.src.countryremplaceip.geoip.country, déclaré obsolète. - Une règle par pays gêne vos administrateurs en déplacement : prévoyez une exception par adresse ou un accès par VPN.
Erreurs fréquentes
| Erreur | Symptôme | Correction |
|---|---|---|
| Mode SSL/TLS « Flexible » avec redirection HTTPS sur l’origine | Boucle de redirections infinie | Passer en Full ou Full (strict), que Cloudflare recommande |
Lire la première valeur de X-Forwarded-For | Adresses inventées dans les journaux | Lire CF-Connecting-IP, restauré par le serveur |
| Plages IPv6 oubliées | Une partie des visiteurs garde une adresse Cloudflare | Déclarer les plages IPv4 et IPv6 |
| Origine joignable en direct | Pare-feu contourné, en-têtes falsifiables | Tunnel, Authenticated Origin Pulls ou liste blanche |
| Règle de cache « tout mettre en cache » sans exception | Pages de connexion ou de compte servies à d’autres visiteurs | Exclure /wp-admin/, wp-login.php, panier, compte et les visiteurs connectés |
Par défaut, Cloudflare ne met en cache ni le HTML ni les réponses qui contiennent un en-tête Set-Cookie. Le risque vient des règles qui forcent la mise en cache des pages : c’est là qu’il faut prévoir les exclusions.
WP Masquerade derrière Cloudflare
WP Masquerade Pro ignore volontairement l’en-tête X-Forwarded-For reçu du client, pour éviter l’usurpation décrite plus haut. Sa prise en compte de Cloudflare lit CF-Connecting-IP uniquement quand la requête arrive d’une plage d’adresses officielle de Cloudflare, mise à jour chaque semaine ; la limitation des connexions, les bannissements et les journaux voient alors la vraie adresse du visiteur. Si votre serveur restaure déjà l’adresse (mod_remoteip, real_ip de Nginx), c’est encore mieux et cette option peut rester désactivée. Les compteurs utilisent une empreinte HMAC de l’adresse, jamais l’adresse en clair. Les réglages selon l’hébergement sont détaillés sur la page compatibilité hébergeurs et caches.
À retenir
- Derrière Cloudflare,
REMOTE_ADDRcontient l’adresse de Cloudflare tant que le serveur ne la restaure pas. - Restaurez-la au niveau du serveur (mod_remoteip, realip, option LiteSpeed) avec
CF-Connecting-IPet les seules plages publiées par Cloudflare, IPv6 comprises. - Ne faites jamais confiance à un en-tête d’adresse sans vérifier d’où vient la connexion.
- Fermez l’accès direct à l’origine : Tunnel, Authenticated Origin Pulls ou liste blanche.
- Avec l’offre gratuite, cinq règles personnalisées suffisent pour XML-RPC, la connexion et le PHP dans les médias.
- Évitez le mode SSL Flexible et les règles de cache sans exclusions.
Sources
- Cloudflare : Cloudflare HTTP headers (nouvel onglet)
- Cloudflare : Restoring original visitor IPs (nouvel onglet)
- Apache HTTP Server : mod_remoteip (nouvel onglet)
- Nginx : ngx_http_realip_module (nouvel onglet)
Autres sources consultées : documentation officielle et pages officielles des éditeurs.


