Dual-Hop VPN with Terraform and V2Ray
A self-hosted VPN with a relay hop and an exit hop in two AWS regions. One terraform apply stands it all up.
Built ahead of a trip to a country where I knew I would run into network restrictions, as an alternative to trusting a commercial VPN. Traffic flows through two hops: a relay node in one AWS region takes in the encrypted traffic and hands it off to an exit node in a different region, the one that actually talks to the open internet. From the outside, the relay looks like an ordinary HTTPS site serving static content, so there is nothing obvious to fingerprint or block. A single `terraform apply` provisions both EC2 instances and handles TLS certificates via a Cloudflare DNS challenge. It also drops a ready-to-import client config onto your machine, and tearing everything down is just as quick. A small Python CLI generates a VMess URI and QR code so a phone client can be set up in about ten seconds.
Challenges
- Making the relay indistinguishable from an ordinary HTTPS static site to avoid fingerprinting
- Automating TLS issuance across two regions via a Cloudflare DNS challenge
- Keeping the entire stack to a single one-command deploy and teardown
Outcomes
- One-command deploy: a single terraform apply provisions both nodes and a ready-to-import client config
- Python CLI generates a VMess URI and QR code for phone setup in about ten seconds
- Open-sourced on GitHub after months of daily personal use