Permitir solo las IP de Cloudflare en nginx, Apache e IIS
Cómo permitir solo las IP de Cloudflare en los puertos 80 y 443 con UFW, nginx, Apache e IIS, mantener la lista al día y evitar accesos directos al origen.
El proxy de Cloudflare oculta la dirección IP de tu servidor y añade protección DDoS, pero solo para el tráfico que de verdad pasa por Cloudflare. [1] Quien descubra la IP real puede conectarse directamente al servidor y saltarse todo eso. Esta guía explica cómo permitir solo las IP de Cloudflare en los puertos 80 y 443, con UFW y nginx o Apache en Ubuntu 24.04 y con Windows Defender Firewall e IIS en Windows Server 2022 o 2025, y cómo mantener al día la lista de Cloudflare.
Por qué cualquiera con la IP de tu servidor puede saltarse Cloudflare
Las peticiones que van directamente a la IP de tu servidor nunca pasan por Cloudflare, así que no se les aplica ninguna de sus protecciones. Un registro DNS con proxy oculta la IP de origen, y Cloudflare te pide que permitas sus direcciones IP en el origen para que lleguen sus propias peticiones. [1] Su recomendación a nivel de red va más allá: bloquear de forma explícita todo el tráfico que no venga de Cloudflare ni de socios de confianza. [1]
Limita a Cloudflare solo los puertos TCP 80 y 443. Mantén SSH en Linux y el Escritorio remoto en Windows limitados a tu propia dirección IP o a una VPN: nuestra lista de comprobación para reforzar SSH y la guía de red privada con WireGuard explican cómo hacer ambas cosas.
Cloudflare considera que una lista de IP permitidas es moderadamente segura, y que Authenticated Origin Pulls y Cloudflare Tunnel son muy seguros. [1] Por eso esta guía combina varias comprobaciones en capas:
| Capa | Qué comprueba | Herramientas |
|---|---|---|
| 1. Cortafuegos | Que la conexión venga de un rango de Cloudflare | UFW, Windows Defender Firewall |
| 2. Servidor web | IP real del visitante, nombres de host desconocidos | nginx, Apache, IIS |
| 3. Authenticated Origin Pulls | El certificado de cliente de Cloudflare | nginx o Apache |
| Alternativa: Cloudflare Tunnel | Ningún puerto web abierto | cloudflared |
Un cortafuegos en el propio servidor no puede frenar una inundación de tráfico lo bastante grande como para saturar su conexión. Los planes de la UE de StealthRDP incluyen protección DDoS a nivel de red; los planes de EE. UU. no. Nuestra lista de comprobación de protección DDoS para VPS cubre esa parte.
Dónde publica Cloudflare sus rangos de IP
La página IP Ranges de Cloudflare, en www.cloudflare.com/ips, está pensada como la lista definitiva. Enlaza copias en texto plano en www.cloudflare.com/ips-v4 y www.cloudflare.com/ips-v6, y la misma lista está disponible en la API de Cloudflare. [2]
La lista sí cambia. Su historial de cambios muestra que 199.27.128.0/21 se retiró en 2017, que 104.16.0.0/12 se sustituyó en 2021 por 104.16.0.0/13 y 104.24.0.0/14, y que 2405:b500::/32 se retiró en 2022 y volvió a añadirse en 2023. [2] Si te falta un rango, se bloquean las peticiones de Cloudflare que llegan desde él [1], así que una lista copiada una sola vez acabará quedándose desfasada.
Cómo permitir solo las IP de Cloudflare en UFW
Para permitir solo las IP de Cloudflare en UFW, añade reglas para los puertos 80 y 443 desde cada rango de Cloudflare y después borra las reglas que abren esos puertos a todo el mundo. UFW es la herramienta de cortafuegos predeterminada de Ubuntu y viene desactivada; puede abrir un puerto a un solo host o a una red, como en sudo ufw allow proto tcp from 192.168.0.2 to any port 22, y gestiona tanto IPv4 como IPv6. [3]
Permite SSH desde tu propia IP antes de activar UFW o de borrar cualquier regla. Si te quedas fuera, solo podrás volver a entrar desde la consola de tu proveedor.
1. Mantén SSH abierto para tu propia IP
sudo ufw allow proto tcp from 198.51.100.7 to any port 22
sudo ufw enable
sudo ufw status verbose2. Añade el script de actualización
El script descarga las dos listas y se detiene si alguna parece incorrecta. Añade las reglas de los rangos nuevos antes de borrar las de los rangos retirados, así que el sitio sigue funcionando mientras se ejecuta; para eliminar una regla, basta con ufw delete seguido de la regla. [3] También genera los archivos de rangos para nginx y Apache.
#!/usr/bin/env bash
# Rebuild Cloudflare's IP ranges for UFW, nginx and Apache.
set -euo pipefail
export LC_ALL=C PATH=/usr/sbin:/usr/bin:/sbin:/bin
STATE=/etc/cloudflare-ips.txt
NEW=$(mktemp)
trap 'rm -f "$NEW"' EXIT
v4=$(curl -fsS --max-time 30 https://www.cloudflare.com/ips-v4)
v6=$(curl -fsS --max-time 30 https://www.cloudflare.com/ips-v6)
printf '%s\n%s\n' "$v4" "$v6" | grep -E '^[0-9a-fA-F:.]+/[0-9]+$' | sort -u > "$NEW"
# Stop before touching anything if a list is missing or cut short.
if ! grep -q '\.' "$NEW" || ! grep -q ':' "$NEW" || [ "$(wc -l < "$NEW")" -lt 10 ]; then
echo "Cloudflare lists look wrong; nothing changed" >&2
exit 1
fi
touch "$STATE"
# Add new ranges first, then remove the ones Cloudflare dropped.
comm -13 "$STATE" "$NEW" | while read -r net; do
ufw allow proto tcp from "$net" to any port 80
ufw allow proto tcp from "$net" to any port 443
done
comm -23 "$STATE" "$NEW" | while read -r net; do
ufw delete allow proto tcp from "$net" to any port 80 || true
ufw delete allow proto tcp from "$net" to any port 443 || true
done
cp "$NEW" "$STATE"
if command -v nginx > /dev/null; then
{ sed 's/.*/set_real_ip_from &;/' "$NEW"; echo 'real_ip_header CF-Connecting-IP;'; } \
> /etc/nginx/conf.d/cloudflare-realip.conf
nginx -t && systemctl reload nginx
fi
if command -v apache2ctl > /dev/null; then
cp "$NEW" /etc/apache2/cloudflare-ips.lst
apache2ctl configtest && systemctl reload apache2
fi3. Prográmalo y borra las reglas web abiertas a todos
Ejecuta el script una vez y después deja que cron lo ejecute cada día:
sudo chmod 755 /usr/local/sbin/cloudflare-ips
sudo /usr/local/sbin/cloudflare-ips
echo '17 4 * * * root /usr/local/sbin/cloudflare-ips' | sudo tee /etc/cron.d/cloudflare-ipsBorra las reglas web abiertas a todos solo después de que el script haya añadido los rangos de Cloudflare. Si no, el sitio dejará de funcionar para todo el mundo.
Después, muestra las reglas numeradas y borra todas las que todavía permitan el 80 o el 443 desde cualquier dirección, incluidos los perfiles de aplicación, escribiendo cada regla igual que cuando la añadiste. [3]
sudo ufw status numbered
# For example, if you once ran "ufw allow 80" and "ufw allow 443":
sudo ufw delete allow 80
sudo ufw delete allow 443
sudo ufw status numberedLos puertos publicados por Docker se saltan UFW
Si tu servidor web se ejecuta en Docker con puertos publicados, estas reglas de UFW no lo protegen.
Docker desvía el tráfico de un puerto publicado en la tabla nat, antes de que llegue a la cadena INPUT que usa UFW, así que las reglas de UFW no se aplican a ese puerto. [4] Docker también desaconseja editar sus reglas, y desactivar su gestión de iptables probablemente rompa la red de los contenedores. [4] Ejecuta directamente en el host el servidor web que recibe el tráfico de Cloudflare, o filtra el tráfico en un cortafuegos situado delante del servidor.
nginx y Apache: restaura la IP de los visitantes y rechaza las peticiones directas a la IP
Los dos servidores web pueden sustituir la dirección de Cloudflare por la del visitante, que Cloudflare envía en la cabecera CF-Connecting-IP. [5] Lo necesitas porque, con el cortafuegos en marcha, todas las peticiones llegan desde una dirección de Cloudflare. Confía en la cabecera solo si llega desde los rangos de Cloudflare; Cloudflare advierte de que, si no, podría falsificarse. [5]
nginx
La configuración de Cloudflare para nginx usa el módulo realip: una línea set_real_ip_from por cada rango de Cloudflare más real_ip_header CF-Connecting-IP, con los rangos siempre al día. [5] El script de actualización genera este archivo:
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
# ...one line for every Cloudflare range...
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;Después, rechaza las peticiones dirigidas a nombres que no alojas, como una petición directa a la IP: Cloudflare recomienda aceptar solo los valores de la cabecera Host que esperas. [1] En nginx, de eso se encarga un servidor por defecto. deny all rechaza todas las peticiones que llegan a él [6], y ssl_reject_handshake on rechaza los handshakes TLS en su bloque server; el propio ejemplo de nginx lo combina con default_server, de modo que fallan los handshakes para cualquier otro nombre. La directiva requiere nginx 1.19.4 o una versión posterior. [7]
server {
listen 80 default_server;
listen [::]:80 default_server;
deny all;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_reject_handshake on;
}Quita default_server de cualquier otro bloque server en estos puertos, activa el archivo y recarga nginx.
nginx también podría guardar la lista de Cloudflare como líneas allow seguidas de un deny all final, ya que las reglas se comprueban en orden hasta que una coincide. [6] Usa esto solo en un servidor que no restaure las IP de los visitantes y, en ese caso, registra en el log $http_cf_connecting_ip. [5] Una dirección restaurada es la del visitante, así que una lista de permitidos solo con las IP de Cloudflare rechazaría a los visitantes reales, como explica con detalle la documentación de Apache para su propio módulo. [8]
Apache 2.4
Los pasos de Cloudflare para Apache usan mod_remoteip: activa el módulo, define RemoteIPHeader CF-Connecting-IP, incluye los rangos de Cloudflare como proxies de confianza en /etc/apache2/conf-available/remoteip.conf, activa ese archivo y cambia %h por %a en la línea LogFormat del formato combined de /etc/apache2/apache2.conf. [5] RemoteIPTrustedProxyList lee los rangos de un archivo al arrancar, lo que encaja con el script. [8]
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxyList /etc/apache2/cloudflare-ips.lstsudo a2enmod remoteip
sudo a2enconf remoteip
sudo apache2ctl configtest
sudo systemctl restart apache2Hay dos detalles importantes. Sin proxies de confianza, mod_remoteip confía en la cabecera venga del host que venga, así que cualquiera podría falsificar su dirección. [8] Y, tras la sustitución, Require ip y el campo %a del log ven la dirección del visitante, mientras que %{c}a y CONN_REMOTE_ADDR conservan la dirección de Cloudflare que abrió la conexión. [8] Por eso, mantén los rangos de Cloudflare en la lista de confianza y en el cortafuegos, y usa Require ip solo para reglas sobre visitantes, como una página de administración limitada a tu IP.
IIS en Windows Server: limita los puertos 80 y 443 a Cloudflare
En un VPS Windows con Windows Server 2022 o 2025, Windows Defender Firewall hace lo mismo desde PowerShell. New-NetFirewallRule acepta subredes IPv4 e IPv6 en formato CIDR en el parámetro -RemoteAddress, así que una sola regla puede contener todos los rangos, y Set-NetFirewallRule modifica una regla existente. [9]
No toques las reglas de Escritorio remoto y mantén RDP limitado a tu propia IP. Si desactivas la regla equivocada, puedes quedarte fuera del servidor.
$ErrorActionPreference = 'Stop'
$ranges = foreach ($list in 'ips-v4', 'ips-v6') {
(Invoke-RestMethod "https://www.cloudflare.com/$list") -split "`n" |
ForEach-Object { $_.Trim() } | Where-Object { $_ -match '^[0-9a-fA-F:.]+/\d+$' }
}
$v6 = @($ranges | Where-Object { $_ -match ':' })
if ($ranges.Count -lt 10 -or $v6.Count -eq 0 -or $v6.Count -eq $ranges.Count) {
throw 'Cloudflare lists look wrong; nothing changed'
}
$name = 'Cloudflare HTTP and HTTPS'
if (Get-NetFirewallRule -DisplayName $name -ErrorAction SilentlyContinue) {
Set-NetFirewallRule -DisplayName $name -RemoteAddress $ranges
} else {
New-NetFirewallRule -DisplayName $name -Direction Inbound -Protocol TCP `
-LocalPort 80,443 -RemoteAddress $ranges -Action Allow
}Una regla con la acción Allow deja pasar todos los paquetes que coinciden con ella [9], así que cualquier otra regla activada que permita el 80 o el 443 desde cualquier dirección los deja abiertos para todo el mundo. Muestra esas reglas, revisa cada una y desactiva las que no sean tuyas:
Get-NetFirewallRule -Direction Inbound -Action Allow -Enabled True |
Where-Object { $_.DisplayName -ne 'Cloudflare HTTP and HTTPS' -and
(($_ | Get-NetFirewallPortFilter).LocalPort -match '^(80|443)$') } |
Select-Object Name, DisplayName
# After checking a rule: Set-NetFirewallRule -Name '<Name>' -Enabled FalseEn IIS, de la versión 8.5 a la 10, Cloudflare explica cómo registrar la IP real del visitante añadiendo CF-Connecting-IP como campo personalizado: en IIS Manager, abre Logging en el sitio, selecciona el formato W3C, elige Select Fields y añade la cabecera. [5] Eso solo cambia el log; tu aplicación sigue viendo la dirección de Cloudflare. [5]
Authenticated Origin Pulls: la comprobación más sólida en el origen
Authenticated Origin Pulls (AOP) añade TLS mutuo: Cloudflare presenta un certificado de cliente cuando se conecta a tu origen, y el servidor web lo comprueba. Requiere el modo de cifrado SSL/TLS Full o superior. [10] La configuración global usa un certificado de Cloudflare que comparten todas las cuentas de Cloudflare, así que solo demuestra que la petición viene de la red de Cloudflare; para una comprobación vinculada a tu cuenta, sube tu propio certificado con AOP a nivel de zona o por nombre de host. [10]
Descarga el certificado de origin pull de Cloudflare (.PEM) desde la guía de configuración y cópialo al servidor; no es el certificado de Cloudflare Origin CA. [10] Configura el servidor web para que lo use, todavía sin exigir nada; en nginx eso significa ssl_verify_client optional, que pide un certificado de cliente y lo verifica si se envía. [7] Después activa AOP en Cloudflare: página Origin Server, pestaña Authenticated Origin Pulls, sección Global. [10]
Haz obligatoria la comprobación solo cuando AOP esté activado en Cloudflare y el sitio siga funcionando. Si el origen exige un certificado que Cloudflare no envía, todos los visitantes reciben un error.
Si el sitio sigue funcionando, hazla obligatoria: ssl_verify_client on en nginx, SSLVerifyClient require en Apache. [10]
ssl_client_certificate /etc/nginx/certs/cloudflare.crt;
ssl_verify_client optional; # change to "on" to enforceSSLCACertificateFile /etc/apache2/certs/origin-pull-ca.pem
# add this line to enforce:
SSLVerifyClient requireCloudflare Tunnel: sin ningún puerto web de entrada
Cloudflare Tunnel cierra los puertos web en lugar de filtrarlos. El demonio cloudflared de tu servidor solo establece conexiones salientes hacia Cloudflare, así que el sitio no necesita una dirección IP enrutable públicamente. [1] Con el túnel activo, los puertos 80 y 443 pueden quedarse cerrados. Cloudflare califica Tunnel como muy seguro y lo ofrece a todos sus clientes; a cambio, tienes un servicio más que mantener en marcha. [1]
Cómo se filtra la IP de origen y cómo comprobar el bloqueo
La IP de origen suele filtrarse a través de registros en modo DNS only, del correo en el mismo servidor o del historial antiguo de DNS, como explica la guía de protección del origen de Cloudflare. [1]
- Registros en modo DNS only que contienen la IP de origen, incluidos los registros SPF y TXT.
- Correo en el mismo servidor: un correo a una dirección inexistente rebota y muestra la IP del servidor de correo.
- Historial de DNS: los registros antiguos se conservan y muestran la IP que usabas antes de Cloudflare.
Cloudflare recomienda cambiar la IP de origen una vez que tengas el dominio en Cloudflare. [1] Hazlo después de restringir el acceso, para que la nueva dirección nunca haya sido pública. Todos los servidores de StealthRDP, ya sean VPS Linux o Windows, tienen una dirección IPv4 dedicada, y cada cambio de IP cuesta 5 € y se solicita al soporte.
Después, haz la prueba desde tu propio equipo, al que el cortafuegos ya no deja entrar por los puertos 80 y 443:
# Straight to the origin IP: both should hang, then fail
curl http://203.0.113.10/
curl https://203.0.113.10/
# Through Cloudflare: should return your page
curl https://www.example.com/Lo que quieres ver es un timeout. Una página 403, o cualquier error de TLS o de certificado, significa que la petición llegó al servidor web, así que el cortafuegos sigue abierto.
Una vez que AOP sea obligatorio, una petición que no pase por Cloudflare también debería fallar en la comprobación del certificado. [10] Desde tu equipo, el cortafuegos detiene esa petición antes de que llegue hasta ahí, así que haz esta prueba en el propio servidor:
curl -k --resolve www.example.com:443:127.0.0.1 https://www.example.com/nginx debería responder con un error 400 porque no se envió ningún certificado de cliente, y Apache debería rechazar el handshake TLS. Si después los visitantes ven páginas de error de Cloudflare, comprueba que estén todos los rangos; nuestra guía del error 502 Bad Gateway trata otros errores del origen detrás de Cloudflare.
Preguntas frecuentes
¿Dónde encuentro los rangos de IP de Cloudflare?
Cloudflare los publica en www.cloudflare.com/ips, con listas en texto plano en www.cloudflare.com/ips-v4 y www.cloudflare.com/ips-v6, y los mismos datos en su API. La lista cambia de vez en cuando, así que actualiza tu copia de forma automática. [2]
¿Se puede saltar Cloudflare con la IP de mi servidor?
Sí, si el servidor acepta tráfico web de cualquiera. Los registros en modo DNS only, los rebotes de correo y los registros DNS antiguos pueden revelar la IP, así que Cloudflare recomienda bloquear el tráfico que no venga de sus direcciones. [1]
¿Cómo veo la IP real del visitante detrás de Cloudflare?
Cloudflare la envía en la cabecera CF-Connecting-IP. El módulo realip de nginx y mod_remoteip de Apache pueden usarla, siempre que solo confíes en la cabecera cuando llegue desde los rangos de Cloudflare. [5]
¿UFW bloquea los puertos de Docker?
No bloquea los puertos que publica un contenedor. Docker desvía ese tráfico en la tabla nat antes de que llegue a las cadenas que usa UFW, así que las reglas de UFW no se aplican a esos puertos. [4]
¿Necesito puertos abiertos para Cloudflare Tunnel?
No hace falta ningún puerto web de entrada. El demonio cloudflared solo establece conexiones salientes hacia Cloudflare, así que el servidor no necesita una dirección IP enrutable públicamente para el sitio. [1]
Fuentes y referencias
- Protect your origin server — Cloudflare (consultado el 2026-11-03)
- IP Ranges — Cloudflare (consultado el 2026-11-03)
- Firewall — Ubuntu Server documentation (consultado el 2026-11-03)
- Packet filtering and firewalls — Docker Docs (consultado el 2026-11-03)
- Restoring original visitor IPs — Cloudflare (consultado el 2026-11-03)
- Module ngx_http_access_module — nginx (consultado el 2026-11-03)
- Module ngx_http_ssl_module — nginx (consultado el 2026-11-03)
- Apache Module mod_remoteip — Apache HTTP Server Project (consultado el 2026-11-03)
- New-NetFirewallRule — Microsoft Learn (consultado el 2026-11-03)
- Global authenticated origin pulls — Cloudflare (consultado el 2026-11-03)
Sigue leyendo
Panel de control VPS y herramientas: 6 opciones comparadas
Compara Plesk, cPanel, Webmin, Virtualmin y DirectAdmin por precio, funciones y nivel técnico, y aprende a elegir un panel de control VPS.
Servidor de alta disponibilidad en VPS: failover automático
Diseña un servidor de alta disponibilidad con redundancia, replicación, failover automatizado y monitorización, y compara VPS y cloud en uptime.
Monitorización de servidores: 7 herramientas de uptime
Compara herramientas de monitorización de servidores y uptime, qué revisar en alertas y comprobaciones, y cuándo basta con un monitor autoalojado.
