DEV Community

James Okonkwo
James Okonkwo

Posted on

Building Your Own Virtual Private Cloud (VPC) on Linux: A Complete Guide

Introduction

Have you ever wondered how cloud providers like AWS, Azure, and Google Cloud implement their Virtual Private Cloud (VPC) services? In this comprehensive guide, I'll walk you through building your own VPC implementation from scratch using Linux networking primitives. By the end of this tutorial, you'll have a deep understanding of how network isolation, routing, and security work at the infrastructure level.

This project recreates the fundamental concepts of cloud VPCs using only Linux native tools like network namespaces, veth pairs, bridges, routing tables, and iptables. No third-party virtualization software required – just the power of the Linux kernel.

What You'll Learn

Throughout this guide, you'll master:

  • Creating isolated virtual networks using Linux network namespaces
  • Implementing subnet routing with Linux bridges
  • Setting up NAT gateways for internet access
  • Enforcing network isolation between VPCs
  • Implementing VPC peering for controlled cross-network communication
  • Applying firewall rules to simulate security groups
  • Building a complete CLI tool for VPC management

Project Overview

Our VPCctl system provides a command-line interface for managing virtual networks that behave just like cloud VPCs. The architecture includes:

  • VPCs: Isolated virtual networks with dedicated IP address ranges
  • Subnets: Network segments within VPCs, implemented as network namespaces
  • Routing: Linux bridges connecting subnets within VPCs
  • NAT Gateway: Internet access for public subnets using iptables
  • VPC Peering: Controlled communication between different VPCs
  • Firewall Rules: Security policies using iptables for traffic filtering

Architecture Diagram

Internet
    |
    | (NAT Gateway)
    |
┌───┴────────────────┐         ┌─────────────────────┐
│      VPC1          │ Peering │       VPC2          │
│   10.1.0.0/16      │◄────────┤   10.2.0.0/16       │
│                    │         │                     │
│  ┌──────────────┐  │         │  ┌──────────────┐   │
│  │ Public       │  │         │  │ Public       │   │
│  │ 10.1.1.0/24  │  │         │  │ 10.2.1.0/24  │   │
│  │ (Namespace)  │  │         │  │ (Namespace)  │   │
│  └──────────────┘  │         │  └──────────────┘   │
│         │           │         │         │           │
│  ┌──────┴──────┐   │         │  ┌──────┴──────┐    │
│  │   Bridge    │   │         │  │   Bridge    │    │
│  │ vpc1-br     │   │         │  │ vpc2-br     │    │
│  └──────┬──────┘   │         │  └──────┬──────┘    │
│         │           │         │         │           │
│  ┌──────┴──────┐   │         │  ┌──────┴──────┐    │
│  │ Private     │   │         │  │ Private     │    │
│  │ 10.1.2.0/24 │   │         │  │ 10.2.2.0/24 │    │
│  │ (Namespace) │   │         │  │ (Namespace) │    │
│  └─────────────┘   │         │  └─────────────┘    │
└────────────────────┘         └─────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Prerequisites

Before starting, ensure you have:

  • A Linux system with root/sudo access
  • Basic understanding of networking concepts (IP addresses, subnets, routing)
  • Familiarity with command-line operations
  • The following tools installed:
    • ip (iproute2 package)
    • iptables
    • jq for JSON processing
    • bash shell

Getting Started

Step 1: Clone the Repository

First, clone the project repository from GitHub:

git clone https://github.com/james-eo/devops-stage4-linux-vpcs.git
cd devops-stage4-linux-vpcs
Enter fullscreen mode Exit fullscreen mode

Step 2: Project Structure

The project is organized into several components:

├── vpcctl.sh           # Main CLI script
├── config/
│   └── vpcctl.conf     # Configuration file
├── lib/
│   ├── common.sh       # Shared utility functions
│   ├── networking.sh   # Network operations
│   └── vpc_mgmt.sh     # VPC management functions
├── logs/               # Operation logs
├── state/              # JSON state files for persistence
├── demo.sh            # Complete demonstration script
├── cleanup-all.sh     # System cleanup script
└── test-*.sh          # Individual test scripts
Enter fullscreen mode Exit fullscreen mode

Step 3: Understanding the CLI Tool

The vpcctl.sh script provides all the functionality needed to manage your virtual infrastructure. Let's explore the main commands:

# Show available commands
sudo ./vpcctl.sh --help
Enter fullscreen mode Exit fullscreen mode

Implementation Walkthrough

Creating Your First VPC

Let's start by creating a VPC with a dedicated IP address range:

# Create VPC1 with CIDR 10.1.0.0/16
sudo ./vpcctl.sh create-vpc --name vpc1 --cidr 10.1.0.0/16
Enter fullscreen mode Exit fullscreen mode

This command creates:

  • A Linux bridge named vpc1-br that acts as the VPC router
  • A gateway IP address (10.1.0.1) assigned to the bridge
  • A JSON state file to persist VPC configuration

Adding Subnets to Your VPC

Subnets in our implementation are Linux network namespaces with dedicated IP ranges:

# Create a public subnet (with internet access)
sudo ./vpcctl.sh create-subnet --vpc vpc1 --name public --cidr 10.1.1.0/24 --type public

# Create a private subnet (internal only)
sudo ./vpcctl.sh create-subnet --vpc vpc1 --name private --cidr 10.1.2.0/24 --type private
Enter fullscreen mode Exit fullscreen mode

Each subnet creation:

  1. Creates a network namespace (e.g., vpc1-public)
  2. Sets up a veth pair to connect the namespace to the VPC bridge
  3. Configures IP addresses and routing within the namespace
  4. Enables NAT for public subnets to provide internet access

Deploying Applications

Now let's deploy web applications to test our network setup:

# Deploy nginx web server in the public subnet
sudo ./vpcctl.sh deploy-workload --vpc vpc1 --subnet public --type nginx --name web1 --port 80

# Deploy Python HTTP server in VPC2's public subnet (after creating VPC2)
sudo ./vpcctl.sh create-vpc --name vpc2 --cidr 10.2.0.0/16
sudo ./vpcctl.sh create-subnet --vpc vpc2 --name public --cidr 10.2.1.0/24 --type public
sudo ./vpcctl.sh deploy-workload --vpc vpc2 --subnet public --type python --name web2 --port 8080
Enter fullscreen mode Exit fullscreen mode

Testing Network Isolation

One of the key features of VPCs is network isolation. Let's verify that different VPCs cannot communicate by default:

# This should fail - VPCs are isolated by default
sudo ./vpcctl.sh exec-in-subnet --vpc vpc1 --subnet public --command "curl --connect-timeout 3 http://10.2.1.10:8080"
Enter fullscreen mode Exit fullscreen mode

Implementing VPC Peering

To enable controlled communication between VPCs, we can establish peering connections:

# Create peering connection
sudo ./vpcctl.sh peer-vpcs --vpc1 vpc1 --vpc2 vpc2

# Now cross-VPC communication should work
sudo ./vpcctl.sh exec-in-subnet --vpc vpc1 --subnet public --command "curl http://10.2.1.10:8080"
Enter fullscreen mode Exit fullscreen mode

The peering implementation:

  1. Creates veth pairs connecting the VPC bridges
  2. Adds routing entries in subnet namespaces for cross-VPC traffic
  3. Maintains state information for proper cleanup

Applying Security Rules

Security groups are implemented using iptables rules within network namespaces:

# Create firewall rules JSON file
cat > /tmp/firewall-rules.json << 'EOF'
{
  "subnet": "10.1.1.0/24",
  "ingress": [
    {
      "port": 80,
      "protocol": "tcp",
      "action": "allow",
      "source": "0.0.0.0/0"
    },
    {
      "port": 8080,
      "protocol": "tcp",
      "action": "deny",
      "source": "0.0.0.0/0"
    }
  ]
}
EOF

# Apply the rules to VPC1
sudo ./vpcctl.sh apply-rules --rules-file /tmp/firewall-rules.json --vpc vpc1
Enter fullscreen mode Exit fullscreen mode

Key Technical Concepts

Network Namespaces

Network namespaces provide complete network isolation, giving each subnet its own network stack including interfaces, routing tables, and firewall rules. This is the foundation of container networking and our VPC implementation.

Linux Bridges

Bridges operate at Layer 2 (data link layer) and function as virtual switches within our VPCs. They learn MAC addresses and forward frames between connected interfaces, enabling communication between subnets.

Veth Pairs

Virtual Ethernet pairs create point-to-point connections between network namespaces and bridges. Think of them as virtual network cables connecting different network segments.

IPTables NAT

Network Address Translation (NAT) enables private subnet addresses to access the internet by translating private IPs to public IPs at the gateway level.

Testing and Validation

Running the Complete Demo

The project includes a comprehensive demo script that showcases all features:

# Run the automated demo
sudo ./demo.sh
Enter fullscreen mode Exit fullscreen mode

This script demonstrates:

  • VPC and subnet creation
  • Workload deployment and accessibility
  • Network isolation between VPCs
  • NAT gateway functionality
  • VPC peering setup and testing
  • Firewall rule enforcement
  • Complete cleanup

Individual Test Scripts

For focused testing, use the individual test scripts:

# Test VPC peering functionality
sudo ./test-peering.sh

# Test network isolation
sudo ./test-isolation.sh
Enter fullscreen mode Exit fullscreen mode

Manual Validation Commands

You can also perform manual testing:

# List all VPCs
sudo ./vpcctl.sh list-vpcs

# List subnets in a specific VPC
sudo ./vpcctl.sh list-subnets --vpc vpc1

# List running workloads
sudo ./vpcctl.sh list-workloads

# Execute commands within subnet namespaces
sudo ./vpcctl.sh exec-in-subnet --vpc vpc1 --subnet public --command "ip route"
Enter fullscreen mode Exit fullscreen mode

Troubleshooting

Common Issues and Solutions

Problem: "File exists" error when creating interfaces
Solution: Run the cleanup script first: sudo ./cleanup-all.sh

Problem: Cannot access deployed applications
Solution: Check if workloads are running: sudo ./vpcctl.sh list-workloads

Problem: Cross-VPC communication not working after peering
Solution: Verify routing tables in namespaces: sudo ip netns exec vpc1-public ip route

Problem: Internet access not working from public subnets
Solution: Check NAT rules: sudo iptables -t nat -L -n -v

Cleanup and Resource Management

Always clean up resources after testing:

# Complete system cleanup
sudo ./cleanup-all.sh

# Or remove specific VPCs
sudo ./vpcctl.sh delete-vpc --name vpc1
Enter fullscreen mode Exit fullscreen mode

The cleanup process removes:

  • All network namespaces
  • Bridge interfaces
  • Veth pairs
  • IPTables rules
  • State files

Advanced Features

State Management

All VPC configurations are persisted in JSON format under the state/ directory. This enables:

  • System recovery after restarts
  • Configuration inspection and debugging
  • Integration with other tools

Modular Architecture

The codebase is organized into modules:

  • lib/common.sh: Logging, validation, and shared utilities
  • lib/networking.sh: Low-level network operations
  • lib/vpc_mgmt.sh: High-level VPC management functions

Logging and Monitoring

All operations are logged to logs/vpcctl.log with detailed information about:

  • Resource creation and deletion
  • Network configuration changes
  • Error conditions and debugging information

Real-World Applications

This VPC implementation demonstrates concepts used in:

  • Container orchestration platforms (Kubernetes networking)
  • Cloud provider VPC services (AWS VPC, GCP VPC, Azure VNet)
  • Software-defined networking (SDN) solutions
  • Network function virtualization (NFV) platforms

Conclusion

Building a VPC from scratch provides invaluable insights into modern networking infrastructure. You've learned how cloud providers implement network isolation, routing, and security at the kernel level using standard Linux tools.

The skills demonstrated in this project directly apply to:

  • DevOps and infrastructure automation
  • Container and Kubernetes networking
  • Cloud architecture and networking
  • Network security and isolation

This implementation serves as a foundation for understanding more complex networking concepts and can be extended with additional features like load balancing, DNS services, or integration with container orchestration platforms.

Source Code and Resources

Next Steps

To extend this project, consider implementing:

  • Load balancers for high availability
  • DNS services for service discovery
  • Monitoring and metrics collection
  • Integration with container runtime
  • Multi-host networking capabilities
  • Advanced routing protocols

The foundation you've built provides a solid platform for exploring these advanced networking concepts and building production-ready infrastructure automation tools.


This project was developed as part of the HNG DevOps internship program, demonstrating practical skills in Linux networking, infrastructure automation, and systems programming.

Top comments (0)