Una medición reproducible de cuántos relays de Nostr comparten en realidad la infraestructura de una sola empresa — y qué implica de verdad esa decisión para un operador.
— @ifuensan / hacknodeslab
Resumen (TL;DR)
- La descentralización de Nostr se suele contar en relays. El número que importa para la resistencia a la censura es cuánta infraestructura comparten.
- En un snapshot de nostr.watch de mayo de 2026 con 1.067 relays activos en clearnet, el 28,2% está detrás de Cloudflare — y Cloudflare es prácticamente el único CDN en uso (CloudFront 0,2%, Fastly 0%). La centralización en Nostr es, casi por completo, una historia de Cloudflare.
- Eso significa que un único evento a nivel de Cloudflare — una caída, un bloqueo regional o una orden judicial contra rangos de IP de CF — golpea ~1 de cada 4 relays activos a la vez, sin que nadie esté apuntando a Nostr.
- Peor aún: para algunos operadores el CDN no aporta ninguna protección. Usando solo datos públicos y gratuitos (DNS, certificate transparency, registros de correo) y sin ninguna API key, recuperé y validé criptográficamente la IP de origen real de 4 de 185 relays tras CF que publican un pubkey. Con herramientas de recon de pago, esa cifra es un suelo, no un techo.
- Todo esto es reproducible con dos pequeños scripts de Python y una lista pública de relays. Puedes re-ejecutarlo sobre el panorama actual en menos de treinta minutos.
Por qué importa
Nostr se vende como una red de difusión resistente a la censura. La intuición es simple: si hay cientos de relays independientes, ningún actor puede silenciar la red. Pero “independientes” carga con mucho peso en esa frase. Dos relays con dominios distintos, operadores distintos y pubkeys distintas no son independientes si ambos terminan detrás del mismo edge de Cloudflare. Una sola decisión en ese edge tumba a los dos a la vez.
Esto no es hipotético. En el caso en curso de LaLiga en España, juzgados de lo mercantil han ordenado a las operadoras bloquear rangos de IP de Cloudflare durante los partidos de fútbol — del orden de ~3.000 IPs por jornada, tumbando de forma colateral más de 13.500 sitios sin relación (incluyendo, en un caso muy comentado, el servicio público Madrid Salud). La orden nunca menciona Nostr. No le hace falta: si ~1 de cada 4 relays activos responde en una IP de Cloudflare, un usuario español pierde un cuarto de la red mientras dura el partido, como daño colateral.
El recuento de relays dice que la red está descentralizada. La infraestructura dice que una porción significativa tiene un punto único de fallo compartido y expuesto a una jurisdicción. Este artículo cuantifica esa brecha y nombra el trade-off con precisión.
Paso 1 — ¿Cuántos relays se esconden detrás de un CDN?
Método. Tomar una lista de relays, resolver cada hostname a sus registros A/AAAA, y comprobar cada IP contra los rangos de direcciones publicados por los principales CDN:
- Cloudflare —
https://www.cloudflare.com/ips-v4+ips-v6 - CloudFront —
https://ip-ranges.amazonaws.com/ip-ranges.json(service=CLOUDFRONT) - Fastly —
https://api.fastly.com/public-ip-list
Sin sondeo, sin explotación — solo resolución DNS y una comprobación de rango. Los snapshots de rangos de CDN se cachean para que un tercero pueda reproducir los veredictos exactos. La herramienta es check_cf.py.
Entrada. Un export xlsx de nostr.watch (nw-relays-all-20260503.xlsx), filtrado al conjunto de relays activos (in_rstate=True) y solo clearnet — 1.079 hosts únicos, de los cuales 1.067 resolvieron. El export sin filtrar está dominado por relays muertos hace tiempo e infla el denominador; el subconjunto activo-clearnet es la población honesta.
Resultado (snapshot de mayo de 2026):
| Veredicto | Conteo | % de resueltos |
|---|---|---|
| cloudflare | 301 | 28,2% |
| cloudfront | 2 | 0,2% |
| fastly | 0 | 0% |
| directo | 764 | 71,6% |
| dns_error | 12 | — |
~28% de los relays activos está detrás de un CDN, y ese CDN es Cloudflare. Añadir CloudFront y Fastly apenas mueve la aguja. Así que, para todo lo que sigue, “detrás de Cloudflare” y “detrás de un CDN” son efectivamente la misma pregunta.
Paso 2 — ¿El CDN esconde de verdad el origen?
Estar detrás de Cloudflare solo protege si tu IP de servidor real permanece secreta. Si un adversario puede encontrar el origen, puede atacarlo o bloquearlo directamente y el CDN se vuelve decorativo. Así que la segunda pregunta es: en un relay tras CF, ¿se puede recuperar la IP de origen solo con datos públicos — y demostrar que es correcta?
Fuentes de candidatos (gratis, sin API keys):
- DNS directo — el dominio apex y subdominios hermanos comunes (
ssh.,mail.,direct.,origin., …). Los operadores meten habitualmente el relay detrás de Cloudflare pero dejan el apex o un subdominio de administración apuntando directo a la máquina. - Certificate Transparency (crt.sh) — hostnames hermanos en la misma cadena de certificados, que luego se resuelven.
- Tokens
ip4:de SPF / TXT — configuración de correo que nombra la IP del servidor. - Hosts MX — el servidor de correo suele correr en la misma máquina que el relay.
Las consultas DNS para TXT/MX y nombres de CT van por DNS-over-HTTPS (la API JSON de 1.1.1.1), de modo que toda la herramienta se mantiene solo con la librería estándar y es reproducible sin ninguna cuenta. Cualquier IP candidata que caiga dentro de los rangos publicados de Cloudflare se descarta — eso es el frente, no el origen.
Validación — la parte que convierte esto en evidencia, no en una conjetura. Todo relay de Nostr puede servir un documento NIP-11, y muchos incluyen el pubkey del operador. Para cada IP candidata, la herramienta abre una conexión TLS a esa IP manteniendo el SNI/Host con el hostname real del relay (el patrón curl --resolve), descarga el documento NIP-11 y compara su pubkey con el que sirve el frente de Cloudflare. Si las pubkeys coinciden, el origen queda confirmado criptográficamente — no inferido por ASN, geografía o una corazonada. Cuando un relay no publica pubkey, la herramienta recurre a una huella estructural (name + software + NIPs soportados ordenados + contact) y lo reporta como una coincidencia “probable” más débil. La herramienta es find_origin.py.
Un caso paso a paso (anonimizado: “Relay A”)
Por práctica de divulgación responsable, el relay y su IP de origen están redactados aquí. El método es totalmente reproducible contra tu propio relay.
Relay A es un relay khatru servido en relay-a.example y respondiendo en una IP de Cloudflare — según la medición del Paso 1, está “detrás de un CDN”.
Ejecutando find_origin.py relay-a.example:
- La herramienta descarga el NIP-11 de Relay A a través del frente de Cloudflare y registra el
pubkeyde referencia (una clave de 64 hex). - Reúne IPs candidatas. El dominio apex de Relay A y un subdominio
ssh.resuelven ambos a una única IP en un proveedor cloud económico — fuera de los rangos de Cloudflare. El operador puso el subdominio del relay detrás de CF pero dejó el resto de la zona apuntando a la máquina real. - La herramienta conecta a esa IP candidata con SNI/
Hostigual arelay-a.example, descarga el documento NIP-11 y lee supubkey. - El pubkey es idéntico al servido vía Cloudflare. Origen confirmado.
Tiempo total: unos segundos. Sin explotación, sin escaneo de puertos — solo DNS público y un GET HTTPS. Para Relay A, el frente de Cloudflare no protege nada: el origen está a un dig de distancia.
¿Cómo de extendido está?
Sobre los 185 relays tras CF que publican un pubkey en vivo (el subconjunto validable criptográficamente de los 301), el barrido con fuentes gratuitas confirmó el origen real de 4 relays en 3 operadores — 2,2%, por dos vectores de fuga distintos:
- Fuga por DNS — el apex / un subdominio hermano apunta directo al origen (el vector de Relay A).
- Fuga por correo — el host MX del relay resuelve a la misma máquina que corre el relay.
2,2% es un suelo, y uno honesto. Cuenta solo orígenes demostrables con datos gratuitos, solo en relays que publican pubkey, sobre un único snapshot. Añade recon de pago (Censys, Shodan, DNS histórico de ZoomEye) y la fracción recuperable sube. El punto no es el porcentaje exacto — es que, para una porción no trivial de operadores, el CDN aporta el coste y la complejidad de Cloudflare sin nada de la protección de origen que da por supuesta.
El trade-off, nombrado
Poner un relay detrás de Cloudflare es una decisión de ingeniería real con ventajas reales. Conviene ser preciso sobre contra qué adversario ayuda y a cuál le entrega, calladamente, más poder.
De qué te protege Cloudflare:
- DDoS volumétrico — absorbido en el edge antes de llegar a tu máquina.
- Exposición casual del origen — tu IP de servidor no está en el registro A del relay, así que el atacante más perezoso no la encuentra (hasta que DNS/correo/CT la filtran — ver arriba).
- Carga operativa — TLS, caché y un frente anycast global, gratis.
A qué te expone Cloudflare — y esta es la parte que el marketing omite:
- Bloqueo jurisdiccional al que no te apuntaste. Una orden judicial contra rangos de Cloudflare en cualquier jurisdicción tumba tu relay ahí, aunque la orden apuntara a la piratería de fútbol. Heredas todas las peleas en las que está metido el espacio de direcciones de Cloudflare.
- Fallo correlacionado. Ya no eres un relay independiente; eres uno de ~300 que comparten destino. La aritmética de resiliencia de la red se apoya en una independencia que no existe.
- Un único punto de estrangulamiento de moderación/deplatforming. La decisión de términos de servicio de una sola empresa puede retirar un cuarto del edge activo de la red en una sola acción.
Y para los operadores que filtran, el peor caso: la desventaja sin la ventaja. Su origen es público, así que cargan con la exposición jurisdiccional y el riesgo de fallo correlacionado de estar detrás de Cloudflare, mientras que un atacante que quiera tumbar su relay concreto simplemente apunta al origen directamente.
Esto no es un argumento de que los operadores no deban usar Cloudflare. Es un argumento de que la elección es un trade-off frente a un modelo de amenaza concreto, no una victoria gratis — y de que una red cuya historia de resistencia a la censura depende del recuento de relays debería saber que ~1 de cada 4 de esos relays responde en la puerta de la misma empresa.
Reprodúcelo tú mismo
Todo el instrumental es código abierto — hacknodeslab/nostr-cf-recon:
python3 -m venv .venv
.venv/bin/pip install rich openpyxl
# 1. Desde un export xlsx fresco de nostr.watch, extrae los relays activos clearnet:
.venv/bin/python extract_relays.py nw-relays-all-YYYYMMDD.xlsx relays.txt --online --clearnet
# 2. Mide la presencia de CDN (Paso 1):
.venv/bin/python check_cf.py relays.txt --json out.json
# 3. Intenta desenmascarar el origen de un relay (Paso 2):
.venv/bin/python find_origin.py <host-de-un-relay-tras-cf>
Si cae una nueva orden de bloqueo con forma de LaLiga, re-ejecuta el Paso 1 contra la lista de relays actual para cuantificar el impacto colateral sobre Nostr el mismo día.
Límites del método y ética
- Solo datos públicos. Sin explotación, sin bypass de autenticación, sin escaneo de puertos, sin sondeo más allá de la resolución DNS estándar y un GET HTTPS contra endpoints NIP-11 públicos. La validación al estilo
--resolveconecta a una IP candidata que ya está publicada en DNS. - La reproducibilidad es obligatoria. Las entradas, los snapshots de rangos de CDN y los veredictos por host se persisten para que un tercero pueda re-ejecutar de extremo a extremo.
- Sin doxxing de operadores. El resultado del desenmascaramiento es evidencia metodológica, presentada de forma anonimizada. Las fugas de origen confirmadas se comunicaron en privado a los operadores afectados; este artículo no nombra ningún mapeo relay→IP.
- Snapshot, no vigilancia. Esto es una medición puntual de una lista pública de relays, no una monitorización continua de ningún operador.
Herramientas: check_cf.py (Paso 1), find_origin.py (Paso 2), extract_relays.py. Inspirado en la técnica de recon anti-Cloudflare de CF-Hero; aquí usada solo para medir un trade-off de centralización, no para atacar. Código completo: github.com/hacknodeslab/nostr-cf-recon.