
InfraGuard is a Command & Control Redirection Proxy and Manager which protects your Red Team Infrastructure against threat attribution
Red team infrastructure tracker and C2 redirector -- a modern alternative to RedWarden.
InfraGuard sits between the internet and your C2 teamserver, validating every inbound request against your malleable C2 profile and blocking anything that doesn't conform. Scanners, bots, and blue team probes get redirected to a decoy site while legitimate beacon traffic passes through to your teamserver.


mythic_file backend proxies Mythic's /direct/download/{uuid} at clean URLs; fixed UUID or proxy mode; access control provided by InfraGuard's filter stack/metrics endpoint exposing request counters, upstream latency histograms, circuit breaker state, feed freshness, and active connectionson_event hooks, per-plugin config, and event filtering.env file support.htaccess and robots.txt files.env file auto-loaded; ${VAR} syntax works in all config values and keysCheck out the Wiki Page for installation
infraguard --version Show version
infraguard --help Show help
infraguard run -c config.yaml Start the reverse proxy
infraguard run -c config.yaml --port 8443 Override listen port
infraguard run -c config.yaml --host 0.0.0.0 Override bind address
infraguard dashboard -c config.yaml Start the web dashboard
infraguard dashboard -c config.yaml --port 9090 Override dashboard port
infraguard tui Launch TUI with login screen
infraguard tui --url http://host:8080 --token TOK Auto-connect to dashboard
infraguard tui -c config.yaml Read URL/token from config
infraguard command-post -c command-post.yaml Start multi-instance dashboard
infraguard command-post --instance name:url:token Add instance via CLI (repeatable)
infraguard profile parse <file> Parse and display a C2 profile
infraguard profile parse <file> --format json Output as JSON
infraguard profile parse <file> --type brute_ratel Force profile type
infraguard profile convert <file> -o out.json Convert profile to JSON
# Supported --type values: auto, cobalt_strike, mythic, brute_ratel, sliver, havoc, nighthawk, poshc2
# Auto-detection: .profile = CS, .toml = Havoc, .yaml = PoshC2, .json = auto-detect by keys
infraguard ingest <files...> Ingest .htaccess/robots.txt rules
infraguard ingest <files...> --format blocklist Output as IP blocklist
infraguard ingest <files...> --format json Output as JSON
infraguard ingest <files...> -o banned_ips.txt Write blocklist to file
infraguard generate nginx -c config.yaml Generate Nginx config
infraguard generate caddy -c config.yaml Generate Caddyfile
infraguard generate apache -c config.yaml Generate Apache VirtualHost
infraguard init -o config.yaml Generate starter config
infraguard validate -c config.yaml Validate config file
The generate command accepts additional flags for operator customization:
| Flag | Description |
|---|---|
--listen-port PORT | Override listen port (default: from config) |
--ssl-cert PATH | Override SSL certificate path |
--ssl-key PATH | Override SSL key path |
--redirect-url URL | Override redirect URL for blocked requests |
--default-action redirect|404 | Action for non-matching requests |
--no-ip-filter | Omit IP allow/deny blocks |
--no-header-check | Omit header validation rules |
--alias DOMAIN:ALIAS | Add server name alias (repeatable) |
--header NAME:VALUE | Add custom response header (repeatable) |
When running multiple InfraGuard instances across different VPSes or cloud providers, the Command Post aggregates stats, requests, and live events from all nodes into a single dashboard.
┌─────────────────────────────┐
│ Command Post Dashboard │
│ http://localhost:9090 │
└──────────┬──────────────────┘
│ parallel fetch
┌─────┼──────┬──────────┐
▼ ▼ ▼ ▼
IG-1 IG-2 IG-3 ... IG-N

# Via config file
infraguard command-post -c config/command-post.yaml
# Via CLI args
infraguard command-post \
--instance "prod:https://ig1.example.com:8080:TOKEN1" \
--instance "staging:https://ig2.example.com:8080:TOKEN2" \
--port 9090
# Via Docker
docker compose --profile command-post up -d command-post
Create config/command-post.yaml:
instances:
- name: "prod-cs"
url: "https://ig1.example.com:8080"
token: "${IG_PROD_TOKEN}"
- name: "prod-mythic"
url: "https://ig2.example.com:8080"
token: "${IG_MYTHIC_TOKEN}"
- name: "staging"
url: "https://ig3.example.com:8080"
token: "${IG_STAGING_TOKEN}"
port: 9090
# auth_token: "${COMMAND_POST_TOKEN}"
| Endpoint | Method | Description |
|---|---|---|
/api/instances | GET | List all instances with health status |
/api/stats | GET | Merged stats from all instances |
/api/requests | GET | Interleaved request log from all instances |
/api/intel/whitelist | POST | Whitelist an IP on all instances |
/api/intel/blocklist | POST | Block an IP on all instances |
/api/intel/blocklist | DELETE | Unblock an IP on all instances |
/ws/events | WS | Multiplexed live events from all instances |
cp .env.example .env
# Edit .env with your domain, teamserver, and token
docker compose up -d
This starts two services:
# Set in .env:
# INFRAGUARD_LETSENCRYPT=true
# INFRAGUARD_DOMAIN=cdn.example.com
# [email protected]
# Obtain the initial certificate
docker compose --profile letsencrypt up certbot
# Start the proxy (will use the LE cert)
docker compose up -d proxy dashboard
# Start auto-renewal (checks every 12 hours)
docker compose --profile letsencrypt up -d certbot-renew
Requirements for Let's Encrypt:
INFRAGUARD_DOMAIN must resolve to this host's public IPINFRAGUARD_DOMAIN_EMAIL must be a valid email address# Download all three GeoLite2 databases (City, ASN, Country)
docker compose --profile geoip up geoip-update
# Then start normally - databases are mounted at /app/geoip/
docker compose up -d proxy dashboard
# Start PwnDrop alongside the proxy
docker compose --profile pwndrop up -d pwndrop
# Access PwnDrop admin UI at https://localhost:8443
# InfraGuard reaches it internally at http://pwndrop:80
Then configure content routes in your config to proxy payload paths to PwnDrop:
domains:
cdn.example.com:
content_routes:
- path: "/downloads/*"
backend:
type: "pwndrop"
target: "http://pwndrop:80"
auth_token: "${PWNDROP_TOKEN}"
# Start the Ollama service
docker compose --profile ollama up -d ollama
# Pull the default model (~5 GB)
docker compose --profile ollama exec ollama ollama pull qwen3:8b
# The dashboard's AI chat panel will connect automatically
The dashboard environment variable INFRAGUARD_OLLAMA_URL is pre-configured in docker-compose.yml. When Ollama is running, the AI Assistant toggle appears in the dashboard's decoys and profiles page.
# Run multiple redirector nodes
docker compose up -d --scale proxy-node=3
Uncomment the proxy-node service in docker-compose.yml to enable.
| Volume | Purpose |
|---|---|
./config | Configuration files (mounted read-only) |
./examples | C2 profiles (mounted read-only) |
./rules | Ingested blocklists and rule source files (mounted read-only) |
./data | SQLite database and generated profiles (persisted) |
certs | TLS certificates (shared between proxy and certbot) |
geoip | GeoLite2 databases (populated by geoip-update service) |
pwndrop-data | PwnDrop uploaded files and database |
ollama-data | Ollama model weights and configuration |
infraguard/
__init__.py Package init
__main__.py python -m infraguard entry
main.py Click CLI
config/ YAML config loading, .env support, Pydantic validation
core/ ASGI proxy engine (app, proxy, router, TLS, drop actions, content delivery)
profiles/ C2 profile parsers and generators (8 types)
pipeline/ Request validation filters (JA3, IP, bot, header, DNS, geo, profile, replay, enumeration, sandbox)
intel/ IP intelligence (blocklists, GeoIP, rDNS, feeds, rule ingestion)
tracking/ SQLite persistence (request logging, stats, node registry)
plugins/ Plugin system (protocol, loader, builtins)
ui/
api/ REST API + WebSocket (Starlette)
web/ SPA dashboard (HTML/JS/CSS)
tui/ Terminal UI (Textual) with login screen
command_post/ Multi-instance aggregation dashboard
listeners/ Protocol listeners (HTTP, DNS, MQTT, WebSocket)
backends/ Config generators (Nginx, Caddy, Apache)
models/ Shared types and event models
| Feature | RedWarden | InfraGuard |
|---|---|---|
| Architecture | Single ~99KB file | Modular package |
| Profile parsing | Regex state machine | Structured parser with full block/transform support |
| C2 support | Cobalt Strike only | Cobalt Strike, Mythic, Brute Ratel C4, Sliver, Havoc, Nighthawk, PoshC2 |
| Profile management | Manual file editing | Dashboard wizard with generate, import, hot-swap, and AI assist |
| Protocols | HTTP only | HTTP, DNS, MQTT, WebSocket |
| Filter model | Binary pass/fail | Scoring-based (0.0--1.0 threshold), 10-filter chain |
| TLS fingerprinting | None | JA3 blocking (Masscan, ZGrab2, Shodan, curl, Python requests, Nmap) |
| Sandbox detection | None | Headless browser / Safe Links / sandbox UA and header scoring |
| Enumeration detection | None | Path enumeration + DNS NXDOMAIN tracking with auto-block |
| Burn detection | None | CT log monitoring, domain reputation, cross-domain analyst detection, confidence scoring |
| Infrastructure resilience | None | Circuit breaker, protocol failover, dead man's switch, infrastructure rotation |
| Payload delivery | None | PwnDrop, Mythic file store, filesystem, HTTP proxy with conditional delivery |
| Payload protection | None | One-time tokens, per-route rate limiting, delivery guards |
| Phishing protection | None | Campaign token validation (static list or HMAC-signed) |
| Operator UI | None | Web dashboard + Terminal UI + multi-instance Command Post |
| Observability | None | Prometheus metrics, engagement reports, structured logging |
| Config generation | None | Nginx, Caddy, Apache with full customization |
| Rule ingestion | None | .htaccess + robots.txt parser |
| Threat intel feeds | None | Auto-update from 5 public sources |
| Plugin system | Basic 4-method interface | Event-driven with on_event hooks + per-plugin config |
| SIEM integration | None |
If you would like to contribute to the project, then please create a new branch with the version name and specify the same version name in the pull request. E.g. branch=v1.2.3 | [v1.2.3] Added blah item.
BSD 2-Clause License. See LICENSE for details.
Copyright (c) 2026, Whispergate
| Elasticsearch, Wazuh, Syslog (CEF/JSON) |
| Webhook alerts | None | Discord, Slack, generic webhook |
| Whitelist intelligence | None | Auto-enrich CIDRs with ASN/org/country on startup |
| Anti-replay | SQLite hash | Persistent SQLite with in-memory L1 cache, survives restarts |
| Drop actions | redirect, reset, proxy | redirect, reset, proxy, tarpit |
| TLS management | Manual only | Auto self-signed + Let's Encrypt integration |
| Edge deployment | None | Cloudflare Worker + AWS Lambda edge proxies with domain fronting |
| Config security | None | age and SOPS encryption, validation checks, API key management |
| Deployment | Manual | Docker Compose with health checks |
| Async | Tornado callbacks | Native async/await (ASGI + uvicorn) |