- Home
- Traffic Generator
- Runner
Runner
Overview
Section titled “Overview”runner.sh is the suite orchestrator that executes all numbered scripts in a suite directory in order, captures output, and records results metadata. It is installed at /opt/traffic-generator/suites/runner.sh on the VM.
runner.sh <suite-name> [--dry-run]Arguments:
| Argument | Required | Description |
|---|---|---|
suite-name | Yes | Name of the suite directory (e.g., web-app-attacks, api-attacks) |
--dry-run | No | Print what would execute without running any scripts |
Examples:
# Run the web-app-attacks suite/opt/traffic-generator/suites/runner.sh web-app-attacks
# Dry-run to preview api-attacks scripts/opt/traffic-generator/suites/runner.sh api-attacks --dry-run
# Run bot simulation/opt/traffic-generator/suites/runner.sh bot-simulationConfiguration
Section titled “Configuration”config.env
Section titled “config.env”The runner reads configuration from /opt/traffic-generator/config.env:
# Required: target FQDN (F5 XC load balancer domain)TARGET_FQDN=demo.example.com
# Optional: direct origin IP for baseline testing (bypasses F5 XC)TARGET_ORIGIN_IP=This file is written automatically during Terraform provisioning from the target_fqdn and target_origin_ip variables. To change the target after deployment, edit this file directly on the VM.
Environment Variable Override
Section titled “Environment Variable Override”Any variable in config.env can be overridden by exporting it before running the suite:
# Override target FQDN for a single runTARGET_FQDN=staging.example.com /opt/traffic-generator/suites/runner.sh web-app-attacks
# Override via exportexport TARGET_FQDN=staging.example.com/opt/traffic-generator/suites/runner.sh web-app-attacksThe config file path itself can also be overridden:
CONFIG_FILE=/tmp/my-config.env /opt/traffic-generator/suites/runner.sh web-app-attacksDry-Run Mode
Section titled “Dry-Run Mode”The --dry-run flag prints each script that would be executed without running it:
/opt/traffic-generator/suites/runner.sh web-app-attacks --dry-runOutput:
=== 01-sqli.sh ===[DRY-RUN] Would execute: /opt/traffic-generator/suites/web-app-attacks/01-sqli.sh demo.example.com=== 02-xss.sh ===[DRY-RUN] Would execute: /opt/traffic-generator/suites/web-app-attacks/02-xss.sh demo.example.com=== 03-command-injection.sh ===[DRY-RUN] Would execute: /opt/traffic-generator/suites/web-app-attacks/03-command-injection.sh demo.example.com=== 04-path-traversal.sh ===[DRY-RUN] Would execute: /opt/traffic-generator/suites/web-app-attacks/04-path-traversal.sh demo.example.com=== 05-nikto-scan.sh ===[DRY-RUN] Would execute: /opt/traffic-generator/suites/web-app-attacks/05-nikto-scan.sh demo.example.com=== 06-nuclei-scan.sh ===[DRY-RUN] Would execute: /opt/traffic-generator/suites/web-app-attacks/06-nuclei-scan.sh demo.example.com=== Suite Complete ===Passed: 0 | Failed: 0 | Skipped: 6Results: /opt/traffic-generator/results/20260425-143000-web-app-attacksUse dry-run to verify suite structure after deployment or before running a suite against a new target.
Results Directory
Section titled “Results Directory”Each suite run creates a timestamped results directory:
/opt/traffic-generator/results/<YYYYMMDD-HHMMSS>-<suite-name>/Structure:
/opt/traffic-generator/results/20260425-143000-web-app-attacks/ meta.json 01-sqli.sh.log 02-xss.sh.log 03-command-injection.sh.log 04-path-traversal.sh.log 05-nikto-scan.sh.log 06-nuclei-scan.sh.logEach script’s stdout and stderr are captured to a .log file named after the script.
meta.json Format
Section titled “meta.json Format”The meta.json file records suite execution metadata:
{ "suite": "web-app-attacks", "target": "demo.example.com", "started": "2026-04-25T14:30:00Z", "completed": "2026-04-25T14:45:23Z", "status": "completed", "passed": 5, "failed": 1, "skipped": 0}| Field | Description |
|---|---|
suite | Suite name |
target | Target FQDN used for the run |
started | UTC timestamp when the suite started |
completed | UTC timestamp when the suite finished |
status | running during execution, completed when done |
passed | Number of scripts that exited with code 0 |
failed | Number of scripts that exited with non-zero code |
skipped | Number of scripts skipped (not executable or dry-run) |
Running Individual Scripts
Section titled “Running Individual Scripts”Each script can be executed standalone without the runner:
# Run a single script directly/opt/traffic-generator/suites/web-app-attacks/01-sqli.sh demo.example.com
# Run a specific API attack/opt/traffic-generator/suites/api-attacks/01-vampi-owasp-top10.sh demo.example.comScripts accept the target FQDN as the first positional argument. They do not read config.env directly — only the runner does that. When running standalone, you must pass the FQDN explicitly.
Running All Suites in Sequence
Section titled “Running All Suites in Sequence”To run every suite back-to-back:
for suite in web-app-attacks api-attacks bot-simulation reconnaissance ssl-scanning javascript-exploits traffic-generation; do echo "=========================================" echo "Starting suite: ${suite}" echo "=========================================" /opt/traffic-generator/suites/runner.sh "$suite" echo ""doneThis generates comprehensive traffic across all F5 XC security features. Expect the full run to take 45-80 minutes depending on the target’s response times.
Remote Execution via SSH
Section titled “Remote Execution via SSH”Run suites from your local machine without maintaining an SSH session:
TGEN_IP=$(terraform output -raw public_ip)
# Run a single suitessh azureuser@${TGEN_IP} '/opt/traffic-generator/suites/runner.sh web-app-attacks'
# Run a suite with target overridessh azureuser@${TGEN_IP} 'TARGET_FQDN=staging.example.com /opt/traffic-generator/suites/runner.sh api-attacks'
# Run in background (disconnection-safe)ssh azureuser@${TGEN_IP} 'nohup /opt/traffic-generator/suites/runner.sh web-app-attacks > /tmp/web-app-attacks.log 2>&1 &'
# Check results laterssh azureuser@${TGEN_IP} 'ls -la /opt/traffic-generator/results/ | tail -5'ssh azureuser@${TGEN_IP} 'cat /opt/traffic-generator/results/$(ls -t /opt/traffic-generator/results/ | head -1)/meta.json'For long-running suites, use nohup or tmux to prevent SSH disconnection from killing the process:
ssh azureuser@${TGEN_IP} 'tmux new-session -d -s traffic "/opt/traffic-generator/suites/runner.sh reconnaissance"'
# Reattach later to watch progressssh -t azureuser@${TGEN_IP} 'tmux attach-session -t traffic'Execution Flow
Section titled “Execution Flow”-
Load configuration — Runner reads
config.env(orCONFIG_FILEoverride), then checks forTARGET_FQDNin environment. -
Validate suite — Confirms the named suite directory exists under the suites directory. Lists available suites if not found.
-
Create results directory — Creates
/opt/traffic-generator/results/<timestamp>-<suite>/and writes initialmeta.jsonwithstatus: running. -
Execute scripts — Iterates through files matching
[0-9]*in the suite directory, sorted by name. Skips non-executable files. PassesTARGET_FQDNas the first argument. Captures output to<script-name>.log. -
Record results — Updates
meta.jsonwith completion timestamp and pass/fail/skip counts.