A beginner’s guide to understanding AWS VPCs by building one with ip, iptables, and network namespaces
By Osasehi Iyamu - DevOps Intern, HNG Stage 4
🔍 What Is a VPC?
If you’ve used AWS or Azure, you’ve probably heard of a VPC - Virtual Private Cloud.
It’s like a private network in the cloud where you can run servers, connect subnets, control traffic with firewalls, and give some machines internet access while keeping others isolated.
But how does it actually work under the hood?
I set out to find out - and built my own Linux-based VPC using only native Linux tools, no Docker, no cloud, no magic.
Here’s how I did it - and how you can too.
🛠️ What I Built
I created a CLI tool called vpcctl that lets you:
- ✅ Create multiple isolated VPCs
- ✅ Add public and private subnets
- ✅ Enable NAT so public subnets can reach the internet
- ✅ Block traffic with firewall rules (like AWS Security Groups)
- ✅ Connect VPCs with peering (optional)
- ✅ Clean up everything cleanly
All using only:
- ip netns (network namespaces)
- veth pairs
- Linux bridges
- iptables
- bash
No third-party tools. Just pure Linux networking.
🏗️ Architecture: How It Works
Here’s what happens when you run:
sudo ./vpcctl create --name prod --internet-interface eth0
A Linux bridge (br-prod) is created → acts as the VPC router
-
Two network namespaces are created:
- prod-pub → public subnet (10.10.1.0/24)
- prod-priv → private subnet (10.10.2.0/24)
veth pairs connect each namespace to the bridge
IP addresses and routes are assigned
NAT (MASQUERADE) is enabled on eth0 → lets prod-pub access the internet
Firewall rules are applied from firewall.json:
{
"vpc": "prod",
"subnet_type": "public",
"ingress": [
{"port": 8000, "protocol": "tcp", "action": "allow"},
{"port": 22, "protocol": "tcp", "action": "deny"}
]
}
Now, prod-pub can:
- ✅ Reach the internet (
curl ifconfig.me) - ✅ Be reached on port 8000 (e.g., a web server)
- ❌ Be blocked on port 22 (SSH)
And prod-priv:
- ✅ Can reach prod-pub (same VPC)
- ❌ Cannot reach the internet
- ❌ Cannot reach any other VPC (like
dev)
🧪 Testing It Out
✅ 1. Deploy a Web Server
#Start a simple server in the public subnet
sudo ip netns exec prod-pub python3 -m http.server 8000 --bind 0.0.0.0``
✅ 2. Access It from Private Subnet (Same VPC)
bash
sudo ip netns exec prod-priv curl -s http://10.10.1.2:8000 | head -1
Output: Directory listing for /...
✅ Works! Subnets inside the same VPC can talk.
❌ 3. Block SSH (Firewall Test)
bash
sudo ip netns exec prod-priv nc -zv 10.10.1.2 22
Output: nc: connect to 10.10.1.2 port 22 (tcp) failed: Connection timed out
✅Firewall blocked it!
❌ 4. Try from Another VPC (Isolation)
bash
sudo ./vpcctl create --name dev --internet-interface eth0
sudo ip netns exec dev-pub curl -s http://10.10.1.2:8000
Output: (no response - timeout)
✅ Isolation works! Different VPCs can’t talk - unless you peer them.
✅ 5. Internet Access from Public Subnet
bash
sudo ip netns exec prod-pub curl -s ifconfig.me
Output: 102.89.85.251 (your public IP!)
✅ NAT is working!
✅ 6. Cleanup
bash
sudo ./vpcctl delete --name prod
sudo ./vpcctl delete --name dev
✅ All namespaces, bridges, iptables rules - one. No leftovers.
🧠 Why This Matters
This isn’t just a fun project - it’s real DevOps knowledge.
- AWS VPCs use exactly these same primitives under the hood.
- Kubernetes CNI plugins? Same idea.
- Understanding this makes you a better cloud engineer.
You don’t need to know Terraform to understand networking.
You just need to understand Linux.
📁 GitHub Repo
Check out the full code: https://github.com/Sehiconcept/hng-stage4-devops-vpc
Includes:
- vpcctl - the CLI tool
- firewall.json - security group rules
- README.md - usage guide
💡 Final Thoughts
Stage 4 of HNG’s DevOps track forced me to think like a cloud provider.
I didn’t just learn commands - I learned how the internet is built, one namespace, one bridge, one iptables rule at a time.
If you’re a junior DevOps engineer don’t skip the basics.
Build your own VPC.
You’ll be amazed at what you learn.
🙌 Thanks to HNG for this incredible challenge.
👋 You got this, cool keeds!
Top comments (0)