Cómo saltarse los bloqueos de IP de LaLiga cuando tu SaaS comparte Cloudflare con sitios pirateados
Si gestionas un SaaS detrás de Cloudflare y tienes clientes en España, hay probabilidades de que durante los partidos de LaLiga tu web esté caída en Movistar, Orange, DIGI, Masmóvil y Vodafone sin que tu monitoring se entere. El problema no es tuyo: una sentencia judicial obtenida por LaLiga permite a los operadores españoles bloquear rangos enteros de IPs de Cloudflare en tiempo real con el pretexto de combatir streaming pirata. El daño colateral cae sobre miles de aplicaciones legítimas. Este post explica el problema, recopila los proyectos open source que ya lo resuelven y da una guía genérica de implementación reutilizable en cualquier stack.
¿Qué es "LaLigaGate"?
En la comunidad técnica española el incidente se conoce como LaLigaGate: el escándalo por el que LaLiga, amparada en una sentencia judicial, consigue que los principales ISPs del país (Movistar, Orange, DIGI, Masmóvil, Vodafone) bloqueen rangos enteros de IPs de Cloudflare durante los partidos para combatir el streaming pirata, tirando por el camino miles de webs legítimas que comparten esos rangos. El término se popularizó a través de la cuenta colectiva @laligagate en X, que documenta caso por caso los sitios afectados — desde tiendas online y SaaS hasta administraciones públicas — y agrega evidencia del alcance real del daño colateral. El nombre engancha con el sufijo "-gate" precisamente para subrayar que no se trata de fallos aislados sino de un patrón sistemático con responsables concretos: una liga deportiva privada decidiendo qué partes de internet se ven en España.
El problema en una frase
LaLiga consiguió en 2024 una resolución judicial que permite ordenar a los ISPs españoles bloquear "IPs sospechosas" de servir streams pirata durante ventanas de partidos. Los operadores ejecutan esos bloqueos por rangos enteros — no por IP individual — y Cloudflare es el blanco principal porque buena parte del streaming pirata se sirve detrás de su CDN. El resultado: cualquier sitio legítimo que comparta rango con un dominio listado se cae durante horas, sin previo aviso ni mecanismo de reclamación útil.
El bloqueo se aplica a nivel de routing en la red del operador, así que tampoco hay forma de detectarlo desde tu propio servidor: tu servidor está perfectamente vivo, pero los paquetes desde España nunca le llegan. Visto desde el cliente final, tu dominio sencillamente no resuelve o se queda colgando. Es muy fácil que se te escape días.
Por qué Cloudflare no lo arregla por ti
Cloudflare ha demandado en los tribunales españoles y publicado varios comunicados en contra, pero el procedimiento sigue en curso. Mientras se resuelve, la responsabilidad práctica recae en cada cliente. Las opciones son tres:
- Migrar a otro CDN (Fastly, Bunny, CloudFront). Funciona, pero pierdes la integración con todo el ecosistema Cloudflare (Workers, R2, Pages, Turnstile, etc.) y rompes cualquier configuración de DNS, WAF y cache que tengas montada.
- Dual-CDN con failover. Caro y complejo de mantener; sólo merece la pena para tráfico muy grande.
- Alternar dinámicamente el proxy de Cloudflare. Mantienes Cloudflare como NS y CDN el 95% del tiempo, y cuando se detecta un bloqueo activo se pone el registro DNS del apex en modo "DNS-only" (nube gris) — el tráfico va directo al origen, saltándose la IP de Cloudflare bloqueada. Es la opción más realista para un SaaS pequeño o mediano. El resto del post se centra en esta tercera opción.
Detectando el bloqueo en tiempo real: hayahora.futbol
Para alternar el proxy automáticamente, necesitas saber cuándo se activa un bloqueo. Tu propio servidor no puede comprobarlo (vive fuera de España). Afortunadamente, la comunidad mantiene hayahora.futbol, un servicio que ejecuta sondas continuas dentro de cada operador español y publica los resultados en un endpoint público y estable:
GET https://hayahora.futbol/estado/data.json
La respuesta es un JSON keyed por IP con el histórico de cambios de estado por operador:
{
"lastUpdate": "2026-05-18 13:14:10",
"data": [
{
"ip": "104.16.93.114",
"isp": "Movistar",
"description": "Cloudflare",
"stateChanges": [
{ "timestamp": "2026-04-04 15:21:43Z", "state": true },
{ "timestamp": "2026-04-04 21:27:03Z", "state": false }
]
}
]
}
Para saber si una IP está bloqueada ahora, basta con leer el último
elemento de stateChanges para esa IP. Si state es
true, sigue bloqueada por ese operador. Si false,
ya volvió a funcionar.
El dataset cachea resultados aproximadamente cada 5–10 minutos, así que desde que un operador activa el bloqueo hasta que la API lo refleja pueden pasar unos minutos. Para una web de menús de restaurante en horario de cena es perfectamente aceptable; para un servicio crítico en tiempo real puede no serlo.
Estrategia: alternar el proxy de Cloudflare vía API
El bucle de control es trivial. Cada 2–3 minutos:
- Resuelve tu dominio (apex) por DNS público para obtener su IP actual.
- Descarga
data.jsonde hayahora y comprueba si esa IP está bloqueada por algún operador. - Si está bloqueada y el proxy es naranja → llama a la API de Cloudflare y pon
proxied: falseen el registro A del apex. - Si ya no está bloqueada y el proxy es gris → vuelve a
proxied: true.
Mientras la nube está en gris, el tráfico va directo a tu origen (tu VPS, EC2, Hetzner, etc.), saltándose la IP de Cloudflare que estaba bloqueada. Tu origen no aparece en ninguna lista de bloqueo porque LaLiga sólo apunta a rangos de CDNs grandes.
Edge case: cuando ya estás en gris
Si ya hiciste el bypass, tu dominio resuelve a la IP de tu origen — no a
Cloudflare — y esa IP no aparece en data.json. Sin información,
no podrías decidir cuándo volver a naranja. La solución es trivial:
cuando estés en naranja, cachea la última IP de Cloudflare observada. Si
más tarde la resolución no aparece en el dataset, usa esa IP cacheada como
referencia para preguntar "¿sigue bloqueada?". Cuando se desbloquee, pon
proxied: true y la siguiente comprobación volverá a resolver
una IP fresca de Cloudflare.
Pseudocódigo genérico (no específico de ningún lenguaje)
cada 2 minutos:
ip_actual = resolver_dns("midominio.com", servidor: "1.1.1.1")
dataset = http_get_json("https://hayahora.futbol/estado/data.json")
entradas = dataset.data.filter(e => e.ip == ip_actual)
if entradas.vacio:
# Estamos en gris (origen). Caemos a la última IP CF cacheada.
entradas = dataset.data.filter(e => e.ip == cache.get("last_cf_ip"))
else:
cache.set("last_cf_ip", ip_actual, ttl: 7_dias)
bloqueada = entradas.alguno(e => ultimo(e.stateChanges).state == true)
proxy_actual = cloudflare_api.get_record("midominio.com").proxied
if bloqueada and proxy_actual == true:
cloudflare_api.patch_record(record_id, { proxied: false })
elif not bloqueada and proxy_actual == false:
cloudflare_api.patch_record(record_id, { proxied: true })
Toda la lógica son dos llamadas HTTP y un poco de estado. En cualquier stack — Rails, Django, Laravel, Express, Go, una Lambda, un cron de bash — puedes implementar esto en una tarde. Los requisitos previos a tener resueltos antes de habilitarlo:
- TLS válido en tu origen sin Cloudflare delante. Cuando estés en gris, los clientes hablan TLS directamente con tu servidor. Si tu Nginx/Caddy/Apache no tiene certificado propio (porque has estado dependiendo de la terminación TLS de Cloudflare), arregla eso primero. Let's Encrypt + certbot resuelve en minutos.
-
API Token de Cloudflare con
Zone:DNS:Editsólo para tu zona. Nunca uses la Global API Key. -
Decide qué registros vas a alternar. Normalmente apex y
www. Ojo con subdominios que apunten a R2, Cloudflare Pages o cualquier otro producto Cloudflare que exija el proxy activo — esos deben quedarse en naranja siempre. - Monitoring del propio job. Si el script falla silenciosamente durante un partido, te quedas igual que ahora. Un healthcheck externo (healthchecks.io o equivalente) que te alerte si el job no corre en X minutos es barato y útil.
Proyectos open source que ya implementan esto
El problema lleva activo el tiempo suficiente como para que haya
implementaciones de referencia en varios stacks. Todas leen
hayahora.futbol y todas hablan con la API DNS de Cloudflare;
difieren en lenguaje y en si son standalone o plugin de algún CMS:
- aitorroma/cloudflare-laliga-bypass — script standalone en Node, buena base de inspiración. Sirve como referencia conceptual para portar a cualquier otro lenguaje.
- fernandotellado/bypass-laligagate — plugin de WordPress. Útil si tu web es WP.
- jcastro/stopliga — herramienta de línea de comandos, fácil de meter en un cron.
- eryalito/smart-dns-proxy — enfoque distinto: un resolver DNS inteligente que sirve respuestas diferentes según el estado de bloqueo. Más complejo de operar pero elegante para infraestructuras grandes.
- SusoDiz/laligagate-extension — del lado cliente, extensión de navegador. Útil para usuarios finales afectados, no para operadores de servicio.
Si tu stack no encaja con ninguno de estos, replicar la lógica desde cero
es un fichero de menos de 100 líneas. La API de Cloudflare es
GET /zones/:zone/dns_records?name=midominio.com seguida de un
PATCH /zones/:zone/dns_records/:id con
{ "proxied": false }.
Limitaciones honestas que conviene conocer
Antes de desplegar esto en producción, dos avisos que no siempre aparecen en los READMEs:
- Pierdes WAF, bot protection y cache de Cloudflare mientras estás en gris. Globalmente, no sólo para España. Para una ventana corta es asumible; si tu negocio depende del WAF para parar abuso constante, no lo es. Mide la frecuencia y duración real de los bloqueos antes de habilitarlo.
- No arregla todo el dominio si tienes subdominios que dependen de Cloudflare (R2 con custom domain, Pages, Workers). Esos deben permanecer proxied y por tanto siguen bloqueados durante el incidente. Mitigación: servir los assets críticos desde el origen, o desde un CDN distinto. En la práctica, la web HTML carga (signup, transacciones, áreas de cliente funcionan) y las imágenes alojadas en R2 son la parte degradada. Es mucho mejor que la situación previa, pero no perfecto.
- Cambios DNS no son instantáneos. El TTL bajo por defecto de Cloudflare (300s) ayuda, pero algunos resolvers intermedios cachean más agresivamente. Cuenta con 5–15 minutos hasta que los cambios se propaguen para la mayoría de usuarios.
- Si tu origen cae durante un partido, no tienes airbag. Ya no hay Cloudflare absorbiendo el golpe. Para un SaaS pequeño que igualmente operaría sin él durante el bloqueo, el delta es cero. Para cargas grandes, considera mantener al menos un cache estático mínimo.
Nuestra implementación, como referencia
En topfood.app — un SaaS gratuito de cartas digitales para restaurantes con QR — pasamos exactamente por esto. Lo resolvimos con un job Ruby recurrente que ejecuta el bucle descrito arriba cada 2 minutos. Tres ficheros:
- Un servicio que descarga
hayahora.futbol/estado/data.json, resuelve el apex y decide si está bloqueado, cacheando la última IP CF observada. - Un cliente fino contra la API de Cloudflare que sólo expone
set_proxied(bool)sobre los registros del apex. - Un job en
recurring.yml(Solid Queue) que orquesta los dos anteriores. Cualquier error sube a Sentry; el siguiente tick reintenta.
Total: ~120 líneas de Ruby. Si gestionas la web de un restaurante en España y los bloqueos te están haciendo perder reservas en noches de partido, puedes probar el servicio gratis — no es necesario migrar nada, basta con redirigir tu QR a una de nuestras cartas:
Preguntas Frecuentes
¿Qué es "LaLigaGate"?
LaLigaGate es el nombre con el que la comunidad técnica española se refiere al escándalo por el que LaLiga, amparada en una sentencia judicial de 2024, consigue que los ISPs españoles bloqueen rangos enteros de IPs de Cloudflare durante los partidos para combatir el streaming pirata, tirando miles de webs legítimas que comparten esos rangos. El sufijo "-gate" subraya que no son fallos aislados sino un patrón sistemático con responsables identificables. La cuenta colectiva @laligagate en X documenta caso por caso los sitios afectados — desde tiendas online y SaaS hasta administraciones públicas — y agrega evidencia del alcance real del daño colateral.
¿Por qué mi web no carga en Movistar, Orange o DIGI durante los partidos de LaLiga?
Porque LaLiga obtuvo en 2024 una resolución judicial que obliga a los ISPs españoles a bloquear rangos enteros de IPs de Cloudflare durante las ventanas de partido para combatir el streaming pirata. El bloqueo se aplica por rango, no por dominio, así que cualquier web legítima detrás de Cloudflare cuya IP caiga en uno de esos rangos queda inaccesible en esos operadores aunque no tenga absolutamente nada que ver con streaming. Tu servidor sigue vivo; los paquetes desde España nunca le llegan.
¿Cómo puedo comprobar si mi web está bloqueada por LaLiga ahora mismo?
Resuelve tu dominio por DNS (por ejemplo dig +short midominio.com @1.1.1.1) y consulta esa IP en hayahora.futbol, que ejecuta sondas continuas desde dentro de Movistar, Orange, DIGI, Masmóvil y Vodafone. Si el último stateChange de tu IP en cualquier operador es true, está bloqueada en ese ISP. Tu propio monitoring no lo verá porque vive fuera de España.
¿Es legal saltarse los bloqueos cambiando el proxy de Cloudflare a "DNS only"?
Sí. La orden judicial obliga a los operadores a bloquear ciertas IPs; no prohíbe que tú cambies a qué IP resuelve tu propio dominio. Pasar el registro DNS de "proxied" (nube naranja) a "DNS only" (nube gris) es una operación rutinaria de Cloudflare y simplemente hace que el tráfico vaya directo a tu origen, que no aparece en ninguna lista de bloqueo. Lo que es ilegal es servir streams pirata, no servir tu propio SaaS.
¿Cuánto tardan los cambios DNS en propagarse cuando alterno el proxy?
Cloudflare usa un TTL bajo por defecto (300 segundos) en los registros proxied, lo que ayuda. En la práctica, cuenta entre 5 y 15 minutos para que la mayoría de resolvers intermedios sirvan la nueva IP. Algunos resolvers cachean más agresivamente de lo que indica el TTL, así que no esperes recuperación instantánea para el 100% de usuarios.
¿Qué pasa con subdominios que usan R2, Cloudflare Pages o Workers durante el bypass?
Esos productos requieren que el registro DNS esté proxied (nube naranja) y por lo tanto siguen afectados por el bloqueo mientras dure el incidente. En la práctica, la web HTML carga normalmente (signup, login, áreas de cliente, transacciones) pero los assets servidos desde R2 o Pages aparecen rotos en España durante la ventana de partido. Mitigación: servir los assets críticos desde el origen o desde un CDN distinto al detectar el bloqueo.
¿Pierdo el WAF y la protección anti-bots de Cloudflare cuando estoy en "DNS only"?
Sí, globalmente — no sólo para los usuarios españoles. Mientras la nube esté gris, el tráfico va directo a tu origen sin pasar por las reglas WAF, rate limiting ni bot management de Cloudflare. Para una ventana corta de un par de horas en horario de partido es asumible para la mayoría de SaaS; si tu negocio depende del WAF para frenar abuso constante, mide la frecuencia real de los bloqueos antes de habilitar el bypass automático.
¿Funciona este método si uso Vercel, Netlify u otro hosting que ya está detrás de su propio CDN?
Sólo si Cloudflare está delante como proxy explícito (NS de Cloudflare y nube naranja). Si tu dominio apunta directamente a Vercel o Netlify, el bloqueo no aplica porque LaLiga sólo ataca rangos de Cloudflare — pero esos hosts pueden tener problemas distintos si comparten IPs con dominios listados. La estrategia de este post (alternar proxied via API de Cloudflare) sólo aplica al caso en que tú controlas Cloudflare en tu zona DNS.
¿Por qué Cloudflare no resuelve el problema por sus clientes?
Cloudflare ha presentado recursos judiciales en España y publicado comunicados públicos contra la medida, pero el procedimiento sigue en curso y los bloqueos continúan ejecutándose cada jornada. Mientras tanto, la responsabilidad práctica recae en cada cliente, que debe migrar de CDN, montar dual-CDN o alternar el proxy dinámicamente como se describe en este post.