Building a Virtualized Cybersecurity Lab: Networking and pfSense Setup

Published: (December 11, 2025 at 08:33 PM EST)
4 min read
Source: Dev.to

Source: Dev.to

The Reason Why

Over the past year I’ve used individual virtual machines, Docker containers, and online training platforms like TryHackMe to build hands‑on cybersecurity experience. While valuable, those tools don’t provide the realism or complexity of a fully controlled network environment.

With the start of my Cyber Security degree at Maryville University—and after moving my main workstation to a Fedora‑based Linux distribution when Windows 10 reached end‑of‑life—I decided it was time to build a proper virtualized homelab. Running Linux as the host OS also let me avoid Windows 11’s hardware requirements (Secure Boot, TPM), giving me full control over my virtualization stack and allowing me to design an enterprise‑style lab tailored for cybersecurity training.

This post is the first entry in a four‑part series documenting my homelab build. Here I cover the foundational architecture choices, explain how I configured the virtualization environment, and walk through deploying pfSense as the core router and firewall for the entire network. Because my workstation runs Linux natively, I chose KVM and QEMU for their performance, flexibility, and deep OS integration. Combined with libvirt, virsh, and virt‑viewer, this gives me a fast, lightweight, and highly customizable virtualization ecosystem—ideal for learning how real infrastructure operates behind the scenes.


Virtual Networks

  • lab‑NAT – Provides pfSense with upstream Internet access through the Linux host.
  • lab‑LAN – A fully isolated internal network where all client and server VMs live.

This separation models a real enterprise network with distinct external and internal segments.


pfSense Firewall/Router

pfSense serves as the central security appliance of the lab, providing:

  • Routing between WAN and LAN
  • Stateful firewalling
  • DHCP services
  • NAT translation
  • Segmentation and network‑boundary control

All traffic entering or leaving the internal network passes through pfSense, mirroring the design of most corporate environments.


Internal Systems

These systems make up the “enterprise network” inside the lab:

  • Windows Server 2022 (Active Directory + DNS)
  • Windows 11 workstation
  • Ubuntu Desktop running Splunk
  • Additional Linux servers for testing and future projects

Together they provide a functional identity, endpoint, and logging ecosystem that represents a realistic enterprise environment.


External Attack Machine (Kali ThinkPad via VPN)

I’m integrating my physical Kali Linux ThinkPad as an external attacker machine. It connects to the pfSense firewall through a VPN tunnel, simulating either:

  1. An external threat actor accessing the network from outside, or
  2. A rogue device connecting through a controlled entry point.

This setup allows penetration testing, vulnerability discovery, and attack simulations against the isolated lab‑LAN while keeping everything safely contained and segmented from my real devices.


Installing KVM/QEMU and Tools

# Install the virtualization stack
sudo rpm-ostree install @virtualization virt-manager libvirt libvirt-daemon-kvm qemu-kvm bridge-utils --allow-inactive

Enable and start libvirtd

sudo systemctl enable --now libvirtd
sudo systemctl status libvirtd   # verify it’s running

Verify KVM support

egrep -c '(vmx|svm)' /proc/cpuinfo

Defining Virtual Networks

Create XML definitions for lab‑LAN and lab‑NAT (example XML omitted for brevity). Then define, start, and enable autostart:

# lab‑LAN
sudo virsh net-define /etc/libvirt/qemu/networks/lab-lan.xml
sudo virsh net-start lab-lan
sudo virsh net-autostart lab-lan

# lab‑NAT (same steps with lab-nat.xml)
sudo virsh net-define /etc/libvirt/qemu/networks/lab-nat.xml
sudo virsh net-start lab-nat
sudo virsh net-autostart lab-nat

Verify the networks are active:

sudo virsh net-list --all

Creating the pfSense VM with virt-install

sudo virt-install \
  --name pfSense \
  --ram 2048 \
  --vcpus 2 \
  --os-variant freebsd13.0 \
  --disk path=/var/lib/libvirt/images/pfSense.qcow2,size=10,format=qcow2 \
  --cdrom /var/lib/libvirt/boot/pfsense.iso \
  --network network=lab-nat,model=virtio \
  --network network=lab-lan,model=virtio \
  --graphics spice \
  --boot uefi

Open the installer console:

sudo virt-viewer pfSense

pfSense Interface Assignment

During the pfSense installation assign the two virtual NICs:

  • WANlab‑NAT
  • LANlab‑LAN

After installation, configure DHCP, firewall rules, and NAT as needed. This completes the initial network segmentation and routing.


Reflections & Next Steps

Building the firewall and virtual networking foundation significantly improved my confidence with virsh, virt-viewer, and KVM‑based virtualization. The process reinforced key infrastructure concepts such as defining virtual networks, bridging interfaces, configuring routing, and assigning DHCP at the firewall layer. Deploying pfSense deepened my understanding of segmentation, NAT behavior, and multi‑interface design.

Upcoming work

  • Expand pfSense capabilities: advanced firewall rules, VLAN segmentation, DNS resolver tuning, static DHCP mappings.
  • Evaluate pfSense packages: pfBlockerNG (threat intelligence) and Suricata (IDS/IPS).
  • In the next post I’ll install Windows Server 2022, promote it to a Domain Controller, configure DNS, and integrate it with pfSense. Windows and Linux clients will join the domain, establishing the Active Directory foundation for future posts on SOC workflows, blue‑team tooling, detection engineering, and attack simulations.
Back to Blog

Related posts

Read more »