Funcionamiento interno
Cómo llega de verdad una petición a estos servidores: tu cliente, Cloudflare, nginx, una de las tres instancias, su salida WireGuard y el destino pedido.
El camino de una petición
Una llamada a cualquiera de los dos servidores cruza los mismos seis pasos antes de volver — la figura los dibuja, y la lista numerada de debajo recorre cada uno. Lo único que elige quien llama es el servidor: apuntar el cliente a /libgen o a /gitlab pasa antes de que la petición exista en el cable, y a partir de ahí el recorrido es el mismo.
- https
- local
- WireGuard
Tu cliente abre la petición, con un token Bearer o sin él
Cloudflare la pasa al origen
Aquí se calcula la clave: tu IP, o el hash del token
La misma clave elige siempre el mismo nodo
Ese nodo sale por su salida fija
Esa petición sale hacia el servidor que la responde
Los mismos seis pasos, completos:
Empieza en tu máquina: tu cliente MCP envía la petición al endpoint al que lo apuntaste, /libgen o /gitlab, con una cabecera `Authorization: Bearer` si ese servidor la necesita — gitlab sí, libgen no.
Cloudflare la recibe en el borde y la reenvía, sin tocarla, al servidor de casa que da la cara por los dos MCP.
nginx convierte la petición en una clave de enrutado: tu dirección IP si no hay credencial, o un MD5 de una sal secreta más el token que va en tu cabecera `Authorization: Bearer` si lo hay — la directiva que lo hace está citada entera más abajo, en «Afinidad».
Esa clave alimenta un balanceador por hash consistente, por eso elige siempre la misma de las tres instancias en marcha para ti — nunca una distinta de una llamada a la siguiente. Si esa instancia no responde, nginx reintenta la misma petición en otra y deja fuera a la que falló durante un rato; una instancia reiniciada vuelve sola, y las actualizaciones se hacen de una en una, así que las otras dos siguen sirviendo — ver «Cuando algo falla», más abajo.
Esa instancia sale siempre por su propio nodo de salida — uno de tres, dos en España y uno en Reino Unido, fijo por instancia salvo que el vigilante descrito en «Cuando algo falla» tenga que moverla —, así que tus llamadas siguen pareciendo venir de la misma dirección en vez de alternar.
Esa conexión llega al destino real: un mirror de Library Genesis si llamaste a libgen, o gitlab.com si llamaste a gitlab — fijo en este despliegue, no un host que elija quien llama.
Qué guarda el inspector, y cómo comprobarlo
Nada. El token que pegas —o, cuando el botón de acceso esté activo, el que consigue él— vive en la memoria del componente de la página y en ningún sitio más: sin localStorage, sin sessionStorage, sin cookies, sin parámetros en la URL y sin logs. Al recargar desaparece, al navegar a cualquier sitio desaparece —este sitio no lleva enrutador de cliente, así que cada enlace es un documento nuevo— y al cerrar la pestaña desaparece.
Eso es una afirmación sobre una ausencia, que es justo la clase que nunca deberías creerte por las buenas. Así puedes verlo tú mismo, con el navegador que ya tienes abierto.
En Chrome o Edge, pulsa F12 y ve a Aplicación → Almacenamiento. Pega un token en el inspector, llama a algo y vuelve a mirar: Local Storage, Session Storage y Cookies de este sitio siguen vacíos. En Firefox ese panel se llama Almacenamiento; en Safari es Desarrollo → Mostrar inspector web → Almacenamiento.
Después mira a dónde va. En la pestaña Red, lanza una llamada y abre la petición a /gitlab: la cabecera Authorization está en esa petición y en ninguna otra. El único otro sitio donde podría aparecer el token es el intercambio de acceso con gitlab.com, y solo si usaste ese botón, que ahora mismo está desactivado — así que hoy hay exactamente un destino. La frontera la impone el propio navegador, porque la Content-Security-Policy de esta página nombra esos dos destinos y ningún otro. Todo lo de este párrafo se ve en ese panel, sin fiarte de nadie.
Por el cable: qué va cifrado y dónde deja de estarlo
Todo salto que cruza una red va cifrado. Tu cliente llega a Cloudflare por HTTPS; Cloudflare llega a este servidor también por HTTPS —el HTTP a secas se responde con una redirección y el dominio está en la lista de precarga de HSTS—, y la llamada que sale por fin hacia su destino es HTTPS igualmente, negociada por la propia instancia y solo reenviada, aún sellada, por el túnel WireGuard que le da su salida. Entre nginx y las instancias no sale nada de esta máquina, aunque conviene ser exacto con qué significa eso: nginx marca 127.0.0.1 y el núcleo entrega la conexión directamente al contenedor, sin ningún proxy en espacio de usuario entre medias. Ese tramo no es loopback, así que lo honesto no es decir que no hay red, sino que no hay nadie en ella — los seis contenedores de ese bridge privado son los seis sidecars WireGuard, uno por instancia; cada instancia vive dentro del espacio de red de su sidecar con todas las capacidades de Linux retiradas y el sistema de ficheros en solo lectura, y solo el sidecar conserva la única capacidad que un túnel necesita.
Así que nadie que esté entre medias puede leer tu token. Sí lo ven dos puntos, y a propósito: el borde de Cloudflare, que descifra y vuelve a cifrar todo lo que reenvía, como cualquier CDN; y este servidor, donde nginx necesita el token para calcular el hash de afinidad y la instancia lo necesita para hacer la llamada que le has pedido. Ninguno de los dos lo apunta: ningún log de acceso de esta máquina registra la cabecera `Authorization`, y el hash que sale de ella tampoco se registra — vive lo justo para elegir instancia.
El último salto es HTTPS contra un host que declara este despliegue — gitlab.com, el único servidor de autorización que OAuth admite —, nunca contra uno que aporte quien llama.
Tres instancias, un solo nginx
Detrás de ese nginx hay tres instancias de cada servidor, balanceadas en vez de correr como un único proceso.
Cada instancia tiene su propia caché, así que un acierto en una no lo es en las otras: el reparto entre tres es el precio de poder repartir carga entre ellas.
Afinidad: por qué la segunda petición cae en el mismo nodo
nginx no rota en round-robin entre esas tres instancias: elige una por hash consistente, así que el mismo cliente sigue cayendo en el mismo nodo en vez de en uno distinto cada vez.
libgen hace el hash sobre la IP del cliente (`hash $binary_remote_addr consistent`) — no hay token en el que apoyarse, y la ganancia es la caché de lectura: las llamadas repetidas del mismo visitante siguen cayendo en la instancia que ya las tiene calientes.
gitlab hace el hash sobre la credencial `Authorization: Bearer` del cliente, con la IP como respaldo cuando una petición no lleva ninguna. El motivo es estructural, no de caché: gitlab levanta un servidor aislado por cliente, y su pool de conexiones se indexa por `(token, URL)` — cada entrada comprueba scopes y edición contra GitLab la primera vez que se usa. Con OAuth pesa aún más: cada instancia cachea además la identidad de un token ya verificado durante quince minutos, así que rebotar entre nodos obligaría a re-verificar ese token contra gitlab.com —una llamada de red a un tercero— en cada salto. Un token de acceso OAuth se hashea igual que un PAT, porque llega en la misma cabecera, con un matiz: gitlab.com caduca los tokens de acceso a las dos horas, y un token renovado es una cadena distinta. Así que la afinidad aguanta lo que dure un token, no para siempre, y mudarse cuesta una verificación.
La directiva que convierte una credencial en una decisión de enrutado es esta. Lee la cabecera `Authorization`, y al token que va dentro le pasan dos cosas: nginx lo combina con una sal secreta y lo hashea en `$mcp_affinity`, que es el valor sobre el que de verdad decide el balanceo por hash consistente.
Ese hash es necesario, no decorativo — es la única forma que tiene nginx de devolver a un cliente a la instancia que ya tiene su pool, sin comparar tokens entre sí directamente.
Lo que NO pasa: el token en sí no se escribe en ningún sitio, y el hash tampoco. `$mcp_affinity_salt` y `$mcp_affinity` son variables de nginx corrientes, con el ámbito de la petición que las calculó — nada de esto llega a una línea de log, y nada sobrevive a la petición.
Aun así: desconfía por defecto de cualquier servidor remoto al que le entregues un token — este incluido. Precisamente por eso se enseña la directiva entera en vez de solo afirmarlo.
set $mcp_affinity_salt "…"; # el valor real no se publica
set_by_lua_block $mcp_affinity {
local auth = ngx.var.http_authorization
if auth then
local scheme, token = auth:match("^(%a+)%s+([^%s]+)")
if scheme and scheme:lower() == "bearer" and token ~= "" then
return ngx.md5(ngx.var.mcp_affinity_salt .. token)
end
end
return ngx.var.remote_addr or ""
}El efecto práctico: como cada instancia tiene además un nodo de salida fijo (siguiente sección), caer en el mismo nodo significa que tus llamadas siguen pareciendo venir de la misma dirección — estable, no alternando de una petición a la siguiente.
Salida: por dónde sale una petición
Toda llamada saliente, desde cualquier instancia, sale por un túnel WireGuard hacia uno de tres nodos de salida —un VPS de IONOS en Reino Unido, otro en España y una conexión doméstica en otro punto de España cuya IP dinámica se mantiene al día por DDNS— nunca por la dirección de la red en la que está este servidor.
La asignación es fija por instancia e idéntica en los dos servidores: cada uno tiene una instancia en cada uno de los tres nodos de salida, así que dos de sus tres instancias salen por España y una por Reino Unido. Sea cual sea, lo que ve el destino es la dirección de esa salida, nunca la de esta red.
Cuando algo falla
Una instancia puede caerse o colgarse. Una actualización la retira a propósito, pero eso no es un fallo que nginx llegue a ver: la instancia se drena antes, como describe el párrafo siguiente. Una petición cuya conexión con una instancia caída nunca llegó a abrirse se reintenta en otra — hasta tres intentos en total, y de forma transparente: el cliente ve una respuesta, no un fallo. Una petición que ya se había entregado no se reintenta, y es a propósito: una llamada a una herramienta puede tener efectos — una escritura en GitLab, por ejemplo — y repetirla a ciegas es peor que informar de que falló. Una instancia colgada es justo ese caso: acepta la llamada y no contesta, así que la llamada agota su tiempo en vez de repetirse. Tres fallos seguidos, rechazados o agotados, apartan la instancia diez segundos; pasados, se vuelve a probar, y un acierto la mantiene dentro.
Por debajo, Docker reinicia una instancia cuyo proceso muere, y una comprobación cada dos minutos recrea cualquier contenedor que haya desaparecido del todo. Las actualizaciones siguen el mismo camino, de una instancia en una: se marca fuera en nginx, sus conexiones abiertas tienen hasta cuarenta y cinco segundos para terminar, se recrea con la versión nueva, tiene que contestar a su propia comprobación de salud y solo entonces vuelve — y nada de eso empieza si otra instancia del mismo servidor no está sirviendo, comprobado, en ese momento. Quien estuviera fijado a ella pasa a otra instancia durante ese par de minutos, y después vuelve.
- 0 s No contesta Su conexión se rechaza porque el proceso ya no está. Una instancia colgada es el caso difícil: acepta la llamada, la deja agotar su tiempo, y esa llamada tampoco se reintenta.
- esa llamada Reintento La misma petición va a otra instancia, hasta tres intentos en total; una ya entregada no se repite nunca.
- 3 fallos Apartada Diez segundos fuera, y se vuelve a probar.
- 2 min Reiniciada Docker reinicia al momento un proceso muerto; una comprobación cada dos minutos detecta un contenedor desaparecido y lo recrea.
- otra llamada Vuelve Un acierto la mantiene dentro, y quien estaba fijado a ella vuelve con ella.
Una salida también puede fallar, y ese es el fallo alrededor del que está montado este despliegue. El túnel de cada instancia mide su propia salida una vez por minuto — una conexión por el túnel hasta internet abierto y vuelta, no un saludo al otro extremo, porque un nodo puede contestar al handshake y no encaminar nada. Tres lecturas fallidas seguidas, y un vigilante que las lee cada minuto saca esa instancia de rotación: unos tres o cuatro minutos después del corte, mientras las otras dos instancias de ese servidor siguen. Vuelve cuando lleva al menos tres minutos fuera y se ha leído sana en dos comprobaciones con un minuto entre ellas. Solo cuando las dos instancias que comparten un nodo de salida llevan veinte minutos fuera — o antes, si cae un segundo nodo y un servidor se quedaría con una sola instancia — el vigilante mueve una de ellas a otro nodo, y deja la otra fuera como sensor que dice cuándo ha vuelto el nodo; veinte minutos de ese sensor funcionando y la movida regresa a casa. Si fallan los seis túneles a la vez, no se mueve nada: eso es esta máquina o internet, no tres nodos a la vez — y el tráfico nunca sale por la conexión de casa en su lugar.
- 0 min Corte El nodo deja de encaminar; puede seguir contestando al handshake del túnel.
- unos 3 min Enferma Tres lecturas fallidas seguidas, una por minuto, por el túnel hasta internet abierto.
- unos 4 min Fuera de rotación El vigilante, que lee cada minuto, la marca fuera en nginx; las otras dos siguen.
- +3 min Vuelve Si la salida se recupera: al menos tres minutos fuera, y sana de nuevo en dos comprobaciones con un minuto entre ellas.
- +20 min Se muda Si no: con las dos instancias de ese nodo veinte minutos fuera, o antes si cae un segundo nodo, una se muda a otro nodo y la otra se queda fuera como sensor.
- +20 min A casa El sensor vuelve primero, igual que arriba; veinte minutos sano y la movida regresa.
Lo que eso significa para ti se sigue de la sección de afinidad. Tu clave en el anillo no cambia cuando una instancia está fuera: solo el arco que era de esa instancia se cede al siguiente punto del anillo, así que caes en una de las otras dos — la misma mientras dure la avería, no una distinta por petición — y los demás se quedan donde estaban. Que te cedan puede cambiar el país del que parecen venir tus llamadas, porque la sustituta sale por el suyo; vuelve con tu instancia. Que la muevan es lo contrario: pasado el par de minutos que tarda la mudanza, estás de nuevo en tu instancia, y su salida es la del nodo nuevo mientras esté fuera de casa. Una instancia que solo salió de rotación conserva lo que tenía tuyo cuando vuelve; una recreada — por una mudanza o una actualización — empieza vacía: en gitlab es la verificación que la sección de afinidad ya da por descontada, en libgen una caché de lectura fría, que se vuelve a llenar con el uso.
Un servicio personal
Nada de esto cambia lo que son estos servidores: un proyecto personal, mantenido por una persona, sin SLA y sin garantía de que ninguno de los dos endpoints siga en pie — o igual — de un día para otro.
Esta página se actualizó por última vez el