Build in dependency order
The hypervisor came first, then routing, segmentation, remote access, identity services, and finally monitoring and automation.
HOME INFRASTRUCTURE · BUILD JOURNAL
This portfolio documents the lab in the order I built it. Each entry explains the goal, the configuration steps, how I tested the result, and what I learned when the first attempt did not work.
01 · OVERVIEW
The goal was not to collect unrelated virtual machines. It was to build a small environment where networking, identity, access, and administration depend on one another in realistic ways.
The hypervisor came first, then routing, segmentation, remote access, identity services, and finally monitoring and automation.
Management systems, lab services, the jumpbox, and personal home devices should not share unrestricted access.
Remote access begins with WireGuard. RDP and administrative web interfaces remain behind the firewall.
Handshake counters, port tests, DNS queries, packet captures, logs, and external scans show where a path succeeds or fails.
02 · ARCHITECTURE
The upstream router provides internet access and forwards only the WireGuard UDP service to pfSense. pfSense routes the internal lab networks and applies policy before traffic crosses a trust boundary.
Administrative interfaces such as Proxmox, pfSense management, and SSH.
Windows Server, domain services, DNS, Ubuntu systems, and test clients.
The single Windows system used as the remote administrative entry point.
03 · BUILD LOG
These are practical build notes, not universal production designs. The sequence and validation methods are the important parts; exact menus and addresses may vary.
FOUNDATION · COMPLETE
Turn one physical computer into the compute and networking foundation for the rest of the lab.
Enable Intel VT-x/VT-d or the equivalent virtualization and IOMMU options. Confirm the system boots from the installation media.
Select the target disk, set the administrative credentials, and assign a static management address that belongs to the current home subnet.
From another computer, browse to https://<proxmox-address>:8006 and sign in.
Confirm vmbr0 is attached to the physical NIC and contains the host address and default gateway. The bridge allows VMs to use the physical connection.
Upload the pfSense, Windows Server, and Ubuntu installation images. Reserve enough free storage for VM disks, snapshots, and future updates.
After initial setup, add a named user and grant only the Proxmox path and role required for normal VM administration.
ROUTING · COMPLETE
Move lab routing and firewall policy into a virtual firewall instead of placing every VM on the home LAN.
Add one bridge for each isolated segment. Internal-only bridges do not need a physical NIC attached.
Allocate approximately 2 vCPU, 2–4 GB RAM, and a small virtual disk. Mount the pfSense installer.
Attach one adapter to the upstream bridge for WAN and one adapter to each internal bridge for management, services, and jumpbox traffic.
Identify WAN and each internal adapter by MAC address, then assign clear interface names before setting addresses.
Give every internal interface a static address that will act as the default gateway for that segment.
Use DHCP for convenience or static addressing for infrastructure systems. Keep servers, the jumpbox, and management interfaces predictable.
Automatic outbound NAT is sufficient for the initial lab. Confirm internal clients can reach the internet through the pfSense WAN interface.
SEGMENTATION · COMPLETE
Allow the jumpbox to administer specific systems without granting access to the entire home or management networks.
Add host aliases such as PROXMOX_HOST and network aliases such as HOME_NET. Names make policy easier to read and update.
On the jumpbox interface, allow the jumpbox host to reach PROXMOX_HOST on TCP 8006.
If the jumpbox must open the router's local management page, allow only that host and TCP 443.
Place a block rule for HOME_NET below the narrow router allow. This prevents access to other personal devices.
After each approved management-host allow, block the remainder of the management subnet.
An allow-to-any rule can provide outbound internet access because protected internal destinations have already been matched and blocked above it.
Use descriptions that explain the source, destination, service, and reason. Avoid unexplained broad rules.
REMOTE ACCESS · COMPLETE
Create one encrypted entry path into the lab without forwarding RDP from the public internet.
Generate the tunnel keys, choose a private tunnel subnet, and configure a UDP listen port.
Enter the client's public key and tunnel address. Keep AllowedIPs limited to the lab destinations the client needs.
Interface assignment makes firewall rules and routing easier to understand and inspect.
On the home router, forward the selected WireGuard UDP port to the pfSense WAN address.
Allow the VPN peer to reach the jumpbox on the required traffic. Do not begin with unrestricted access to every internal subnet.
Assign a predictable address, enable RDP with Network Level Authentication, and scope the Windows Firewall rule to the VPN source network.
Use a mobile hotspot or another network so the test traverses the public edge rather than staying inside the home LAN.
Test-NetConnection <jumpbox-address> -Port 3389
IDENTITY + DNS · COMPLETE
Add centralized identity, domain DNS, administrative account separation, and the foundation for Group Policy.
Assign a static address, set the pfSense interface as the gateway, rename the server clearly, and install current updates.
After promotion, the domain controller should use its own address for DNS. Configure external DNS through server forwarders instead of the NIC.
Add both roles, promote the server to a new forest, and choose the lab domain name.
Confirm it is stored in Active Directory and uses secure dynamic updates. The domain controller should have host and service records.
Flush and register DNS, restart Netlogon, and request domain-controller DNS registration.
ipconfig /flushdns
ipconfig /registerdns
net stop netlogon
net start netlogon
nltest /dsregdns
Query the LDAP SRV record and confirm it returns the domain controller and port 389.
Point the client's DNS setting only to the domain controller, verify name resolution, and then join the domain.
Use a normal account for daily sign-in, a named administrative account for privileged work, and preserve the built-in administrator for controlled recovery use.
AUTOMATION · COMPLETE
Combine common connectivity and system checks into one repeatable PowerShell 5.1 workflow.
Accept DNS names, TCP targets, internet URLs, service names, certificate-warning days, timeouts, and an output directory.
Use PASS, WARN, FAIL, and INFO so every check can be displayed and exported consistently.
Run each diagnostic in its own error handler so one failure does not stop the rest of the report.
Resolve DNS, connect to TCP host/port pairs with explicit timeouts, test internet URLs, and collect adapters and routes.
Collect WinHTTP and user proxy settings, firewall profiles, services, system time, and certificate information.
Create a readable text summary and JSON output for later filtering, comparison, or automation.
Use 0 when clean, 1 when warnings exist, and 2 when a check fails.
.\Invoke-WindowsNetworkDiagnostic.ps1
EDGE VALIDATION · COMPLETE
Test the network from outside and confirm that the firewall exposes the VPN rather than management services.
Record the current public IP without publishing it in project documentation.
Check common TCP services first and note whether results are open, closed, or filtered.
Confirm services such as SSH, HTTPS administration, Proxmox 8006, and RDP 3389 are not public.
A normal Nmap scan does not answer the UDP question. Use a targeted UDP scan for the configured listener.
nmap <public-ip>
nmap -sU -p <wireguard-port> <public-ip>
open|filtered is normal when the scanner receives no response. WireGuard intentionally ignores unauthenticated probe data.
The desired result is no public TCP management service and only the planned UDP VPN path.
PACKET TROUBLESHOOTING · COMPLETE
Build the packet in PowerShell and prove its path before treating the BIOS or NIC as the problem.
Enable PCIe wake, disable ErP if it removes standby NIC power, and confirm the Ethernet LEDs remain active after a normal shutdown.
Use ethtool on the physical interface and confirm it supports and enables magic-packet wake with Wake-on: g.
Use the physical Ethernet MAC, not the bridge MAC, and the subnet broadcast address.
$mac = "AA:BB:CC:DD:EE:FF"
$macBytes = $mac -split '[:-]' | ForEach-Object {
[Convert]::ToByte($_, 16)
}
$packet = [byte[]](,0xFF * 6 + ($macBytes * 16))
$udp = New-Object System.Net.Sockets.UdpClient
$udp.EnableBroadcast = $true
$udp.Connect("192.168.1.255", 9)
[void]$udp.Send($packet, $packet.Length)
$udp.Close()
While Proxmox is running, listen for the packet on every interface and send it from Windows.
sudo tcpdump -ni any udp port 9
A 102-byte packet should appear on the physical NIC and the Linux bridge with the broadcast destination.
If the packet was proven but the host still does not wake, investigate shutdown-state NIC power, firmware, and driver behavior rather than rewriting the sender.
04 · ROADMAP
The next stages are ordered around recovery first, visibility second, and additional complexity last.
Move backups away from VM storage, define retention, enable verification, and complete a documented restore.
Collect infrastructure metrics and security events so changes and failures are visible across the environment.
Build a small virtual cluster for services, ingress, CNI, persistent storage, and NetworkPolicy practice.
CONNECT
If you would like to discuss the lab, its architecture, or any of the walkthroughs, LinkedIn is the best place to reach me.