Saltar al contenido principal
Version: 1.0.0

bitcollector

bitcollector lee un host y publica lo que encuentra. Nunca escribe en el host.

Responde a "qué hay en esta máquina y en qué estado está" — de forma continua, en toda una flota, y en una forma que usted puede entregar a un auditor y defender.

Versión0.1.0-ga, commit 8819759, compilada con go1.25.12
PlataformasLinux amd64/arm64, macOS amd64/arm64, Windows amd64 — ver plataformas
Cadena de suministroCompilación reproducible, SBOM CycloneDX, firma cosign, atestación del SBOM, SHA256SUMS firmado
Superficie de red entranteNinguna. El único socket de escucha es solo de loopback
Escrituras en el hostSu propio directorio de datos y su fichero de log — más cualquier fichero que usted le pida explícitamente escribir a export-pubkey

Antes de ejecutarlo, verifique la descarga.

Qué recopila y cuánto cuesta ejecutarlo está más abajo. Dos de las cosas que hace son lo bastante grandes como para tener página propia: la cadena de evidencia — la firma, el encadenamiento y la verificación sin conexión que hacen que el dato sea defendible — y la privacidad y las cuentas locales, que es lo que hace que se pueda desplegar en Francia sin discusiones.

Qué recopila​

Nueve recopiladores, cada uno habilitado de forma independiente y cada uno con su propio intervalo:

RecopiladorQué reporta
processProcesos en ejecución. Las líneas de comandos están desactivadas por defecto — véase Privacidad
portPuertos a la escucha
softwarePaquetes instalados
systemHardware y sistema operativo
metricsMétricas de recursos del host
networkInterfaces y pares establecidos
posturePostura de seguridad viva — véase Postura
accountsCuentas locales privilegiadas e inactivas — véase Cuentas
fileEntradas de logs y ficheros (requiere activación explícita; deshabilitado en la configuración distribuida)

Dos reglas los atraviesan a todos:

  • Cada registro lleva su marca de tiempo de recopilación y el recopilador que lo produjo.
  • "Ausente" y "sin permiso para mirar" nunca son la misma respuesta. Un recopilador que no puede ejecutarse reporta por qué, como un valor de primera clase. Un agente sin privilegios que no puede leer /etc/shadow reporta unknown con el motivo — nunca reporta un certificado de buena salud que no observó.

Esa segunda regla no es un detalle amable. Un inventario que reporta en silencio "sin hallazgos" cuando en realidad se le denegó el permiso es peor que no tener inventario, porque usted actuará en consecuencia.

Postura: observada, no supuesta​

El recopilador posture es la entrada que convierte miles de hallazgos en el puñado que importa: "CVE presente, pero el control Y está verificado como aplicado."

Todo lo que reporta es estado observado del host, nunca un fichero de configuración:

ControlLeído de
SELinux/sys/fs/selinux/enforce — el kernel en ejecución
AppArmor/sys/module/apparmor/…, /sys/kernel/security/apparmor/…
FirewallEl conjunto de reglas vivo de nftables/iptables/ip6tables, en ambas familias de direcciones
sshdsshd -T (con repliegue a sshd -G) — el propio análisis del demonio, que sigue los Include
Sysctls/proc/sys/… — no /etc/sysctl.conf

La distinción es el producto. Un fichero de configuración dice lo que alguien pretendía. sshd -T dice lo que sshd hará realmente. Difieren más a menudo de lo que nadie querría, y es la brecha entre ambos la que hace fracasar las auditorías.

Es de solo lectura: seis comandos de listado con argv fijo a través de una lista de permitidos, sin shell, y cada fichero abierto en O_RDONLY. Se ejecuta sin privilegios y reporta, por cada control, si el control estaba ausente o si el agente no tenía permiso para mirar. Ejecutarlo como root (o con CAP_NET_ADMIN) proporciona además el conjunto de reglas del firewall y el inventario de perfiles de AppArmor.

El flujo de cambios​

Telemetría de estado completo en cada ciclo es lo que hace que un DBA vete su despliegue. El flujo de cambios (A4) envía solo lo que cambió.

Medido en un host de referencia real, publicado junto con la forma del host que lo produjo:

Línea base de estado completo284.57 KB/cycle (media de 4 ciclos consecutivos de 60 s, dispersión del 0.53 %)
Delta distribuido6.55 KB de media, 7.84 KB p95, 10.57 KB en el peor caso — dentro del presupuesto en los 21 ciclos
Forma del host558 procesos, 714 paquetes, 45 puertos a la escucha, 71 conexiones establecidas, 32 interfaces, 6 recopiladores, command_line: off, sin root

El 86.36 % de los bytes de los recopiladores con forma de lista se repite literalmente en cada ciclo, y alrededor del 13 % de los registros de procesos "cambia" en cada ciclo solo por los valores de muestreo de CPU y memoria — por eso esto es una división de esquema (hechos del parque frente a muestras) y no un algoritmo de diferencias. Una diferencia ingenua a nivel de registro midió solo 7.4×, aún muy por encima del presupuesto.

Un flujo delta se reconstruye exactamente hasta el mismo estado que una instantánea completa, y una instantánea completa vuelve a anclar el flujo de forma programada (snapshot_interval: 6h por defecto), de modo que un delta perdido no puede desincronizar en silencio la visión que la plataforma tiene de un host.

El flujo de cambios se distribuye DESACTIVADO, y es deliberado

delta.enabled: false en la configuración distribuida, y activarlo es necesario pero no suficiente: el agente exige además que el plano de control anuncie que entiende el protocolo, y sigue enviando estado completo hasta que lo haga.

Esa segunda barrera está en el código y no en un manual de operaciones porque el modo de fallo es silencioso. Un delta enviado a un receptor que no lo entiende se reenvía aguas abajo como si fuera una carga completa — lo cual no da error, sino que corrompe en silencio la imagen que la plataforma tiene de su parque. Actívelo cuando su tenant de Cert-IX lo admita, no como efecto colateral de otro cambio.

Dos dominios no viajan en absoluto por la ruta delta: posture y accounts se publican solo por la ruta completa, de modo que un agente con el flujo de cambios activado no los enviaría. Ese límite está declarado en el fichero de configuración distribuido, no dejado para que se descubra.

Seguro de ejecutar en producción​

El objetivo de esta sección es darle permiso para instalarlo en una máquina que importa.

Los topes de recursos se aplican, no se documentan.

agent:
max_memory_mb: 50
max_cpu_percent: 80
  • max_memory_mb se aplica como límite de memoria del runtime de Go, de modo que el recolector de basura trabaja progresivamente más para mantenerse por debajo. Cubre el heap de Go, las pilas de las goroutines y las estructuras del runtime. No es un OOM killer: superarlo hace que el agente sea más lento, nunca que muera — un agente que se mata a sí mismo bajo presión de memoria deja de ser evidencia justo cuando está pasando algo interesante.
  • max_cpu_percent es un techo sobre el propio ciclo de trabajo del agente como porcentaje de un núcleo (80 = 0.8 núcleos). Se aplica por aplazamiento: cuando la media de la ventana deslizante supera el techo, el siguiente tic de recopilación se omite y se contabiliza. La entrega, los latidos, la cola de reenvío y el endpoint local de salud nunca se aplazan — un host bajo carga debe seguir pudiendo enviar lo que ya tiene.

El aplazamiento es visible cuando ocurre:

Collection tick DEFERRED: this agent is above agent.max_cpu_percent. Delivery and
heartbeats are unaffected; the deferral is counted on the local health endpoint so a
permanently throttled agent cannot pass for a quiet host

Cero superficie de red entrante. El único socket de escucha es un endpoint local de salud/métricas, y se enlaza solo a loopback — 127.0.0.1 y [::1], como dos listeners explícitos, con las direcciones de enlace como constantes de compilación. No hay ninguna clave de configuración para ampliarlo, porque un listener que un operador puede ampliar acaba ampliándose.

curl -s 127.0.0.1:9713/status

Un watchdog reinicia un recopilador atascado sin reiniciar el agente. Lento y atascado se distinguen por medición, no por conjeturas: lento significa que el recopilador devuelve tarde (ya reportado como timeout); atascado significa que su contexto se canceló y aun así no ha devuelto. La rotación de logs poda tanto por tamaño como por antigüedad, de modo que el agente no puede llenarle /var y provocarle una caída.

Almacenar y reenviar. La telemetría que no pudo entregarse se reintenta con retardo progresivo y se entrega cuando la pasarela vuelve. Un 401 en la ruta de telemetría refresca el token y reintenta. Lo que no pudo entregarse es atribuible — un hueco nunca es indistinguible de "no existían datos".

Cómo ejecutarlo​

bitcollector es un único binario estático. Verifíquelo primero (cómo), y después:

# Check what you have
bitcollector --version
# bitcollector 0.1.0-ga (commit: 8819759, built: 2026-08-09T12:08:13Z)

# Run with a configuration file
bitcollector -config /etc/bitcollector/bitcollector.yaml

# Turn up the detail while you are setting it up
bitcollector -config /etc/bitcollector/bitcollector.yaml -log-level debug

Las variables de entorno tienen prioridad sobre los valores del fichero de configuración:

VariablePropósito
CERTIX_TENANT_IDSu tenant, en Settings → Organization
CERTIX_ENROLLMENT_TOKENToken de enrolamiento de un solo uso, generado en el panel. Obligatorio salvo que estén configurados certificados de cliente mTLS
CERTIX_GATEWAY_URLAgent Gateway (registro, refresco de token, política)
CERTIX_INGEST_URLAgent Ingestion Gateway (latido, telemetría)
CERTIX_TLS_CA_CERT / CERTIX_TLS_CLIENT_CERT / CERTIX_TLS_CLIENT_KEYMateriales mTLS

El agente se niega a arrancar antes que ejecutarse sin una identidad que pueda demostrar:

ERROR: Failed to load configuration: missing required configuration:
control_plane.enrollment_token (CERTIX_ENROLLMENT_TOKEN) required when mTLS client
certificates are not configured

Ajustar lo que cuesta​

Se respetan los valores interval: y timeout: por recopilador. Cada recopilador habilitado se ejecuta en su propio intervalo y llena una caché; un tic de publicación independiente, en agent.collection_interval, envía un lote que lleva los dominios que produjeron datos nuevos.

Cuota medida de cada recopilador en un lote, para que pueda ajustar contra números reales en lugar de conjeturas (5 ciclos a 60 s, sin root, command_line: off):

RecopiladorCuota del lote
process89.79 %
software6.85 %
port1.86 %
system1.20 %
network0.27 %
metrics0.01 %

El recopilador cuyo intervalo hay que alargar si quiere menos bytes es process, no software.

No hay ningún valor que signifique "sin límite"

timeout: 0s significa "no configurado": se usa el valor por defecto incorporado y el agente registra un aviso nombrando la clave. No es una forma de decir "tómate el tiempo que necesites" — todos los recopiladores comparten una única goroutine de planificación, así que una ejecución que nada puede cancelar detiene también la publicación, el latido y todos los demás recopiladores. Fije el tiempo máximo que tarda una ejecución sana en este host, con margen.

Plataformas​

0.1.0-ga publica cinco binarios firmados, y no se retiene nada — bitcollector es el único bit que se distribuye en todas las plataformas a las que apunta la familia:

PlataformaPublicadaNotas
Linux amd64Sí
Linux arm64Sí
macOS amd64Sí
macOS arm64Sí
Windows amd64SíSe distribuye como bitcollector-windows-amd64.exe

Puede hacerlo porque lee, y cada colector tiene una implementación por sistema operativo, con una respuesta explícita de «no disponible aquí» allí donde una plataforma no tiene equivalente. Los otros tres bits retienen cada uno al menos una plataforma, y cada una de sus páginas dice cuál y por qué — bitscanner, bitenforcer, bitmapper.

Distribuirse en una plataforma no es lo mismo que observarlo todo allí. Los controles que el agente no lee en un sistema dado se informan con un estado distinto — no soportado por el agente en esta plataforma — que lleva la plataforma como origen y una instrucción explícita de no puntuar el control como ausente. Es una afirmación sobre el agente, nunca un hallazgo sobre el host.

Es la misma regla que en el resto de esta página: ausente, sin permiso para mirar y no observado en esta plataforma son tres respuestas distintas, y ninguna de ellas es un certificado de buena salud.

Próximos pasos​

¿Te resultó útil esta página?