Homelab · Part 3

Homelab Build — Part 3 — Networking with pfSense

With the server built in Part 2, this part turns the plan’s four network segments into a real pfSense firewall: WAN and LAN assigned, VLANs created for each segment, DHCP handing out addresses, and firewall rules that actually enforce the isolation the plan called for.

Quick idea: pfSense turns the four network segments planned on paper in Part 1 into VLANs a switch and firewall actually enforce — one interface per trust zone, its own DHCP scope, and its own ruleset deciding what can talk to what.
WAN / LAN

The boundary between the outside network and everything this lab controls.

VLANs

Servers, Clients, and DMZ from Part 1’s plan, carried as tagged traffic on one trunk.

Firewall Rules

Per-interface rulesets, evaluated top to bottom, deciding what crosses a segment boundary.

What This Part Covers

Part 1 reserved four network segments — Management, Servers, Clients, and DMZ/Guest — as ranges in a planning file. Part 2 built the Proxmox host that everything in this series runs on. This part is where those two things meet: pfSense goes in as a VM on that same host, gets assigned a WAN and LAN interface, and then grows a VLAN sub-interface for each of the remaining segments, each with its own IP, DHCP scope, and firewall rules.

Think of pfSense as the wall and the door between segments. Before this part, “Servers” and “Clients” are just two rows in a table — nothing stops a device on one from reaching the other, because nothing is enforcing the split. After this part, they are VLANs with a firewall between them, and crossing from one to the other requires a rule that explicitly allows it.

Series scope: This post continues directly from Part 1 — Planning the Lab Like Real Infra and Part 2 — Building the Server. It uses Part 1’s segment table (Management 10.10.1.0/24, Servers 10.10.10.0/24, Clients 10.10.20.0/24, DMZ/Guest 10.10.99.0/24, static range .1.20, DHCP range .50.200) and Part 2’s host pve01 at 10.10.1.5.

Why a Dedicated Firewall Instead of the Home Router?

A consumer or ISP-supplied router can hand out one DHCP scope on one flat network and not much else. It has no concept of VLANs, no per-segment firewall rules, and usually no way to say “Clients can reach the Internet but not the Servers segment.” That is fine for a household network. It stops being fine the moment a lab has more than one trust zone that needs to be kept apart.

WAN / LAN Separation

Only an interface with a gateway configured is treated as WAN — that single distinction is how pfSense tells the outside network apart from everything it protects.

VLAN Trunking

One wire between the switch and pfSense can carry every segment’s traffic at once, each tagged with its own VLAN ID.

Per-Interface Rules

Every interface — LAN or a VLAN — gets an independent ruleset. Traffic is evaluated first match, top to bottom, against that interface’s own rules.

This is the same separation of concerns real network edges use: a router/firewall that owns the boundary between zones, a switch that carries tagged traffic, and servers that never have to enforce segmentation themselves because the network already does it for them.

Deploying pfSense on the Proxmox Host

Part 1’s plan assumes a single physical host, and Part 2 built that host as a Proxmox hypervisor — so pfSense runs as a VM on pve01 rather than on dedicated hardware. pfSense’s own minimum requirements are modest: a 64-bit CPU, 1 GB of RAM, and an 8 GB disk. This lab gives it 2 vCPUs, 2 GB RAM, and an 8 GB disk on the local directory storage from Part 2 — comfortable headroom without taking meaningfully away from the VMs later parts will create on the ZFS pool.

The VM needs two virtual NICs, and getting their bridge assignment right matters more than any other setting on the creation screen:

VM NIC Proxmox Bridge Carries
net0vmbr0 (untagged)The uplink to the home network / ISP router — becomes pfSense’s WAN.
net1A VLAN-aware trunk bridge, VLAN tag left blankAll four segments’ tagged traffic — becomes pfSense’s LAN, with VLANs layered on top of it inside pfSense.

Configuring a Linux bridge on Proxmox as a VLAN-aware trunk — enabling bridge-vlan-aware, and getting a VM’s NIC to pass every tag through instead of just one — is covered in full in the existing Proxmox Networking: Bridges, VLANs, and Bonding post. This part does not repeat that mechanic; it picks up once net1 is attached to a trunk bridge and pfSense itself is ready to split that trunk into per-segment interfaces.

Practical note: Leaving the VLAN tag field blank on net1 in the Proxmox VM hardware settings is deliberate — it means the bridge passes every tag through untouched, and pfSense’s own VLAN sub-interfaces (configured below) are what actually separate the traffic. Setting a tag here instead would strip it before pfSense ever sees it.

Assigning WAN and LAN

On first boot, the pfSense installer’s console prompts for interface assignment directly; the same assignment can be revisited later from the console menu’s option 1) Assign Interfaces, or from the GUI at Interfaces > Assignments. pfSense distinguishes WAN from LAN by one rule: an interface with a gateway selected is treated as WAN for NAT and related functions, and no LAN-side interface should have one.

Interface VM NIC Value for This Lab
WANnet0 (vtnet0)DHCP client from the home network, gateway auto-assigned — this is what makes it WAN.
LANnet1 (vtnet1)Static 10.10.1.1/24 — the Management segment’s gateway address from Part 1’s plan, no gateway configured on the interface itself.
Important: pfSense enables an anti-lockout rule on LAN by default, permitting any host on that interface to reach the GUI (TCP 443, TCP 80 for the redirect) and SSH (TCP 22, if enabled). Leave it in place for now — Part 1 scoped the Management segment specifically for infrastructure with fixed addresses, so LAN access is already limited to that segment.

Creating VLANs for the Remaining Segments

With LAN (vtnet1) assigned as the trunk-facing interface, the Servers, Clients, and DMZ/Guest segments from Part 1 become VLAN sub-interfaces on top of it. VLANs are created at Interfaces > Assignments, on the VLANs tab, via Add: choose a Parent Interface, a VLAN Tag (VID) from 1–4094, leave the VLAN Tag Type at its default of C-Tag (standard 802.1Q), and give it a Description.

Practical rule: Match each VLAN ID to the third octet of its segment’s subnet from Part 1 — VLAN 10 for 10.10.10.0/24, VLAN 20 for 10.10.20.0/24, VLAN 99 for 10.10.99.0/24. It is not a pfSense requirement, but it means the VLAN tag is never a separate fact to remember on top of the subnet.
VID Parent Interface Description
10vtnet1Servers
20vtnet1Clients
99vtnet1DMZ

Each saved VLAN appears in the Available Network Ports list as, for example, “VLAN 10 on vtnet1 (Servers)”. Back on the main Interfaces > Assignments tab, assign each one as a new interface (they land as OPT1, OPT2, OPT3), then open each and set it Enabled, rename it, and give it a static IPv4 address — the gateway address for that segment from Part 1’s plan:

Interface VLAN Static IP Purpose
SERVERS1010.10.10.1/24Domain controllers and member servers, starting with Part 4.
CLIENTS2010.10.20.1/24Windows client VMs used for logon and GPO testing.
DMZ9910.10.99.1/24Anything that should not reach Servers or Clients directly.
Practical note: Deploying VLANs requires a managed switch capable of 802.1Q trunking on the port between the switch and whatever physical NIC backs the Proxmox trunk bridge — Part 1 flagged this as a tooling decision to make up front. An unmanaged switch cannot carry tagged traffic and will not work here.

DHCP Scopes Per Segment

pfSense’s DHCP daemon can only run on an interface that already has a static IP, which is why WAN never gets a tab here but LAN and the three new VLAN interfaces all do. Configuration lives at Services > DHCP Server, one tab per eligible interface: check Enable, then set the pool’s From and To addresses. Part 1’s plan already reserved the DHCP range as .50.200 of each segment, leaving .1.20 for static infrastructure like the gateway addresses just assigned above.

Interface Pool Notes
SERVERS10.10.10.5010.10.10.200DNS and gateway left blank for now — both default to pfSense until Part 5 hands DNS to the domain controllers.
CLIENTS10.10.20.5010.10.20.200Same defaults; client VMs in later parts pick this up automatically.
DMZ10.10.99.5010.10.99.200Kept enabled even though nothing occupies the DMZ yet.

LAN (Management) intentionally gets no DHCP pool. Part 1 scoped that segment for fixed-address infrastructure — the Proxmox host, pfSense’s own management IP, and later a switch or iDRAC/IPMI interface — and every device on it should be assigned a static address deliberately rather than picking one up dynamically.

Key point: Default Lease Time is 7200 seconds and Maximum Lease Time is 86400 seconds unless changed — both are reasonable defaults for a lab this size and neither needs adjusting here.

Firewall Rules Between Segments

A newly assigned interface in pfSense starts with no rules at all, which combined with the implicit default-deny at the bottom of every ruleset means a brand-new VLAN interface passes nothing until a rule explicitly allows it. Rules are created at Firewall > Rules, on the tab for the interface they apply to, and evaluated top to bottom — the first matching rule wins, and everything unmatched is silently dropped.

pfSense does not ship a built-in alias for the RFC 1918 private ranges — it has to be created once at Firewall > Aliases > Add: Name PRIVATE_NETWORKS, Type Network(s), with three entries — 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 — covering all of RFC 1918. That alias is what the DMZ rule below negates.

Interface Rule Purpose
SERVERSPass IPv4, source SERVERS net, destination anyLets the future domain controllers reach the Internet for updates and reach other segments during setup; narrowed once Part 4 exists.
CLIENTSPass IPv4, source CLIENTS net, destination anyLets client test VMs reach the Internet and the Servers segment for domain logon.
DMZPass IPv4, source DMZ net, destination !PRIVATE_NETWORKSAllows DMZ hosts out to the Internet only — the negated alias blocks any destination inside the three private ranges, keeping the DMZ from reaching Servers or Clients even though no explicit block rule was written for either.
Key rule: A single “destination not PRIVATE_NETWORKS” rule on DMZ does more isolation work than three separate block rules, and it survives new segments being added later without needing a rewrite. The alias only needs to be created once; every future DMZ-style segment can reuse it.

Every rule created this way should carry a short Description — the field exists specifically so a ruleset read six months from now still explains itself, the same discipline Part 1 applied to the planning file.

Verification Commands

Before creating the first domain controller in Part 4, confirm every interface pfSense created actually exists, the routing table looks right, and the ruleset just written is the one actually loaded. These run from the console’s 8) Shell option, over SSH, or from Diagnostics > Command Prompt in the GUI.

# Confirm every interface, including the three VLAN sub-interfaces, is present and up
ifconfig -a

# Confirm the default route points out through WAN's gateway
netstat -rn

# List the loaded firewall ruleset in evaluation order, with rule counters
pfctl -vvsr
Healthy output: ifconfig -a should show vtnet1_vlan10, vtnet1_vlan20, and vtnet1_vlan99 (naming varies by pfSense version) all in an UP state, and pfctl -vvsr should list a pass rule on each of SERVERS, CLIENTS, and DMZ.

Networking Setup Issues

Symptom Likely Cause Fix
Locked out of the pfSense GUI after reassigning interfaces LAN was reassigned to the wrong NIC, or the anti-lockout rule was disabled before a replacement rule existed. Use console option 1) Assign Interfaces to correct the assignment, or option 2) Set interface(s) IP address to restore a reachable LAN address.
A VLAN interface shows UP in pfSense but passes no traffic to the switch The switch port facing the Proxmox trunk NIC is not configured as an 802.1Q trunk, or the Proxmox bridge isn’t VLAN-aware. Recheck the switch port’s trunk configuration and the Proxmox bridge settings in the Proxmox Networking post.
DHCP clients on a VLAN never get an address The DHCP server tab for that interface isn’t enabled, or the interface didn’t have a static IP set before the tab was configured. Confirm the interface has a static IPv4 address first, then enable it at Services > DHCP Server.
DMZ hosts can still reach the Servers segment A broader pass rule sits above the DMZ isolation rule, and first-match-wins means it never gets evaluated. Move the DMZ net -> !PRIVATE_NETWORKS rule above any more permissive rule on that interface’s tab.
pfSense VM has no WAN connectivity after a host reboot The Proxmox bridge for net0 didn’t come up before the VM started, or the home router hadn’t yet issued a lease. Confirm vmbr0 is up on the Proxmox host with ip -4 addr show vmbr0, then check WAN’s DHCP status under Interfaces > WAN.

Final Thoughts

None of the segments from Part 1’s plan meant anything to the network itself until this part. A subnet in a table is a reservation; a VLAN with an interface, a DHCP scope, and a firewall rule is an actual network boundary that a real device on real hardware has to respect.

What this part produces is deliberately unfinished in one direction: the SERVERS and CLIENTS rules are still broad “allow everything out” rules, because nothing has been built on those segments yet to narrow them against. That’s expected. Part 4 gives the Servers segment its first real occupant.

That domain controller is now live: Part 4 — Domain Controllers walks through creating the forest on dc01 and adding dc02 for redundancy, on top of the SERVERS segment this part built.

Key takeaway: Confirm ifconfig -a shows all three VLAN sub-interfaces up, pfctl -vvsr lists a pass rule for each segment, and a DHCP lease is obtainable on both SERVERS and CLIENTS, before creating the first domain controller in Part 4.
Next in this series

Part 4 stands up the first domain controller on the Servers segment this part just created — forest and domain creation, then a second DC for redundancy.