Building Your Own Virtual Private Cloud (VPC) on Linux

Ever wondered how cloud providers like AWS create isolated networks for their customers? In this tutorial, I'll show you how to recreate the core functionality of AWS VPC using only Linux networking primitives.
This is the same technology that powers Docker, Kubernetes, and AWS VPC!
What You'll Learn
- Network namespace isolation
- Virtual networking with veth pairs
- Linux bridge routing
- NAT gateway implementation
- VPC-level isolation
Prerequisites
Before starting, you need:
- Linux machine (Ubuntu 20.04+ or WSL2)
- Root/sudo access
- Basic networking knowledge
- 1-2 hours of time
Understanding the Core Concepts
What is a VPC?
A Virtual Private Cloud (VPC) is an isolated section of a cloud provider's network where you can launch resources. Think of it like having your own private data center in the cloud.
Key components:
VPC: The overall isolated network (e.g., 10.0.0.0/16)
Subnets: Subdivisions within the VPC (e.g., 10.0.1.0/24, 10.0.2.0/24)
Router: Connects subnets together
NAT Gateway: Allows private resources to access the internet
Security Groups: Firewall rules controlling traffic
Linux Networking Primitives
Network Namespaces: A network namespace is an isolated copy of the network stack. Each namespace has its own:
Network interfaces
Routing tables
Firewall rules
Network sockets
This is what Docker uses to isolate containers!
veth Pairs: Virtual Ethernet devices that come in pairs - like a virtual network cable with two ends. Whatever goes in one end comes out the other.
Linux Bridge: A virtual network switch that connects multiple network interfaces together, allowing them to communicate.
iptables: The Linux firewall that can filter, modify, and route network packets. We'll use it for NAT and security rules.
Imagine an apartment building:
- The building = Your VPC
- Each apartment = A subnet
- The hallway = The router (Linux bridge)
- The front door = NAT gateway (for internet access)
- Locked doors = Isolation between apartments On Linux, we create this using:
- Network Namespaces = The apartments (isolated environments)
- veth pairs = Network cables connecting apartments to hallway
- Linux Bridge = The hallway (connects everything) - iptables = Door locks (firewall rules)
Step-by-Step Implementation
Step 1: Create Project Directorys: mkdir vpc-project
cd vpc-project

Step 2: Create the VPC CLI Tool
Create a file called `vpcctl


Key functions explained:
1. Creating a VPC:
def create_vpc(self, vpc_name, cidr_block):
# Create Linux bridge (VPC router)
self.run_cmd(f"ip link add br-{vpc_name} type bridge")
# Assign gateway IP (e.g., 10.0.0.1)
self.run_cmd(f"ip addr add {gateway_ip} dev br-{vpc_name}")
# Bring the bridge up
self.run_cmd(f"ip link set br-{vpc_name} up")
# Enable IP forwarding
self.run_cmd("sysctl -w net.ipv4.ip_forward=1")
2. Adding a Subnet:
def add_subnet(self, vpc_name, subnet_name, subnet_cidr, subnet_type):
# Create network namespace (isolated network)
self.run_cmd(f"ip netns add {namespace_name}")
# Create veth pair (virtual cable)
self.run_cmd(f"ip link add {veth_host} type veth peer name {veth_ns}")
# Connect to bridge
self.run_cmd(f"ip link set {veth_host} master {bridge_name}")
# Move other end into namespace
self.run_cmd(f"ip link set {veth_ns} netns {namespace_name}")
# Configure IP and routing
self.run_cmd(f"ip netns exec {namespace_name} ip addr add {ip} dev {veth_ns}") self.run_cmd(f"ip netns exec {namespace_name} ip route add default via {gateway}")
# Set up NAT if public subnet if subnet_type == "public":
self.run_cmd(f"iptables -t nat -A POSTROUTING -s {subnet_cidr} -o {internet_if} -j MASQUERADE")
Step 3: Make it Executable: chmod +x vpcctl

Important: If you're on WSL2 or have Docker installed, you need to disable bridge netfilter:
# Add this to your create_vpc function
self.run_cmd("modprobe br_netfilter", check=False, silent=True) self.run_cmd("sysctl -w net.bridge.bridge-nf-call-iptables=0", check=False) self.run_cmd("sysctl -w net.bridge.bridge-nf-call-ip6tables=0", check=False) self.run_cmd("sysctl -w net.bridge.bridge-nf-call-arptables=0", check=False)
Step 4: Create Your First VPC: sudo ./vpcctl create-vpc myvpc 10.0.0.0/16

What's happening here?
1. A bridge named br-myvpc is created
2. IP 10.0.0.1/16 is assigned as gateway 3. IP forwarding is enabled
Add public subnet (with internet access)
sudo ./vpcctl add-subnet myvpc web-subnet 10.0.1.0/24 --type public

Add private subnet (no internet)
sudo ./vpcctl add-subnet myvpc db-subnet 10.0.2.0/24 --type private

List your VPCs
sudo ./vpcctl list


The above command confirms that your VPC networking foundation is solid and ready for deploying applications or additional subnets.

the above also showed that the VPC network is stable and reliable also that the bridge to namespace connectivity is performant.

the above also confirms that the VPC has a full internet connectivity
destination: Google’s public DNS {8.8.8.8} and the result is successfully all 3 packets received.

the above shows that my deployed application A python HTTP server running in the public subnet
Apply Security Rules
Create a rules file web-rules.json:
json
{
"subnet": "10.0.1.0/24",
"ingress": [
{"port": 80, "protocol": "tcp", "action": "allow"},
{"port": 443, "protocol": "tcp", "action": "allow"},
{"port": 22, "protocol": "tcp", "action": "deny"}
]
}
Apply the rules:
sudo ./vpcctl apply-rules myvpc web-subnet web-rules.json

To make testing easier, I created automated test scripts.
1. Final Test Script (final-test.sh)
This script runs all validation tests automatically:
cat > final-test.sh <<'EOF'
#!/bin/bash
echo "=========================================="
echo "FINAL VPC PROJECT VALIDATION"
echo "=========================================="
PASS=0
FAIL=0
echo "TEST 1: Inter-subnet communication"
if sudo ip netns exec myvpc-web-subnet ping -c 2 -W 3 10.0.2.10 > /dev/null 2>&1; then
echo " ✓ PASS - Subnets communicate within VPC"
((PASS++))
else
echo " ✗ FAIL"
((FAIL++))
fi
echo ""
chmod +x final-test.sh

Run the tests:
sudo ./final-test.sh

I also created a Demo script [final-demo.sh] this script provides an intereactive demostration.
cat > final-demo.sh <<'EOF'
#!/bin/bash
echo "=========================================="
echo "VPC PROJECT DEMONSTRATION"
echo "=========================================="
echo ""
read -p "Press Enter to start..."
echo ""
echo "=== STEP 1: VPC Inventory ==="
sudo ./vpcctl list
echo ""
read -p "Press Enter to continue..."

Run the demo:
bash
sudo ./final-demo.sh
This script walks through each feature interactively, perfect for video recording

Cleanup
l also created a clean up that will delete all VPC namespace
sudo ./vpcctl delete-vpc myvpc
Complete System Cleanup
Create a cleanup script:
bash
#!/bin/bash
# Delete all VPC namespaces
for ns in $(ip netns list | grep "^vpc" | awk '{print $1}'); do
ip netns del "$ns"

Please NOTE Complete Code:
The full implementation is available on GitHub: https://github.com/Nweke-cloud/linux-vpc-implementation.git
Clone and run:
git clone https://github.com/Nweke-cloud/linux-vpc-implementation.git
Troubleshooting
First the namespace can’t reach the gateway so l made use of ns_ip = "10.0.1.10/16" to ensure namespace IPs use/16netmask not /24
Key Takeaways
What I learned:
Network namespaces provide kernel-level network isolation
veth pairs act as virtual cables connecting namespaces
Linux bridges function as virtual switches
iptables can perform NAT and filtering
WSL2 requires special handling for bridge netfilter
Real-world applications:
Container networking (Docker, Kubernetes)
Network function virtualization (NFV)
Development/testing environments
Understanding cloud networking internals
Resources
GitHub Repository: https://github.com/Nweke-cloud/linux-vpc-implementation.git
Linux Network Namespaces: https://man7.org/linux/man-pages/man8/ip-netns.8.html
iptables Tutorial: https://www.netfilter.org/documentation/
Conclusion
Building a VPC from scratch taught me how cloud providers implement network isolation and routing. The same primitives (namespaces, veth pairs, bridges) power Docker, Kubernetes, and other containerization platforms.
This project demonstrates that complex cloud features are built on simple Linux networking fundamentals. With just a few commands, you can create sophisticated network architecture
This project was completed as part of the HNG DevOps Internship. Learn more at https://hng.tech/internship



