All posts
AWSTerraformPythonNetworkingPrivacy

CloakVPN: A Personal, Region-Aware Stealth VPN Built with Python & Terraform

Commercial VPNs are black boxes, so I built one I own end to end. Terraform provisions OpenVPN nodes across AWS regions, and a Python orchestrator rotates your exit IP on a timer.

A commercial VPN routes your traffic through infrastructure you cannot inspect, and you take its logging policy on trust. I wanted to own the network path instead.

So I built CloakVPN, a personal VPN system where the infrastructure is yours. It provisions AWS EC2 instances in multiple regions, configures OpenVPN on each, and rotates connections based on the mode you pick. All of it runs from your own machine.

No third-party provider, no opaque logs, no data sharing. Just VPN nodes on your own cloud account.

Why build your own VPN

Commercial VPNs offer convenience at a cost:

  • You don't control the servers, so you cannot verify what they do.
  • Traffic logs could be retained, and data isolation is not guaranteed.
  • Configurability is limited: no custom modes, no rotation, no deeper tuning.

With CloakVPN, traffic is routed through AWS EC2 nodes that you launch and destroy yourself. It is built to:

  • Give full visibility and ownership of IP infrastructure
  • Rotate VPN identities across regions automatically
  • Match your browsing identity to IP geography
  • Explore network-level privacy from the ground up

Architecture

CloakVPN architecture: Terraform provisions OpenVPN EC2 nodes across multiple AWS regions, orchestrated by a local Python runner

Folder structure

πŸ“¦ CloakVPN
β”œβ”€β”€ terraform/                 # Infra provisioning
β”‚   β”œβ”€β”€ main.tf
β”‚   β”œβ”€β”€ outputs.tf
β”‚   β”œβ”€β”€ variables.tf
β”‚   └── modules/
β”‚       └── vpn/               # OpenVPN EC2 module
β”œβ”€β”€ orchestrator/              # Python runner
β”‚   β”œβ”€β”€ cloakvpn_gui.py        # tkinter GUI
β”‚   β”œβ”€β”€ provisioner.py         # Terraform + OVPN orchestration
β”‚   β”œβ”€β”€ vpn_connector.py       # OpenVPN connector (full/partial mode)
β”‚   β”œβ”€β”€ download_ovpn.py       # SSH download logic
β”‚   β”œβ”€β”€ utils.py               # Logging, ping utils, sudo checks
β”‚   └── constants.py
β”œβ”€β”€ regions.json               # Input config (regions + count)
└── README.md

Philosophy

This project is about control and observability. Instead of outsourcing VPN trust, you:

  • Decide where VPN nodes are (per region)
  • Own all .ovpn credentials locally
  • Rotate connections every N seconds (full mode)
  • Lock to a single trusted region (partial mode)
  • Always know which IP you're using, because it's yours

Features

  • GUI to select regions and modes
  • Live Terraform apply with streaming logs
  • Auto-fetch of .ovpn files over SSH
  • Ping-based selection of the fastest OpenVPN node
  • IPv6 hard-disabled during VPN use
  • A log file tracking all activity
  • CLI and GUI both work

Budget comparison against NordVPN

NordVPN base plan: $12.99/month β‰ˆ $0.43/day

At that price point, this is how many AWS VPN instances run per day:

Cost comparison: number of AWS EC2 VPN instances runnable per day at NordVPN's $0.43/day price point

You get dynamic IPs and no third-party logging, on infrastructure you control. EC2 has a reputation for being expensive, but managed carefully it is cheap.

VPN modes

1. Full cloak mode

  • Chooses a random region from available .ovpn files
  • Connects for N seconds β†’ disconnects β†’ rotates
  • Ensures frequent IP rotation, ideal for general privacy and geo-hopping

2. Partial cloak mode

  • Locks to a specific region
  • Picks the best .ovpn from that region by ping
  • Ideal for persistent identity, but via a trusted exit node

How it works

Step 1: choose regions

Using the GUI, select your desired AWS regions (e.g. US-East, EU-Central, Japan).

Step 2: provision infrastructure

  • CloakVPN uses Terraform to spin up EC2 instances
  • Each instance is bootstrapped with OpenVPN and generates a .ovpn client file
  • Files are pulled back over SSH

Step 3: run the VPN in full or partial mode

  • In Full Mode, the system rotates through available .ovpn files automatically
  • In Partial Mode, it picks the fastest server in your chosen region

Requirements

  • macOS or Linux
  • Python 3.8+
  • AWS CLI + credentials
  • Terraform installed
  • OpenVPN installed

Python dependencies (from requirements.txt):

ping3
requests

Running it locally

Clone the repo:

git clone git@github.com:BitanSarkar/cloak-vpn.git
cd cloak-vpn

Install dependencies:

pip install -r requirements.txt

Run the GUI with sudo:

sudo python3 orchestrator/cloakvpn_gui.py

Screenshots

Region selection and provisioning

First select the regions.

CloakVPN GUI showing the AWS region selection screen

Then click Provision + Fetch OVPN to terraform the architecture.

Terraform apply running with streaming logs in the CloakVPN GUI

Wait for the .ovpn files to download.

OpenVPN .ovpn client config files being fetched over SSH

Ping summary

After provisioning, it creates the ping summary.

Ping latency summary across provisioned OpenVPN nodes in each region

VPN control

A. Partial mode

Choose a region and click Start. Connection logs stream on the right.

Partial mode connected to a single region with live OpenVPN connection logs

Then go to whatismyipaddress.com to verify location.

IP lookup confirming the exit IP resolves to the selected AWS region

Open YouTube and the location will have changed.

YouTube showing region-specific content for the VPN exit node's country

Open Netflix, Prime, or any site, and you'll get the content available in those regions.

B. Full mode

Your IP rotates randomly between regions every 120 seconds.

Full mode running, rotating OpenVPN connections across regions on an interval

For the first 120 seconds:

Exit IP during the first 120-second rotation window

Next 120 seconds:

A different exit IP and region after the next rotation window

When to use each mode

The two modes trade stealth against stability.

Full mode

What it does

  • Periodically rotates VPN connections across multiple regions.
  • Each connection randomly selects one .ovpn configuration file from that region.
  • IP, geolocation, and network fingerprint keep changing every N seconds.

Best for

  • Stealth operations: testing region-specific access, censorship circumvention, or rotating IPs during scraping.
  • Temporary obfuscation: you don't want your identity tied to a single region or address.
  • Ad blocking, rate limiting, and firewall avoidance scenarios.

Trade-off

  • Your session may be interrupted briefly during rotation.
  • Not ideal for apps requiring a persistent connection (e.g. streaming or banking).

Partial mode

What it does

  • Connects to only one region.
  • Picks the best .ovpn file based on lowest ping latency.
  • VPN stays fixed and stable.

Best for

  • Long sessions in a consistent region (e.g. browsing, file transfers).
  • Country-specific content like streaming platforms or government portals.
  • Secure browsing using a single trusted server that you control.

Trade-off

  • IP stays static (until you re-run provisioning).
  • Less stealth, but more stability and predictability.

If you're unsure, start with partial mode for stability. Use full mode when you want dynamic IP hopping, or to avoid long-term association with one region.

Why this matters

Outsourcing your exit node means trusting a company's word about what it logs. CloakVPN replaces that with:

  • An exit node setup you can read
  • Infrastructure you own
  • Direct control over how and where you appear

You own the pipe instead of trusting someone else's.

What's still missing

  • Add Docker-based deployment
  • Deploy OpenVPN nodes on cheaper spot instances
  • Auto-destroy idle nodes on exit
  • Add a CLI wrapper for headless mode
  • Extend to support WireGuard

Where this leaves it

This was a weekend of Terraform, Python glue code, SSH and privacy tooling. It won't replace an everyday VPN yet. What it does give you is an identity layer where you understand every moving part.

The code is on GitHub as cloak-vpn.

β€”β€”

Leave a comment

No account needed. Leave the name blank and you'll get a random one.

0/2000
By email

Get the next one in your inbox.

Engineering post-mortems, mathematics, and short fiction, in English and Bengali. Infrequent by design: an email only when there is something new worth reading, never on a schedule. One click to leave, any time.

Double opt-in: you'll get one email to confirm, and nothing else until you do.