Geolocalización IP en Cloudflare Workers: caché y arranques en frío
La geolocalización IP en Cloudflare Workers consiste en leer datos de ubicación de un visitante dentro de un Worker, ya sea a partir del objeto integrado request.cf o llamando desde el edge a una API externa de inteligencia de IP. Los dos enfoques responden a preguntas distintas, y conviene entender el comportamiento de caché y de arranque en frío de cada uno antes de construir sobre ellos.
Lo que Workers te da gratis
Cada petición que llega a un Worker lleva un objeto request.cf rellenado por Cloudflare. Incluye el país, la ciudad, la región, las coordenadas, la zona horaria, el ASN y la organización del AS del visitante, además del campo colo, que nombra el centro de datos que atendió la petición. La cabecera CF-IPCountry también transporta el código de país. Como estos datos se adjuntan antes de que se ejecute tu código, no cuestan ninguna subpetición adicional ni latencia añadida.
El límite es el alcance. request.cf describe al cliente que se conecta en la petición actual y nada más. No puede informarte sobre una dirección IP que aparezca en una línea de registro, en un campo de formulario, en la carga de un webhook o en una cadena X-Forwarded-For, y no incluye señales de reputación como los indicadores de VPN, Tor o abuso. En cuanto necesitas enriquecer una dirección arbitraria, estás llamando a una API, y ahí empiezan las decisiones de caché.
Almacenar en caché los datos de enriquecimiento en el edge
Una consulta de IP desde un Worker es una subpetición, por lo que cada consulta sin caché añade un viaje de ida y vuelta por la red a la ruta de la petición. Cloudflare ofrece varios lugares donde almacenar el resultado: la Cache API (por centro de datos, no replicada globalmente), KV (legible globalmente pero con consistencia eventual, y con escrituras que tardan en propagarse) y Durable Objects cuando necesitas una única copia coordinada. Ninguno es una caché global lista para usar, así que elige según lo que puedas tolerar: la Cache API es la más sencilla y rápida para consultas con mucha lectura, mientras que KV es adecuado para valores que quieres que sean visibles desde todas las ubicaciones.
La decisión de diseño más útil es el tiempo de vida por campo, porque los datos de inteligencia de IP no envejecen de manera uniforme. Las asignaciones de país y de ASN cambian despacio, ya que los bloques de direcciones se reasignan a lo largo de meses o años, por lo que un TTL de muchas horas es razonable. Los indicadores de reputación son distintos. Los feeds de VPN, Tor y abuso de ipto se actualizan cada 6 horas y sus conjuntos de datos de IP y ASN a diario, de modo que almacenar un indicador como is_tor durante más de unas pocas horas significa servir respuestas más antiguas que la propia fuente. Un reparto práctico es almacenar los datos de red (asn, asn_org, país, ciudad) durante aproximadamente un día y los indicadores (is_vpn, is_tor, is_abuser, is_datacenter) durante no más que el intervalo del feed.
- Usa como clave de la caché la IP normalizada (en IPv6, plantéate usar el /64 si tu caso de uso es por red y no por host).
- Almacena también los resultados negativos, para que las consultas repetidas de una dirección no listada no lleguen a la API cada vez.
- Nunca almacenes por accidente resultados bogon bajo una clave pública: una dirección privada como
10.0.0.1se puede resolver localmente sin ninguna llamada a la API.
Arranques en frío en Workers
Los Workers se ejecutan en aislados de V8 y no en contenedores, por lo que un arranque en frío suele medirse en milisegundos y no en las centenas de milisegundos habituales de las funciones basadas en contenedores. Aun así, tu código paga su propia inicialización: un paquete grande, un análisis pesado a nivel de módulo de una tabla de consulta voluminosa o los await de nivel superior ocurren en la primera petición a un aislado nuevo. La solución es la habitual: mantener el paquete pequeño, evitar construir grandes estructuras en memoria al arrancar y preferir una única llamada pequeña a una API antes que incluir una base de datos de geolocalización completa dentro del Worker.
Los pings de calentamiento que se usan con el serverless tradicional aquí son en su mayoría un desperdicio. Los aislados se crean y se expulsan según el calendario de Cloudflare, un ping solo llega a una ubicación, y el coste de un arranque en frío es lo bastante pequeño como para que almacenar en caché el resultado de la consulta importe mucho más que mantener vivo el aislado. Mide primero con los análisis de Workers y con tus propios tiempos alrededor de la subpetición antes de optimizar nada.
Cómo combinarlo con ipto
Un patrón sensato es usar request.cf para los datos instantáneos y gratuitos sobre el cliente que se conecta y llamar a una API de enriquecimiento solo cuando necesites más. La documentación de la API de ipto muestra la respuesta de la consulta de IP, que devuelve país, ciudad, ASN, org, currency_code y los indicadores is_vpn, is_tor, is_abuser, is_datacenter y bogon/bogon_type. Es gratuita, sin registro y con 1000 solicitudes gratuitas al día, lo que basta para prototipar un Worker sin el paso de gestionar claves.
Cuando la consulta te indique que la dirección pertenece a una red de alojamiento, puedes continuar en la consulta de ASN para ver quién la opera y qué rangos anuncia. Para el tráfico señalado, el verificador de VPN, Tor y proxy muestra las evidencias detrás de is_vpn e is_tor, y el verificador de abuso de IP muestra la puntuación corroborada. Recuerda que la ubicación a nivel de ciudad es una estimación de dónde está registrada o enrutada una red, no de dónde está sentada una persona, una limitación que se explica en por qué la precisión a nivel de ciudad es limitada.
El edge hace que las consultas sean rápidas, pero no hace más precisos los datos subyacentes. Trata request.cf y cualquier resultado de una API como la misma clase de evidencia, almacena cada uno según la rapidez con que cambia, y deja que sea la actualidad de la fuente, y no la velocidad del edge, la que decida tus TTL.