Back to Articles

Building a Private Cloud Proxy Botnet: Inside ProxyCannon-NG's Architecture

[ View on GitHub ]

Building a Private Cloud Proxy Botnet: Inside ProxyCannon-NG's Architecture

Hook

A two-day hackathon at a security conference produced a tool that lets penetration testers route traffic through dozens of cloud IPs with a single command—no custom protocols, no exotic dependencies, just clever orchestration of commodity services.

Context

Penetration testers face a predictable problem: modern applications aggressively rate-limit and block traffic from single IP addresses. Make too many authentication attempts, scan too many endpoints, or trigger anomaly detection systems, and you're locked out. Traditional solutions fall short—commercial proxy services are expensive and ethically questionable, TOR is too slow for active scanning, and manually managing VPN credentials across multiple providers is operationally painful.

ProxyCannon-NG emerged from the Wild West Hackin' Fest 2018 hackathon to address this gap. The premise is elegant: what if you could treat cloud infrastructure as disposable exit nodes, spinning up dozens of EC2 instances across AWS regions, routing all your traffic through them in a load-balanced fashion, then tearing everything down when your engagement ends? The result is a private proxy botnet that gives you the IP diversity of a commercial proxy service with the control and transparency of infrastructure you provision yourself. Unlike residential proxy networks where you're routing through compromised home routers, every IP is legitimately yours, making it appropriate for authorized security testing.

Technical Insight

Data Plane - AWS

Control Plane

User Environment

VPN Connection

Route Traffic

Distribute Packets

Distribute Packets

Distribute Packets

Provision & Configure

Provision & Configure

Provision & Configure

Source IP 1

Source IP 2

Source IP N

Workstation

OpenVPN Server

Persistent Hub

iptables Load Balancer

Round-Robin

Terraform IaC

Provisioning

Exit Node 1

t3.micro

Exit Node 2

t3.micro

Exit Node N

t3.micro

Internet

System architecture — auto-generated

ProxyCannon-NG's architecture separates concerns cleanly: a persistent OpenVPN control server acts as the hub, while ephemeral exit-node instances are the spokes. Your workstation connects to the VPN server, which maintains routes to all active exit-nodes. When you send traffic through the VPN, iptables rules on the control server distribute packets across exit-nodes using round-robin load balancing. Each exit-node then forwards traffic to the internet, making your requests appear to originate from different AWS IPs.

The Terraform configuration is where the magic happens. Rather than building custom provisioning logic, ProxyCannon-NG uses infrastructure-as-code to declaratively define exit-nodes. Here's the core resource definition pattern:

resource "aws_instance" "exit_node" {
  count         = var.exit_node_count
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
  key_name      = aws_key_pair.proxycannon.key_name
  
  vpc_security_group_ids = [aws_security_group.exit_nodes.id]
  subnet_id              = element(aws_subnet.public.*.id, count.index)
  
  user_data = templatefile("${path.module}/scripts/setup_exit_node.sh", {
    vpn_server_ip = aws_instance.vpn_server.private_ip
    vpn_cert_data = base64encode(file(var.client_cert_path))
  })
  
  tags = {
    Name = "proxycannon-exit-${count.index}"
    Role = "exit-node"
  }
}

The user_data script handles the bootstrapping. Each exit-node installs OpenVPN, retrieves its configuration from the control server, establishes the VPN tunnel, then configures iptables to NAT outbound traffic. The control server's routing configuration is the crucial piece—it uses iptables SNAT rules with nth-match to distribute connections:

# Simplified version of the load balancing logic
for i in $(seq 0 $((NUM_EXITS - 1))); do
  iptables -t nat -A POSTROUTING \
    -m statistic --mode nth --every $NUM_EXITS --packet $i \
    -j SNAT --to-source ${EXIT_NODE_IPS[$i]}
done

This statistic module approach is elegant because it requires no connection tracking beyond what iptables already does—every nth packet gets routed to a different exit-node in a deterministic rotation. The state is maintained at the kernel level, not in user-space, keeping performance overhead minimal.

The shell-based orchestration ties everything together. The main control script provisions infrastructure via Terraform, waits for instances to become healthy, generates OpenVPN certificates, distributes them to exit-nodes, then configures your local routing table to send traffic through the VPN. Teardown is equally straightforward—a single command destroys all Terraform-managed resources, leaving no persistent costs.

What makes this architecture effective for penetration testing is the separation of control and data planes. The VPN server can remain running across multiple engagements while exit-nodes are cycled between tests. If you need fresh IPs, you don't reconfigure anything—just run terraform destroy followed by terraform apply to get an entirely new set of exit-node IPs. The infrastructure-as-code approach means this operation is idempotent and reproducible, unlike manual VPN configuration.

Gotcha

The hackathon origins create real operational limitations. Error handling is minimal—if an exit-node fails to provision or the VPN tunnel doesn't establish, you'll be debugging bash scripts and Terraform state files manually. The code assumes happy-path scenarios: network connectivity is stable, AWS APIs respond promptly, and OpenVPN configurations are valid. In production use, expect to add significant retry logic and health checking.

More fundamentally, cloud IPs are not anonymous. Security-conscious organizations maintain blocklists of AWS, GCP, and Azure IP ranges. If your target already blocks cloud traffic, ProxyCannon-NG won't help—your requests will be rejected regardless of how many exit-nodes you provision. The comparison to TOR is misleading; this is IP rotation for rate-limit avoidance, not anonymity. Additionally, AWS costs accumulate quickly. Running twenty t3.micro instances across multiple regions for an eight-hour engagement can exceed $50 in compute costs alone, not counting data transfer fees. The economics work for professional penetration testers billing clients, but hobbyist use gets expensive fast.

Verdict

Use ProxyCannon-NG if you're conducting authorized penetration tests or red team operations where you need legitimate, diverse source IPs to bypass rate limiting, and you're comfortable with AWS infrastructure and shell-script debugging. It's ideal for scenarios like testing account enumeration protections, validating IP-based blocking rules, or simulating distributed attacks during security assessments. The infrastructure-as-code approach makes it reproducible and auditable for professional engagements. Skip it if you need production-grade reliability, multi-cloud support beyond AWS, or actual anonymity—the rough edges from its hackathon heritage mean you'll spend time troubleshooting instead of testing. Also skip if you're not conducting authorized security work with proper legal authorization, as this tool's entire purpose is offensive security testing, and misuse carries serious legal consequences. For hobbyist learning, the AWS costs alone make this impractical compared to studying the concepts and using free-tier VPN services.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/proxycannon-proxycannon-ng.svg)](https://starlog.is/api/badge-click/cybersecurity/proxycannon-proxycannon-ng)