DEV Community

Ronny Cruz
Ronny Cruz

Posted on

La Compatibilidad Que No Me Había Ganado

La Compatibilidad Que No Me Había Ganado

Por Ronny Cruz Alvarez, fundador de Open Feed Network (Candor Network). Fundador solo, una plataforma en producción y —desde esta semana— una instancia muy pequeña del Fediverso.

La línea en mi propio README

Sentinel Signup es un servicio de filtrado de registros para instancias del Fediverso. Lee tu cola de solicitudes pendientes, evalúa a cada solicitante, y aprueba o rechaza a través de la API de administración. Lo lancé durante la ola de spam de julio, cuando los administradores de instancias se estaban ahogando en solicitudes falsas.

Esta era la instrucción de configuración que envié con él:

Mastodon: Preferencias → Desarrollo → Nueva aplicación, permisos admin:read admin:write.

Léelo otra vez. El producto dice Fediverso. La documentación dice Mastodon. No son la misma palabra, y la distancia entre ambas era una afirmación para la que no tenía evidencia.

El Fediverso no es un solo programa. Es Mastodon y GoToSocial y Akkoma y Pleroma y Misskey y Sharkey e Iceshrimp y una docena más, la mayoría de los cuales implementan "la API cliente de Mastodon" en grados variables y no documentados. Mi sidecar hablaba cuatro endpoints de esa API. Los había verificado contra exactamente cero servidores, porque nunca en mi vida había administrado una instancia.

Estaba vendiendo herramientas anti-abuso a una comunidad de la que no era miembro. No es un fallo moral, pero sí es uno epistémico: todo lo que sabía sobre cómo se comportan esos servidores lo sabía por leer especificaciones. Las especificaciones describen intenciones. Los despliegues tienen opiniones.

Así que construí el banco de pruebas que debí haber tenido primero

La restricción era que no podía costar nada. Mastodon es un inquilino pesado —Ruby, Sidekiq, Redis, su propio Postgres— y la máquina donde lo pondría ya corre cinco servicios en producción. GoToSocial es un solo binario en Go con SQLite que reposa en un par de cientos de megabytes, e implementa la API cliente de Mastodon. Esa es justo la razón por la que era la elección correcta: no es Mastodon, lo que lo convierte en una prueba real y no en un ensayo.

Dos cosas salieron mal antes de que llegara a arrancar, y ambas vale la pena anotarlas.

La CPU se negó. La compilación estándar de GoToSocial ejecuta su ffmpeg y su SQLite integrados a través de wazero, un runtime de WebAssembly, y el compilador de wazero requiere instrucciones x86-64-v2. Mi VPS se reporta como una CPU virtual genérica de QEMU —sin SSE4.2, sin SSSE3, sin POPCNT— porque eso es lo que anuncian muchos hosts virtualizados económicos o antiguos. GoToSocial no degrada a modo intérprete; lanza un pánico a propósito, cosa que respeto. La solución es una compilación oficial nowasm que usa el ffmpeg nativo del sistema. Si te autoalojas en virtualización barata, revisa /proc/cpuinfo antes de asumir instrucciones modernas. La mía llevaba meses siendo silenciosamente antigua.

El proxy mintió sobre quién tocaba la puerta. La instancia está detrás de Cloudflare, y mi configuración de nginx reenviaba la dirección del cliente de la forma convencional. Detrás de un CDN, esa dirección es la del CDN — cada registro del planeta habría llegado desde el mismo puñado de IPs de borde.

Ese merece detenerse, por cómo falla. Nada da error. El servicio de filtrado sigue devolviendo veredictos. Los logs siguen viéndose sanos. Simplemente se vuelve ciego en exactamente la dimensión donde más vale: reputación de IP, velocidad por subred, detección de ráfagas — todas las señales que atrapan una granja de bots colapsan en "una dirección, siempre". Un sistema de seguridad que reporta éxito mientras no mide nada es peor que uno que está obviamente roto, lección que sigo reaprendiendo con disfraces nuevos. La solución fue una directiva de nginx leyendo la cabecera de cliente real del CDN. El hábito es: después de cualquier cambio de infraestructura, verifica que tus señales sigan llevando información, no solo que tus peticiones sigan devolviendo 200.

Cómo se vio la verificación de verdad

Con el nodo corriendo y accesible, revisé las cuatro llamadas que hace mi sidecar, una por una, contra un servidor que nunca había probado:

  • GET /api/v2/admin/accounts — 200
  • GET /api/v1/admin/accounts (la ruta de respaldo) — 200
  • GET /api/v2/instance — 200
  • POST /api/v1/admin/accounts/{id}/reject — 200

Luego la pregunta que realmente determinaba si el producto sirve de algo en GoToSocial: ¿expone la API de administración la IP del registro? Mastodon sí. Si GoToSocial no lo hiciera, entonces en instancias GTS Sentinel estaría funcionando solo con el nombre de usuario y el texto de la solicitud — algo, pero una fracción de la defensa, y tendría que decirlo en voz alta en la documentación.

Sí la expone. El campo ip volvió con valor. Velocidad, subred y reputación funcionan. La afirmación de compatibilidad sobrevive sin matices y —esto es lo que importa— sobrevive porque la ejecuté, no porque la asumí.

También encontré dos diferencias que vale documentar. GoToSocial coloca una solicitud en la cola pendiente de inmediato, sin esperar confirmación de correo, cosa que Mastodon no hace. Y su CLI de administración no tiene delete para cuentas en absoluto — solo disable, más el rechazo vía API. Ninguna de las dos rompe nada. Ambas habrían sido sorpresas frente a un cliente.

El primer registro real

Después registré una cuenta desechable en mi propia instancia, en una ventana de incógnito, como lo haría un desconocido, y escribí una frase genuina en el campo de motivo.

Treinta segundos más tarde, el sidecar la sacó de la cola, la envió al servicio de filtrado en vivo y registró:

APROBARÍA: @[redactado] veredicto=pass confianza=1 — Historial de IP limpio y lenguaje de solicitud natural.

Modo de prueba, así que no hizo nada, que es exactamente para lo que sirve el modo de prueba. Pero la cadena completa había corrido por primera vez en su vida: solicitud pendiente → API de administración → motor de filtrado → veredicto → decisión de acción. Cada pieza que había construido por separado, funcionando junta, en un tipo de servidor que nunca había tocado.

Rechazar la cuenta de prueba después devolvió 200 y dejó la cola en cero, lo que de paso verificó el último endpoint.

Lo dejé en modo de prueba, a propósito

El siguiente movimiento obvio es activarlo para que mi propia instancia se filtre automáticamente. No lo hice.

Mi instancia no es una comunidad — es una cuenta y un banco de pruebas. Encender la aprobación automática significa que desconocidos consiguen cuentas, lo que significa que estoy alojando contenido federado, lo que significa que le he añadido una superficie de moderación a una máquina que ya corre cinco servicios en producción. Esa es una decisión real con obligaciones reales, no una bandera de configuración, y no la voy a tomar como efecto secundario de probar algo.

Así que el sidecar corre continuamente en modo de prueba: cada registro futuro se filtra y se registra, dándome las observaciones, mientras la aprobación sigue siendo una decisión humana. El valor del banco de pruebas está completo. La obligación no se asume por accidente. Puedo activarlo cuando lo decida de verdad.

Limitaciones honestas

  • Una instancia, un registro, mi propia IP. Esto prueba que la tubería conecta. No es una prueba de carga, ni una prueba adversaria, ni evidencia sobre precisión. Nadie ha atacado esta instancia, porque nadie sabe todavía que existe.
  • Una versión. GoToSocial 0.22.1. La cobertura de la API se mueve entre versiones; una afirmación verificada hoy es una afirmación sobre hoy.
  • "Compatible con el Fediverso" sigue siendo excesivo, y lo retiro. Lo que ahora puedo decir es: Mastodon y GoToSocial, verificados. Akkoma, Pleroma, Misskey, Sharkey, Iceshrimp — sin probar. Si administras alguno de esos y quieres averiguarlo conmigo, hago el trabajo contigo.
  • La compilación nowasm no tiene soporte oficial para procesamiento de medios. Bien para un banco de pruebas. Vale saberlo antes de ponerla bajo una comunidad real.
  • Uso herramientas de IA intensivamente —Claude, sobre todo— para construir y para escribir, incluido este texto. El motor de filtrado en sí es deliberadamente heurístico y basado en reglas, sin modelo en el ciclo, porque tiene que funcionar a un costo marginal efectivamente cero para instancias que no pueden pagar por protección contra spam. Donde las máquinas ayudaron, ayudaron; de donde viene la evidencia, son los logs de mi propio servidor.

El punto de ser el cliente cero

"Construido para nosotros, disponible para ti" ha sido la propuesta desde que los módulos de seguridad se extrajeron de mi propia plataforma. Esta semana se volvió más literal: el registro de mi plataforma está filtrado por este producto, y ahora un segundo tipo de servidor también, sobre infraestructura que yo administro.

La razón por la que eso importa no es de mercadeo. Es que cada hueco que acabo de describir —la CPU, las IPs cegadas, el comportamiento de la cola, el verbo faltante en la CLI— lo habría encontrado, de otro modo, un administrador bajo ataque, en el peor momento posible, en un sistema que había confiado por mi palabra. Encontrarlos me costó una tarde y cero dólares. Encontrarlos del otro modo le cuesta a alguien su instancia.

Si administras una instancia del Fediverso de cualquier sabor y tu cola de registros está llena de basura, Sentinel Signup es gratis durante la beta: signup.candortheopenfeednetwork.com. Si corres algo que no he verificado, dímelo y lo probamos como se debe — tips@candortheopenfeednetwork.com. Respondo todo yo mismo.

Top comments (0)