Skip to content

TLSStress.Art — Para qué sirve

Lea en su idioma: English · Português · Español

Estado del scope (post-Scope-Freeze 2026-05-10) — Véase ARCHITECTURE.md para la arquitectura canónica de 37 MÓDULOs + 7 Test Kinds + DOM/CPOS/PIE-PA de seguridad. ADRs 0014, 0019-0025 cubren adiciones post-Freeze. Web Agent Cluster for NGFW TLS Inspection performance test — banco de pruebas open-source para medir la capacidad real de inspección TLS de Next-Generation Firewalls (NGFWs) bajo carga HTTP/2 y HTTP/3.

Autor: André Luiz Gallon · Licencia: PolyForm Noncommercial 1.0.0 + Appendix A · Público objetivo: empleados de Cisco y socios certificados


1. Por qué existe este software

Cuando una empresa necesita probar la capacidad de inspección TLS de un firewall corporativo, el mercado tiene dos extremos:

Categoría Ejemplos Limitación
Herramientas gratuitas TRex, iPerf3, wrk, Locust No generan tráfico TLS realista a escala — paquetes crudos o HTTP simple, sin JavaScript, sin handshake TLS completo, sin HTTP/3
Appliances comerciales Spirent CyberFlood, Ixia BreakingPoint, IXIA IxLoad US$ 50K–500K por chasis; hardware propietario; difícil de automatizar en CI/CD
TLSStress.Art Este proyecto (open-source, PolyForm Noncommercial) Corre en hardware commodity (Ubuntu + k3s); navegador real (browser engine) + carga sintética (k6); HTTP/2 y HTTP/3 nativos; sin costo de licencia para el público elegible

TLSStress.Art llena esa brecha: provee pruebas de inspección TLS con realismo de nivel de producción — navegadores reales, JavaScript, cookies, certificados válidos — sin costo de licencia y con automatización completa vía Kubernetes y GitHub Actions.

La pregunta que responde el producto: ¿cuántas conexiones TLS simultáneas puede manejar el firewall antes de que el rendimiento se degrade — y cuál es el impacto comparativo entre HTTP/2 y HTTP/3?


2. Cómo funciona — vista de 30 segundos

┌─────────────────────────┐
│ Load robots             │  browser engine (real browser) + k6 (HTTP)
│ up to 300 PW + 1000 synthetic-load engine  │  generate TLS traffic against the personas
└──────────┬──────────────┘
           │ Leg 1: encrypted HTTPS (robots trust the firewall cert)
           ▼
┌─────────────────────────┐
│ FIREWALL (DUT)          │  Appliance under test — decrypts, inspects,
│ — under test, measured  │  re-encrypts every packet
└──────────┬──────────────┘
           │ Leg 2: re-encrypted HTTPS (firewall talks to persona)
           ▼
┌─────────────────────────┐
│ 30 Caddy personas       │  20 Synthetic (always-on) + 10 Cloned slots
│ 20 Synthetic + 10       │  (operator picks public sites to clone)
│ Cloned slots            │
└─────────────────────────┘

         ┌─── Telemetry collected in parallel (4 pillars) ─────┐
         ▼                                                     ▼
   SNMP exporter        Promtail/Loki          DUT API REST       OpenTelemetry → Tempo
   (CPU/mem/IF of       (events from Nexus,    (config + state    (distributed tracing
    Nexus + DUT)         NGFW, UCS hosts)       of FTD/Nexus/      opt-in in agents)
                                                UCS/Fortinet)

Leg 1 — los robots abren conexiones HTTPS hacia las direcciones de las personas. El firewall intercepta y presenta su propio certificado (el operador configura los agentes para confiar en ngfw-ca).

Leg 2 — el firewall abre una segunda conexión HTTPS hacia la persona de destino. El certificado lo emite cert-manager (CA persona-ca).

4 pilares de telemetría recopilan evidencia simultáneamente — métricas (Prometheus + SNMP), eventos (correlación de syslog vía Loki), estado del dispositivo (DUT API REST) y traces (Tempo) — respondiendo no solo "cuál fue el p99" sino también "qué ocurrió en el DUT cuando el p99 se disparó".


3. Las 30 personas

La flota de personas se divide en dos grupos:

20 Synthetic (always-on)

Definidas en personas.yaml, generadas a partir de templates Caddy. Cada persona corre en un namespace Kubernetes dedicado, con certificado TLS, IP fijo, VLAN exclusiva (101–120) y entrada DNS dedicada.

Distribuidas en 4 arquetipos:

Arquetipo Ejemplos Cómo se genera el tráfico
skin CDN, blog, portal, news, gov, edu, gallery, stream, download, docs HTML/CSS/JS sintético; assets estáticos de alto throughput
mock api-rest, api-graphql, chat, webhook, telemetry, ads JSON/XML configurable por YAML; simula microservicios
har-replay har-saas, har-social, har-webmail, har-media Replay de grabaciones HAR (HTTP Archive) de sesiones reales
real-app shop (Saleor, e-commerce completo) Aplicación real con base de datos, estado, JavaScript dinámico

10 Cloned slots (poblados por el operador)

VLANs 200–209. El operador elige un sitio público (ej.: globo.com, cnn.com), el Cloner hace crawl + snapshot del contenido estático y la réplica pasa a servir localmente como una persona "real" en *.persona.internal.

El Cloner usa tres interfaces de red distintas: OOBI (mgmt), VLAN 40 (DHCP del ISP del cliente, para descargar contenido de la Internet pública) y una VLAN macvlan dentro del cluster (para servir contenido clonado a las demás personas/agentes).


4. Los 4 pilares de telemetría

El producto no mide solo latencia. Para responder por qué una métrica cambió — prerrequisito para que una prueba NGFW sea válida — se recopila evidencia de cuatro fuentes simultáneamente:

Pilar Fuente Lo que captura Endpoint
1. Métricas (SNMP + Caddy + agentes) SNMP exporter, Caddy /metrics, browser-engine/synthetic-load CPU, memoria y contadores de interfaz del switch y del firewall; req/s, bytes, conexiones activas, QUIC vs TCP en personas; latencia, throughput, tasa de error, handshake TLS en agentes Prometheus → Grafana
2. Eventos (correlación Syslog) Promtail (NodePort 30514) → Loki Eventos del Nexus 9000, del NGFW DUT, de los hosts UCS. Política OOBI-only (NUNCA en el data plane). La ingesta es impuesta por dos recursos NetworkPolicy a nivel de cluster Loki → Grafana Explore + dashboard "Syslog Correlation"
3. Estado del DUT (REST API) Worker de polling en el pod Dashboard Para cada DUT registrado: versión, config NTP, política de inspección SSL/TLS, estado HA, vecinos LLDP/CDP, inventario de hardware. Snapshots firmados con SHA-256 (cadena de custodia forense) DUT API REST adapters (FTD, Nexus, UCS, Fortinet) → Postgres dut_api_snapshots
4. Traces (OpenTelemetry → Tempo) SDK opt-in en browser-engine + synthetic-load Distributed tracing por ciclo de prueba, con spans para cada handshake TLS. Cubre el camino extremo-a-extremo: agente → NGFW → persona Tempo → Grafana → Dashboard

La combinación de los cuatro permite respuestas como: "latencia p99 disparada a las 14:23 → confirmado en syslog: NGFW registró CPU alta a las 14:22 → confirmado en DUT API: política de decryption fue alterada por otro operador 4 minutos antes → trace muestra handshake tomando 380ms vs baseline de 95ms".


5. DUT API — integración multi-vendor

Patrón adapter con 4 vendors entregados (Palo Alto en el roadmap):

Vendor Adapter Auth Estado
Cisco FTD (FDM-managed) cisco-ftd.ts OAuth2 → Bearer ✅ Entregado
Cisco Nexus 9000 cisco-nexus.ts NX-API cookie (APIC-cookie) ✅ Entregado
Cisco UCS C-Series CIMC cisco-ucs-cimc.ts Basic Auth (Redfish) ✅ Entregado
Fortinet FortiGate fortinet-fortigate.ts API key Bearer (FortiOS REST v2) ✅ Entregado
Palo Alto (PAN-OS) API key (XML API) 📋 Roadmap

Flujo del operador: 1. UI en /admin/dut-api registra un dispositivo (URL, credenciales — cifradas con AES-256-GCM) 2. Worker de polling en el Dashboard recolecta snapshots cada N minutos (configurable; por defecto 5min) 3. Cada snapshot se vuelve una fila en dut_api_snapshots con payload JSON + SHA-256 de la forma canónica 4. Los snapshots aparecen en dashboards Grafana ("DUT Live State") y (en el roadmap) en los Anexos B/C/D del Test Run Report

Catálogo de 45 features mapeado por vendor — qué adapter expone config NTP, qué expone estado HA, etc. — en docs/API_FEATURE_CATALOG.{md,pt-BR,es}.md.


6. Test Plans + Test Run Reports

Test Plan engine — 15 planes preconfigurados (catálogo en docs/TEST_PLANS.{md,pt-BR,es}.md): - Identificadores estables (string ID, no hash) para comparaciones entre engagements - Validados por schema Zod, sincronizados a Postgres al boot - Cada plan declara el estado NGFW esperado (ej.: ngfw_state_required: decryption-on) - Los planes cubren: baseline H2/H3, max-CPS handshake, throughput sostenido, decryption-on vs decryption-off, fallas de cert, protocolo mixto, etc.

Test Run Report — Fase 1 entregada (#185): - HTML print-styled (/runs/{id}/report) con portada, página de licencia en 3 idiomas, resumen ejecutivo, config del plan, anexos placeholder - Pie de licencia fijado en cada página - Hashes SHA-256 del informe completo + plan-snapshot + por-anexo (cadena forense) - API JSON paralela: /api/test-runs/{id}/report.json

Roadmap de las fases pendientes: - Fase 2 — render server-side con Puppeteer → PDF real (actualmente HTML print) - Fase 3 — Anexos B/C/D conectados (snapshots Nexus/NGFW/UCS embebidos en el informe) - Fase 4 — firma Cosign + entrada Rekor/Sigstore (log de transparencia público) - Fase 5 — comparación N-runs (run A vs run B), rollups de tendencia (semanal/mensual), replay de snapshot


7. Pre-flight, time-sync, validez del test bed

Pre-flight checks (engine + catálogo de 5) — antes de cada run, valida el estado del lab: - ngfw-deploy-clean — ningún deploy pendiente en el DUT - ngfw-decrypt-state-matches-plan — estado de decryption alineado con el plan - ntp-source-configured — todo componente tiene NTP definido - ngfw-ha-state-sane — par HA en estado consistente - snapshot-fresh — última recolección DUT API < threshold

Capa time-sync — reloj de todo el lab sincronizado: - El script scripts/check-time-sync.sh mide skew entre componentes; las alertas Prometheus disparan por encima del threshold - El Cloner puede actuar como NTP relay (stratum-2) cuando la Internet del data center es restringida - Browser-clock fallback documentado e implementado: la UI admin en /admin/time-sync envía la hora del laptop del operador vía POST /api/time-sync/set-from-browser (con acknowledgement: NOT_FORENSIC obligatorio), retorna el comando kubectl chronyc settime para que el operador lo aplique manualmente. El audit log marca forensic_grade: false automáticamente.

Prueba de validez del test-bed — evolución de observabilidad en 4 fases entregadas: 1. Thresholds deployment-aware + fleet readiness (PR-1+2, #173) — alertas que saben qué deploy mode (single/dual/tri/multi) está activo 2. Correlación causal topology-aware (PR-3, #177) — correlaciona métricas por los nodos/personas/agentes que de hecho se comunican entre sí 3. SLO + alertas multi-window multi-burn-rate + detección de anomalía + Tempo (PR-4, #179) 4. Banner de licencia siempre visible en Dashboard, Grafana, Prometheus (#178)


8. Compliance, forense, protección de IP

Marca registrada y tagline oficial: - Nombre: TLSStress.Art (™ — registro en curso) - Tagline: Web Agent Cluster for NGFW TLS Inspection performance test

Licencia: PolyForm Noncommercial 1.0.0 + Appendix A — uso solo no comercial, y el Appendix A restringe el público elegible a empleados de Cisco (y sus subsidiarias) y a ingenieros pre-/post-venta de socios certificados de Cisco. Detalles en LICENSE y USAGE_POLICY.md.

License Acceptance Modal — el primer login en el Dashboard intercepta al operador con un modal que requiere aceptación de la licencia + USAGE_POLICY. La aceptación escribe una fila en audit_log (visible en /admin/audit/license-acceptances). Política de privacidad en PRIVACY_POLICY.md, política de auditoría en AUDIT_LOG.md.

Infraestructura forense (IP_PROTECTION.md): - FINGERPRINT_REGISTRY en branch privado (private/forensic) — fingerprints intencionales en el código que prueban autoría si surge un clon - Asset hashes manifest firmado en cada release - Tamper-check workflow corre en PRs y en main, comparando hashes contra el manifest - Roadmap: migrar FINGERPRINT_REGISTRY a un repo separado para evitar fuga vía el Access Broker

TLS Decrypt Mode Verification (#180) — probe que cruza el issuer-cert observado en la conexión contra la política de decryption esperada del plan. Garantiza que la medición refleja el modo operativo real del NGFW (sin esperar a los logs del dispositivo).


9. Onboarding del operador

Cinco docs encadenados para llevar a un operador de cero al primer run:

Access Request   →   Clone   →   Install (Runbook)
[ACCESS_REQUEST]     [CLONE_FOR_INSTALL]   [RUNBOOK_FIRST_INSTALL]
                                              │
                                              └── alternate: [AIRGAP_INSTALL]

Maintainer-only setup (one-time): [PRIVATE_REPO_SETUP]
  • Access Broker (ACCESS_REQUEST.md) — template de issue + GitHub Action /approve /deny. Auto-list de dominios controlados por Cisco (cisco.com, meraki.com, duo.com, webex.com, splunk.com, thousandeyes.com); flujo manual con partner ID para socios certificados.
  • Clone (CLONE_FOR_INSTALL.md) — 4 opciones de git clone autenticado (HTTPS+PAT, SSH key, GitHub CLI, tarball firmado).
  • Runbook First Install (RUNBOOK_FIRST_INSTALL.md) — protocolo de 4 pasos: lab→DUT→smoke→measure. Time budget: ~2h.
  • Instalación airgap (AIRGAP_INSTALL.md) — alternativa para data centers sin Internet (regulado / clasificado).
  • Private repo setup (PRIVATE_REPO_SETUP.md) — setup maintainer-only (una vez, por el dueño del repo).

10. Tuning aplicado en cada capa

Para que los resultados reflejen el límite real del firewall — no limitaciones del test bed — cada componente de la plataforma fue tuneado con parámetros específicos. Scripts automatizados aplican el tuning de forma reproducible.

Componente Parámetros Impacto
Linux Ubuntu host (DaemonSet node-tuning) rmem_max/wmem_max = 64 MB; TCP BBR + FQ; tcp_max_syn_backlog=65535; vm.swappiness=5; CPU governor performance; THP madvise; nf_conntrack_max=2M; tcp_orphan_retries=2 Crítico para QUIC/HTTP3: buffers UDP grandes evitan drops; BBR mejora throughput en redes con variación de RTT
Caddy webserver (por pod persona) GOMAXPROCS vía resourceFieldRef; GOMEMLIMIT=460MiB; GOGC=200; QoS Guaranteed (CPU 2/2, Mem 512Mi/512Mi) Go usa todos los cores disponibles sin over-commit; GC menos frecuente reduce tail latency
Switch Nexus 9000 (script automatizado) EEE off, flow control off, MTU 9216 (jumbo frames), QoS DSCP AF41, hash ECMP con puerto UDP, ARP timeout 300s Jumbo frames aumentan throughput; EEE deshabilitado elimina latencia añadida; ECMP con puerto UDP distribuye QUIC correctamente
agentes browser-engine + synthetic-load NODE_EXTRA_CA_CERTS / SSL_CERT_FILE apuntando a persona-ca; GOMAXPROCS/GOMEMLIMIT en k6; resources right-sized; topology spread; CYCLE_CONCURRENCY=3 Confianza en los certs sin warnings; UDP 443 abierto; ocupación máxima de cores sin conflicto

Guías detalladas: docs/PERFORMANCE_TUNING_HOST.md, docs/NEXUS9K_TUNING.md, además de los artefactos k8s/85-node-tuning.yaml + scripts/nexus/0[1-3]-*.nxos.

La configuración completa fue diseñada para ser low-friction: ./scripts/k8s-dut-up.sh up levanta toda la plataforma en fases automáticas.


11. Arquitectura de red

Ubuntu Server (k3s)
├── eth0       →  OOBI network  (mgmt, metrics, dashboard, control, Service VIPs)
└── eth1       →  Nexus 9000 trunk  (data VLANs)
               ├── VLAN 20  (172.16.0.0/16)   →  browser-engine agents  (dut-pw)
               ├── VLAN 30  (172.17.0.0/16)   →  synthetic-load agents          (dut-k6)
               ├── VLAN 40  (DHCP from ISP)   →  Cloner ISP egress  (Internet uplink, outside our scheme)
               ├── VLAN 99  (192.168.90.0/24) →  OOBI mgmt          (dut-mgmt, SNMP, syslog, NTP)
               │
               │   20 Synthetic VLANs (101–120) — one per Caddy persona:
               ├── VLAN 101–120  (10.1.x.0/27)  →  shop, news, blog, docs, gallery, stream, download,
               │                                   edu, gov, cdn, api-rest, api-graphql, chat, webhook,
               │                                   telemetry, ads, har-saas, har-social, har-webmail, har-media
               │
               │   10 Cloned VLANs (200–209) — dynamic slots filled by the Cloner:
               └── VLAN 200–209  (10.2.x.0/27)  →  cloned-1 .. cloned-10
                               │
                        FIREWALL (DUT) ←── inspects TLS on all VLANs
                               │
                        4 telemetry pillars collect evidence in parallel
                        (SNMP + Syslog + DUT API + Tempo)

¿Por qué separación estricta entre OOBI ↔ data plane? - El data plane (VLANs 20, 30, 40, 101–120, 200–209) lleva el tráfico de prueba. Cualquier tráfico de mgmt aquí contamina las métricas por ciclo. - La OOBI (VLAN 99 / 192.168.90.0/24) es exclusiva para mgmt — Prometheus scrape, SNMP, syslog, NTP, kubectl, dashboard. Las políticas syslog-oobi-only + syslog-deny-data-plane se imponen a nivel de cluster por dos recursos NetworkPolicy complementarios. - Service VIPs en la OOBI (.50–.69) — Promtail :514, NTP relay :123, Dashboard :3000, Prometheus :9090, Grafana :3001, Loki :3100, SNMP-Exporter, Alertmanager, Tempo. Los dispositivos DUT apuntan a IPs fijos, no a NodePorts en un UCS específico.


12. 4 modos de deployment

Modo Cuándo usarlo Guía
Single-node (1 UCS) Evaluación inicial; hardware limitado UBUNTU_K3S_SINGLENODE
Dual-node (2 UCS) UCS-1 = agentes; UCS-2 = personas + servicios + observabilidad UBUNTU_K3S_DUALNODE
Tri-node (3 UCS) UCS-1 = solo browser engine; UCS-2 = solo k6; UCS-3 = personas + servicios + obs UBUNTU_K3S_TRINODE
Multi-node (4 UCS dedicados) UCS-1 = 30 personas · UCS-2 = browser engine · UCS-3 = k6 · UCS-4 = Dashboard/Postgres/Grafana/Cloner. Throughput máximo, sin contención UBUNTU_K3S_MULTINODE

Los modos dual/tri/multi usan overlays Kustomize bajo overlays/{dual-node,tri-node,multi-node}/ que aplican nodeSelector a cada Deployment/StatefulSet. Permiten escalar browser engine hasta 300 instancias y k6 hasta 1.000 instancias sin compartir CPU/memoria con los webservers de las personas.


13. Dashboard de operaciones

Cockpit web (Next.js) en /. Páginas principales:

  • Overview — estado de las 30 personas en tiempo real (running, paused, error)
  • Personas individuales — start/pause/deprovision; configurar rutas de respuesta de la mock-persona (YAML inline vía API)
  • /admin/dut-api — registrar dispositivos DUT, probar conectividad, disparar snapshot, ejecutar pre-flight
  • /admin/time-sync — UI admin para el flujo de browser-clock fallback (con acknowledgement NOT_FORENSIC obligatorio)
  • /admin/audit/license-acceptances — visor de las aceptaciones de licencia (auditoría forense)
  • Test Plans — elegir un plan, disparar un run, monitorear progreso
  • Test Runs — historial, enlace al HTML report (Fase 1)
  • Métricas Grafana — embebidas por persona y por protocolo (HTTP/2 vs HTTP/3 vs HTTP/3-fallback-TCP)

Resumen en una frase

TLSStress.Art es un banco de pruebas open-source (PolyForm Noncommercial, público Cisco) que llena la brecha entre herramientas gratuitas sin escala (TRex, iPerf) y appliances comerciales que cuestan hasta US$ 500K (Spirent, Ixia) — simulando hasta 30 sitios realistas (20 Synthetic + 10 slots Cloned por el operador) con browser-engine/synthetic-load contra el NGFW bajo prueba, integrando 4 pilares de telemetría (SNMP de hardware + correlación de syslog + DUT API REST multi-vendor para FTD/Nexus/UCS/Fortinet + tracing OpenTelemetry), con 15 planes de prueba preconfigurados, Test Run Reports HTML/PDF firmados forensicamente, License Acceptance Modal + audit log + tamper-check, y todo tuneado del host Linux al switch Nexus para que el cuello de botella medido sea siempre el NGFW — nunca el test bed.