Contexto

Se necesitaba analizar tráfico ASTERIX CAT062 recibido mediante UDP.

Existía una dificultad operativa importante: la aplicación en producción debía continuar recibiendo la señal mientras se realizaban pruebas.

Esto generó varias preguntas:

  • ¿se puede ejecutar tcpdump sobre un puerto que ya está usando una aplicación?
  • ¿es necesario duplicar el puerto?
  • ¿cómo capturar sin afectar al servicio?
  • ¿cómo conservar la captura si se cierra la sesión SSH?
  • ¿cómo rotar PCAP sin perder paquetes?
  • ¿cómo distinguir pérdidas reales de paquetes de pérdidas introducidas por la herramienta de captura?

Decisión clave: distinguir captura pasiva de consumo del socket

Una confusión habitual es pensar que si una aplicación escucha un puerto UDP, una segunda herramienta no puede observar ese tráfico.

Eso es cierto para dos procesos intentando consumir el mismo socket en ciertas condiciones, pero tcpdump trabaja a otro nivel mediante mecanismos de captura de paquetes.

Por tanto:

text
NIC
 |
 +------> kernel network stack ------> UDP socket ------> application
 |
 +------> packet capture -----------> tcpdump

La captura puede realizarse de manera pasiva sin convertirse en el consumidor del socket de aplicación.

Esta distinción permitió plantear capturas directamente sobre el tráfico de entrada antes de modificar la topología.

Uso de tcpdump

Un ejemplo de captura trabajado fue conceptualmente:

bash
sudo tcpdump \
  -i ens192 \
  -nn \
  -s 0 \
  -B 32768 \
  'udp dst port 60001' \
  -w entrada_60001.pcap

Cada parámetro tiene una razón:

  • -i ens192: interfaz concreta;
  • -nn: no resolver nombres;
  • -s 0: capturar el paquete completo;
  • -B 32768: aumentar el buffer de captura;
  • filtro BPF: reducir tráfico irrelevante;
  • -w: guardar PCAP para análisis posterior.
También se consideró:
bash
-i any

cuando interesaba observar el puerto con independencia de la interfaz.

Decisión: aumentar el buffer de captura

Cuando hay mucho tráfico, tcpdump puede perder paquetes porque el proceso no vacía suficientemente rápido el buffer que recibe del kernel.

El parámetro -B permite solicitar un buffer de captura mayor.

Esta decisión es importante porque una captura destinada a demostrar pérdidas no puede ser fiable si la propia herramienta está descartando paquetes.

La validación debe incluir las estadísticas finales de tcpdump, especialmente los contadores de paquetes capturados y descartados.

Mantener la captura tras cerrar sesión

Una captura larga no debe depender de que la terminal permanezca conectada.

El patrón utilizado puede basarse en:

bash
nohup sudo tcpdump ... > tcpdump.log 2>&1 &

o, en entornos más administrables:

  • tmux;
  • screen;
  • una unidad systemd.
La decisión depende de si se trata de:
  • una prueba puntual;
  • una herramienta repetible;
  • un servicio operativo.
Para un entorno estable, systemd suele ser preferible porque proporciona estado, logs y política de reinicio.

Rotación de PCAP

Guardar un único fichero durante horas puede generar:

  • archivos muy grandes;
  • dificultad para copiar;
  • riesgo de perder toda la captura si hay corrupción;
  • análisis pesado.
tcpdump permite rotación por tamaño o por tiempo.

Conceptualmente:

bash
tcpdump ... -C 500 -W 20 -w captura.pcap

o:

bash
tcpdump ... -G 300 -w 'captura_%Y%m%d_%H%M%S.pcap'

Pregunta técnica importante

¿Se pierden paquetes entre una rotación y la siguiente?

El diseño de la propia rotación de tcpdump evita detener y arrancar externamente el proceso para cada archivo, por lo que es preferible a scripts que maten y relancen capturas.

La principal preocupación sigue siendo:

  • rendimiento de disco;
  • buffer;
  • carga CPU;
  • tasa de entrada;
  • dropped packets reportados.

Duplicación de UDP

Además de captura pasiva, se trabajó con un servicio capaz de recibir tráfico en un puerto y reenviarlo a dos puertos de salida.

Arquitectura:

mermaid
flowchart LR
    A[Fuente CAT062] -->|UDP 60001| B[Duplicador]
    B -->|UDP 60003| C[Capturador / analizador]
    B -->|UDP 60004| D[Aplicacion / segundo consumidor]

La duplicación era útil cuando se necesitaba entregar copias independientes del mismo datagrama a procesos distintos.

Decisión: separar duplicación y captura

El script inicialmente ejecutaba ambas funciones de forma acoplada.

Después surgió la necesidad operativa de disponer de tres modos:

text
1. duplicación + captura
2. solo duplicación
3. solo captura

Esto llevó a introducir flags equivalentes a:

text
--dup-only
--capture-only
modo por defecto: ambos

Por qué esta decisión es buena arquitectura

Duplicar paquetes y analizarlos son responsabilidades distintas.

Acoplarlas provoca problemas:

  • no se puede mantener el forwarding al detener captura;
  • no se puede depurar cada componente aisladamente;
  • una incidencia del capturador puede afectar al duplicador;
  • se generan ficheros aunque no se deseen.
La separación de modos aplica el principio de separación de responsabilidades incluso dentro de una herramienta shell.

Control de ruido no CAT062

El capturador Python diferenciaba:

  • tráfico CAT062;
  • tráfico no reconocido o ruido.
Existían opciones para almacenar el contenido hexadecimal del ruido.

Se detectó que una opción estaba hardcodeada:

text
--save-non-cat62-hex

aunque desde el shell se intentaba desactivar.

El problema no estaba necesariamente en Python sino en la construcción final del comando.

Decisión

No dejar flags funcionales críticos hardcodeados en la línea de arranque.

El shell debe construir los argumentos en función del modo solicitado:

bash
ARGS=(...)
if save_noise; then
    ARGS+=(--save-non-cat62-hex ruido_hex)
else
    ARGS+=(--no-save-non-cat62-hex)
fi

Lo que aprendí

Cuando una CLI admite opciones mutuamente excluyentes, la capa que la invoca debe mantener una única fuente de verdad.

Cómo verificar que existe duplicación

No basta con saber que el proceso está ejecutándose.

La verificación se puede realizar en varios niveles:

text
Nivel 1: proceso
Nivel 2: socket
Nivel 3: paquetes enviados
Nivel 4: paquetes recibidos por destinos
Nivel 5: contenido de payload

Herramientas:

bash
ps
ss
lsof
tcpdump
tshark

Ejemplo conceptual:

bash
sudo tcpdump -ni any 'udp port 60003 or udp port 60004'

Si el duplicador funciona correctamente se deberían observar copias saliendo hacia ambos destinos.

Diagnóstico de pérdidas

El análisis correcto requiere comparar varios puntos.

mermaid
flowchart LR
    A[Proveedor] --> B[Entrada servidor]
    B --> C[Duplicador]
    C --> D[Capturador]
    C --> E[Aplicacion]

Si el proveedor afirma haber enviado N datagramas pero la aplicación procesa menos, hay que determinar dónde se produce la diferencia.

Una estrategia sólida:

1. obtener contadores del proveedor;
2. capturar en interfaz del servidor;
3. revisar drops de captura;
4. revisar contadores de interfaz;
5. revisar buffers UDP;
6. revisar errores del socket;
7. revisar logs del proceso;
8. comparar secuencias o timestamps ASTERIX;
9. comprobar carga de CPU/disco;
10. comparar con la salida del duplicador.

La pregunta no es únicamente "¿faltan paquetes?" sino:

¿En qué frontera del sistema dejan de ser observables?