Proteger tu endpoint de activación de Keyright frente al abuso y el uso compartido de claves
Tu ruta caliente de activación —/v1/activate y /v1/validate— no está autenticada por diseño: es la ruta que llaman las apps de tus clientes con una clave de licencia, sin token de administrador. Así que la defiendes con lógica de licenciamiento y controles en el borde, no con autenticación. Aquí tienes el manual por capas: topes de puestos y bloqueo por equipo como estrangulador natural, detección de activaciones duplicadas para claves compartidas y VM clonadas, revocación para una clave filtrada, un límite de tasa o WAF en tu propio proxy inverso delante de /v1/*, y registros de licencia estructurados que ocultan la clave.
Aquí tienes un dato sobre tu servidor de licencias que suena alarmante hasta que lo entiendes: el endpoint más concurrido e importante que expone —el que llama el software de tus clientes para convertir una clave en una licencia en marcha— no tiene autenticación alguna. /v1/activate y /v1/validate aceptan una petición que lleva una clave de licencia y nada más. Sin token de administrador, sin secreto de API, sin cabecera de portador. No es un descuido. Es el único diseño que puede funcionar, y este artículo trata de cómo defender un endpoint que has dejado deliberadamente abierto al público.
Idea clave: La ruta caliente de ejecución de Keyright (/v1/activate, /v1/validate) no está autenticada por diseño —es la ruta que llaman las apps de tus clientes con una clave de licencia, y no tienen token de administrador que presentar. Así que no la proteges con autenticación. La proteges por capas: los topes de puestos y el bloqueo por equipo topan cuántas máquinas puede encender una clave, la detección de activaciones duplicadas saca a la luz claves compartidas y VM clonadas, la revocación anula una clave filtrada, un límite de tasa o WAF en tu propio proxy inverso absorbe el abuso delante de /v1/*, y unos registros estructurados (con la clave oculta) te dejan verlo todo.
Por qué la ruta caliente no tiene autenticación —y por qué es correcto
Piensa en quién llama a /v1/activate. Es una copia de tu software, instalada en la máquina de un cliente, a la que un usuario acaba de darle una clave de licencia escribiéndola en un diálogo. Esa app instalada no tiene cuenta contigo, ni credencial de administrador, ni más secreto que la propia clave. La clave de licencia es la credencial. El servidor la toma, verifica su firma contra la clave de firma del inquilino, busca el registro de activación, comprueba el número de puestos y, o bien vincula un puesto y devuelve un arrendamiento firmado, o lo rechaza. Exigir una segunda credencial encima de la clave significaría embarcar un secreto compartido dentro de cada copia de tu app —lo que no es secreto alguno, y una exposición mucho peor que el endpoint abierto.
La superficie de administración es la imagen especular. /admin/* —emitir licencias, revocar claves, leer la lista de activaciones— sí requiere el token de administrador, porque solo tú la llamas, desde tus propios sistemas. La disciplina que mantiene esto seguro es simple y absoluta: expón públicamente solo /v1/*, y mantén /admin/* alcanzable solo desde dentro de tu red. Tus clientes nunca necesitan ninguna ruta salvo /v1/*. Acierta esa separación y el “endpoint sin autenticación” es solo la ruta de activación haciendo su trabajo; fállala y habrás publicado tu plano de control.
Así que el modelo de amenazas de /v1/* no es “alguien sin credenciales lo llama” —todo el mundo lo llama sin credenciales, ese es el punto. Las amenazas son el abuso de la ruta abierta: una clave pegada en cien máquinas, un ejército de VM clonadas, una clave filtrada en un foro o una burda avalancha de peticiones. Cada una tiene su propia capa.
Capa 1 — topes de puestos y bloqueo por equipo: el estrangulador de licenciamiento
El primer y más importante estrangulador no es un control de red en absoluto; es la propia lógica de licenciamiento. Una clave bloqueada por equipo se vincula a la huella de una máquina, y el servidor impone un número de puestos: activa más máquinas de las que la licencia permite y el servidor registra que se ha alcanzado el tope y rechaza la siguiente, devolviendo un resultado de límite de puestos y ningún arrendamiento. No hay contador del lado del cliente que parchear —el recuento vive en el servidor.
Esto importa enormemente para el endpoint abierto, porque significa que el daño que puede hacer una clave está acotado por la licencia, por mucho que se martillee el endpoint. Una clave vendida como tres puestos puede activar tres máquinas y no más, tanto si se la llama diez veces como diez mil. El bloqueo por equipo y los topes de puestos convierten “cualquiera puede llamar a /v1/activate” en “cualquiera puede llamarlo, y aun así solo encenderá los puestos que la clave pagó.” La mecánica completa —tolerancia al cambio de la huella, reactivación idempotente, liberación de puesto de autoservicio— está en bloqueo por equipo y gestión de puestos, y el panorama anti-uso compartido más amplio está en cómo detener el uso compartido de claves de licencia.
Capa 2 — detectar claves compartidas y VM clonadas
Los topes de puestos acotan el radio de la explosión; no te dicen que una clave está siendo abusada. Para eso vigilas el patrón. Como los clientes revalidan en línea periódicamente —refrescando un arrendamiento firmado de vida corta— una clave compartida se vuelve visible: una clave de un solo puesto que de repente late desde una docena de máquinas en tres países no es ambigua. Las VM clonadas son más sutiles, porque un clon copia la huella de la máquina al pie de la letra, así que el bloqueo por equipo por sí solo no puede distinguir dos copias. Keyright las separa con un identificador de instancia de ejecución por arranque que el clon no puede copiar de forma significativa: dos copias de una activación latiendo al mismo tiempo se revelan como concurrentes, cosa que una huella nunca podría. El mecanismo completo está en detectar VM clonadas y activaciones duplicadas.
Cuando lo ves, tienes respuestas graduadas en lugar de un gatillo sensible. Desactiva la activación infractora para liberar el puesto para una máquina legítima; para un clon confirmado, deja que el servidor elija ganador (newest-wins desaloja a la copia más antigua en su siguiente latido) o marca-y-retén para que aflore en tu panel. Para una clave genuinamente comprometida, escalas a la siguiente capa.
Capa 3 — revocación para una clave filtrada
Cuando una clave se filtra de pleno —publicada en un foro, reembolsada, con contracargo— anulas esa clave concreta. La revocación es una declaración negativa firmada: marca la clave como revocada en el lado de administración (POST /admin/licenses/{id}/revoke, o un clic en el panel) y el cliente cae al estado sin licencia en su siguiente revalidación. Como los arrendamientos son de vida corta, la “siguiente revalidación” llega por sí sola, así que la clave publicada en el foro deja de funcionar dondequiera que se haya propagado sin que tú muevas un dedo después del clic. Para instalaciones sin conexión, una lista de revocación firmada distribuida con una actualización llega incluso a los clientes desconectados. La ventana de exposición y las disyuntivas entre en línea y sin conexión se exponen en estrategias de revocación de licencias —la versión corta es que la revocación convierte una clave filtrada de una pérdida permanente en una acotada y recuperable.
Capa 4 — la protección en el borde que añades delante de /v1/*
Todo lo anterior es lógica de licenciamiento. La última capa es higiene de red, y es tuya para añadir —Keyright no tiene un limitador de tasa incorporado, y no lo necesita, porque la app no tiene estado tras un balanceador de carga. El estrangulamiento corresponde al borde que ya ejecutas: el proxy inverso, el balanceador de carga o la CDN donde terminas TLS. Ahí es donde pones un límite de tasa, un tope de conexiones o un WAF completo delante de /v1/*.
Unas pocas líneas de nginx topan las peticiones por IP de cliente y absorben las ráfagas:
# Estrangula la ruta caliente de activación en tu propio proxy inverso.
# La app no tiene estado tras esto, así que el límite de tasa vive aquí.
limit_req_zone $binary_remote_addr zone=kr_activate:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=kr_conn:10m;
server {
listen 443 ssl;
server_name licensing.example.com;
location /v1/ {
limit_req zone=kr_activate burst=20 nodelay; # absorbe ráfagas cortas
limit_conn kr_conn 20; # topa conexiones por IP
proxy_pass http://keyright_upstream;
proxy_set_header X-Forwarded-For $remote_addr; # IP real del cliente
proxy_set_header X-Forwarded-Proto $scheme;
}
# La superficie de administración nunca es pública. Restríngela a tu red.
location /admin/ {
allow 10.0.0.0/8;
deny all;
proxy_pass http://keyright_upstream;
}
}
Un WAF gestionado en la nube o una pasarela de API hacen el mismo trabajo con reglas más ricas —reputación de IP, puntuación de bots, controles geográficos, mitigación automática de DDoS— pero el principio es idéntico: el límite vive delante de la app, con clave en la IP del cliente, acotado a /v1/*. Mantén la latencia baja dimensionando el límite desde la carga de trabajo real. La activación y la validación no son llamadas por arranque; un cliente activa una vez, cachea un arrendamiento firmado y valida sin conexión hasta que el arrendamiento se acerca a la caducidad. Una máquina dada, por tanto, toca /v1/* un puñado de veces al día. Un límite por IP de decenas de peticiones por segundo con margen de ráfaga es invisible para ese tráfico y solo recorta la IP que martillea el endpoint con una clave compartida o con un script. La ruta caliente en sí es una comprobación de firma más un recuento de puestos, así que la sobrecarga que añades son unos pocos milisegundos de trabajo del proxy, no un cuello de botella.
Un detalle que conviene acertar: asegúrate de que la IP real del cliente llega a tu limitador de tasa. Si otro proxy se sitúa delante, reenvía la dirección genuina del cliente (aquí vía X-Forwarded-For) para que el límite por IP tenga por clave al abusador, no a tu propio nodo de borde —de lo contrario cada petición parece venir de una sola dirección y el límite o bien nunca se dispara o los recorta a todos.
Capa 5 — registros estructurados que ocultan la clave
No puedes estrangular lo que no puedes ver, así que registra los eventos de licencia de forma estructurada —y nunca registres la clave. Una clave de licencia es una credencial de portador; escribirla en un registro que acaba enviado a un agregador o pegado en un ticket de soporte es la misma clase de error que registrar una contraseña. Emite un evento estructurado por activación y validación —estado, licenciatario, una huella corta de la clave, recuentos de puestos y activaciones— para que un panel pueda graficar “huellas distintas vistas esta semana” o alertar sobre una sola clave activándose desde decenas de IP, todo sin que la clave en bruto salga jamás del proceso. El patrón completo —un evento generado por el compilador por el que la clave es literalmente impasable, mapeado sobre niveles de registro que tu alertado ya entiende— está en registro estructurado de eventos de licencia. Esos registros son lo que convierte las otras cuatro capas de esperanza en evidencia: son cómo te das cuenta de la clave compartida, confirmas el clon y decides revocar.
Dónde encaja Keyright
Lo que hay que interiorizar es que un endpoint de activación sin autenticación no es una debilidad de la que disculparse —es la forma correcta para una ruta que el software de tus clientes debe llamar sin más que una clave. Keyright te da las capas de licenciamiento de serie: puestos bloqueados por equipo impuestos en el servidor, detección de activaciones duplicadas y de clones, revocación con un clic que llega a clientes en línea y sin conexión, y eventos de licencia estructurados que puedes registrar con seguridad. La capa de borde —el límite de tasa, el WAF, el blindaje de /admin/*— es tuya para ejecutar delante, exactamente igual que ya ejecutas un proxy delante de cualquier servicio sin estado. Keyright autoalojado se licencia por despliegue entre Standard, Pro y Enterprise; consulta los precios para los niveles actuales. Defiende la ruta abierta como está pensado defenderla —con lógica de licenciamiento y controles en el borde, no con una credencial que habrías tenido que filtrar para poder embarcar.
Prueba Nebula.NET
Endurece tu código .NET en minutos — empieza con la edición gratuita.