Skip to content

NGFW Configuration Reference — TLSStress.Art DUT Mode

Who this is for: The network engineer responsible for configuring the firewall being tested (the Device Under Test — DUT). This document contains every VLAN, IP address, route, and TLS policy the NGFW must be configured with before the test-bed can generate traffic.

Author: André Luiz Gallon — agallon@Cisco.com | Version: v3.6.0

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.


Table of Contents

  1. How the Test-Bed Works
  2. Physical Connectivity
  3. Complete VLAN and IP Reference
  4. NGFW Interface Configuration
  5. Routing Table
  6. PKI — The Two CAs
  7. TLS Inspection Policy
  8. Vendor Configuration Examples
  9. Cisco FTD (FMC)
  10. Cisco FTD (FDM)
  11. Cisco ASA
  12. FortiGate
  13. Palo Alto PAN-OS
  14. Check Point
  15. Verification
  16. Troubleshooting

1. How the Test-Bed Works

The TLSStress.Art places the NGFW in the middle of all HTTPS traffic between simulated users (agents) and simulated websites (personas). The NGFW must perform TLS inspection on every connection — this is exactly what is being measured.

┌─────────────────────────────────────────────────────────────────┐
│                   TLSStress.Art (Ubuntu + k3s)              │
│                                                                 │
│  browser-engine agents (VLAN 20 — 172.16.x.x)                      │
│  synthetic-load agents         (VLAN 30 — 172.17.x.x)                      │
└───────────────────────────┬─────────────────────────────────────┘
                            │  TLS Leg 1
                            │  Agents → NGFW
                            │  NGFW presents its own CA-signed cert
                            │  Agents trust ngfw-ca (installed in cluster)
                            ▼
              ┌─────────────────────────┐
              │   NGFW (Device Under    │  ◄── This is what is being tested
              │        Test)            │
              │                         │
              │  TLS Inspection Engine  │
              │  Decrypt → Inspect →    │
              │  Re-encrypt             │
              └─────────────┬───────────┘
                            │  TLS Leg 2
                            │  NGFW → Persona webservers
                            │  Persona certs signed by persona-ca
                            │  NGFW trusts persona-ca (installed on NGFW)
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│               20 Persona Webservers (Caddy + Kubernetes)        │
│                                                                 │
│  shop        VLAN 101 — 10.1.1.0/27                            │
│  news        VLAN 102 — 10.1.2.0/27                            │
│  ...         ...                                               │
│  har-media   VLAN 120 — 10.1.20.0/27                           │
└─────────────────────────────────────────────────────────────────┘

Two TLS legs — two separate certificate trust relationships:

Leg Direction Who presents cert Who must trust it How
Leg 1 Agent → NGFW NGFW (forward-proxy cert) Agents (browser-engine + synthetic-load) ngfw-ca.crt installed in Kubernetes cluster
Leg 2 NGFW → Persona webservers Persona webserver (Caddy) NGFW persona-ca.pem installed in NGFW trust store

2. Physical Connectivity

Cabling

Ubuntu Server (test-bed)
  eth1 (802.1q trunk) ──────────► Nexus 9000 trunk port
                                        │
                                   VLAN trunk
                                   (all VLANs)
                                        │
                               ┌────────┴────────┐
                               │   Nexus 9000    │
                               └────────┬────────┘
                                        │
                             ┌──────────┴──────────┐
                             │   Access port(s)    │
                             │   to NGFW data      │
                             │   interfaces        │
                             └──────────┬──────────┘
                                        │
                                   ┌────┴────┐
                                   │  NGFW   │
                                   │  (DUT)  │
                                   └─────────┘

Nexus 9000 requirements

The Nexus 9000 must be configured with the following VLANs and trunk:

vlan 20,30,99,101-120,200-209

interface <trunk-to-ubuntu>
  switchport mode trunk
  switchport trunk allowed vlan 20,30,99,101-120,200-209

interface <to-ngfw-inside>           ! agent-side NGFW port
  switchport mode trunk
  switchport trunk allowed vlan 20,30

interface <to-ngfw-outside>          ! webserver-side NGFW port (Synthetic + Cloned Personas)
  switchport mode trunk
  switchport trunk allowed vlan 101-120,200-209

interface <to-ngfw-mgmt>             ! management NGFW port (optional)
  switchport mode access
  switchport access vlan 99

Note on VLAN 10 (removed in v3.7.0): the legacy single-Caddy Docker-mode webserver layer that lived on VLAN 10 / 10.20.30.0/24 was removed. Kubernetes is the single source of truth for DUT webservers — 20 Synthetic Personas on VLANs 101–120 + 10 Cloned Persona slots on VLANs 200–209.


3. Complete VLAN and IP Reference

3.0 NGFW Security Zone Mapping (v4.3, locked 2026-05-09)

The NGFW has 8 interfaces (or sub-interfaces on a trunk) distributed across 3 zones:

Zone VLANs Carries
TRUST / INSIDE 20, 30, 2900 Agent corporate LANs (browser-engine + synthetic-load) + control-plane stress agent (MAC + ARP/NDP)
UNTRUST / OUTSIDE 1982, 2001, 2809, 4338 VyOS routing/peer endpoints (OSPF, ISP/edge, BGP, MÓDULO SDWAN/CoR-N.Art local mode — legacy "VPN-REMOTE")
MGMT 99 Management — SNMP only

VLANs that do NOT terminate on the NGFW:

VLAN Reason
40 (cloner-isp) Cloner egress goes directly to public Internet — bypasses NGFW
101–120 (Synthetic Personas) Personas live BEHIND the VyOS-ISP pod (one country /24 per VLAN); the NGFW only sees the single edge link (VLAN 2001) — VyOS-ISP routes onward to each country
200–209 (Cloned Personas) Being deprecated — cloned personas migrate to country /24s alongside Synthetic ones

⚠️ Sections 3.3 and 4.2 below describe the LEGACY v3.x topology where personas terminated on NGFW sub-interfaces (one per VLAN 101–120, with NGFW gateway 10.1.x.1). For v4.3, personas live behind VyOS-ISP and the NGFW only has the single VLAN 2001 outside interface for all persona traffic. See docs/ARCHITECTURE.md "DUT network segments" for the corrected topology. Migration tracked separately (Personas v4.3 IP migration option B).

3.1 Agent VLANs (Inside — toward NGFW)

These are the subnets where the test agents live. The NGFW is the default gateway for agents.

VLAN Purpose Subnet NGFW Interface IP Agent IP range Protocol
20 browser-engine agents (real browser) 172.16.0.0/16 172.16.0.1 172.16.1.0 – 172.16.255.254 HTTPS (TCP 443)
30 synthetic-load agents (HTTP load) 172.17.0.0/16 172.17.0.1 172.17.1.0 – 172.17.255.254 HTTPS (TCP 443)

browser-engine agents generate real browser-style HTTPS with full TLS handshake and JavaScript. synthetic-load agents generate high-scale HTTP/2 and HTTP/3 load.

3.2 Management VLAN

VLAN Purpose Subnet Nexus 9000 IP NGFW mgmt IP K8s SNMP pod range
99 SNMP monitoring 10.254.254.0/24 10.254.254.2 10.254.254.3 10.254.254.10 – .49

The SNMP Exporter pod collects CPU, memory, and interface counters from both the Nexus 9000 and the NGFW to correlate traffic load with hardware performance.

3.3 Persona VLANs (Outside — toward Caddy webservers)

There are two groups of persona VLANs, both in the data path (NGFW → Caddy):

Synthetic Personas — 20 permanent personas, each with its own Kubernetes namespace and generated content:

Each persona runs in its own Kubernetes namespace with a dedicated VLAN, /27 subnet, TLS certificate, and DNS name. The NGFW is the gateway for inbound connections from the agent side.

VLAN Persona Subnet NGFW Interface IP Webserver IP(s) DNS name Site type
101 shop 10.1.1.0/27 10.1.1.1 10.1.1.2 shop.persona.internal E-Commerce (Saleor)
102 news 10.1.2.0/27 10.1.2.1 10.1.2.2 news.persona.internal News Portal
103 blog 10.1.3.0/27 10.1.3.1 10.1.3.2 blog.persona.internal Blog
104 docs 10.1.4.0/27 10.1.4.1 10.1.4.2 docs.persona.internal Technical Documentation
105 gallery 10.1.5.0/27 10.1.5.1 10.1.5.2 gallery.persona.internal Image Gallery
106 stream 10.1.6.0/27 10.1.6.1 10.1.6.2 stream.persona.internal HLS Video Streaming
107 download 10.1.7.0/27 10.1.7.1 10.1.7.2 download.persona.internal File Hosting
108 edu 10.1.8.0/27 10.1.8.1 10.1.8.2 edu.persona.internal Learning Platform
109 gov 10.1.9.0/27 10.1.9.1 10.1.9.2 gov.persona.internal Government Portal
110 cdn 10.1.10.0/27 10.1.10.1 10.1.10.2 cdn.persona.internal Asset CDN
111 api-rest 10.1.11.0/27 10.1.11.1 10.1.11.2 api-rest.persona.internal REST API
112 api-graphql 10.1.12.0/27 10.1.12.1 10.1.12.2 api-graphql.persona.internal GraphQL API
113 chat 10.1.13.0/27 10.1.13.1 10.1.13.2 chat.persona.internal Chat / Messaging
114 webhook 10.1.14.0/27 10.1.14.1 10.1.14.2 webhook.persona.internal Webhooks
115 telemetry 10.1.15.0/27 10.1.15.1 10.1.15.2 telemetry.persona.internal Analytics / Telemetry
116 ads 10.1.16.0/27 10.1.16.1 10.1.16.2 ads.persona.internal Ad Network
117 har-saas 10.1.17.0/27 10.1.17.1 10.1.17.2 har-saas.persona.internal Enterprise SaaS (HAR replay)
118 har-social 10.1.18.0/27 10.1.18.1 10.1.18.2 har-social.persona.internal Social Network (HAR replay)
119 har-webmail 10.1.19.0/27 10.1.19.1 10.1.19.2 har-webmail.persona.internal Webmail (HAR replay)
120 har-media 10.1.20.0/27 10.1.20.1 10.1.20.2 har-media.persona.internal Media Streaming (HAR replay)

Webserver IPs: each persona pod gets the first available IP in its range (.2). If replicas > 1, additional IPs (.3, .4 …) are assigned. The TLS certificate covers the full range .2–.30. The NGFW connects to the webserver IP directly (IP SAN validation).

Cloned Personas — 10 dynamic slots serving static site mirrors cloned from public websites:

VLAN Slot Subnet NGFW Interface IP Webserver IP(s) Content
200 clone-persona-1 10.2.1.0/27 10.2.1.1 10.2.1.2 Cloned site (file_server from PVC)
201 clone-persona-2 10.2.2.0/27 10.2.2.1 10.2.2.2 Cloned site (file_server from PVC)
202 clone-persona-3 10.2.3.0/27 10.2.3.1 10.2.3.2 Cloned site (file_server from PVC)
203 clone-persona-4 10.2.4.0/27 10.2.4.1 10.2.4.2 Cloned site (file_server from PVC)
204 clone-persona-5 10.2.5.0/27 10.2.5.1 10.2.5.2 Cloned site (file_server from PVC)
205 clone-persona-6 10.2.6.0/27 10.2.6.1 10.2.6.2 Cloned site (file_server from PVC)
206 clone-persona-7 10.2.7.0/27 10.2.7.1 10.2.7.2 Cloned site (file_server from PVC)
207 clone-persona-8 10.2.8.0/27 10.2.8.1 10.2.8.2 Cloned site (file_server from PVC)
208 clone-persona-9 10.2.9.0/27 10.2.9.1 10.2.9.2 Cloned site (file_server from PVC)
209 clone-persona-10 10.2.10.0/27 10.2.10.1 10.2.10.2 Cloned site (file_server from PVC)

Cloned Persona slots are assigned via Dashboard: PATCH /api/clone/persona-slots/{n} { "siteName": "<site>" }. Certs are signed by the same persona-ca-issuer as Synthetic Personas. The NGFW CA trust configuration is identical.

3.4 Summary — all subnets

VLAN Subnet Role NGFW interface IP
20 172.16.0.0/16 browser-engine agents 172.16.0.1
30 172.17.0.0/16 synthetic-load agents 172.17.0.1
99 10.254.254.0/24 SNMP management 10.254.254.3
101 10.1.1.0/27 shop 10.1.1.1
102 10.1.2.0/27 news 10.1.2.1
103 10.1.3.0/27 blog 10.1.3.1
104 10.1.4.0/27 docs 10.1.4.1
105 10.1.5.0/27 gallery 10.1.5.1
106 10.1.6.0/27 stream 10.1.6.1
107 10.1.7.0/27 download 10.1.7.1
108 10.1.8.0/27 edu 10.1.8.1
109 10.1.9.0/27 gov 10.1.9.1
110 10.1.10.0/27 cdn 10.1.10.1
111 10.1.11.0/27 api-rest 10.1.11.1
112 10.1.12.0/27 api-graphql 10.1.12.1
113 10.1.13.0/27 chat 10.1.13.1
114 10.1.14.0/27 webhook 10.1.14.1
115 10.1.15.0/27 telemetry 10.1.15.1
116 10.1.16.0/27 ads 10.1.16.1
117 10.1.17.0/27 har-saas 10.1.17.1
118 10.1.18.0/27 har-social 10.1.18.1
119 10.1.19.0/27 har-webmail 10.1.19.1
120 10.1.20.0/27 har-media 10.1.20.1
200 10.2.1.0/27 clone-persona-1 10.2.1.1
201 10.2.2.0/27 clone-persona-2 10.2.2.1
202 10.2.3.0/27 clone-persona-3 10.2.3.1
203 10.2.4.0/27 clone-persona-4 10.2.4.1
204 10.2.5.0/27 clone-persona-5 10.2.5.1
205 10.2.6.0/27 clone-persona-6 10.2.6.1
206 10.2.7.0/27 clone-persona-7 10.2.7.1
207 10.2.8.0/27 clone-persona-8 10.2.8.1
208 10.2.9.0/27 clone-persona-9 10.2.9.1
209 10.2.10.0/27 clone-persona-10 10.2.10.1

4. NGFW Interface Configuration

4.1 Required interfaces

The NGFW must have at minimum two physical interfaces (or one trunk):

Interface Connected to Carries VLANs Direction
Inside (agent-side) Nexus 9000 20, 30 Agents → NGFW
Outside (server-side) Nexus 9000 101–120, 200–209 NGFW → Persona webservers (Synthetic + Cloned)
Management (optional) Nexus 9000 99 SNMP monitoring only

4.2 Subinterface IPs to configure

For each VLAN, the NGFW needs a subinterface with the gateway IP listed in section 3. Example for a trunk-capable inside interface:

# Inside interface — agent-facing
VLAN 20  → IP 172.16.0.1/16   (browser-engine agent gateway)
VLAN 30  → IP 172.17.0.1/16   (synthetic-load agent gateway)

# Outside interface — webserver-facing (Synthetic Personas)
VLAN 101 → IP 10.1.1.1/27    (shop gateway)
VLAN 102 → IP 10.1.2.1/27    (news gateway)
VLAN 103 → IP 10.1.3.1/27    (blog gateway)
VLAN 104 → IP 10.1.4.1/27    (docs gateway)
VLAN 105 → IP 10.1.5.1/27    (gallery gateway)
VLAN 106 → IP 10.1.6.1/27    (stream gateway)
VLAN 107 → IP 10.1.7.1/27    (download gateway)
VLAN 108 → IP 10.1.8.1/27    (edu gateway)
VLAN 109 → IP 10.1.9.1/27    (gov gateway)
VLAN 110 → IP 10.1.10.1/27   (cdn gateway)
VLAN 111 → IP 10.1.11.1/27   (api-rest gateway)
VLAN 112 → IP 10.1.12.1/27   (api-graphql gateway)
VLAN 113 → IP 10.1.13.1/27   (chat gateway)
VLAN 114 → IP 10.1.14.1/27   (webhook gateway)
VLAN 115 → IP 10.1.15.1/27   (telemetry gateway)
VLAN 116 → IP 10.1.16.1/27   (ads gateway)
VLAN 117 → IP 10.1.17.1/27   (har-saas gateway)
VLAN 118 → IP 10.1.18.1/27   (har-social gateway)
VLAN 119 → IP 10.1.19.1/27   (har-webmail gateway)
VLAN 120 → IP 10.1.20.1/27   (har-media gateway)

# Outside interface — webserver-facing (Cloned Persona slots)
VLAN 200 → IP 10.2.1.1/27    (clone-persona-1 gateway)
VLAN 201 → IP 10.2.2.1/27    (clone-persona-2 gateway)
VLAN 202 → IP 10.2.3.1/27    (clone-persona-3 gateway)
VLAN 203 → IP 10.2.4.1/27    (clone-persona-4 gateway)
VLAN 204 → IP 10.2.5.1/27    (clone-persona-5 gateway)
VLAN 205 → IP 10.2.6.1/27    (clone-persona-6 gateway)
VLAN 206 → IP 10.2.7.1/27    (clone-persona-7 gateway)
VLAN 207 → IP 10.2.8.1/27    (clone-persona-8 gateway)
VLAN 208 → IP 10.2.9.1/27    (clone-persona-9 gateway)
VLAN 209 → IP 10.2.10.1/27   (clone-persona-10 gateway)

# Management interface
VLAN 99  → IP 10.254.254.3/24 (SNMP monitoring)

4.3 Security zones

Create two security zones on the NGFW:

Zone name Interfaces Trust level
agents VLAN 20, VLAN 30 Lower (clients — untrusted traffic source)
personas VLANs 101–120, 200–209 Higher (servers — inspect traffic going here)

5. Routing Table

The NGFW must be able to route traffic between the agent and persona subnets. Since it is the gateway for all subnets, the connected routes cover local forwarding. No static routes are strictly required unless the NGFW needs a management default route.

Destination Next Hop Interface Purpose
172.16.0.0/16 directly connected Inside.20 browser-engine agents
172.17.0.0/16 directly connected Inside.30 synthetic-load agents
10.1.1.0/2710.1.20.0/27 directly connected Outside.101–120 Synthetic Persona webservers
10.2.1.0/2710.2.10.0/27 directly connected Outside.200–209 Cloned Persona slots
10.254.254.0/24 directly connected Mgmt.99 SNMP management
0.0.0.0/0 management network GW Management Internet access for updates (optional)

Policy-based routing: some NGFWs apply routing decisions per security policy rule. Ensure your access policy allows traffic from agents zone to personas zone on TCP 443 (and UDP 443 for HTTP/3 / QUIC).


6. PKI — The Two CAs

This is the most critical part of the NGFW configuration. There are two completely different CAs, each used for a different TLS leg.

6.1 CA for Leg 2 — persona-ca-issuer CA (import INTO the NGFW)

What it is: the internal CA used by cert-manager (persona-ca-issuer ClusterIssuer in platform/pki/) to sign the TLS certificates of all 20 Synthetic Persona webservers and all 10 Cloned Persona slots (Caddy).

Why the NGFW needs it: in TLS Leg 2 (NGFW → webserver), the NGFW acts as a TLS client and must validate the server certificate presented by Caddy. If the NGFW doesn't trust this CA, it will reject the connection with a certificate validation error.

How to export it from the cluster:

# On the Ubuntu server (after running k8s-dut-up.sh or k8s-install.sh)
kubectl get secret persona-ca-bundle -n web-agents \
  -o jsonpath='{.data.ca\.crt}' | base64 -d > persona-ca.pem

# Verify the certificate
openssl x509 -in persona-ca.pem -text -noout | grep -E "Subject:|Issuer:|Not After"

Expected output:

Subject: O=Web Agent Cluster, OU=Persona PKI, CN=Persona CA
Issuer:  O=Web Agent Cluster, OU=Persona PKI, CN=Persona CA
Not After: <date ~10 years from cluster creation>

Where to import it on the NGFW: see section 8 for vendor-specific instructions. Generally: trusted CA store / SSL inspection trusted CAs.

This single CA signs certs for all 30 webserver VLANs (20 Synthetic Personas on VLANs 101–120 + 10 Cloned Persona slots on VLANs 200–209). You only need to import one CA into the NGFW.

6.2 CA for Leg 1 — ngfw-ca (export FROM the NGFW, install in cluster)

What it is: the CA the NGFW uses to sign the forward-proxy certificates it presents to the agents during TLS Leg 1. This is the NGFW's own interception CA.

Why the cluster needs it: browser engine (Node.js) and synthetic-load engine (Go) agents validate the server certificate during every HTTPS connection. If they don't trust the NGFW's CA, every connection will fail with CERT_AUTHORITY_INVALID or similar.

How to export it from each NGFW vendor:

Vendor Where to find it Export format
Cisco FTD (FMC) Objects → PKI → CA Certificates → select intercept CA → Export PEM
Cisco FTD (FDM) Policies → SSL → Trusted CA → export PEM
Cisco ASA crypto ca export <trustpoint> certificate PEM (copy from terminal)
FortiGate Security Profiles → SSL/SSH Inspection → CA Certificate → Download PEM
Palo Alto Device → Certificate Management → Certificates → select forward-trust cert → Export PEM
Check Point SmartConsole → Gateways → HTTPS Inspection → CA Certificate → Export PEM or Base64
Huawei USG System → PKI → CA Certificate → Export PEM
Meraki MX Security & SD-WAN → Content Filtering → SSL Inspection → Download CA Certificate PEM

How to install it in the cluster:

# Replace with the actual path to the exported PEM file
kubectl create configmap ngfw-ca \
  -n web-agents \
  --from-file=ngfw-ca.crt=./ngfw-ca.pem \
  --dry-run=client -o yaml | kubectl apply -f -

# Verify it was applied
kubectl get configmap ngfw-ca -n web-agents -o yaml | grep 'ngfw-ca.crt' -A 3

# Restart agents to pick up the new CA
kubectl rollout restart deployment/web-agent  -n web-agents
kubectl rollout restart deployment/k6-agent   -n web-agents
kubectl rollout status  deployment/web-agent  -n web-agents
kubectl rollout status  deployment/k6-agent   -n web-agents

7. TLS Inspection Policy

7.1 What to inspect

Configure the TLS inspection policy to decrypt and inspect all HTTPS traffic between the agent subnets and the persona subnets:

Source Destination Port Action
172.16.0.0/16 (browser engine) 10.1.0.0/16 (Synthetic Personas) TCP 443 Decrypt & Inspect
172.17.0.0/16 (synthetic-load engine) 10.1.0.0/16 (Synthetic Personas) TCP 443 Decrypt & Inspect
172.16.0.0/16 (browser engine) 10.1.0.0/16 (Synthetic Personas) UDP 443 Decrypt & Inspect (QUIC/HTTP3)
172.17.0.0/16 (synthetic-load engine) 10.1.0.0/16 (Synthetic Personas) UDP 443 Decrypt & Inspect (QUIC/HTTP3)
172.16.0.0/16 (browser engine) 10.2.0.0/16 (Cloned Persona slots) TCP 443 Decrypt & Inspect
172.17.0.0/16 (synthetic-load engine) 10.2.0.0/16 (Cloned Persona slots) TCP 443 Decrypt & Inspect
172.16.0.0/16 (browser engine) 10.2.0.0/16 (Cloned Persona slots) UDP 443 Decrypt & Inspect (QUIC/HTTP3)
172.17.0.0/16 (synthetic-load engine) 10.2.0.0/16 (Cloned Persona slots) UDP 443 Decrypt & Inspect (QUIC/HTTP3)

7.2 TLS versions

The Caddy webservers support TLS 1.2 and TLS 1.3. Configure the NGFW to inspect both:

  • Minimum: TLS 1.2
  • Maximum: TLS 1.3
  • Disable: TLS 1.1, TLS 1.0, SSL 3.0

7.3 Cipher suites

Caddy uses only ECDHE+AEAD cipher suites (ECDSA certificates). Ensure your inspection policy does not downgrade to RSA or CBC ciphers:

TLS_AES_256_GCM_SHA384          (TLS 1.3)
TLS_AES_128_GCM_SHA256          (TLS 1.3)
TLS_CHACHA20_POLY1305_SHA256    (TLS 1.3)
ECDHE-ECDSA-AES256-GCM-SHA384  (TLS 1.2)
ECDHE-ECDSA-AES128-GCM-SHA256  (TLS 1.2)
ECDHE-ECDSA-CHACHA20-POLY1305  (TLS 1.2)

7.4 HTTP/3 (QUIC) — important note

The synthetic-load agent can generate HTTP/3 (QUIC over UDP 443). HTTP/3 TLS inspection is harder for NGFWs and is one of the key metrics being measured. Check your NGFW vendor documentation for QUIC inspection support:

  • If QUIC inspection is supported: enable it and include UDP 443 in the inspection policy.
  • If QUIC inspection is not supported (or you want to measure only HTTP/2): add a rule to block or reset UDP 443, which forces agents to fall back to HTTP/2 over TCP. This is a valid test scenario — it measures the impact of forcing QUIC-capable clients to downgrade.

7.5 Certificate validation on Leg 2

The NGFW must validate the server certificate during Leg 2 (NGFW → Caddy). Ensure:

  • Server certificate validation: Enabled (not bypassed)
  • Trusted CA store: includes persona-ca.pem (see section 6.1) — this single CA covers both Synthetic Personas (VLANs 101–120) and Cloned Persona slots (VLANs 200–209)
  • Certificate revocation: CRL/OCSP can be disabled — this is a lab with no revocation infrastructure

8. Vendor Configuration Examples

8.1 Cisco FTD — Firepower Management Center

Step 1: Import persona-ca (trust persona webserver certs)

  1. Objects → PKI → Trusted CAs → Add Trusted CA
  2. Name: Persona-CA
  3. Upload persona-ca.pem
  4. Click Save

Step 2: Export ngfw-ca (so agents can trust NGFW)

  1. Objects → PKI → CA Certificates → select your intercept CA
  2. Click Export → download PEM
  3. Install on cluster: kubectl create configmap ngfw-ca -n web-agents --from-file=ngfw-ca.crt=<file>.pem

Step 3: Create SSL Policy

  1. Policies → SSL → New Policy
  2. Name: DUT-TLS-Inspection
  3. Add rule:
  4. Action: Decrypt — Resign
  5. Source Zones: agents
  6. Destination Zones: personas
  7. Destination Ports: TCP 443, UDP 443
  8. Resign CA: select your intercept CA
  9. Default Action: Do Not Decrypt (pass through other traffic)

Step 4: Create Access Control Policy rule

  1. Policies → Access Control → your policy
  2. Add rule above the default:
  3. Source Networks: 172.16.0.0/16, 172.17.0.0/16
  4. Destination Networks: 10.1.0.0/16
  5. Destination Ports: TCP 443, UDP 443
  6. SSL Policy: DUT-TLS-Inspection
  7. Action: Allow (with inspection)
  8. Intrusion Policy: attach if you want IPS metrics during the test
  9. Deploy to the FTD sensor

Step 5: Configure interfaces

# In FMC: Devices → Device Management → select your FTD → Interfaces
# Set up subinterfaces on the physical interfaces:

Inside interface (trunk):
  Subinterface 20: VLAN 20, IP 172.16.0.1/16, Security Zone: agents
  Subinterface 30: VLAN 30, IP 172.17.0.1/16, Security Zone: agents

Outside interface (trunk):
  Subinterface 101: VLAN 101, IP 10.1.1.1/27,  Security Zone: personas
  Subinterface 102: VLAN 102, IP 10.1.2.1/27,  Security Zone: personas
  ...
  Subinterface 120: VLAN 120, IP 10.1.20.1/27, Security Zone: personas

Management interface:
  Subinterface 99: VLAN 99, IP 10.254.254.3/24  (out-of-band, SNMP)

8.2 Cisco FTD — Firepower Device Manager

Import persona-ca

  1. Objects → Certificates → Trusted CA → Add
  2. Name: Persona-CA, upload persona-ca.pem

Export ngfw-ca

  1. Policies → SSL → Trusted CA → export your intercept CA

Create SSL Decryption Policy

  1. Policies → SSL Decryption → Add Rule
  2. Source: 172.16.0.0/16, 172.17.0.0/16
  3. Destination: 10.1.0.0/16
  4. Port: HTTPS (443/tcp)
  5. Action: Decrypt — Resign with your intercept CA

8.3 Cisco ASA

ASA with FirePOWER Services (SFR module) or ASA with AnyConnect SSL inspection:

# Import persona-ca as trusted CA
crypto ca authenticate DUT-ROOT-CA

# Paste the PEM content when prompted (the persona-ca.pem contents)

# Create crypto map or SSL inspection policy targeting:
#   src 172.16.0.0 255.255.0.0 and 172.17.0.0 255.255.0.0
#   dst 10.1.0.0 255.255.0.0
#   port 443

# Create subinterfaces for agent VLANs
interface GigabitEthernet0/0.20
 encapsulation dot1Q 20
 ip address 172.16.0.1 255.255.0.0
 nameif agents-pw
 security-level 50

interface GigabitEthernet0/0.30
 encapsulation dot1Q 30
 ip address 172.17.0.1 255.255.0.0
 nameif agents-k6
 security-level 50

# Create subinterfaces for persona VLANs (repeat for 101-120)
interface GigabitEthernet0/1.101
 encapsulation dot1Q 101
 ip address 10.1.1.1 255.255.255.224
 nameif persona-shop
 security-level 0

# ... repeat for VLANs 102-120 ...

# Enable SSL inspection via FirePOWER module or ASA CX

8.4 FortiGate

Create VLANs and interface IPs

# In CLI:
config system interface
  edit "inside.20"
    set vdom "root"
    set ip 172.16.0.1 255.255.0.0
    set allowaccess ping
    set type vlan
    set interface "port1"
    set vlanid 20
    set role lan
  next
  edit "inside.30"
    set vdom "root"
    set ip 172.17.0.1 255.255.0.0
    set type vlan
    set interface "port1"
    set vlanid 30
    set role lan
  next
  edit "outside.101"
    set vdom "root"
    set ip 10.1.1.1 255.255.255.224
    set type vlan
    set interface "port2"
    set vlanid 101
    set role wan
  next
  # ... repeat for VLANs 102-120 ...
end

Import persona-ca

# GUI: Security Profiles → SSL/SSH Inspection → Create/Edit profile
# Under "CA Certificate": import persona-ca.pem

# Or via CLI:
config vpn certificate ca
  edit "Persona-CA"
    set ca "<base64-encoded-persona-ca>"
  next
end

Export ngfw-ca

# GUI: Security Profiles → SSL/SSH Inspection → select your profile
#       → CA Certificate → Download
# This downloads the FortiGate's intercept CA in PEM format.

Create SSL/SSH Inspection Profile

# GUI: Security Profiles → SSL/SSH Inspection → Create New
config firewall ssl-ssh-profile
  edit "DUT-Inspection"
    set comment "TLSStress.Art DUT mode"
    config https
      set ports 443
      set status deep-inspection
      set proxy-after-tcp-handshake enable
    end
    config ssl
      set inspect-all deep-inspection
    end
    set caname "Persona-CA"
  next
end

Create firewall policy

config firewall policy
  edit 100
    set name "DUT-agents-to-personas"
    set srcintf "inside.20" "inside.30"
    set dstintf "outside.101" "outside.102" ... "outside.120"
    set srcaddr "172.16.0.0/16" "172.17.0.0/16"
    set dstaddr "10.1.0.0/16"
    set action accept
    set schedule "always"
    set service "HTTPS"
    set ssl-ssh-profile "DUT-Inspection"
    set utm-status enable
    set logtraffic all
  next
end

8.5 Palo Alto PAN-OS

Import persona-ca

# GUI: Device → Certificate Management → Certificates → Import
# Name: Persona-CA
# File: persona-ca.pem
# Mark as: "Trusted Root CA"

# Or via CLI:
scp import certificate from <user@host:/path/persona-ca.pem>
> certificate-name Persona-CA
> category trusted-root-CA

Export ngfw-ca

# GUI: Device → Certificate Management → Certificates →
#       select your forward-trust certificate → Export Certificate
# Format: Base64 Encoded Certificate (PEM)

Create interfaces

# GUI: Network → Interfaces → Ethernet → Add Sub-Interface

# Inside interface (toward agents)
Ethernet1/1.20:  IP 172.16.0.1/16, VLAN 20, Zone: agents
Ethernet1/1.30:  IP 172.17.0.1/16, VLAN 30, Zone: agents

# Outside interface (toward personas)
Ethernet1/2.101: IP 10.1.1.1/27,   VLAN 101, Zone: personas
Ethernet1/2.102: IP 10.1.2.1/27,   VLAN 102, Zone: personas
# ... repeat for 103-120 ...

Create Decryption Profile

# GUI: Objects → Decryption Profile → Add
# Name: DUT-Decrypt-Profile
# SSL Forward Proxy:
#   Forward Trust Certificate: <your intercept CA>
#   Forward Untrust Certificate: <your untrust CA>
# Server Certificate Verification:
#   Block sessions with expired certificates: yes
#   Block sessions with untrusted issuers: yes (with persona-ca as trusted)

Create Decryption Policy

# GUI: Policies → Decryption → Add
# Name: DUT-Decrypt-All
# Source Zone: agents
# Destination Zone: personas
# Source Address: 172.16.0.0/16, 172.17.0.0/16
# Destination Address: 10.1.0.0/16
# Service: application-default (or create HTTPS service for 443/tcp + 443/udp)
# Type: SSL Forward Proxy
# Profile: DUT-Decrypt-Profile

Create Security Policy

# GUI: Policies → Security → Add
# Name: agents-to-personas
# Source Zone: agents
# Destination Zone: personas
# Application: ssl, web-browsing
# Service: application-default
# Action: Allow
# Profile Group: attach your threat/URL profile

8.6 Check Point

Import persona-ca

# SmartConsole → Objects → New → Certificate Authority → Trusted CA
# Name: Persona-CA
# Upload: persona-ca.pem

Export ngfw-ca

# SmartConsole → Gateways & Servers → double-click your gateway
# → HTTPS Inspection → CA Certificate → Export
# Save as PEM

Configure HTTPS Inspection

# SmartConsole → Security Policies → HTTPS Inspection → Policy
# Add rule:
# Name: DUT-Inspection
# Source: Group(172.16.0.0/16, 172.17.0.0/16)
# Destination: Group(10.1.1.0/27 - 10.1.20.0/27)
# Services: HTTPS (443)
# Site Category: Any
# Action: Inspect
# Track: Log

# Under Blade Control → SSL Inspection → Trusted CA:
# Add Persona-CA to the trusted store

Configure interfaces

# SmartConsole → Gateways → Interfaces → Add VLAN
# Create sub-interfaces for each VLAN (20, 30, 101-120)
# Assign IPs per section 3 above

9. Verification

9.1 Verify connectivity from the cluster

# SSH into one of the agent pods
kubectl exec -it -n web-agents deployment/web-agent -- sh

# Test that the NGFW gateway is reachable
ping -c 3 172.16.0.1        # browser-engine VLAN 20 gateway
ping -c 3 172.17.0.1        # K6 VLAN 30 gateway (from K6 pod)

# Test HTTPS to a persona (should succeed if TLS inspection is working)
curl -v https://shop.persona.internal/ --max-time 5
# Expected: HTTP 200, certificate issued by NGFW CA

9.2 Verify TLS inspection is active

# From an agent pod, inspect the certificate chain presented by the NGFW
echo | openssl s_client -connect shop.persona.internal:443 -servername shop.persona.internal 2>/dev/null \
  | openssl x509 -noout -issuer -subject

# Expected output (certificate issued by NGFW, not by persona-ca):
# issuer=CN=<your NGFW intercept CA name>
# subject=CN=shop.persona.internal   (re-signed by NGFW)

9.3 Verify SNMP monitoring

# From the SNMP pod, test connectivity to the NGFW
kubectl exec -it -n web-agents deployment/snmp-exporter -- sh
snmpwalk -v2c -c <community> 10.254.254.3 1.3.6.1.2.1.1.1.0

# Expected: sysDescr of the NGFW

9.4 Verify TLS Leg 2 (NGFW trusts webserver cert)

Check NGFW logs for TLS errors on the outbound leg. If you see certificate validation failures toward 10.1.x.x (Synthetic Personas) or 10.2.x.x (Cloned Personas), the persona-ca was not imported correctly.

# On the cluster: confirm the webserver certificate chain
echo | openssl s_client -connect 10.1.1.2:443 2>/dev/null \
  | openssl x509 -noout -issuer -subject

# Expected (before NGFW interception — direct from Ubuntu server):
# issuer=CN=Persona CA  (or similar — the persona-ca-issuer CN)
# subject=CN=shop.persona.internal

10. Troubleshooting

Symptom Likely cause Fix
Agents get CERT_AUTHORITY_INVALID ngfw-ca not installed in cluster, or agents not restarted Re-run kubectl create configmap ngfw-ca ... and kubectl rollout restart deployment/web-agent
NGFW shows TLS Leg 2 cert validation error persona-ca not imported in NGFW trust store Export persona-ca.pem from cluster (kubectl get secret persona-ca-bundle ...) and import in NGFW trusted CA store
HTTP/3 connections fail but HTTP/2 works NGFW doesn't support QUIC inspection Block UDP 443 on NGFW to force HTTP/2 downgrade; note this in test results
Agents can't reach persona IPs (10.1.x.x) Missing routes or NGFW policy blocking Check NGFW security policy allows 172.16.0.0/16 and 172.17.0.0/16 to 10.1.0.0/16
SNMP exporter shows no data from NGFW NGFW SNMP not enabled, wrong community, or VLAN 99 not reachable Verify NGFW SNMP is enabled with community public (or matching observability/snmp/snmp.yml); verify VLAN 99 IP 10.254.254.3 is pingable
TLS inspection not triggered SSL policy not attached to access rule, or zones misconfigured Verify source/destination zones match agent and persona interfaces
Certificate errors after persona cert renewal NGFW cached old cert fingerprint Cert-manager auto-renews persona certs every 11 months; Stakater Reloader restarts Caddy pods — no NGFW change needed

For test-bed architecture details, see docs/ARCHITECTURE.md. For deployment instructions, see docs/UBUNTU_K3S_SINGLENODE_QUICKSTART_DEPLOY.en.md. For the automated Kubernetes installer, see scripts/k8s-install.sh.