← lab.maninejad.com

☁ AWS Security Lab

VPC · EC2 · security groups · DNS
ec2-user@aws:~$ region us-east-1
> two-tier VPC build — public + private subnet, EC2, DNS routing to a live web server
> class exercise, deployed and documented end-to-end
Methodology
dnf install httpd -y && systemctl enable --now httpd
curl -I http://localhost
dig lab-exercise.yourdomain.com +short
Architecture — request flow

Every hop a browser request crosses before Apache on the public EC2 instance returns a response.

Browser sends request DNS (Route 53) domain → public IP Internet / ISP carries packet to AWS Internet gateway Public route table Security group EC2 (public) — Apache httpd, port 80
green = confirmed working  ·  amber = security boundary / gate
Architecture — full VPC

Both subnets, both EC2 instances, both security groups, and the still-pending NAT path.

Internet gateway VPC · 99.99.99.0/24 Private subnet 99.99.99.32/27 Security group EC2 (private) no direct internet route Outbound: pending NAT Public subnet 99.99.99.0/27 · rtb → IGW Security group EC2 (web server) httpd, port 80 NAT gateway not configured yet
green = internet-reachable  ·  red = isolated / pending  ·  amber = security group
Build log

Elastic IP + Internet Gateway

Associated an Elastic IP with the public EC2 so the DNS record wouldn't break on reboot, attached an IGW to the VPC, and added 0.0.0.0/0 → igw-xxxx to the public subnet's route table — the route, not the subnet name, is what actually makes it "public."

Inbound rules

Opened inbound 80 (HTTP) and 22 (SSH). SSH working while HTTP silently failed was the debugging signal — classic sign of a security group only allowing port 22.

Amazon Linux, not Ubuntu

The instance prompt (ec2-user@ip-...) revealed Amazon Linux, so apt failed outright. Installed Apache via dnf instead.

sudo dnf install httpd -y
sudo systemctl start httpd
sudo systemctl enable httpd
curl http://localhost

Route 53 A record

Pointed a subdomain at the Elastic IP and verified propagation before testing in a browser.

dig lab-exercise.yourdomain.com +short

Private IP vs. 0.0.0.0/0

These are unrelated. The instance's private IP (e.g. 99.99.99.28) comes from the subnet CIDR and is always assigned. 0.0.0.0/0 is never assigned to anything — it's route-table shorthand for "any destination," used only to point default traffic at the IGW or NAT gateway.

NAT gateway not yet configured

The private EC2 currently has zero outbound internet access — deferred intentionally to keep the class exercise scoped to the public-side path first.

Client deployment — hybrid AD / DR architecture

A related build: SVR1 onsite as the primary domain controller (AD DS + DNS), an AWS EC2 instance held in reserve purely as a disaster-recovery target with no public IP, VLAN segmentation, and a non-overlapping private addressing scheme so the site-to-site VPN can route between sites without ambiguity.

Onsite — trusted LAN Firewall / NAT / DHCP WAN: public IP / DDNS · blocks unsolicited inbound Managed switch (VLAN trunk) VLAN 10 — Servers 10.10.10.0/24 SVR1 — PRIMARY AD DS + DNS · .10 NAS · .20 SIEM (Wazuh) · .30 VLAN 20 — Users 10.10.20.0/24 2 Manager PCs OU: Managers 18 Staff PCs OU: Staff · DHCP pool All 20 PCs receive 10.10.10.10 as their DNS server via DHCP AWS — DR site VPC 10.20.0.0/16 EC2 SVR2 — DR Private only · .10 · no public IP Warm standby or cold backup — TBD with client Site-to-site VPN 10.10.0.0/16 ↔ 10.20.0.0/16
green = trusted LAN  ·  amber = AWS DR boundary  ·  red = VPN tunnel / no public IP
Addressing table
DeviceTypeRange / IPNote
Firewall WANPublic (static/DDNS)ISP-assignedOnly onsite device with a public address
SVR1 (AD DS + DNS)Private, static10.10.10.10Primary domain controller
NASPrivate, static10.10.10.20File shares + local backup target
SIEM (Wazuh)Private, static10.10.10.30Ingests AD, firewall & EC2 logs over VPN
2 Manager PCsPrivate, DHCP10.10.20.xOU: Managers — elevated share access
18 Staff PCsPrivate, DHCP10.10.20.xOU: Staff — standard restrictions
AWS VPN endpointPublicAWS-assignedTunnel termination only
AWS EC2 (SVR2)Private only10.20.1.10No public IP — DR target, VPN-reachable only

Why the ranges can't overlap

Onsite (10.10.0.0/16) and the AWS VPC (10.20.0.0/16) must use non-overlapping ranges — otherwise the VPN can't determine which side a given private address belongs to. It's also why SVR2 gets no public IP at all: since it isn't serving anything to the internet in this DR design, removing the public IP means it simply can't be scanned or attacked from outside.

EC2 runs 24/7, replicates continuously — fast failover, higher cost.

EC2 off/minimal, rebuilt from backups on demand — cheaper, slower RTO.

Current status

Public-side path fully working end to end (DNS → IGW → EC2 → httpd). NAT gateway and full DR replication for the client build remain open items.