Overview
In this project, I built a Mini Virtual Private Cloud (VPC) system on Linux using nothing but Python and native networking tools.
It mimics real AWS networking — with public/private subnets, NAT, VPC peering, and firewall policies — but all runs locally.
This setup is perfect for DevOps learners and cloud enthusiasts who want to see how networks actually work behind the scenes.
Bridge (br0) → acts like your VPC switch
Namespaces → represent isolated networks
veth pairs → connect subnets to bridge
iptables NAT → allows outbound access only from the public subnet
Step 1: Setup
make setup
Step 2: Create the VPC
sudo python3 vpcctl.py create-vpc vpc1 10.10.0.0/16 --public-interface wlp2s0
This creates a virtual private cloud (VPC) simulation with the name vpc1 and a designated IP address range, linked to your actual public network interface.
10.10.0.0/16: This is the IP address range (specifically, a CIDR block) that the VPC will use for its internal network. The /16 denotes the specific size of the network, allowing for over 65,000 internal IP addresses within the VPC.
--public-interface wlp2s0: This flag tells the script to connect the simulated VPC to your actual physical network interface named wlp2s0(your system can have a different interface, run this command to see yours: ip addr show or ifconfig). This allows the resources inside your simulated VPC to communicate with the outside world (e.g., the internet) via your computer's real connection.
Step 3: Add Subnets
sudo python3 vpcctl.py add-subnet vpc1 public --type public --base-cidr 10.10.0.0/16
sudo python3 vpcctl.py add-subnet vpc1 private --type private --base-cidr 10.10.0.0/16
Creates:
vpc1-public → 10.10.1.0/24 (Internet access)
vpc1-private → 10.10.2.0/24 (Internal only)
Step 4: Deploy Demo Applications
Run a web app in the public subnet
sudo ip netns exec vpc1-public python3 -m http.server 80
From your host:
curl 10.10.1.2:80
You should see the directory listing
Run a web app in the private subnet
sudo ip netns exec vpc1-private python3 -m http.server 80
From host:
curl 10.10.2.2:80
You’ll get no response — because private subnets aren’t exposed externally.
Step 5: Validate Connectivity
Communication within the same VPC
sudo ip netns exec vpc1-private ping -c 3 10.10.1.2
Works (internal VPC communication).
Internet access from public subnet
sudo ip netns exec vpc1-public ping -c 3 8.8.8.8
Works via NAT.
Internet access from private subnet
sudo ip netns exec vpc1-private ping -c 2 8.8.8.8
Blocked — no default route to internet.
Step 6: Test Multiple VPCs and Peering
Create two VPCs
sudo python3 vpcctl.py create-vpc vpc2 10.20.0.0/16 --public-interface wlp2s0
sudo python3 vpcctl.py create-vpc vpc3 10.30.0.0/16 --public-interface wlp2s0
Add subnets to VPC2 and VPC3
# PUBLIC SUBNET on vpc2
sudo python3 vpcctl.py add-subnet vpc2 public --type public --base-cidr 10.20.0.0/16
# PRIVATE SUBNET on vpc2
sudo python3 vpcctl.py add-subnet vpc2 private --type private --base-cidr 10.20.0.0/16
# PUBLIC SUBNET on vpc3
sudo python3 vpcctl.py add-subnet vpc3 public --type public --base-cidr 10.30.0.0/16
# PRIVATE SUBNET on vpc3
sudo python3 vpcctl.py add-subnet vpc3 private --type private --base-cidr 10.30.0.0/16
Check isolation
sudo ip netns exec vpc1-public ping -c 2 10.20.1.2
Blocked — fully isolated by default.
Peer them
sudo python3 vpcctl.py peer-vpc vpc1 vpc2
Now ping again:
sudo ip netns exec vpc1-public ping -c 2 10.20.1.2
Works (controlled communication after peering).
Step 7: Apply Security Policies (Firewall)
sudo python3 vpcctl.py apply-policies vpc2 --policies policies.json
Policies.json:
[
{
"subnet": "10.20.2.0/24",
"ingress": [
{"port": 80, "protocol": "tcp", "action": "allow"},
{"port": 22, "protocol": "tcp", "action": "deny"},
{"port": 443, "protocol": "tcp", "action": "allow"}
]
}
]
would automatically block SSH access while keeping web traffic open.
Test policies:
Start a simple HTTP server on port 80 in the target namespace (vpc2)
sudo ip netns exec vpc2-public python3 -m http.server 80
Test from the source namespace using nc:
sudo ip netns exec vpc2-private nc -vz 10.20.1.2 80
Step 8: Cleanup
make cleanup
Or
./cleanup.sh
Removes:
All namespaces
The bridge
NAT/firewall rules
Ensures no residual configuration remains.
To run this with just one command:
make all
and clean up with
make cleanup

Top comments (0)