TLSStress.Art — Para que serve¶
Leia no seu idioma: English · Português · Español
Scope status (post-Scope-Freeze 2026-05-10) — See ARCHITECTURE.md for the canonical 37 MÓDULOs + 7 Test Kinds + DOM/CPOS/PIE-PA safety architecture. ADRs 0014, 0019-0025 cover post-Freeze additions. Web Agent Cluster for NGFW TLS Inspection performance test — uma bancada de testes open-source para medir a capacidade real de inspeção TLS de Firewalls de Próxima Geração (NGFWs) sob carga HTTP/2 e HTTP/3.
Autoria: André Luiz Gallon · Licença: PolyForm Noncommercial 1.0.0 + Appendix A · Audiência: funcionários Cisco e parceiros certificados
1. Por que este software existe¶
Quando uma empresa precisa testar a capacidade de inspeção TLS de um firewall corporativo, há dois extremos de mercado:
| Categoria | Exemplos | Limitação |
|---|---|---|
| Ferramentas free | TRex, iPerf3, wrk, Locust | Não geram tráfego TLS realista em escala — pacotes brutos ou HTTP simples, sem JavaScript, sem handshake TLS completo, sem HTTP/3 |
| Appliances comerciais | Spirent CyberFlood, Ixia BreakingPoint, IXIA IxLoad | US$ 50 mil a US$ 500 mil por chassi; hardware proprietário; difíceis de automatizar em CI/CD |
| TLSStress.Art | Este projeto (open-source, PolyForm Noncommercial) | Roda em commodity hardware (Ubuntu + k3s); navegador real (browser engine) + carga sintética (k6); HTTP/2 e HTTP/3 nativos; sem custo de licença para a audiência elegível |
O TLSStress.Art preenche esse gap: oferece testes de inspeção TLS com realismo de produção — navegadores reais, JavaScript, cookies, certificados válidos — sem custo de licença e com automação total via Kubernetes e GitHub Actions.
A pergunta que o produto responde: quantas conexões TLS simultâneas o firewall suporta antes de degradar performance — e qual o impacto comparado entre HTTP/2 e HTTP/3?
2. Como funciona — visão de 30 segundos¶
┌─────────────────────────┐
│ Robôs de carga │ browser engine (browser real) + k6 (HTTP)
│ até 300 PW + 1000 synthetic-load engine │ geram tráfego TLS contra as personas
└──────────┬──────────────┘
│ Leg 1: HTTPS encriptado (robôs confiam no cert do firewall)
▼
┌─────────────────────────┐
│ FIREWALL (DUT) │ Aparelho sob teste — descriptografa,
│ — sob teste e medido │ inspeciona, recriptografa cada pacote
└──────────┬──────────────┘
│ Leg 2: HTTPS re-encriptado (firewall fala com persona)
▼
┌─────────────────────────┐
│ 30 personas Caddy │ 20 Sintéticas (sempre ativas) +
│ 20 Sintéticas + 10 │ 10 slots Clonados (operador escolhe sites
│ slots Clonados │ públicos para clonar)
└─────────────────────────┘
┌─── Telemetria coletada em paralelo (4 pilares) ────┐
▼ ▼
SNMP exporter Promtail/Loki DUT API REST OpenTelemetry → Tempo
(CPU/mem/IF do (eventos do Nexus, (config + state (distributed tracing
Nexus + DUT) NGFW, UCS) do FTD/Nexus/ opt-in nos agentes)
UCS/Fortinet)
Leg 1 — robôs abrem conexões HTTPS contra os endereços das personas. O firewall intercepta e apresenta seu próprio certificado (operador configura agentes para confiar no ngfw-ca).
Leg 2 — firewall abre uma segunda conexão HTTPS contra a persona de destino. Certificado é emitido pelo cert-manager (CA persona-ca).
4 pilares de telemetria coletam evidência simultaneamente — métricas (Prometheus + SNMP), eventos (syslog correlation via Loki), estado do dispositivo (DUT API REST), e traces (Tempo) — para responder não só "qual foi o p99" mas também "o que aconteceu no DUT quando o p99 subiu".
3. As 30 personas¶
A frota de personas é dividida em dois grupos:
20 Sintéticas (sempre ativas)¶
Definidas em personas.yaml, geradas a partir de templates Caddy. Cada persona roda em namespace Kubernetes dedicado, com certificado TLS, IP fixo, VLAN exclusiva (101–120) e entrada DNS dedicada.
Distribuídas em 4 arquétipos:
| Arquétipo | Exemplos | Como o tráfego é gerado |
|---|---|---|
| skin | CDN, blog, portal, news, gov, edu, gallery, stream, download, docs | HTML/CSS/JS sintético; assets estáticos de alta vazão |
| mock | api-rest, api-graphql, chat, webhook, telemetry, ads | JSON/XML configurável via YAML; simula microsserviços |
| har-replay | har-saas, har-social, har-webmail, har-media | Reproduz gravações HAR (HTTP Archive) de sessões reais |
| real-app | shop (Saleor, e-commerce completo) | Aplicação real com banco de dados, estado, JavaScript dinâmico |
10 Slots Clonados (preenchidos pelo operador)¶
VLANs 200–209. Operador escolhe um site público (ex.: globo.com, cnn.com), o Cloner faz crawl + snapshot do conteúdo estático, e a réplica passa a servir localmente como uma persona "real" com domínio *.persona.internal.
O Cloner usa três interfaces de rede distintas: OOBI (gerência), VLAN 40 (DHCP do ISP do cliente, para baixar conteúdo público da Internet) e VLAN macvlan no cluster (para servir o conteúdo clonado às demais personas/agentes).
4. Os 4 pilares de telemetria¶
O produto não mede só latência. Para responder por que uma métrica mudou — pré-requisito para um teste de NGFW ser válido — coletamos evidência de quatro fontes simultaneamente:
| Pilar | Fonte | O que captura | Endpoint |
|---|---|---|---|
| 1. Métricas (SNMP + Caddy + agentes) | SNMP exporter, Caddy /metrics, browser-engine/synthetic-load |
CPU, memória e contadores de interface do switch e do firewall; req/s, bytes, conexões ativas, QUIC vs TCP nas personas; latência, throughput, taxa de erro, handshake TLS nos agentes | Prometheus → Grafana |
| 2. Eventos (Syslog correlation) | Promtail (NodePort 30514) → Loki | Eventos de Nexus 9000, NGFW DUT, UCS hosts. Política OOBI-only (NEVER no data plane). Ingestão validada por dois NetworkPolicy no nível do cluster |
Loki → Grafana Explore + dashboard "Syslog Correlation" |
| 3. Estado do DUT (REST API) | Polling worker no Dashboard pod | Para cada DUT registrado: versão, NTP config, política de inspeção SSL/TLS, estado HA, vizinhos LLDP/CDP, inventário de hardware. Snapshots assinados com SHA-256 (cadeia forense) | DUT API REST adapters (FTD, Nexus, UCS, Fortinet) → Postgres dut_api_snapshots |
| 4. Traces (OpenTelemetry → Tempo) | SDK opt-in em browser-engine + synthetic-load | Distributed tracing por cycle de teste, com spans de cada handshake TLS. Cobre o caminho fim-a-fim: agent → NGFW → persona | Tempo → Grafana → Dashboard |
A combinação dos quatro permite respostas como: "latência p99 subiu às 14:23 → conferido em syslog: NGFW logou alta utilização de CPU às 14:22 → conferido em DUT API: política de decryption alterada por outro operador 4 minutos antes → trace mostra handshake gastando 380ms vs 95ms baseline".
5. DUT API — integração multi-vendor¶
Adapter pattern com 4 vendors shipped (Palo Alto no roadmap):
| Vendor | Adapter | Auth | Status |
|---|---|---|---|
| Cisco FTD (FDM-managed) | cisco-ftd.ts |
OAuth2 → Bearer | ✅ Shipped |
| Cisco Nexus 9000 | cisco-nexus.ts |
NX-API cookie (APIC-cookie) | ✅ Shipped |
| Cisco UCS C-Series CIMC | cisco-ucs-cimc.ts |
Basic Auth (Redfish) | ✅ Shipped |
| Fortinet FortiGate | fortinet-fortigate.ts |
API key Bearer (FortiOS REST v2) | ✅ Shipped |
| Palo Alto (PAN-OS) | — | API key (XML API) | 📋 Roadmap |
Workflow do operador:
1. UI em /admin/dut-api registra um device (URL, credenciais — encriptadas com AES-256-GCM)
2. Polling worker no Dashboard coleta snapshots a cada N minutos (configurável; default 5min)
3. Cada snapshot vira uma linha em dut_api_snapshots com payload JSON + SHA-256 do canonical form
4. Snapshots aparecem em dashboards Grafana ("DUT Live State") e (futuramente) nos Annexes B/C/D do Test Run Report
Catálogo de 45 features mapeadas por vendor — qual adapter expõe NTP config, qual expõe HA state, etc. — em docs/API_FEATURE_CATALOG.{md,pt-BR,es}.md.
6. Test Plans + Test Run Reports¶
Test Plan engine — 15 plans pré-configurados (catálogo em docs/TEST_PLANS.{md,pt-BR,es}.md):
- Identificadores estáveis (string ID, não hash) para comparações cross-engagement
- Validados por schema Zod, sincronizados para Postgres no boot
- Cada plan declara o estado esperado do NGFW (ex.: ngfw_state_required: decryption-on)
- Planos cobrem: baseline H2/H3, max-CPS handshake, sustained throughput, decryption-on vs decryption-off, falhas de cert, mixed protocol, etc.
Test Run Report — Phase 1 shipped (#185):
- HTML print-styled (/runs/{id}/report) com capa, página de licença em 3 idiomas, executive summary, plan config, anexos placeholder
- Footer de licença pinned em todas as páginas
- SHA-256 hashes do report inteiro + plan-snapshot + per-anexo (cadeia forense)
- API JSON paralela: /api/test-runs/{id}/report.json
Roadmap das phases pendentes: - Phase 2 — Puppeteer server-side render → PDF real (hoje é HTML print) - Phase 3 — Annexes B/C/D wired (snapshots Nexus/NGFW/UCS embebidos no report) - Phase 4 — Cosign signing + entrada Rekor/Sigstore (transparency log público) - Phase 5 — N-run comparison (run A vs run B), trend rollups (semanal/mensal), replay snapshot
7. Pre-flight, time-sync, validade do test bed¶
Pre-flight checks (engine + 5 catalog) — antes de cada run, valida estado do lab:
- ngfw-deploy-clean — sem deploy pendente no DUT
- ngfw-decrypt-state-matches-plan — estado de decryption alinhado com o plan
- ntp-source-configured — todos os componentes têm NTP definido
- ngfw-ha-state-sane — par HA em estado consistente
- snapshot-fresh — última coleta DUT API < threshold
Time-sync layer — relógio do lab inteiro sincronizado:
- Script scripts/check-time-sync.sh mede skew entre componentes; alertas Prometheus disparam acima do threshold
- Cloner pode atuar como NTP relay (stratum-2) quando a Internet do data center é restrita
- Fallback browser-clock documentado e implementado: admin UI em /admin/time-sync envia o tempo do laptop do operador via POST /api/time-sync/set-from-browser (com acknowledgement: NOT_FORENSIC obrigatório), retorna o kubectl chronyc settime para o operador aplicar manualmente. Audit log marca forensic_grade: false automaticamente.
Test-bed validity proof — observabilidade evolution em 4 phases shipped: 1. Deployment-aware thresholds + fleet readiness (PR-1+2, #173) — alertas que conhecem qual modo de deploy (single/dual/tri/multi) está ativo 2. Topology-aware causal correlation (PR-3, #177) — correlaciona métricas pelos nodes/personas/agents que conversam entre si 3. SLO + multi-window multi-burn-rate alerts + anomaly detection + Tempo (PR-4, #179) 4. Always-visible license banner no Dashboard, Grafana, Prometheus (#178)
8. Compliance, forensic, proteção de IP¶
Brand registrada e tagline oficial: - Nome: TLSStress.Art (™ — registro em curso) - Tagline: Web Agent Cluster for NGFW TLS Inspection performance test
Licença PolyForm Noncommercial 1.0.0 + Appendix A — uso noncommercial apenas, e Appendix A restringe a audiência elegível a funcionários Cisco (e suas subsidiárias) e engenheiros pré/pós-vendas de parceiros Cisco certificados. Detalhes em LICENSE e USAGE_POLICY.pt-BR.md.
License Acceptance Modal — primeiro login no Dashboard intercepta o operador com modal exigindo aceite da licença + USAGE_POLICY. Aceite gera linha em audit_log (visível em /admin/audit/license-acceptances). Política de privacidade em PRIVACY_POLICY.pt-BR.md, audit policy em AUDIT_LOG.md.
Forensic infrastructure (IP_PROTECTION.pt-BR.md):
- FINGERPRINT_REGISTRY em branch privada (private/forensic) — fingerprints intencionais no código que provam autoria se um clone aparecer
- Asset hashes manifest assinado em cada release
- Tamper-check workflow dispara em PRs e na main, comparando hashes contra o manifest
- Roadmap: migrar FINGERPRINT_REGISTRY para repo separado para evitar vazamento via Access Broker
TLS Decrypt Mode Verification (#180) — probe que cruza o issuer-cert observado na conexão com a política de decryption esperada do plan. Garante que a medição reflete o modo real de operação do NGFW (sem esperar log do dispositivo).
9. Onboarding do operador¶
Cinco docs encadeados para o operador chegar do zero ao primeiro run:
Access Request → Clone → Install (Runbook)
[ACCESS_REQUEST] [CLONE_FOR_INSTALL] [RUNBOOK_FIRST_INSTALL]
│
└── alternativa: [AIRGAP_INSTALL]
Setup do mantenedor (uma vez): [PRIVATE_REPO_SETUP]
- Access Broker (
ACCESS_REQUEST.pt-BR.md) — issue template + GitHub Action/approve/deny. Auto-list de domains Cisco-controlled (cisco.com, meraki.com, duo.com, webex.com, splunk.com, thousandeyes.com); fluxo manual com partner ID para parceiros certificados. - Clone (
CLONE_FOR_INSTALL.pt-BR.md) — 4 opções autenticadas degit clone(HTTPS+PAT, SSH key, GitHub CLI, tarball assinado). - Runbook First Install (
RUNBOOK_FIRST_INSTALL.pt-BR.md) — protocolo de 4 passos: lab→DUT→smoke→measure. Tempo orçado: ~2h. - Air-gapped install (
AIRGAP_INSTALL.pt-BR.md) — alternativa para data center sem Internet (regulado / classificado). - Private repo setup (
PRIVATE_REPO_SETUP.pt-BR.md) — setup do mantenedor (uma vez, pelo dono do repo).
10. Tuning aplicado em todas as camadas¶
Para que os resultados reflitam o limite real do firewall — e não limitações do test bed — cada componente da plataforma foi ajustado com parâmetros específicos. Scripts automatizados aplicam o tuning de forma reproduzível.
| Componente | Parâmetros | Impacto |
|---|---|---|
Host Linux Ubuntu (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 evitam descarte; BBR melhora throughput em redes com variação de RTT |
| Webserver Caddy (por pod de persona) | GOMAXPROCS via resourceFieldRef; GOMEMLIMIT=460MiB; GOGC=200; QoS Guaranteed (CPU 2/2, Mem 512Mi/512Mi) |
Go usa todos os cores disponíveis sem over-commit; GC menos frequente reduz latência de cauda |
| Switch Nexus 9000 (script automatizado) | EEE off, flow control off, MTU 9216 (jumbo frames), QoS DSCP AF41, ECMP hash com porta UDP, ARP timeout 300s | Jumbo frames aumentam throughput; EEE desativado elimina latência adicional; ECMP com porta UDP distribui QUIC corretamente |
| Agentes browser-engine + synthetic-load | NODE_EXTRA_CA_CERTS / SSL_CERT_FILE apontando para persona-ca; GOMAXPROCS/GOMEMLIMIT no k6; resource right-sized; topology spread; CYCLE_CONCURRENCY=3 |
Confiança nos certs sem warnings; UDP 443 liberado; máxima ocupação dos cores sem conflito |
Guias detalhados: docs/PERFORMANCE_TUNING_HOST.md, docs/NEXUS9K_TUNING.md, e os artefatos k8s/85-node-tuning.yaml + scripts/nexus/0[1-3]-*.nxos.
O setup completo é projetado para ser baixo atrito: ./scripts/k8s-dut-up.sh up sobe toda a plataforma em fases automáticas.
11. Arquitetura de rede¶
Servidor Ubuntu (k3s)
├── eth0 → rede OOBI (mgmt, métricas, dashboard, controle, Service VIPs)
└── eth1 → trunk Nexus 9000 (VLANs de dados)
├── VLAN 20 (172.16.0.0/16) → Agentes browser-engine (dut-pw)
├── VLAN 30 (172.17.0.0/16) → Agentes k6 (dut-k6)
├── VLAN 40 (DHCP do ISP) → Cloner ISP egress (saída p/ Internet, fora do esquema interno)
├── VLAN 99 (192.168.90.0/24) → OOBI mgmt (dut-mgmt, SNMP, syslog, NTP)
│
│ 20 VLANs Sintéticas (101–120) — uma por persona Caddy:
├── 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 VLANs Clonadas (200–209) — slots dinâmicos preenchidos pelo Cloner:
└── VLAN 200–209 (10.2.x.0/27) → cloned-1 .. cloned-10
│
FIREWALL (DUT) ←── inspeciona TLS em todas as VLANs
│
4 pilares de telemetria coletam evidência em paralelo
(SNMP + Syslog + DUT API + Tempo)
Por que separação rigorosa OOBI ↔ data plane?
- O data plane (VLANs 20, 30, 40, 101–120, 200–209) carrega tráfego de teste. Qualquer mgmt traffic aqui contamina as métricas por ciclo.
- A OOBI (VLAN 99 / 192.168.90.0/24) é exclusiva para mgmt — Prometheus scrape, SNMP, syslog, NTP, kubectl, dashboard. Política syslog-oobi-only + syslog-deny-data-plane é enforced no nível do cluster por dois NetworkPolicy complementares.
- Service VIPs em OOBI (.50–.69) — Promtail :514, NTP relay :123, Dashboard :3000, Prometheus :9090, Grafana :3001, Loki :3100, SNMP-Exporter, Alertmanager, Tempo. Devices DUT apontam para IPs fixos, não para NodePort em UCS específico.
12. 4 modos de deploy¶
| Modo | Quando usar | Guia |
|---|---|---|
| Single-node (1 UCS) | Avaliação inicial; hardware limitado | UBUNTU_K3S_SINGLENODE |
| Dual-node (2 UCS) | UCS-1 = agentes; UCS-2 = personas + serviços + observabilidade | UBUNTU_K3S_DUALNODE |
| Tri-node (3 UCS) | UCS-1 = só browser engine; UCS-2 = só k6; UCS-3 = personas + serviços + obs | UBUNTU_K3S_TRINODE |
| Multi-nó (4 UCS dedicados) | UCS-1 = 30 personas · UCS-2 = browser engine · UCS-3 = k6 · UCS-4 = Dashboard/Postgres/Grafana/Cloner. Throughput máximo, sem contenção | UBUNTU_K3S_MULTINODE |
Os modos dual/tri/multi usam overlays Kustomize em overlays/{dual-node,tri-node,multi-node}/ que aplicam nodeSelector a cada Deployment/StatefulSet. Permitem escalar browser engine até 300 instâncias e k6 até 1.000 instâncias sem compartilhar CPU/memória com os webservers das personas.
13. Dashboard de operação¶
Cockpit web (Next.js) em /. Páginas principais:
- Visão geral — status das 30 personas em tempo real (rodando, pausada, erro)
- Personas individuais — iniciar/pausar/desprovisionar; configurar rotas das personas mock (YAML inline via API)
/admin/dut-api— registrar DUT devices, testar conectividade, disparar snapshot, rodar pre-flight/admin/time-sync— admin UI para o fluxo browser-clock fallback (com aceite NOT_FORENSIC obrigatório)/admin/audit/license-acceptances— viewer das aceitações de licença (audit forense)- Test Plans — escolher plan, disparar run, acompanhar progresso
- Test Runs — histórico, link para HTML report (Phase 1)
- Métricas Grafana — embedded por persona e por protocolo (HTTP/2 vs HTTP/3 vs HTTP/3-fallback-TCP)
Resumo em uma frase¶
TLSStress.Art é uma bancada de testes open-source (PolyForm Noncommercial, audiência Cisco) que preenche o gap entre ferramentas free sem escala (TRex, iPerf) e appliances comerciais de até US$ 500 mil (Spirent, Ixia) — simulando até 30 sites realistas (20 Sintéticas + 10 slots Clonados pelo operador) com browser-engine/synthetic-load contra o NGFW sob teste, integrando 4 pilares de telemetria (SNMP do hardware + syslog correlation + DUT API REST multi-vendor para FTD/Nexus/UCS/Fortinet + OpenTelemetry tracing), com 15 test plans pré-configurados, Test Run Reports HTML/PDF assinados forensicamente, License Acceptance Modal + audit log + tamper-check, e tudo otimizado do host Linux ao switch Nexus para que o gargalo medido seja sempre o NGFW — não o test bed.