-
Notifications
You must be signed in to change notification settings - Fork 7
Providers
Node kinds declare what they need (a public IP, a Windows image, nested virt, private DNS). Providers declare what they can do. The canvas warns at design time when a topology asks for something a target cannot deliver, which is what keeps one provider from forking into many.
| Provider | Target ranges | Attack infrastructure |
|---|---|---|
| GCP | Tested | Tested |
| AWS | Tested | Tested |
| Azure | Roadmap | Roadmap |
| Proxmox | Roadmap | Roadmap |
| ESXi | Roadmap | Roadmap |
GCP and AWS are tested end to end for both target ranges and attack infrastructure. Azure, Proxmox, and ESXi are on the roadmap, not yet supported.
- Azure can stand up hosts and give them public addresses today, but two things are not built yet: private DNS (hosts do not resolve each other by name the way a GCP or AWS range does; treat name resolution the same way you would on-prem, static hosts entries, until this lands) and peering (a topology that depends on peering will not compile the same way it does on GCP or AWS).
- Proxmox and ESXi cannot allocate a public address on their own, so redirector reachability there depends on a network redStackPRO does not control.
AWS quotas are per region, and a compile does not check them against your account. Scope them before you deploy, so an apply does not fail partway and leave partial infrastructure running and billing. Every item below is per region: a new region means re-checking these.
The AWS default is 5 Elastic IPs per region (Service Quotas code L-0263D0A3,
"EC2-VPC Elastic IPs"). The export allocates one for each host that takes a public
address (the jumpbox and, on the attack side, the redirector) and one for each
network that builds a NAT gateway.
| Range | Elastic IPs | What takes them |
|---|---|---|
| Defense/AD range | about 2 | jumpbox, NAT gateway |
| Offense range | about 3 | jumpbox, redirector, NAT gateway |
At the default of 5, a region holds only one or two concurrent ranges. Request an increase per region in advance:
aws service-quotas request-service-quota-increase --service-code ec2 --quota-code L-0263D0A3 --desired-value <n> --region <region>
An EIP shortfall surfaces at provisioning, after the instances are already up, so a failed apply leaves them running. Destroy the partial range explicitly (see Managing a range: status, start, stop, teardown in Deploying a Range) rather than leaving it to bill.
AWS caps running On-Demand instance vCPUs per region under "Running On-Demand
Standard (A, C, D, H, I, M, R, T, Z) instances". Hosts are mostly t3.large and
t3.medium (2 vCPU each), so a large AD range (for example full GOAD plus a SIEM)
can exceed the default. Check the quota and raise it before large deploys.
If a topology includes a Kali operator, the Kali AMI needs a one-time Marketplace subscription on the account, and it is per region. redStackPRO generates code and never performs account actions, so you subscribe once per region you deploy Kali into.
An EC2 key pair name is region-global (unique per region across the account). The
export names the key pair from the topology prefix (var.key_name defaults to
<prefix>-key), so two ranges with the same prefix in one region collide on it.
Keep the topology prefix unique per range.
A GCP deploy needs a project with billing enabled, the right API turned on, and enough quota. A compile does not check any of this against your account.
GCP resources live inside a project, and a project needs billing enabled before it will create anything. If you do not already have one:
gcloud projects create <project-id> --organization=<org-id>
gcloud billing projects link <project-id> --billing-account=<billing-account-id>
Or create the project and link a billing account from the console
(console.cloud.google.com). Either way, project in terraform.tfvars is this
project's id, not its display name.
The export's GCP module only creates Compute Engine resources (instances, networks, addresses, routers, NAT), so that is the one API to enable:
gcloud services enable compute.googleapis.com --project <project-id>
The export does not touch Cloud DNS or any other GCP API. The redirector's DNS A record is something you create by hand at your own registrar, not a GCP resource. See Deploying a Range.
GCP caps running Compute Engine vCPUs per project under CPUS_ALL_REGIONS
(default 32 per project, not per region). This is the quota that actually bites: a
topology with enough hosts can exceed it well before any single-region or
machine-type limit does. Check it, and raise it if needed, under IAM & Admin >
Quotas in the console, filtered to the Compute Engine API, before a large deploy.
The export reserves a static external address for the jumpbox, and for a redirector on the attack side, so each range holds one or two per region. GCP also caps external IP addresses per region. Check the same Quotas page, filtered to Compute Engine "IP addresses", before running more than a couple of ranges in one region.
Flag: unlike AWS's service-quotas CLI, a GCP quota increase is normally
requested through the console UI, not a single scriptable command. Confirm the
current process in the console before planning around a CLI-only flow.
Exposure is a ceiling, not a default. A segment declares how exposed its hosts may be,
and the compiler will not emit a host more exposed than its segment allows. If a host
asks for a public address in a segment that permits none, the validator raises EXP005
rather than deploying something that reads as exposed and is actually unreachable.
See Validation.
Every ingress rule the compiler writes exists because an edge in the topology called
for it, or because of operator_source_ranges. Nothing is open by default. Egress is
a separate question: both providers leave the security group or firewall open at
egress, and what actually leaves is decided by a segment's egress field and its NAT
or internet gateway routing, not by a port rule.
| Node kind | Source | Port | Protocol | Purpose |
|---|---|---|---|---|
| jumpbox | operator_source_ranges |
22 | tcp | operator ssh access |
| jumpbox | operator_source_ranges |
443 | tcp | the Guacamole portal, access_mode: public (default) only |
| jumpbox | operator_source_ranges |
the vpn_port overlay (default 51820 WireGuard, 1194 OpenVPN) |
the vpn_protocol overlay (udp or tcp) |
operator VPN access, access_mode: wireguard or openvpn only; the portal then sits behind this tunnel instead of on 443 |
| jumpbox | its own segment | all | all | the foothold rule: accepts traffic range hosts initiate back to it, such as a coerced or relayed NTLM callback, or a pivot return |
| redirector | 0.0.0.0/0 |
the fronts edge's listen_port (443 in every shipped example) |
tcp, or udp when the edge's protocol is dns
|
the fronted C2 traffic |
| redirector | 0.0.0.0/0 |
80 | tcp | the Certbot ACME http-01 challenge, and the http to https redirect |
| teamserver | the operator(s) that drive it | Mythic 7443, Sliver 31337, Adaptix 4321 | tcp | the C2's own operator control plane (a none teamserver opens none; see the note below) |
| collector | senders on a logs_to edge |
the collector's ingest_port overlay, default 5044 |
tcp | log shipping ingest, Logstash's beats input by default |
The jumpbox also reaches every host it manages, on 22 (ssh) or 5986 (WinRM), plus 3389 when the Guacamole portal needs an RDP tile (a Windows host, or a desktop mode Kali operator). Those rules sit on the managed host's own firewall entry, not the jumpbox's, so they are not in the table above.
WireGuard as a provisioning transport. Separate from operator access_mode
above, a jumpbox can also be set to reach the hosts it manages over a
WireGuard tunnel instead of ssh (UDP 51820). The generated firewall does not
open a rule for that port in either provider today.
The none teamserver. A none teamserver stands up no service. It is a plain
Debian box for a custom, operator-supplied C2 (OC2, or a C2 kept for the roadmap such
as Cobalt Strike), so redStackPRO opens no control port for it.