The lab finally does something. Turn on DHCP and DNS, lock down the firewall, install web stacks, promote a Domain Controller, and prove it all works end-to-end. ~9–13 hours · 5 stages.
By the end of this phase, you'll have running web pages, a working database, an Active Directory domain, and a firewall enforcing defense-in-depth. From the Linux Desktop you'll open Firefox, hit a real internal site served by NGINX or Apache, and see a database connection succeed. That's the lab. That's the proof.
Each stage has a dedicated detailed page — click the green button on a stage to open the full hands-on walkthrough.
Turn on pfSense's DHCP server for both internal subnets, configure Unbound as the DNS resolver with DNSSEC enabled, and verify Automatic Outbound NAT is rewriting internal traffic. After this stage, every VM gets an IP automatically and can resolve names.
172.16.0.100–.200192.168.0.100–.200Apply a defense-in-depth ruleset on pfSense's LAN interface: only allow what's needed, deny everything else. This is the single best Week 3 security deliverable in the lab.
Aliases needed first: OUTBOUND_WEB (ports 80, 443, 53, 123) · RFC1918 (10.0/8, 172.16/12, 192.168/16) · DMZ_NET (172.16.0.0/24) · LAN_NET (192.168.0.0/24).
| # | Action | Source → Dest | Description |
|---|---|---|---|
| 1 | PASS | LAN → This Firewall (ICMP) | Ping gateway only |
| 2 | PASS | LAN → This Firewall (UDP/123) | NTP local |
| 3 | PASS | LAN → This Firewall (UDP/53) | DNS local |
| 4 | BLOCK | LAN → This Firewall (any) | No mgmt |
| 5 | BLOCK | LAN → DMZ_NET (any) | No DMZ pivot |
| 6 | BLOCK | LAN → RFC1918 (any) | No lateral move |
| 7 | PASS | LAN → OUTBOUND_WEB (TCP/UDP) | Web/DNS/NTP only |
| 8 | PASS | LAN → port 5985–5986 (TCP) | WinRM |
| 9 | PASS | LAN → port 445 (TCP) | SMB |
On LinuxServer (192.168.0.20) install MariaDB once, then NGINX (port 80) and/or Apache (port 8080) on top. Both stacks share the same database — you can demo two web servers, one DB, side-by-side.
mysql_secure_installation + capstone_db + admin userinfo.php + dbtest.php on both stacksInstall the AD-DS role on Windows Server, then promote the box to a Domain Controller. Creates a new Windows forest (capstone.local or your choice) with WinSrv as the boss of the network.
Three prereqs to check first:
192.168.0.15)Then: Server Manager → Add Roles and Features → ✓ Active Directory Domain Services → Install. After install, click the yellow flag → Promote to domain controller → Add new forest → name it capstone.local → Next through wizard. Server reboots itself when done.
home.arpa (RFC-reserved). Recommended: capstone.local (NetBIOS auto-fills as CAPSTONE). Renaming an AD domain after the fact is painful.From each VM, run a battery of tests and screenshot the results. This is your lab-report evidence. Every screenshot has a slot in the verification page — drop the file in and the page picks it up.
| From | Test | Expected result |
|---|---|---|
| Linux Desktop (Firefox) | http://192.168.0.20/ | NGINX welcome page |
| Linux Desktop | http://192.168.0.20:8080/ | Apache welcome page |
| Linux Desktop | http://192.168.0.20/dbtest.php | "✅ LEMP — connected" |
| Linux Desktop | https://www.google.com/ | Loads (proves NAT) |
| WinSrv (cmd) | nslookup linuxserver.capstone.local | Resolves to .20 |
| WinSrv (cmd) | ping 192.168.0.20 | 0% loss |
| Jumpbox (SSH) | curl http://192.168.0.20/ | HTML returned |
If every box below is checked, you've built the entire lab. Ready for the demo.
curl https://google.com, blocks ping 1.1.1.1 by design)capstone.local created · DC reachable via nltest /dsgetdc:capstone.localPhase 3 is the end of the build. The remaining work is presentation and stretch goals.
realm join · internal Certificate Authority for HTTPS everywhere.