★ PHASE 3 of 3

Services + Verification

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.

Before you start: Phase 1 (Proxmox installed) and Phase 2 (5 VMs running with static IPs, pfSense routing) must be complete. If you can ping pfSense from each LAN VM and reach the internet via curl, you're ready.

5Five stages, in this order

Each stage has a dedicated detailed page — click the green button on a stage to open the full hands-on walkthrough.

Stage 3.1 — pfSense DHCP + DNS Resolver ~30 min

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.

  • Services → DHCP Server → DMZ tab → enable + scope 172.16.0.100–.200
  • Services → DHCP Server → LAN tab → enable + scope 192.168.0.100–.200
  • Services → DNS Resolver → enable + listen on DMZ+LAN, egress WAN, DNSSEC ✓
  • Firewall → NAT → Outbound → Mode = Automatic

Stage 3.2 — Hardened LAN Firewall (9 rules) ~45 min

Apply 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).

#ActionSource → DestDescription
1PASSLAN → This Firewall (ICMP)Ping gateway only
2PASSLAN → This Firewall (UDP/123)NTP local
3PASSLAN → This Firewall (UDP/53)DNS local
4BLOCKLAN → This Firewall (any)No mgmt
5BLOCKLAN → DMZ_NET (any)No DMZ pivot
6BLOCKLAN → RFC1918 (any)No lateral move
7PASSLAN → OUTBOUND_WEB (TCP/UDP)Web/DNS/NTP only
8PASSLAN → port 5985–5986 (TCP)WinRM
9PASSLAN → port 445 (TCP)SMB

Stage 3.3 — Install LAMP and/or LEMP web stack ~60 min

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.

  • MariaDB (shared backend) — mysql_secure_installation + capstone_db + admin user
  • LEMP (port 80) — NGINX + PHP-FPM + Unix socket FastCGI
  • LAMP (port 8080) — Apache + libapache2-mod-php (Directory inside VirtualHost)
  • Test pages: info.php + dbtest.php on both stacks
  • UFW: allow 22, 80, 443, 8080
Why both stacks side-by-side? Demonstrates same protocol, different implementations (mod_php vs PHP-FPM), port multiplexing, and shared backing store. Strong Week 3 talking points.

Stage 3.4 — Promote WinSrv to Active Directory Domain Controller ~60 min

Install 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:

  • WinSrv on a static IP (already done in Phase 2 — 192.168.0.15)
  • Time zone correct (Settings → Time & language) — Kerberos requires accurate clocks
  • All pending Windows Updates installed — DC promotion fails on certain unpatched builds

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.

⚠ Pick a domain name carefully. Don't reuse home.arpa (RFC-reserved). Recommended: capstone.local (NetBIOS auto-fills as CAPSTONE). Renaming an AD domain after the fact is painful.

Stage 3.5 — End-to-end verification ~45 min

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.

FromTestExpected result
Linux Desktop (Firefox)http://192.168.0.20/NGINX welcome page
Linux Desktophttp://192.168.0.20:8080/Apache welcome page
Linux Desktophttp://192.168.0.20/dbtest.php"✅ LEMP — connected"
Linux Desktophttps://www.google.com/Loads (proves NAT)
WinSrv (cmd)nslookup linuxserver.capstone.localResolves to .20
WinSrv (cmd)ping 192.168.0.200% loss
Jumpbox (SSH)curl http://192.168.0.20/HTML returned

Phase 3 done — final lab state

If every box below is checked, you've built the entire lab. Ready for the demo.

Where to go from here

Phase 3 is the end of the build. The remaining work is presentation and stretch goals.

Demo prep: open the demo deck · rehearse end-to-end once · verify screenshots in verification · practice the 15-minute walkthrough.
Stretch goals (Week 3+): Snort or Suricata IDS in pfSense · Proxmox nightly backups · OpenVPN or WireGuard for remote access · Wazuh / Prometheus monitoring · domain-join LinuxServer via realm join · internal Certificate Authority for HTTPS everywhere.