Skip to main content
All redStack configuration is done through terraform.tfvars. Start by copying the example file:
cp terraform.tfvars.example terraform.tfvars
Then open terraform.tfvars in an editor and set your values. The sections below document every variable.
URI prefixes, the C2 header value, and the redirector domain are baked into agent payloads and Apache config at deploy time. Set these before running terraform apply. Changing them after deployment requires redeployment.

Required variables

These three variables have no defaults. terraform apply will fail if they are not set.
localPub_ip
string
required
Your public IP address in CIDR notation with a /32 suffix. Used to scope SSH and management access in security group rules.Get your IP with curl -s ifconfig.me, then append /32.Example: "203.0.113.45/32"
ssh_key_name
string
required
The name of an existing AWS EC2 key pair. Terraform uses this key to associate SSH access with all instances. The key pair must already exist in AWS before running terraform apply — Terraform does not create it.If you followed the prerequisites guide, this is "rs-rsa-key".
ssh_private_key_path
string
required
Path to the .pem private key file on your local machine. Terraform uses this to decrypt the Windows Administrator password generated by AWS at instance launch.If the key file is in your redStack/ directory (the recommended location), this is "./rs-rsa-key.pem".

Deployment mode

redStack supports two deployment modes. Set these before deploying — they affect Apache configuration and payload callback URLs that are baked in at deploy time.
Use this mode when you have a registered domain and internet-accessible targets (public CTFs, self-hosted VMs with public IPs, etc.).Set your domain in terraform.tfvars:
redirector_domain = "c2.yourdomain.tld"
enable_external_vpn                  = false
enable_redirector_htaccess_filtering = true
After deployment you must:
  1. Point your domain’s DNS A record to the redirector’s Elastic IP (Step 1.6 in the deploy guide)
  2. SSH to the redirector and run Certbot to obtain a Let’s Encrypt TLS certificate
Scanner and AV vendor blocking via redirect.rules is enabled by default in this mode.

Instance types

Defaults are tuned for cost/performance balance on a typical training lab. Adjust if you need more resources or want to reduce costs.
mythic_instance_type
string
default:"t3.medium"
EC2 instance type for the Mythic C2 team server. Mythic runs approximately 10 Docker containers, so this instance needs adequate RAM. t3.medium (2 vCPU, 4 GB RAM) is the minimum recommended.
guacamole_instance_type
string
default:"t3.small"
EC2 instance type for the Apache Guacamole access portal. t3.small (2 vCPU, 2 GB RAM) is sufficient for 1-2 concurrent operator sessions.
windows_instance_type
string
default:"t3.medium"
EC2 instance type for the Windows Server 2022 operator workstation. t3.medium (2 vCPU, 4 GB RAM) handles VS Code, MobaXterm, and a browser simultaneously.
redirector_instance_type
string
default:"t3.micro"
EC2 instance type for the Apache redirector. t3.micro (2 vCPU, 1 GB RAM) is sufficient — Apache mod_rewrite proxying is not resource-intensive.
sliver_instance_type
string
default:"t3.small"
EC2 instance type for the Sliver C2 server. t3.small (2 vCPU, 2 GB RAM) is adequate for the Sliver daemon and typical lab workloads.
havoc_instance_type
string
default:"t3.medium"
EC2 instance type for the Havoc C2 server. Havoc is compiled from source during user data, which requires at least 2 GB RAM. t3.medium is the minimum recommended.

Network configuration

use_default_vpc
boolean
default:"false"
When false, Terraform creates a dedicated VPC (vpc_cidr) for the team server infrastructure. This is the default and keeps the lab isolated from other AWS workloads in the same account.Set to true only if you have hit the VPC limit in your account (AWS default is 5 VPCs per region) and need to reuse the existing default VPC.
vpc_cidr
string
default:"10.50.0.0/16"
CIDR block for the team server VPC. Only used when use_default_vpc = false. Change this if 10.50.0.0/16 conflicts with other networks in your environment.
redirector_vpc_cidr
string
default:"10.60.0.0/16"
CIDR block for the redirector VPC. The redirector runs in its own isolated VPC, connected to the team server VPC via VPC peering. Change to 10.61.0.0/16 if you are running two simultaneous redStack deployments.

Domain

redirector_domain
string
default:""
The domain or subdomain that points to the redirector’s Elastic IP. Used in Apache VirtualHost configuration and agent callback URLs.Leave empty for closed environments (HTB/VL/PG). When empty, the redirector uses its public Elastic IP and a self-signed certificate.Example: "c2.yourdomain.tld"

C2 URI prefixes

These paths are configured in Apache’s proxy rules and baked into agent payloads at deploy time. They make C2 callback traffic look like legitimate CDN or cloud storage requests.
Set these before running terraform apply. Changing URI prefixes after deployment requires rebuilding agents and redeploying the redirector configuration.
mythic_uri_prefix
string
default:"/cdn/media/stream"
URI prefix for Mythic C2 callbacks. The redirector strips this prefix before forwarding requests to Mythic internally. Agents use this path for all check-in and tasking traffic.
sliver_uri_prefix
string
default:"/cloud/storage/objects"
URI prefix for Sliver C2 callbacks. The redirector strips this prefix before forwarding requests to Sliver on port 80 internally.
havoc_uri_prefix
string
default:"/edge/cache/assets"
URI prefix for Havoc C2 callbacks. Unlike Mythic and Sliver, the full path including the prefix is forwarded to Havoc because Havoc’s listener validates URIs against the same paths embedded in the demon payload.

C2 header validation

Header validation is always enabled. Every request that reaches the redirector must include the correct header name and token value to be proxied to a C2 backend. Requests without a valid header receive a decoy CloudEdge CDN maintenance page instead.
c2_header_name
string
default:"X-Request-ID"
The HTTP header name required on all C2 callback requests. Agents must include this header on every check-in. Changing this requires rebuilding all agents.
c2_header_value
string
default:""
The token value for the C2 header. Leave empty to auto-generate a random 32-character hex token at deploy time (recommended). Retrieve the active token after deployment:
terraform output deployment_info
# Look for: C2 Header: X-Request-ID: <token>
Set an explicit value only if you need a predetermined token (e.g., for scripted payload generation workflows).

Feature toggles

enable_mythic_autostart
boolean
default:"true"
When true, Mythic starts automatically on instance boot via a systemd service. Set to false if you want to start Mythic manually with sudo ./mythic-cli start.
enable_redirector_htaccess_filtering
boolean
default:"true"
When true, the redirect.rules scanner and AV vendor blocklist is loaded into Apache on the redirector. This blocks known scanning infrastructure (AV vendors, threat intel providers, TOR exits) with 403 Forbidden responses.Set to false for closed lab environments (HTB/VL/PG) where scanner blocking is not needed and could interfere with legitimate lab traffic.
enable_external_vpn
boolean
default:"false"
When true, enables an OpenVPN client on the redirector and configures WireGuard for internal VPN routing. Use this for HackTheBox, Proving Grounds, VulnLab, and other platforms accessed via .ovpn files.See Part 8 of the deployment guide for the full external VPN workflow.

External VPN routing

external_vpn_cidrs
string[]
default:"[\"10.10.0.0/16\"]"
CIDR blocks that should be routed through the redirector’s OpenVPN tunnel. Only used when enable_external_vpn = true.The default 10.10.0.0/16 covers most HackTheBox target ranges. Adjust for other platforms:
external_vpn_cidrs = ["10.10.0.0/16", "10.129.0.0/16"]

Metadata and tagging

aws_region
string
default:"us-east-1"
AWS region for all resources. Must match the region configured in aws configure. All resources are created in a single region.
project_name
string
default:"redStack"
Project name applied as a Project tag to every AWS resource. Use distinct values if running two simultaneous deployments so you can filter resources and costs per deployment.
tags
object
Additional key-value tags applied to every AWS resource (instances, security groups, Elastic IPs, VPCs, etc.). Useful for cost tracking and filtering in the AWS Console.Every resource also receives a Project tag automatically set to project_name, a ManagedBy: Terraform tag, and an Environment: Training tag.
tags = {
  Owner      = "Operator"
  CostCenter = "redStack"
  Purpose    = "Boot-to-Breach Training Environment"
}

Complete example tfvars

The full terraform.tfvars.example file from the repository:
# terraform.tfvars.example
# Copy this to terraform.tfvars and fill in your values

# ============================================================================
# REQUIRED VARIABLES - YOU MUST SET THESE
# ============================================================================

# Your public IP for SSH access (find with: curl ifconfig.me)
# Must be in CIDR format with /32 suffix
localPub_ip = "108.51.27.140/32"

# Name of your existing AWS SSH key pair
# Must already exist in AWS EC2 Console > Key Pairs
ssh_key_name = "rs-rsa-key"

# Path to your SSH private key (.pem file) — used to decrypt the Windows Administrator password
ssh_private_key_path = "./rs-rsa-key.pem"

# Your redirector domain — apex or subdomain (e.g. c2.yourdomain.com)
# Point this domain's A record to the Redirector Elastic IP after deployment
redirector_domain = "c2.yourdomain.tld"

# ============================================================================
# OPTIONAL VARIABLES - Customize as needed
# ============================================================================

# AWS region for deployment
aws_region = "us-east-1"

# Project name (used for resource tagging)
project_name = "redStack"

# Instance types (adjust based on budget/performance needs)
mythic_instance_type     = "t3.medium"  # 2 vCPU, 4GB RAM
guacamole_instance_type  = "t3.small"   # 2 vCPU, 2GB RAM
windows_instance_type    = "t3.medium"  # 2 vCPU, 4GB RAM
sliver_instance_type     = "t3.small"   # 2 vCPU, 2GB RAM
havoc_instance_type      = "t3.medium"  # 2 vCPU, 4GB RAM
redirector_instance_type = "t3.small"   # 2 vCPU, 2GB RAM

# Network configuration
use_default_vpc     = false          # Creates a dedicated VPC (recommended)
vpc_cidr            = "10.50.0.0/16" # TeamServer VPC CIDR
redirector_vpc_cidr = "10.60.0.0/16" # Redirector VPC CIDR

# Mythic configuration
enable_mythic_autostart = true  # Auto-start Mythic on boot

# C2 URI prefixes (CDN/cloud-style paths routed through the redirector)
# These are baked into payloads at deploy time. Customize before deploying.
mythic_uri_prefix = "/cdn/media/stream"
sliver_uri_prefix = "/cloud/storage/objects"
havoc_uri_prefix  = "/edge/cache/assets"

# C2 header validation is always enabled. These override the defaults:
# c2_header_name  = "X-Request-ID"  # Header name (default: X-Request-ID)
# c2_header_value = ""              # Token value — leave empty to auto-generate (recommended)

# --- CTF/Pro Lab mode (HTB/VL/PG via OpenVPN) ---
enable_external_vpn                  = false  # Set to true for HTB/VL/PG
enable_redirector_htaccess_filtering = true   # Set to false for HTB/VL/PG
# external_vpn_cidrs = ["10.10.0.0/16"]

# Optional: Custom tags applied to every AWS resource
tags = {
  Owner      = "Operator"
  CostCenter = "redStack"
  Purpose    = "Boot-to-Breach Training Environment"
}

Build docs developers (and LLMs) love