Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
atproto — Fork de la implementación de referencia del Protocolo AT con AppView optimizado para rendimiento, indexador de firehose basado en Rust, almacenamiento en caché Redis y características comunitarias para redes sociales autoalojadas a escala. | Kitploit
Herramientas/GitHubGitHub/blacksky-algorithms/atproto
Seguridad de Infraestructura en la NubeAuditoría de ConfiguraciónDetección de SecretosGestión de Identidad y Acceso (IAM)AutenticaciónMala ConfiguraciónSeguridad de APIsSeguridad de Bases de DatosAnálisis de Registros
GitHubblacksky-algorithms/atproto

atproto

Fork de la implementación de referencia del Protocolo AT con AppView optimizado para rendimiento, indexador de firehose basado en Rust, almacenamiento en caché Redis y características comunitarias para redes sociales autoalojadas a escala.

Ver Repositorio
9436hace 6 díasRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Blacksky AppView

Esta es una bifurcación (fork) de Blacksky de la implementación de referencia del AT Protocol de Bluesky Social PBC. Impulsa el AppView en api.blacksky.community.

Publicamos esto por transparencia y para que otras comunidades puedan beneficiarse del trabajo. Este repositorio no acepta contribuciones, issues ni PRs. Si desea la implementación canónica de atproto, use bluesky-social/atproto.

¿Qué hay de diferente?

Todos los cambios están en packages/bsky (lógica de AppView), services/bsky (configuración de ejecución) y una migración personalizada. Todo lo demás es upstream.

¿Por qué no el consumidor de firehose integrado?

El dataplane upstream incluye un consumidor de firehose TypeScript (subscription.ts) que indexa eventos directamente. Lo reemplazamos con , un indexador Rust, por varias razones:

rsky-wintermute
  • Rendimiento a escala: El consumidor TypeScript procesa eventos secuencialmente. A escala de red (~1,000 eventos/segundo, 18.5 mil millones de registros totales), una reindexación completa a ~90 registros/segundo tomaría 6.5 años. Wintermute apunta a 10,000+ registros/segundo con procesamiento de colas en paralelo.
  • Arquitectura de reindexación: Wintermute separa la indexación en vivo de la reindexación en colas independientes (firehose_live, firehose_backfill, repo_backfill, labels). Los eventos en vivo nunca se bloquean por el trabajo de reindexación.
  • Herramientas operativas: Wintermute incluye utilidades para indexación directa de cuentas específicas, importación masiva del directorio PLC, reproducción de flujos de etiquetas, reparación de referencias de blobs y gestión de colas, todo necesario al iniciar un AppView desde cero.

El dataplane y el AppView de este repositorio siguen funcionando tal cual. Leen de la base de datos PostgreSQL que escribe wintermute. Simplemente no iniciamos la suscripción de firehose integrada.

Correcciones de rendimiento y operativas

Estas son ampliamente útiles para cualquiera que aloje su propio AppView a escala.

Optimización de consultas LATERAL JOIN (packages/bsky/src/data-plane/server/routes/feeds.ts)

  • getTimeline y getListFeed reescritos con LATERAL JOIN de PostgreSQL para forzar el uso de índices por usuario en lugar de escaneos completos de tabla. Mejora importante para usuarios que siguen a miles de cuentas.

Capa de caché Redis (packages/bsky/src/data-plane/server/cache/)

  • Perfiles de actores (TTL 60s), registros (5m), contadores de interacción (30s), metadatos de publicaciones (5m)
  • Reduce la carga de la base de datos bajo tráfico de producción
  • Problema conocido: La caché de actores tiene un error de serialización de timestamps de protobuf donde los objetos Timestamp pierden su método .toDate() después de un round-trip JSON a través de Redis, causando una hidratación de perfil incompleta en aciertos de caché. Actualmente ejecutamos con la caché Redis deshabilitada. La solución es serializar los timestamps como cadenas ISO al escribir en caché y reconstruirlos al leer.

Aplicación del lado del servidor de preferencias de notificaciones (packages/bsky/src/api/app/bsky/notification/listNotifications.ts)

  • Cuando el cliente no especifica reasons, el servidor aplica las preferencias de notificaciones guardadas del usuario. Sin esto, las preferencias solo se aplican del lado del cliente y no tienen efecto.

Corrección de clave de firma obsoleta en verificador de autenticación (packages/bsky/src/auth-verifier.ts)

  • En reintento de verificación JWT (forceRefresh), omite la caché de identidad en memoria del dataplane y resuelve el documento DID directamente desde el directorio PLC. Soluciona fallos de autenticación después de la migración de cuentas donde la clave de firma rota pero la caché mantiene la clave antigua.

Sanitización JSON (packages/bsky/src/data-plane/server/routes/records.ts)

  • Elimina bytes nulos (\u0000) y caracteres de control de los registros almacenados antes del análisis JSON. Estos son válidos según RFC 8259 pero rechazados por JSON.parse() de Node.js, lo que provoca fallos silenciosos de rowToRecord en el dataplane que se manifiestan como publicaciones faltantes.

Publicaciones comunitarias (específico de Blacksky)

Infraestructura para publicaciones comunitarias privadas que residen en el AppView en lugar de PDS individuales. Específico de cómo funciona Blacksky, pero podría servir como referencia para otras comunidades.

  • Espacio de nombres de lexicon personalizado community.blacksky.feed.* con endpoints para enviar, obtener, eliminar, timeline y vistas de hilos
  • Tabla separada community_post (migración: 20260202T120000000Z-add-community-post.ts)
  • Control de membresía en la capa de dataplane y API
  • Integración con getPostThreadV2 para hilos mixtos de publicaciones estándar y comunitarias
  • Requiere una base de datos de membresía separada (BLACKSKY_MEMBERSHIP_DB_URL)

Arquitectura

root@kitploit:~
Bluesky Relay (bsky.network)
     |
     v
rsky-wintermute -----> PostgreSQL 17 <----- Palomar
  (indexador Rust)         |                (búsqueda Go)
  - consumidor firehose    |                     |
  - reindexador            |                     v
  - indexador de etiquetas |               OpenSearch
  - indexador directo      |
                            v
                    bsky-dataplane (gRPC :2585) <--- Redis (opcional)
                            |
                            v
                    bsky-appview (HTTP :2584)
                            |
                            v
                    Proxy inverso (Caddy/nginx)

Resumen de componentes

ComponenteFuentePropósito
rsky-wintermuteblacksky-algorithms/rskyIndexador de firehose en Rust: consume eventos, reindexa repositorios, indexa registros en PostgreSQL
rsky-relayblacksky-algorithms/rskyRelay del AT Protocol para recibir etiquetas de moderación de servicios etiquetadores
rsky-videoblacksky-algorithms/rskyServicio de subida de vídeo: transcode vía Bunny Stream CDN, sube referencias de blobs a los PDS de los usuarios
bsky-dataplaneEste repositorio (services/bsky)Capa de datos gRPC sobre PostgreSQL
bsky-appviewEste repositorio (services/bsky)Servidor API HTTP para endpoints XRPC de app.bsky.*
Palomarblacksky-algorithms/indigoBúsqueda de texto completo: indexa perfiles y publicaciones en OpenSearch con potenciación por número de seguidores
palomar-syncblacksky-algorithms/rskySincroniza conteos de seguidores y puntuaciones PageRank desde PostgreSQL a OpenSearch

rsky-wintermute en detalle

Wintermute es un servicio monolítico en Rust con cuatro rutas de procesamiento paralelo:

  • Ingester: Se conecta al firehose de bsky.network vía WebSocket, escribe eventos en colas Fjall (almacén clave-valor incrustado)
  • Indexer: Lee de las colas, analiza registros, escribe en PostgreSQL con ON CONFLICT para idempotencia
  • Backfiller: Obtiene archivos CAR completos de repositorios desde los PDS, desempaqueta registros en la cola de reindexación
  • Label indexer: Se suscribe a flujos WebSocket de etiquetadores, procesa eventos de creación/negación de etiquetas

Herramientas CLI adicionales incluidas en el repositorio rsky:

  • queue_backfill -- pone en cola DIDs para reindexación desde CSV, descubrimiento de PDS o listas directas de DIDs
  • direct_index -- obtiene e indexa repositorios específicos sin pasar por colas (útil para reparar cuentas individuales)
  • label_sync -- reproduce flujos de etiquetas desde el cursor 0 para ponerse al día con negaciones perdidas
  • plc_import -- importa asignaciones de handles/DIDs desde el directorio PLC
  • palomar-sync -- sincroniza conteos de seguidores y PageRank a OpenSearch

rsky-video

Servicio de subida de vídeo para usuarios cuyo PDS no soporta video.bsky.app de Bluesky. Usa su propio DID (did:web:video.blacksky.community) para autenticarse en los PDS de los usuarios mediante JWTs de autenticación de servicio. Flujo:

  1. El cliente obtiene un token de autenticación de servicio del PDS (audiencia: DID del servicio de vídeo)
  2. El cliente sube bytes de vídeo a rsky-video
  3. rsky-video genera un CID, sube el blob al PDS del usuario
  4. El vídeo se reenvía a Bunny Stream CDN para transcodificación
  5. Al completarse, el cliente crea la publicación referenciando el blob — el PDS valida que el blob existe

Manejo de etiquetas

Las etiquetas de moderación provienen de servicios etiquetadores (ej., Ozone de Bluesky) mediante suscripción WebSocket. El ingester de Wintermute procesa las etiquetas en una cola dedicada label_live (bajo volumen, separada del firehose principal). La herramienta label_sync puede reproducir el flujo completo de un etiquetador para ponerse al día con negaciones perdidas (eliminaciones de etiquetas) sin reinsertar etiquetas.

Configuración

Requisitos previos

  • Node.js 18+ y pnpm (para construir el dataplane y el appview)
  • PostgreSQL 17 con el esquema bsky
  • Redis (opcional, para caché — ver problema conocido arriba)
  • rsky-wintermute consumiendo el firehose y poblando la base de datos
  • OpenSearch (si se ejecuta la búsqueda de Palomar)

Base de datos

El esquema bsky es creado por las migraciones del dataplane. En la primera ejecución, el dataplane aplicará todas las migraciones automáticamente. La única migración específica de Blacksky es 20260202T120000000Z-add-community-post.ts (tabla de publicaciones comunitarias). Si no necesita publicaciones comunitarias, puede eliminarla.

rsky-wintermute escribe en el mismo esquema. Todas sus instrucciones INSERT usan ON CONFLICT, por lo que es seguro ejecutar wintermute y las migraciones del dataplane en cualquier orden.

Compilación

root@kitploit:~
pnpm install
pnpm build

Ejecutar el Dataplane

root@kitploit:~
node services/bsky/dataplane.js
VariableRequeridaDescripción
DB_PRIMARY_URLSíCadena de conexión PostgreSQL con ?options=-csearch_path%3Dbsky
DB_REPLICA_URLNoCadena de conexión de réplica de lectura
BSKY_DATAPLANE_PORTNoPuerto gRPC (por defecto 2585)
BSKY_REDIS_HOSTNoHost:puerto de Redis para caché (actualmente se recomienda dejarlo deshabilitado)
BLACKSKY_MEMBERSHIP_DB_URLNoBD separada para membresía comunitaria (específico de Blacksky)

Ejecutar el AppView

root@kitploit:~
node services/bsky/api.js
VariableRequeridaDescripción
BSKY_APPVIEW_PORTNoPuerto HTTP (por defecto 2584)
BSKY_DATAPLANE_URLSSíURLs gRPC del dataplane separadas por comas
BSKY_DIDSíDID del AppView (ej. did:web:api.example.com)
BSKY_MOD_SERVICE_DIDSíDID del servicio de moderación Ozone
BSKY_ADMIN_PASSWORDSSíContraseñas de administrador separadas por comas para autenticación básica

Operación a escala

Cronograma de reindexación

Una reindexación completa de la red (todos los ~42M de usuarios, ~18.5B de registros) toma semanas incluso con el procesamiento paralelo de wintermute. Espere:

  • Indexación en vivo: Se mantiene al día en tiempo real desde el día uno (~1,000 eventos/segundo)
  • Reindexación completa: 2-4 semanas a 10,000 registros/segundo dependiendo de la capacidad de respuesta del PDS y las condiciones de la red
  • Reindexación parcial: Horas a días para un subconjunto de usuarios (ej., solo miembros de la comunidad)

Durante la reindexación, el AppView es funcional pero mostrará datos incompletos para los usuarios que aún no han sido reindexados. Los eventos en vivo se indexan inmediatamente independientemente del progreso de la reindexación.

Problemas que resolvimos para llegar hasta aquí

Estos son problemas que encontramos al iniciar un AppView de red completa. Si está haciendo lo mismo, probablemente encontrará algunos de estos:

Corrupción JSON en formato de texto COPY: El protocolo de texto COPY de PostgreSQL trata la barra invertida como un carácter de escape. Si su cargador masivo no escapa las barras invertidas en cadenas JSON, \" se convierte en " y obtiene registros corruptos silenciosamente. La columna record.json es de tipo text (no jsonb), por lo que PostgreSQL no lo detectará. Encontramos ~66,000 registros corruptos y tuvimos que repararlos volviendo a obtenerlos de la API pública.

Bytes nulos en JSON: Algunos registros del AT Protocol contienen \u0000 (byte nulo), que es JSON válido según RFC 8259 pero rechazado por JSON.parse() de Node.js. El dataplane devuelve silenciosamente null para estos registros. Elimine los bytes nulos antes de escribir en la base de datos.

Sensibilidad al formato de timestamp: El dataplane espera timestamps con precisión de milisegundos y sufijo Z (2026-01-12T19:45:23.307Z). La precisión de nanosegundos o el formato de desplazamiento de zona horaria (+00:00) causan problemas sutiles de ordenación y comparación.

Inflado de la tabla de notificaciones: Sin una restricción única en (did, recordUri, reason), la tabla de notificaciones crece sin límite con duplicados. La nuestra alcanzó 1.3 mil millones de filas (663 GB) antes de que lo detectáramos. Agregar ON CONFLICT DO NOTHING a los INSERTs solo ayuda si el índice único existe primero, y crear el índice requiere deduplicación de los datos existentes.

Tablas de incrustaciones de publicaciones: Las tablas post_embed_image y post_embed_video no se pueblan por defecto si su indexador no las maneja. Sin ellas, el filtro de medios en getAuthorFeed no devuelve nada. Estas deben reindexarse por separado.

Orden de negación de etiquetas: Los eventos de negación de etiquetas (eliminación) hacen referencia a la etiqueta original por fuente, URI y valor. Si las negaciones llegan antes que la etiqueta original (común durante la reindexación), se descartan silenciosamente. La herramienta label_sync reproduce el flujo completo para detectarlas.

Envenenamiento de colas Fjall: La base de datos incrustada Fjall (utilizada para las colas de wintermute) puede entrar en un estado "envenenado" después de fallos, bloqueando todas las operaciones de cola. La solución es eliminar el directorio de la base de datos de colas y reiniciar; wintermute se pondrá al día desde el cursor del relay (los relays mantienen ~72 horas de historial).

Inicialización del proveedor TLS: rustls de Rust requiere instalar explícitamente un proveedor criptográfico antes de cualquier conexión TLS. Sin rustls::crypto::aws_lc_rs::default_provider().install_default() al inicio, la primera conexión WebSocket al firehose entra en pánico.

Rotación de clave de firma después de migración de cuenta: Cuando los usuarios migran entre PDS, su clave de firma cambia. El dataplane almacena en caché los datos de identidad con un staleTTL de 1 hora. Durante esa ventana, la verificación JWT falla para los usuarios migrados. La solución es omitir la caché en el reintento de verificación y resolver directamente desde el directorio PLC.

Requisitos de recursos

Basado en la ejecución de un AppView de red completa (todos los ~42M de usuarios, ~18.5B de registros).

RecursoMínimoRecomendado
CPU16 núcleos48+ núcleos
RAM64 GB256 GB
Almacenamiento10 TB NVMe28+ TB NVMe (RAID)
PostgreSQLDedicado, misma máquina o baja latenciaSe recomienda misma máquina
Red100 Mbps sostenidos1 Gbps+

Desglose de almacenamiento (aproximado, red completa):

Grupo de tablasTamaño
Publicaciones + registros~3.5 TB
Me gusta~2 TB
Seguidores~500 GB
Notificaciones~600 GB
Índices~4 TB
OpenSearch (Palomar)~500 GB

Para una comunidad más pequeña que ejecuta un AppView parcial (indexando solo miembros de la comunidad), los requisitos escalan aproximadamente de forma lineal con las cuentas indexadas.

Sincronización con upstream

root@kitploit:~
git remote add upstream https://github.com/bluesky-social/atproto.git
git fetch upstream
git merge upstream/main

Los conflictos normalmente estarán en packages/bsky/src/data-plane/server/routes/ y packages/bsky/src/api/. Resuélvalos manteniendo nuestras adiciones junto con los cambios upstream.

Licencia

Igual que upstream: licencia dual bajo MIT y Apache 2.0. Ver LICENSE-MIT.txt y LICENSE-APACHE.txt.

Descargar herramienta