Saltar al contenido principal
Version: 1.0.0

Cómo captura bitmapper

Esta página describe el pipeline real del comando capture: qué abre, qué filtra, qué recuerda y qué le cuesta cada ajuste.

Todo lo que sigue ocurre en el host. Los paquetes en sí nunca salen de él — lo que sale es un registro de flujo que resume cada conexión seguida. Vea qué sale del host.

interfaces → BPF filter (kernel) → worker pool → connection tracker → flow record → platform
│ │
│ └→ un último
│ intento de atribución
├→ atribución de procesos, reintentada en
│ paquetes posteriores con backoff
└→ statistics (structured JSON log)

Elegir las interfaces​

bitmapper interfaces enumera aquello sobre lo que este host puede capturar. Después, o las nombra, o no nombra ninguna y deja que el agente elija:

capture:
interfaces: ["eth0", "eth1"] # empty = every interface that is up and not loopback

Con capture.interfaces vacío, el agente captura en todas las interfaces que estén activas y no sean loopback. En un host con varias NIC, un puente y las interfaces virtuales de los contenedores, eso suele ser más de lo que pretendía — el mismo paquete puede verse más de una vez al atravesar un puente. Nombre las interfaces que de verdad le importan.

capture.exclude_interfaces elimina nombres de la lista con la que acabe:

capture:
interfaces: [] # auto-detect: every interface up and non-loopback
exclude_interfaces: ["docker0", "veth0"]

Se aplica tanto a una lista explícita de capture.interfaces como al conjunto detectado automáticamente, y la coincidencia no distingue mayúsculas de minúsculas e ignora los espacios que la rodean. Eso lo convierte en la herramienta adecuada para el caso habitual: deje que el agente encuentre las interfaces y luego reste los puentes y las interfaces virtuales cuyo tráfico no quiere ver duplicado.

Filtrado: cuatro claves, un único filtro del kernel​

Cuatro claves deciden qué paquetes llega a ver bitmapper, y las cuatro se compilan en una sola expresión BPF que se entrega a libpcap antes de que arranque la captura. Todo lo que excluyen lo descarta el kernel — no se filtra después en la salida, no se copia al agente en absoluto.

ClaveValor por defectoQué aporta
capture.filter"" — ningunoUna expresión BPF en bruto, usada tal cual, entre paréntesis
capture.protocols["tcp", "udp"]Una lista de permitidos: (tcp or udp). Solo acepta tcp, udp, icmp, all
capture.ports[] — ningunoUna lista de permitidos: (port 80 or port 443)
capture.exclude_ports[] — ningunoUna lista de exclusión: not (port 22)

Las cláusulas se unen con and, en ese orden. La configuración que bitmapper distribuye (configs/bitmapper.yaml) fija protocols: [tcp, udp] y exclude_ports: [22], lo que compila a:

(tcp or udp) and not (port 22)

Rellene las cuatro y obtendrá una sola expresión — por ejemplo filter: "host 10.0.0.1", protocols: [tcp], ports: [443], exclude_ports: [22] compila a (host 10.0.0.1) and (tcp) and (port 443) and not (port 22).

El agente registra la expresión compilada al arrancar siempre que difiera de lo que usted escribió en capture.filter, de modo que puede releer exactamente lo que se le entregó al kernel en lugar de deducirlo. Un puerto fuera de 1–65535 en cualquiera de las dos listas se rechaza al arrancar, en vez de fallar más tarde dentro de libpcap.

Corrección: estas tres claves están activas, y esta página afirmaba lo contrario

Una versión anterior de esta página llevaba un aviso titulado «Tres claves de filtrado que no lee nadie», que afirmaba que capture.protocols, capture.ports y capture.exclude_ports se validaban y luego se ignoraban. Eso era falso. Las tres se compilan en el filtro BPF descrito arriba y las aplica el kernel.

El error iba en la dirección que le cuesta a usted, y capture.exclude_ports es la razón para releer su configuración ahora mismo. La configuración distribuida contiene exclude_ports: [22] — «no capturar SSH» — y esa exclusión es real: los paquetes SSH se descartan antes de llegar al agente. Si leyó el aviso antiguo y borró la clave por considerarla lastre, desactivó un control de privacidad que funcionaba y empezó a recoger tráfico que había excluido deliberadamente. Nada se lo habría advertido, porque desde el punto de vista del agente usted simplemente pidió más tráfico.

El contraejemplo del aviso antiguo también estaba exactamente al revés. capture.ports: [443] no captura todo. Con los protocolos por defecto compila a (tcp or udp) and (port 443) y captura solo el puerto 443:

# This captures TCP/UDP port 443 and nothing else — the ports key is applied, in the kernel
capture:
ports: [443]

El valor por defecto es tcp + udp, así que ICMP no se captura​

capture.protocols vale por defecto ["tcp", "udp"] aunque su archivo de configuración no la mencione nunca. Un host con una configuración de fábrica nunca ve, por tanto, ICMP, ICMPv6, SCTP, GRE, ESP ni AH: el kernel los descarta, el agente nunca los recibe y ningún contador registra lo que se filtró. En la salida, una ausencia y un silencio son indistinguibles.

Es un punto ciego real si usa bitmapper para ver barridos de ping, tráfico tunelizado o IPsec. Para eliminarlo, pida que no haya ninguna restricción de protocolo:

capture:
protocols: ["all"]

Dos detalles fáciles de pasar por alto:

  • protocols: ["icmp"] cubre ambas familias — compila a (icmp or icmp6), de modo que pedir ICMP no le da calladamente solo IPv4.
  • No existe ningún valor para SCTP, GRE, ESP ni AH. protocols solo acepta tcp, udp, icmp y all; cualquier otra cosa se rechaza al arrancar con invalid protocol: … (valid: tcp, udp, icmp, all). Si necesita uno de esos en concreto, fije protocols: ["all"] y exprese el protocolo en capture.filter.

capture.exclude_ports por sí sola no crea este punto ciego. Se traduce a not (port 22), y una prueba de puerto BPF también es cierta para los paquetes que no tienen puertos, así que excluir SSH no descarta ICMP de paso. Eso solo lo hace la lista de permitidos de protocolos.

Prefiera el filtro más estrecho, sea cual sea la clave que lo exprese​

Merece la pena aprender BPF en cualquier caso. tcp and not port 22, port 443 or port 8443, not net 10.0.0.0/8 — cada uno se aplica antes de que el paquete le cueste nada, y capture.filter sigue siendo la única clave capaz de expresar restricciones de host, de red o de sentido. Las tres claves-lista son el atajo legible para los casos de protocolo y puerto; terminan en el mismo sitio.

Lo que aquí es realmente inerte son las opciones de registro​

--log-level y --log-format no hacen nada

Esta página señalaba antes a las claves de filtrado como aquello que se analiza sin tener efecto. Las opciones que se comportan realmente así son las de registro en la línea de comandos.

--log-level y --log-format están declaradas en el comando raíz y aparecen en --help con los valores por defecto info y json, pero ningún código lee ninguna de las dos. El registrador es un registrador zap de producción fijo, construido al arrancar — JSON, nivel info — y ninguna de las dos opciones puede cambiarlo. Pasar --log-level debug no le da ningún detalle adicional; pasar --log-format console le sigue dando JSON.

Las demás opciones de capture se comportan igual. --interfaces, --filter, --snaplen, --promiscuous, --buffer-size, --workers, --queue-size y --stats-interval se enlazan en Viper bajo su nombre de opción mientras que la configuración se lee de claves anidadas (capture.filter, capture.snaplen, performance.workers, …), así que se analizan y se ignoran. --enable-grpc y --enable-http son peores que ignoradas: valen true por defecto en --help y describen servidores que este agente nunca construye — no hay ningún escuchador gRPC ni HTTP que habilitar.

--config es la única opción que cambia lo que hace el agente. Ponga todo lo demás en el archivo YAML.

Leer los paquetes​

ClaveValor por defectoQué hace
capture.snaplen65535Bytes capturados por paquete (validado entre 0 y 65535)
capture.promiscuoustrueModo promiscuo
capture.buffer_size104857600Búfer de captura del kernel, en bytes
capture.timeout100msTiempo de espera de lectura de paquetes

Snaplen es la palanca que más merece la pena bajar. bitmapper construye un mapa de conexiones — quién habla con quién, por qué vía y cuánto — y todo eso vive en las cabeceras de los paquetes. Capturar la carga útil completa de 65535 bytes copia en la memoria del agente datos de aplicación que aquí no lee nadie. Un snaplen de unos pocos cientos de bytes conserva todas las cabeceras que el rastreador necesita e impide por completo que se copie la carga útil, lo que es a la vez más barato y una exposición mucho menor si el host resulta comprometido.

El modo promiscuo hace que la NIC acepte tramas que no van dirigidas a ella. En una red conmutada eso produce sobre todo difusión y multidifusión; en un puerto espejo/SPAN es lo que hace que la captura sirva de algo. Además exige privilegios elevados, y merece la pena desactivarlo cuando solo quiere las conversaciones propias de este host.

Atribución de procesos​

capture:
enable_process_mapping: true
process_mapping_interval: 5s
Esta sección describe la PRÓXIMA versión, no el binario que puede descargar

Todo lo que sigue — la atribución por flujo, el relleno posterior, la inferencia a partir de los sockets a la escucha y el campo attribution — está sin publicar. No está en 0.1.0-ga (commit 64ebc64), que sigue siendo el único binario publicado. Ejecute bitmapper version y compare antes de planificar nada sobre esta página.

Lo que hace el binario que puede descargar hoy. Leído del código en el commit 64ebc64:

  • La atribución se intenta una sola vez, al crear la conexión, a partir de una instantánea de la tabla de sockets que puede tener hasta process_mapping_interval de antigüedad. No hay reintento de ningún tipo.
  • No hay inferencia alguna a partir de los sockets a la escucha. El código que la realiza no existe en ese commit. 0.1.0-ga no puede emitir nunca listening_socket, ni nombrar nunca un proceso que no haya encontrado en el socket propio del flujo.
  • La respuesta se registra siempre en el extremo origen. destination_process no se asigna en ninguna parte de esa versión, así que nunca puede aparecer en un registro exportado.
  • El objeto de proceso exportado lleva pid, name, executable y user — y ningún campo attribution.

El socket de una conexión saliente no puede estar en una instantánea tomada antes de que esa conexión existiera, así que los flujos de 0.1.0-ga a menudo no llevan proceso alguno. Medido en el host de desarrollo: 0 flujos atribuidos de 12. Espere eso de esta versión en lugar de leerlo como un error de configuración.

Lo que hace la próxima versión. El intento se repite en los paquetes posteriores del flujo y una vez más en la ruta de exportación; se atribuyen ambos extremos; y cada objeto de proceso lleva un campo attribution que dice si la identidad vino del socket propio del flujo o de un socket a la escucha. Esa inferencia está condicionada por tres cosas: el extremo debe ser una dirección de este host, debe probarse que exactamente un proceso tiene el socket a la escucha, y el flujo debe ser TCP.

Esto es lo que separa una captura de un volcado de paquetes: una conexión rastreada se resuelve al PID, el nombre del proceso, la ruta del ejecutable y el usuario propietarios del socket, leyendo las tablas de sockets del host.

La atribución es por flujo, no por paquete, y se registra en el extremo del flujo que posee el socket — de modo que un registro de flujo puede llevar source_process, destination_process, o ninguno de los dos. En un host que es uno de los extremos de la conversación, el otro extremo es un par remoto cuyo proceso no está en esta máquina y nunca lo estará; se espera que solo se rellene un extremo.

Se completa a posteriori, no se resuelve una sola vez​

El primer intento de atribución de un flujo ocurre al crear la conexión, y falla muy a menudo: el socket de una conexión saliente no puede aparecer en una instantánea de la tabla de sockets tomada antes de que la conexión existiera. Por eso el intento se repite:

  • En los paquetes posteriores del flujo, con un backoff que arranca en 100 ms y se duplica hasta un techo de 30 s. Un flujo que realmente no tiene socket local — tráfico que el host se limita a reenviar — se estabiliza así en un par de búsquedas por minuto en lugar de una por paquete.
  • En la ruta de exportación, antes de construir un registro para ese flujo. Para un flujo ya terminado es su única oportunidad restante: un ciclo petición/respuesta local puede durar bastante menos de un milisegundo, así que su socket desapareció microsegundos después de su único intento en la ruta de paquetes.
process_mapping_interval no es el mando para los flujos sin atribuir

Esta página describía antes un compromiso en el que un intervalo corto atribuye con más frecuencia las conexiones efímeras y uno largo las pierde. Ya no es así como funciona la atribución, y ahora contradice la configuración que el agente distribuye — configs/bitmapper.yaml afirma lo contrario en un comentario sobre esa misma clave.

process_mapping_interval fija el refresco programado de la tabla de sockets. Ya no es lo único de lo que depende la atribución: una búsqueda que falla la instantánea desencadena una relectura bajo demanda de las tablas de sockets del kernel para ese único flujo, y el intento se reintenta como se describe arriba. Bajar el intervalo no es la solución para los flujos que llegan sin atribuir, y subirlo ya no le cuesta los flujos cortos que antes le costaba.

Las conexiones que no se pueden atribuir se siguen rastreando y exportando; simplemente no llevan ninguna identidad de proceso. Esa es una respuesta correcta, no una carencia — vea más abajo por qué es preferible a la alternativa.

Cómo se hizo la atribución: socket vs listening_socket​

Cada objeto de proceso en un registro de flujo exportado lleva un campo attribution que indica cómo se determinó esa identidad. Es una señal de confianza, y los dos valores no son intercambiables:

"source_process": {
"pid": 41207,
"name": "curl",
"executable": "/usr/bin/curl",
"user": "deploy",
"attribution": "socket"
}
ValorCómo se determinóHasta dónde fiarse
socketCoincidió con el socket propio de este flujo en las tablas de sockets del host, sobre la cuádrupla completaUn hecho. Ese proceso tenía ese socket.
listening_socketNo se encontró socket para este flujo. La identidad se tomó del proceso a la escucha en esa dirección y puerto — y solo cuando esa dirección está en este host, se prueba que exactamente un proceso tiene el socket, y el flujo es TCPUna inferencia, etiquetada como tal. Está acotada, pero sigue siendo una afirmación más débil que socket: vea la regla del dueño único y solo TCP.

El valor más débil existe porque la alternativa es no tener nada: un flujo que vive unos cientos de microsegundos está cerrado mucho antes de que una lectura de /proc pudiera ver su socket, y el socket a la escucha es lo único que le sobrevive. Merece la pena reportarlo — pero no debe leerse como la misma afirmación que socket.

Un consumidor que trate ambos por igual está sacando una conclusión que el agente no sacó. Si construye alertas, mapas de dependencias o políticas sobre los registros de flujo, ramifique según este campo.

Corrección: esta página describía una inferencia aplicada de más que ninguna versión contiene

Una versión anterior de esta página llevaba un bloque de peligro titulado «listening_socket es una inferencia, y hoy se aplica de más». Hacía dos afirmaciones concretas — que la inferencia «no se comprueba contra el host local» y que «no identifica qué proceso a la escucha» — y le decía que descartara listening_socket sin más para cualquier extremo que no fuera una dirección del host que informa.

Ambas afirmaciones son falsas para todas las versiones de bitmapper que usted puede obtener. Describían un estado interno que se corrigió antes de publicar nada:

  • La 0.1.0-ga publicada no tiene nada que aplicar de más. No contiene inferencia alguna a partir de los sockets a la escucha y no puede emitir listening_socket.
  • La próxima versión comprueba esas dos cosas antes de inferir. El extremo debe ser una dirección de este host — que es lo que impide acreditar un flujo saliente hacia un par remoto a un proceso local a la escucha en la dirección comodín — y debe probarse que exactamente un proceso tiene ese socket a la escucha, que es lo que impide nombrar a uno de los hermanos de un servidor que pre-bifurca. Medido tras la corrección, en el mismo host y con el mismo tráfico que produjo las fabricaciones: ninguna atribución inventada, y todas las atribuciones que el agente sí hizo eran correctas.

El consejo que se seguía de esas afirmaciones era un razonamiento acertado sobre código que ningún cliente tiene. listening_socket sigue siendo el más débil de los dos valores y sigue mereciendo que se ramifique según él — es una inferencia, y está etiquetada como tal —, pero es una inferencia acotada y no una sin comprobar, y «descártelo para un extremo no local» describe ahora una regla que el propio agente aplica, antes de construir el registro.

La inferencia es solo para TCP, así que un flujo UDP nunca la lleva​

listening_socket solo puede aparecer en un flujo TCP. UDP no tiene estado LISTEN: un socket UDP enlazado es indistinguible del de un servidor, así que no hay nada de lo que inferir. La inferencia no devuelve nada para cualquier protocolo que no sea TCP, antes de examinar ninguna otra cosa.

No es una limitación a la espera de levantarse: es lo que impide una respuesta equivocada muy concreta. Un flujo UDP puede perfectamente llegar a un puerto en el que escucha un servidor TCP; 53 y 853 son el caso corriente. Sin la comprobación de protocolo, el proceso TCP a la escucha de un servidor DNS se nombraría como dueño de tráfico UDP sin relación en el mismo puerto.

Así que un flujo UDP cuyo propio socket no se pudo encontrar se exporta sin proceso, y ese es el resultado corriente para UDP, no uno raro: una consulta DNS termina en bastante menos de un milisegundo, su socket ha desaparecido antes de que una lectura de /proc pudiera alcanzarlo, y no hay ninguna respuesta más débil a la que recurrir. Lea un campo de proceso vacío en un flujo UDP como la única respuesta honesta disponible para ese protocolo, no como un defecto.

La atribución directa no se ve afectada por la comprobación de protocolo. Los sockets UDP se leen en las mismas tablas de sockets, así que un flujo UDP cuyo propio socket está ahí con una cuádrupla coincidente se atribuye igual que uno TCP, con "attribution": "socket". El matiz es que un socket UDP al que nunca se le hizo connect() no tiene dirección remota que declarar, así que no hay cuádrupla que casar — que es la otra razón por la que la atribución es más escasa en UDP que en TCP.

Una inferencia necesita un socket con un único dueño​

bitmapper solo toma una identidad de un socket a la escucha cuando puede probar que exactamente un proceso lo tiene. Cuando no puede probarlo, el flujo se exporta sin proceso alguno en lugar de con uno de los candidatos.

Un socket a la escucha con varios dueños es el caso corriente, no uno exótico. Medido en el host de desarrollo: un socket de nginx a la escucha en 0.0.0.0:443 — un único inodo de socket — lo tenían 17 procesos, que es el aspecto de cualquier servidor que pre-bifurca sus procesos trabajadores. Un socket, diecisiete nombres que podrían escribirse en el registro. Los flujos entrantes hacia un socket así se dejan sin atribuir, deliberadamente. Nombrar a uno de los diecisiete pondría una conjetura en el mismo campo, y con la misma forma, que una medición.

Solo el refresco periódico completo de /proc puede producir esa prueba. Recorre todos los procesos, de modo que puede establecer que un inodo de socket aparece en los descriptores de un proceso y en los de ningún otro. El recorrido bajo demanda, más barato — el que dispara una búsqueda fallida para un único flujo — se detiene en el primer proceso que tiene el inodo que busca: puede probar que un proceso tiene un socket, pero nunca que sea el único.

Así que de un proceso que acaba de ponerse a la escucha no se infiere hasta que el siguiente refresco completo lo ha cubierto. Durante un breve rato tras el arranque de un servicio, el tráfico efímero dirigido a él puede aparecer sin ninguna atribución de proceso. Dos propiedades acotan esto, y ambas importan cuando está decidiendo si tiene delante un defecto:

  • Cuesta atribución, nunca corrección. En esa ventana no se produce ningún proceso equivocado; el campo queda vacío, no engañoso.
  • Un socket a la escucha sobrevive holgadamente al intervalo de refresco, así que esto es un efecto de ventana de arranque y no de régimen permanente. Una vez que un refresco completo ha cubierto a un proceso a la escucha, sigue cubierto mientras siga escuchando.

Cuánto dura la ventana depende de process_mapping_interval y del host, así que no hay una cifra única que citar. El bucle de refresco está limitado por ciclo de trabajo — recorrer /proc no debe convertirse él mismo en la carga de una máquina ocupada — de modo que un host con una tabla de procesos grande tarda más en terminar un refresco, y allí la ventana es correspondientemente más larga.

Nada de esto impide que un flujo se capture, se siga, se cuente o se exporte. Si tiene delante registros con source_process y destination_process vacíos, lea las estadísticas periódicas que registra el agente antes de concluir que el agente está roto: unos contadores de paquetes y conexiones que siguen avanzando le dicen que la captura funciona, y que lo que ve es una atribución retenida.

Una mala atribución es peor que ninguna: un flujo sin atribuir es visiblemente incompleto, mientras que un flujo que nombra al proceso equivocado es una afirmación falsa y segura de sí misma que ningún consumidor puede detectar. Por eso un flujo sin atribuir se deja sin atribuir en lugar de adivinarlo, y por eso la inferencia se etiqueta en lugar de mezclarse en silencio con los hechos.

El pipeline de trabajadores​

ClaveValor por defectoRestricción
performance.workers4≥ 1
performance.queue_size100000≥ 100

Los paquetes se entregan a un grupo de trabajadores a través de una cola acotada. Cuando la cola está llena, el paquete se descarta y el contador de descartes se incrementa — el agente no bloquea la ruta de captura para ir al día, porque bloquear ahí haría que se desbordara el propio búfer del kernel.

El contador de descartes es la cifra que hay que vigilar. Aparece en las estadísticas periódicas, y un recuento de descartes que sube de forma persistente significa que el host está viendo más tráfico del que esta configuración puede procesar. Por orden de efecto, las soluciones son: afinar el filtro del kernel — cualquiera de capture.filter, capture.protocols, capture.ports o capture.exclude_ports, ya que las cuatro acaban en la misma expresión —, después bajar capture.snaplen y después subir performance.workers.

Seguimiento de conexiones​

ClaveValor por defectoRestricción
performance.connection_table_size1000000≥ 1000 — máximo de conexiones rastreadas antes del desalojo
performance.connection_timeout5m≥ 1s — tiempo de inactividad antes de que una conexión se recolecte
performance.gc_interval1m≥ 1s — con qué frecuencia se ejecuta la recolección

El rastreador empareja ambos sentidos de una conversación en una sola conexión, ejecuta una máquina de estados TCP (SYN_SENT → ESTABLISHED → … → CLOSED) y cuenta paquetes y bytes por conexión.

Dos límites la mantienen finita, y son mecanismos distintos:

  • connection_table_size es un tope duro. Pasado ese punto, las entradas se desalojan — un host bajo una avalancha de conexiones pierde entradas antiguas en lugar de crecer hasta que el proceso muere.
  • connection_timeout + gc_interval recolectan las conexiones que simplemente han quedado inactivas, esté la tabla cerca de su tope o no.

Un host que hace muchas conexiones salientes efímeras — un rastreador web con mucha actividad, un ejecutor de CI — hará rotar esta tabla con fuerza. Ese es el comportamiento previsto: una tabla acotada que olvida es mejor que una sin límite que acaba con el proceso.

Estadísticas​

performance:
stats_interval: 10s # 0 disables the reporter entirely

Los contadores de paquetes, bytes, descartes y conexiones se escriben como JSON estructurado a través del registrador del agente en este intervalo. Son la evidencia local de que la captura en sí funciona, con independencia de que la exportación esté llegando o no a la plataforma:

bitmapper capture --config /etc/bitmapper/config.yaml

La salida es JSON en nivel info y no hay ninguna opción que lo cambie — vea las opciones de registro. Pásela por jq si la quiere legible.

Vigile el contador de descartes a lo largo de varios intervalos. Cero descartes y un recuento de conexiones que sube significa que el pipeline va al día. Si el contador de paquetes se queda a cero en un host que usted sabe que está activo, revise el filtro compilado que el agente registró al arrancar antes de sospechar de la ruta de captura: el valor por defecto de protocolos excluye más de lo que casi nadie espera.

Qué sale del host, y qué no​

El tráfico en sí se queda aquí. Lo que sale es un registro de flujo — el resumen de una conexión, no su contenido. Para ser exactos:

DatoAdónde va
Cabeceras y carga útil de los paquetes hasta snaplenSolo la memoria del agente, mientras dura el procesamiento del paquete
Bytes de carga útil de los paquetesA ningún sitio. Nunca se exportan, nunca se escriben en disco
Registros de conexión, con atribución de procesosLa tabla de conexiones en memoria — y, como registros de flujo, a la plataforma sobre https
Cómo se hizo cada atribución (socket / listening_socket)Va en el registro de flujo junto al proceso a partir de la próxima versión — vea confianza de la atribución
La línea de comandos del procesoA ningún sitio. Excluida deliberadamente: las líneas de comandos llevan habitualmente credenciales como argumentos
Contadores de paquetes/bytes/descartes/conexionesLa propia salida de registro del agente
Registro y latido del agenteEl plano de control, sobre https

Un registro de flujo lleva los extremos, los puertos, el protocolo, el estado de la conexión, los contadores de bytes y paquetes y — para el extremo del flujo que posee el socket — el PID del proceso atribuido, su nombre, la ruta de su ejecutable, su usuario y — a partir de la próxima versión — el marcador attribution que indica cómo se determinó esa identidad. Eso es todo. Si necesita mantener una subred fuera de eso, output.filter.exclude_cidrs descarta el flujo en la entrada — antes de construir un registro — y casa con cualquiera de los dos extremos. Vea la visión general.

No hay implementación de storage.* ni exportación a fichero, así que el agente no persiste nada. Cuando el proceso se detiene, la tabla de conexiones se va con él.

Próximos pasos​

¿Te resultó útil esta página?