Every hop a browser request crosses before Apache on the public EC2 instance returns a response.
green = confirmed working · amber = security boundary / gate
Architecture — full VPC
Both subnets, both EC2 instances, both security groups, and the still-pending NAT path.
green = internet-reachable · red = isolated / pending · amber = security group
Build log
DoneNetworking
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."
DoneSecurity group
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.
NoteOS mismatch
Amazon Linux, not Ubuntu
The instance prompt (ec2-user@ip-...) revealed Amazon Linux, so apt failed outright. Installed Apache via dnf instead.
Pointed a subdomain at the Elastic IP and verified propagation before testing in a browser.
dig lab-exercise.yourdomain.com +short
Concept check
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.
PendingPrivate subnet
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.
green = trusted LAN · amber = AWS DR boundary · red = VPN tunnel / no public IP
Addressing table
Device
Type
Range / IP
Note
Firewall WAN
Public (static/DDNS)
ISP-assigned
Only onsite device with a public address
SVR1 (AD DS + DNS)
Private, static
10.10.10.10
Primary domain controller
NAS
Private, static
10.10.10.20
File shares + local backup target
SIEM (Wazuh)
Private, static
10.10.10.30
Ingests AD, firewall & EC2 logs over VPN
2 Manager PCs
Private, DHCP
10.10.20.x
OU: Managers — elevated share access
18 Staff PCs
Private, DHCP
10.10.20.x
OU: Staff — standard restrictions
AWS VPN endpoint
Public
AWS-assigned
Tunnel termination only
AWS EC2 (SVR2)
Private only
10.20.1.10
No public IP — DR target, VPN-reachable only
Concept check
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.
Warm standby
EC2 runs 24/7, replicates continuously — fast failover, higher cost.
Cold backup
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.