2026年11月12日

2026年11月12日

Configurer Cloudflare avec WordPress : DNS, SSL, IP réelle, WAF

Cet article est une édition localisée de l'original japonais. Lire l'original en japonais

Pour installer Cloudflare sur WordPress, on procède dans l'ordre suivant : ① ajouter le site à Cloudflare et changer les serveurs de noms du domaine, ② passer le mode de chiffrement SSL/TLS en Full (strict), ③ restaurer côté serveur l'IP réelle du visiteur, ④ protéger la page de connexion avec une règle personnalisée du WAF. Même le plan gratuit donne accès au CDN, au SSL, à la protection contre les attaques DDoS et aux règles personnalisées (jusqu'à 5).

Cet article décrit chaque réglage et les points à vérifier après la bascule. Le nom et l'emplacement des écrans de Cloudflare peuvent changer ; il suit ici la documentation officielle (developers.cloudflare.com) en novembre 2026.

Avant de commencer

  • La gestion du DNS passe chez Cloudflare. Le bureau d'enregistrement (registrar) du domaine ne change pas, mais les enregistrements DNS se modifient désormais dans l'interface de Cloudflare.
  • Ne passez pas par le proxy les enregistrements DNS de messagerie (MX, etc.). Seul le trafic web (HTTP/HTTPS) transite par Cloudflare.
  • Vérifiez que l'origine (le serveur qui héberge WordPress) dispose d'un certificat SSL valide. Si HTTPS fonctionne déjà, par exemple avec Let's Encrypt, laissez-le tel quel.
  • Si vous avez activé DNSSEC chez le registrar, désactivez-le avant de changer les serveurs de noms. Un ancien enregistrement DS laissé en place fait échouer la résolution de noms.

Étape 1 : ajouter le site et changer les serveurs de noms

  1. Créez un compte Cloudflare et ajoutez le domaine dans le tableau de bord. Vous pouvez choisir le plan Free.
  2. Cloudflare lit vos enregistrements DNS actuels et les liste : vérifiez qu'il n'en manque aucun. Certains enregistrements ne peuvent pas être lus ; comparez avec votre interface DNS actuelle et ajoutez à la main ceux qui manquent.
  3. Pour les enregistrements A (ou AAAA, CNAME) du site web, activez le proxy (nuage orange). Pour MX et pour les enregistrements A du serveur de messagerie, désactivez-le (DNS uniquement, nuage gris).
  4. Cloudflare affiche deux noms de serveurs de noms, de la forme 〇〇.ns.cloudflare.com, attribués à chaque compte. Utilisez les deux noms affichés sur votre écran, et non ceux cités dans d'autres articles.
  5. Dans l'interface du registrar du domaine, remplacez les serveurs de noms par ces deux-là.

La commande suivante permet de vérifier que la bascule est faite. La propagation peut prendre plusieurs heures.

# Les serveurs de noms sont-ils les deux serveurs de Cloudflare ?
dig NS example.com +short

# Le trafic passe-t-il par Cloudflare ? (server: cloudflare et cf-ray sont renvoyés)
curl -sI https://example.com | grep -iE '^(server|cf-ray):'

Lorsque l'état du domaine passe à actif (Active) dans l'interface de Cloudflare, la bascule est terminée.

Étape 2 : passer SSL/TLS en Full (strict)

Le SSL/TLS de Cloudflare propose des modes qui définissent comment chiffrer la liaison entre le visiteur et Cloudflare, puis entre Cloudflare et l'origine.

Mode Entre Cloudflare et l'origine Pour WordPress
Off Pas de chiffrement À ne pas utiliser
Flexible HTTP (non chiffré) À ne pas utiliser. Cause des boucles de redirection et du contenu mixte
Full HTTPS (certificat non vérifié) Solution provisoire en attendant d'avoir un certificat
Full (strict) HTTPS (certificat vérifié) À choisir

Le réglage se change dans la page d'aperçu (Overview) de SSL/TLS du tableau de bord de Cloudflare. Le mode par défaut « Automatic SSL/TLS » choisit automatiquement le mode le plus sûr dans la limite de ce que l'origine prend en charge. En sélectionnant vous-même Full (strict), vous évitez de fonctionner par erreur dans un autre mode. Le certificat de l'origine peut venir d'une autorité de certification publique (Let's Encrypt, etc.) ou être un certificat Origin CA émis par Cloudflare.

Voici pourquoi il faut éviter Flexible. En Flexible, la requête arrive à l'origine en HTTP ; WordPress ou le serveur répond alors « la requête est arrivée en HTTP, donc je redirige vers HTTPS », puis Cloudflare retourne chercher la page en HTTP, et ainsi de suite en boucle (le navigateur affiche ERR_TOO_MANY_REDIRECTS). Avec Full (strict), la requête arrive aussi en HTTPS à l'origine : il est inutile d'ajouter du code côté WordPress qui lirait X-Forwarded-Proto pour réécrire $_SERVER['HTTPS'].

Vérifiez aussi, dans « Réglages » → « Général » (Settings → General) de WordPress, que « Adresse web de WordPress (URL) » et « Adresse web du site (URL) » commencent par https://. Si des images ou d'autres ressources restent en http://, consultez Comment corriger le contenu mixte.

Étape 3 : restaurer l’IP réelle du visiteur

Lorsque le trafic passe par Cloudflare, la source de connexion (REMOTE_ADDR) que reçoit le serveur est une adresse IP de Cloudflare. En l'état, les journaux d'accès, l'IP des commentaires et les extensions qui limitent les tentatives de connexion traitent tous les visiteurs comme une IP de Cloudflare. Cloudflare transmet l'IP du visiteur dans l'en-tête CF-Connecting-IP ; configurez le serveur pour ne faire confiance à cet en-tête que lorsque la source de la connexion est Cloudflare.

Si l'on réécrit REMOTE_ADDR avec la valeur de l'en-tête sans vérifier la source, quiconque accède directement à l'origine sans passer par Cloudflare peut se faire passer pour l'IP de son choix via l'en-tête. Pour cette raison, n'utilisez pas le code des anciens articles qui se contente d'affecter HTTP_CF_CONNECTING_IP à REMOTE_ADDR s'il existe.

La liste des adresses IP de Cloudflare est publiée sur https://www.cloudflare.com/ips/. Elle peut changer : revoyez-la régulièrement.

Avec Nginx

Utilisez ngx_http_realip_module. Dans le bloc http ou server, listez toutes les plages de Cloudflare.

# Plages d'IP de Cloudflare (état de novembre 2026 ; vérifiez la dernière version sur cloudflare.com/ips)
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;

real_ip_header CF-Connecting-IP;
sudo nginx -t && sudo systemctl reload nginx

Avec Apache (Debian / Ubuntu)

Utilisez mod_remoteip. Créez /etc/apache2/conf-available/remoteip.conf et listez les plages de Cloudflare dans RemoteIPTrustedProxy.

RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22
RemoteIPTrustedProxy 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20
RemoteIPTrustedProxy 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13
RemoteIPTrustedProxy 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22
RemoteIPTrustedProxy 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32
RemoteIPTrustedProxy 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
sudo a2enmod remoteip
sudo a2enconf remoteip
sudo apache2ctl configtest
sudo systemctl restart apache2

Pour que le journal d'accès affiche l'IP réelle, remplacez %h par %a dans le LogFormat (combined) de /etc/apache2/apache2.conf.

Si vous ne pouvez pas modifier la configuration du serveur (wp-config.php)

Sur un hébergement mutualisé où l'on ne peut pas toucher à la configuration du serveur web, faites la même vérification dans wp-config.php. Placez le code avant la ligne require_once ABSPATH . 'wp-settings.php';. La valeur de CF-Connecting-IP (si elle est une adresse IP valide) n'est utilisée que lorsque la source de la connexion appartient aux plages de Cloudflare.

<?php
// N'utiliser CF-Connecting-IP comme IP du visiteur que si la requête passe par Cloudflare
$cf_ranges = [
    '173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22', '103.31.4.0/22',
    '141.101.64.0/18', '108.162.192.0/18', '190.93.240.0/20', '188.114.96.0/20',
    '197.234.240.0/22', '198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/13',
    '104.24.0.0/14', '172.64.0.0/13', '131.0.72.0/22',
    '2400:cb00::/32', '2606:4700::/32', '2803:f800::/32', '2405:b500::/32',
    '2405:8100::/32', '2a06:98c0::/29', '2c0f:f248::/32',
];

function cf_ip_in_range(string $ip, string $cidr): bool
{
    [$net, $bits] = explode('/', $cidr);
    $ip_bin  = inet_pton($ip);
    $net_bin = inet_pton($net);
    if ($ip_bin === false || $net_bin === false || strlen($ip_bin) !== strlen($net_bin)) {
        return false;
    }
    $bits  = (int) $bits;
    $bytes = intdiv($bits, 8);
    if ($bytes > 0 && substr($ip_bin, 0, $bytes) !== substr($net_bin, 0, $bytes)) {
        return false;
    }
    $rest = $bits % 8;
    if ($rest === 0) {
        return true;
    }
    $mask = (0xFF << (8 - $rest)) & 0xFF;
    return (ord($ip_bin[$bytes]) & $mask) === (ord($net_bin[$bytes]) & $mask);
}

if (!empty($_SERVER['HTTP_CF_CONNECTING_IP']) && !empty($_SERVER['REMOTE_ADDR'])) {
    foreach ($cf_ranges as $range) {
        if (cf_ip_in_range($_SERVER['REMOTE_ADDR'], $range)) {
            $visitor = filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP);
            if ($visitor !== false) {
                $_SERVER['REMOTE_ADDR'] = $visitor;
            }
            break;
        }
    }
}

wp-config.php contient déjà <?php dès le début : ne recopiez pas le <?php de la première ligne, et collez à partir de la deuxième ligne. Faites une sauvegarde de wp-config.php avant de coller.

Étape 4 : protéger la page de connexion avec une règle personnalisée du WAF

Les règles personnalisées du WAF de Cloudflare peuvent être créées jusqu'à 5 avec le plan gratuit, et vous pouvez choisir une action autre que Log (Block, Managed Challenge, etc.). Dans le tableau de bord, ouvrez la page Security rules, choisissez « Create rule » puis « Custom rules », indiquez la condition (Field, Operator, Value) et l'action, puis cliquez sur « Deploy ».

Exemple 1 : n’ouvrir la connexion et l’administration qu’à votre propre IP

Exemple pour le cas où vous avez une IP fixe à domicile ou au bureau. L'expression s'écrit comme suit (remplacez 203.0.113.10 et 198.51.100.0/24 par vos propres IP).

(http.request.uri.path eq "/wp-login.php" or starts_with(http.request.uri.path, "/wp-admin/"))
and http.request.uri.path ne "/wp-admin/admin-ajax.php"
and not ip.src in {203.0.113.10 198.51.100.0/24}

Choisissez l'action Block. /wp-admin/admin-ajax.php est exclu de la condition, car il peut être appelé sans connexion par des fonctions des pages publiques, comme les formulaires de contact ou le défilement infini.

Exemple 2 : sans IP fixe, restreindre par pays avec Managed Challenge

(http.request.uri.path eq "/wp-login.php" or http.request.uri.path eq "/xmlrpc.php")
and not ip.src.country in {"JP"}

Pour la détection du pays, utilisez ip.src.country (code à 2 lettres ISO 3166-1). ip.geoip.country, présent dans les anciens articles, est obsolète. Commencez par l'action Managed Challenge, regardez dans les événements de sécurité si des accès légitimes sont bloqués, puis passez à Block si nécessaire. La documentation de Cloudflare recommande aussi cette démarche. xmlrpc.php est utilisé pour publier depuis Jetpack ou depuis une application mobile : vérifiez si vous l'utilisez avant de l'inclure dans la condition.

La restriction par pays est une mesure d'appoint contournable avec un VPN, par exemple. Combinez-la avec l'authentification à deux facteurs et la limitation des tentatives de connexion. La méthode de détection du pays côté Nginx est décrite dans Restreindre l'accès par pays avec Nginx GeoIP2.

Étape 5 : comportement par défaut du cache et purge à la publication

Par défaut, Cloudflare ne met pas le HTML en cache. Il met en cache les fichiers statiques déterminés par leur extension : images, CSS, JavaScript, polices, etc. Il ne met pas non plus en cache les réponses qui contiennent un en-tête Set-Cookie. Ainsi, tant que vous ne changez rien, ni l'administration ni la page de connexion ne sont mises en cache par Cloudflare.

Si vous voulez mettre en cache le HTML aussi, étendez la cible avec les Cache Rules, mais il faut alors exclure de la cible /wp-admin/, /wp-login.php, les aperçus et l'affichage destiné aux utilisateurs connectés. Une exclusion mal faite risque d'afficher à d'autres personnes des écrans destinés aux administrateurs : si vous n'êtes pas sûr de vous, il est plus prudent de rester sur le réglage par défaut.

Si l'affichage ne change pas après le remplacement d'un CSS ou d'une image, purgez (supprimez) le cache depuis les réglages de cache du tableau de bord. Pour purger automatiquement à chaque publication ou mise à jour d'un article, appelez l'API de Cloudflare. Créez d'abord dans Cloudflare un jeton d'API qui n'a que la permission « Cache Purge », puis inscrivez-le, avec l'ID de zone (affiché dans la page d'aperçu du domaine), sous forme de constantes dans wp-config.php.

define( 'CF_ZONE_ID', 'ID_DE_ZONE' );
define( 'CF_API_TOKEN', 'JETON_API' );

Placez le code suivant dans le functions.php d'un thème enfant ou dans une petite extension de votre cru (Code Snippets convient aussi).

<?php
// À la publication ou à la mise à jour d'un article, supprimer de Cloudflare le cache de l'article et de la page d'accueil
function cf_purge_urls(array $urls): bool
{
    if (!defined('CF_ZONE_ID') || !defined('CF_API_TOKEN')) {
        return false;
    }

    $response = wp_remote_post(
        'https://api.cloudflare.com/client/v4/zones/' . CF_ZONE_ID . '/purge_cache',
        [
            'headers' => [
                'Authorization' => 'Bearer ' . CF_API_TOKEN,
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode(['files' => array_values($urls)]),
            'timeout' => 15,
        ]
    );

    if (is_wp_error($response)) {
        error_log('Cloudflare purge failed: ' . $response->get_error_message());
        return false;
    }

    $result = json_decode(wp_remote_retrieve_body($response), true);
    return !empty($result['success']);
}

add_action('publish_post', function (int $post_id): void {
    if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
        return;
    }
    cf_purge_urls([get_permalink($post_id), home_url('/')]);
});

publish_post se déclenche lorsqu'un article est publié et lorsqu'un article déjà publié est mis à jour. L'API purge_cache accepte files, qui désigne des URL, mais aussi purge_everything, qui supprime tout ; toutefois, une purge totale oblige à retélécharger aussi tous les fichiers statiques : ne l'utilisez pas à chaque publication d'article.

À vérifier après la bascule

  • Le résultat de curl -sI contient server: cloudflare et cf-ray, et le navigateur affiche le cadenas
  • Vous pouvez vous connecter à l'administration, enregistrer un article et téléverser un média
  • Les nouveaux commentaires et les journaux d'accès enregistrent l'IP du visiteur et non une IP de Cloudflare
  • Les e-mails du formulaire de contact arrivent (les enregistrements MX ne passent pas par le proxy)
  • Si vous avez créé une règle personnalisée du WAF, ouvrez wp-login.php depuis une connexion non autorisée (par exemple le réseau mobile d'un smartphone) et vérifiez qu'un blocage ou un challenge s'affiche

Problèmes fréquents

ERR_TOO_MANY_REDIRECTS s’affiche

Vérifiez que le mode SSL/TLS n'est pas Flexible. Installez un certificat sur l'origine et passez en Full (strict) : le problème disparaît.

Impossible d’accéder à l’administration

Il est possible que votre IP ou votre pays ne figure pas dans la condition de la règle personnalisée du WAF. Désactivez temporairement la règle depuis le tableau de bord de Cloudflare, repérez dans les événements de sécurité quelle règle a bloqué l'accès, puis corrigez l'expression.

Tous les accès semblent venir de la même IP

La restauration de l'IP réelle de l'étape 3 n'est pas en place. Avec Nginx, vérifiez les plages de set_real_ip_from et real_ip_header ; avec Apache, vérifiez que remoteip est activé.

Conclusion

  • Passez aux deux serveurs de noms attribués à votre compte, et ne faites pas transiter par le proxy les enregistrements de messagerie comme MX
  • SSL/TLS en Full (strict). Flexible provoque des boucles de redirection et du contenu mixte
  • Restaurez l'IP réelle en ne faisant confiance à CF-Connecting-IP que lorsque la source de la connexion est dans les plages de Cloudflare
  • Limitez la page de connexion par IP ou par pays avec une règle personnalisée du WAF, en commençant par Managed Challenge pour observer
  • Le HTML n'est pas mis en cache par défaut. La purge à la publication se fait avec un jeton d'API limité à la permission « Cache Purge »

Articles associés

Références : Restoring original visitor IPs (Cloudflare), Encryption modes (Cloudflare), Custom rules (Cloudflare WAF), Default cache behavior (Cloudflare)

Une question sur WordPress ? L'éditeur de ce site est basé au Japon et répond en japonais. Contact (en japonais)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲