Skip to main content

Command Palette

Search for a command to run...

Building Your Own Virtual Private Cloud (VPC) on Linux

Published
6 min read
Building Your Own Virtual Private Cloud (VPC) on Linux
N
DevOps and Cloud Engineer sharing hands-on projects, real-world labs, and lessons from building and automating cloud infrastructure.

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:

  1. Network namespaces provide kernel-level network isolation

  2. veth pairs act as virtual cables connecting namespaces

  3. Linux bridges function as virtual switches

  4. iptables can perform NAT and filtering

  5. 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

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