2026年11月12日
2026年11月12日
Configurar Cloudflare en WordPress: DNS, SSL, IP real y WAF
Este artículo es una edición localizada del original en japonés. Leer el original en japonés
Instalar Cloudflare en WordPress se hace en este orden: ① añadir el sitio a Cloudflare y cambiar los servidores de nombres del dominio, ② poner el modo de cifrado SSL/TLS en Full (strict), ③ restaurar en el servidor la IP real del visitante y ④ proteger la pantalla de inicio de sesión con una regla personalizada de WAF. Incluso con el plan gratuito puedes usar CDN, SSL, protección contra DDoS y reglas personalizadas (hasta 5).
En este artículo se explica cada ajuste y qué comprobar después del cambio. Los nombres y la ubicación de las pantallas de Cloudflare pueden cambiar, por lo que aquí seguimos la documentación oficial (developers.cloudflare.com) a noviembre de 2026.
Qué decidir antes de empezar
- La gestión del DNS pasa a Cloudflare. El registrador donde está registrado el dominio no cambia, pero los registros DNS se editan en el panel de Cloudflare.
- Los registros DNS del correo (MX, etc.) no se pasan por el proxy. Por Cloudflare solo pasa el tráfico web (HTTP/HTTPS).
- Comprueba que el origen (el servidor donde está WordPress) tiene un certificado SSL válido. Si ya tienes HTTPS con Let's Encrypt u otro, no hace falta tocar nada.
- Si has activado DNSSEC en el registrador, desactívalo antes de cambiar los servidores de nombres. Si queda un registro DS antiguo, falla la resolución de nombres.
Paso 1: añadir el sitio y cambiar los servidores de nombres
- Crea una cuenta de Cloudflare y añade el dominio desde el panel (Dashboard). Puedes elegir el plan Free.
- Cloudflare lee tus registros DNS actuales y los muestra en una lista; comprueba que no falte ninguno. Hay registros que no se pueden leer, así que compárala con tu panel de DNS actual y añade a mano los que falten.
- Pon el estado de proxy en activado (nube naranja) para los registros
A(oAAAA,CNAME) del sitio web. Los registrosMXy los registrosAdel servidor de correo se dejan desactivados (solo DNS, nube gris). - Cloudflare muestra dos nombres de servidores de nombres. Tienen la forma
〇〇.ns.cloudflare.comy se asignan a cada cuenta. Usa los dos que aparecen en tu pantalla, no los que veas escritos en otros artículos. - En el panel de tu registrador de dominios, cambia los servidores de nombres a esos dos.
Para comprobar si el cambio ya está activo, usa estos comandos. La propagación puede tardar unas horas.
# ¿Los servidores de nombres son los dos de Cloudflare?
dig NS example.com +short
# ¿Pasa por Cloudflare? (devuelve server: cloudflare y cf-ray)
curl -sI https://example.com | grep -iE '^(server|cf-ray):'
Cuando el estado del dominio en el panel de Cloudflare pasa a activo (Active), el cambio ha terminado.
Paso 2: poner SSL/TLS en Full (strict)
SSL/TLS de Cloudflare tiene modos que determinan cómo se cifra la conexión entre el visitante y Cloudflare, y entre Cloudflare y el origen.
| Modo | Entre Cloudflare y el origen | Cómo se trata en WordPress |
|---|---|---|
| Off | Sin cifrar | No se usa |
| Flexible | HTTP (sin cifrar) | No se usa. Causa bucles de redirección y contenido mixto |
| Full | HTTPS (sin validar el certificado) | Solución temporal hasta tener un certificado |
| Full (strict) | HTTPS (validando el certificado) | Es el que hay que usar |
El modo se cambia en la página de SSL/TLS (Overview) del panel de Cloudflare. La opción predeterminada "Automatic SSL/TLS" elige automáticamente un modo seguro dentro de lo que admite el origen. Si eliges Full (strict) tú mismo, nunca funcionará en un modo que no pretendías. Como certificado del origen sirve uno de una autoridad certificadora pública (Let's Encrypt, etc.) o un certificado Origin CA emitido por Cloudflare.
Este es el motivo para evitar Flexible: con Flexible las peticiones llegan al origen por HTTP, de modo que WordPress o el servidor responden "ha llegado por HTTP, redirijo a HTTPS", Cloudflare vuelve a ir al origen por HTTP, y así en bucle (el navegador muestra ERR_TOO_MANY_REDIRECTS). Con Full (strict) las peticiones llegan al origen también por HTTPS, así que no hace falta código adicional en WordPress que mire X-Forwarded-Proto y reescriba $_SERVER['HTTPS'].
Comprueba también que, en "Ajustes" (Settings) → "Generales" (General) de WordPress, la "Dirección de WordPress (URL)" y la "Dirección del sitio (URL)" empiezan por https://. Si las imágenes y otros recursos siguen con http://, consulta cómo arreglar el contenido mixto.
Paso 3: restaurar la IP real del visitante
Al pasar por Cloudflare, el origen de la conexión que llega al servidor (REMOTE_ADDR) es una dirección IP de Cloudflare. Así, los registros de acceso, la IP de los comentarios y los plugins que limitan los intentos de inicio de sesión tratan a todos los visitantes como una IP de Cloudflare. Cloudflare transmite la IP del visitante en la cabecera CF-Connecting-IP, así que configura el servidor para que solo cuando la conexión provenga de Cloudflare confíe en esa cabecera.
Si reescribes REMOTE_ADDR con el valor de la cabecera sin comprobar el origen de la conexión, quien acceda directamente al origen sin pasar por Cloudflare podrá hacerse pasar por la IP que quiera mediante la cabecera. Por eso no uses el código que aparece en artículos antiguos que solo asigna a REMOTE_ADDR el valor de HTTP_CF_CONNECTING_IP si existe.
La lista de direcciones IP de Cloudflare está publicada en https://www.cloudflare.com/ips/. Como la lista puede cambiar, revísala periódicamente.
Con Nginx
Se usa ngx_http_realip_module. En el bloque http o en el bloque server, enumera todos los rangos de Cloudflare.
# Rangos de IP de Cloudflare (a noviembre de 2026. Consulta lo último en 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
Con Apache (Debian / Ubuntu)
Se usa mod_remoteip. Crea /etc/apache2/conf-available/remoteip.conf y enumera los rangos de Cloudflare en 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
Para que el registro de acceso muestre la IP real, cambia %h por %a en el LogFormat (combined) de /etc/apache2/apache2.conf.
Si no puedes cambiar la configuración del servidor (wp-config.php)
Si usas un hosting compartido o similar y no puedes tocar la configuración del servidor web, haz la misma comprobación en wp-config.php. Colócala antes de la línea require_once ABSPATH . 'wp-settings.php';. Solo cuando la conexión procede de un rango de Cloudflare se usa el valor de CF-Connecting-IP (si es una dirección IP válida).
<?php
// Solo si viene por Cloudflare, usar CF-Connecting-IP como IP del visitante
$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 ya tiene <?php desde el principio, así que no copies el <?php de la primera línea y pega a partir de la segunda. Antes de pegar, haz una copia de seguridad de wp-config.php.
Paso 4: proteger el inicio de sesión con una regla personalizada de WAF
Las reglas personalizadas del WAF de Cloudflare se pueden crear hasta 5 en el plan gratuito y permiten elegir acciones distintas de Log (Block, Managed Challenge, etc.). Para crearlas, en la página Security rules del panel elige "Create rule" y luego "Custom rules", indica la condición (Field, Operator, Value) y la acción, y pulsa "Deploy".
Ejemplo 1: abrir el inicio de sesión y el panel de administración solo a tu IP
Es un ejemplo para cuando tienes una IP fija en casa o en la oficina. Escrita como expresión, queda así (sustituye 203.0.113.10 y 198.51.100.0/24 por tus propias 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}
La acción es Block. /wp-admin/admin-ajax.php se ha excluido de la condición porque funciones de las páginas públicas, como los formularios de contacto o el scroll infinito, pueden llamarlo sin haber iniciado sesión.
Ejemplo 2: sin IP fija, limitar por país con 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"}
Para detectar el país se usa ip.src.country (código de 2 letras de ISO 3166-1). El ip.geoip.country de artículos antiguos está obsoleto. Como acción, empieza con Managed Challenge, revisa en los eventos de seguridad (Security Events) que no se esté bloqueando acceso legítimo y, si hace falta, cámbiala a Block. La documentación de Cloudflare también recomienda esta forma de proceder. xmlrpc.php se usa cuando se publica desde Jetpack o desde aplicaciones del móvil, así que comprueba si lo usas antes de incluirlo en la condición.
La restricción por país es una medida de apoyo que se puede eludir con una VPN y similares. Combínala con la autenticación en dos pasos y el límite de intentos de acceso. El método para detectar el país desde Nginx se explica en Cómo restringir el acceso por país en Nginx con GeoIP2.
Paso 5: comportamiento predeterminado de la caché y purga al publicar
Por defecto, Cloudflare no almacena el HTML en caché. Lo que cachea son archivos estáticos determinados por su extensión: imágenes, CSS, JavaScript, fuentes, etc. Tampoco cachea las respuestas que incluyen la cabecera Set-Cookie. Por eso, si no configuras nada, Cloudflare no guardará en caché el panel de administración ni la pantalla de inicio de sesión.
Si quieres cachear también el HTML, amplía el alcance con Cache Rules, pero entonces tienes que excluir /wp-admin/, /wp-login.php, las vistas previas y lo que ven los usuarios con sesión iniciada. Si lo excluyes mal, las pantallas de administración podrían mostrarse a otras personas, así que si no estás seguro, lo prudente es dejar la configuración por defecto.
Si has cambiado el CSS o las imágenes y la página no cambia, purga (elimina) la caché desde los ajustes de caché del panel. Si quieres purgar automáticamente cada vez que se publique o actualice una entrada, llama a la API de Cloudflare. Primero crea en Cloudflare un token de API que tenga únicamente el permiso "Cache Purge" y escríbelo como constante en wp-config.php, junto con el ID de zona (se muestra en la página de resumen del dominio).
define( 'CF_ZONE_ID', 'ID de zona' );
define( 'CF_API_TOKEN', 'token de API' );
Coloca el siguiente código en el functions.php del tema hijo o en un pequeño plugin propio (también vale con Code Snippets, etc.).
<?php
// Al publicar o actualizar una entrada, eliminar de Cloudflare la caché de esa entrada y de la portada
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 ejecuta cuando se publica una entrada y cuando se actualiza una ya publicada. Además de files, que indica las URL, la API de purge_cache tiene purge_everything para borrarlo todo, pero la purga total obliga a volver a obtener también todos los archivos estáticos, así que no se usa en cada publicación de un artículo.
Qué comprobar después del cambio
- El resultado de
curl -sIincluyeserver: cloudflareycf-ray, y el navegador muestra el candado - Puedes iniciar sesión en el panel de administración, guardar una entrada y subir archivos multimedia
- En los comentarios nuevos y en el registro de acceso queda registrada la IP del visitante, no la de Cloudflare
- Llega el correo desde el formulario de contacto (los registros
MXno pasan por el proxy) - Si has creado una regla personalizada de WAF, abre
wp-login.phpdesde una conexión que no hayas permitido (por ejemplo, la red móvil de tu teléfono) y comprueba que aparece el bloqueo o el desafío
Problemas frecuentes
Aparece ERR_TOO_MANY_REDIRECTS
Comprueba que el modo de SSL/TLS no esté en Flexible. Instala un certificado en el origen y cámbialo a Full (strict) y se soluciona.
Ya no puedo entrar en el panel de administración
Es posible que la condición de la regla personalizada de WAF no incluya tu IP o tu país. Desactiva la regla temporalmente desde el panel de Cloudflare, mira en los eventos de seguridad qué regla te ha bloqueado y corrige la expresión.
Todos los accesos parecen venir de la misma IP
No se ha hecho bien la restauración de la IP real del paso 3. Con Nginx, comprueba el rango de set_real_ip_from y real_ip_header; con Apache, comprueba que remoteip esté activado.
Resumen
- Cambia los servidores de nombres a los dos asignados a tu cuenta y no pases por el proxy los registros de correo, como
MX - SSL/TLS en Full (strict). Flexible causa bucles de redirección y contenido mixto
- La IP real solo se restaura confiando en
CF-Connecting-IPcuando la conexión procede de un rango de Cloudflare - Limita el inicio de sesión con una regla personalizada de WAF por IP o por país y empieza con Managed Challenge para observar
- El HTML no se cachea por defecto. La purga al publicar se hace con un token de API que tenga solo el permiso "Cache Purge"
Artículos relacionados
- Cómo configurar el DNS de Cloudflare
- Cómo configurar el WAF de Cloudflare
- Cómo restringir el acceso por país en Nginx con GeoIP2
- Cómo arreglar el contenido mixto (Mixed Content)
Referencias: Restoring original visitor IPs (Cloudflare), Encryption modes (Cloudflare), Custom rules (Cloudflare WAF), Default cache behavior (Cloudflare)
¿Dudas sobre WordPress? Quien publica este sitio está en Japón y responde en japonés. Contacto (en japonés)