Skip to main content

Deploying PfSense on the Cluster

Why PfSense Is Part of This Setup

The private vSwitch is a flat layer-2 network. VMs can talk to each other and to the cluster nodes, but they have no route out. PfSense is what changes that — it bridges the private vSwitch (LAN side) with the public vSwitch (WAN side), running NAT so every VM in the 10.100.100.x range can reach the internet through a single public IP.

Without PfSense, the private network is useful for internal VM communication only. PfSense is not optional in this setup.

What This Chapter Covers (and What It Doesn't)

The full PfSense installation — downloading the ISO, creating the VM, running through the installer, and the initial web UI setup — is covered in detail in Public VM Connectivity on Hetzner via PfSense, specifically Method 3 (Hetzner vSwitch). Go there if you haven't deployed PfSense before. This chapter only covers the interface assignments, IP values, and MTU settings specific to this cluster layout. The delta is small but the values matter.

Step 1 — Create the PfSense VM on Node 1

Follow Public VM Connectivity on Hetzner via PfSense — Method 3 for the VM creation and install. When you get to the network interface step in the Proxmox VM wizard, add two NICs:

NICBridgeBecomes
Firstvmbr_pubPfSense WAN
Secondvmbr_privPfSense LAN

During PfSense's first-boot console setup, it asks you to assign interfaces — assign the NIC on vmbr_pub as WAN and the one on vmbr_priv as LAN.

Step 2 — Set MTU 1400 on the WAN Interface

In the PfSense web UI: Interfaces → WAN → set MTU to 1400. Save and apply.

PfSense doesn't inherit the MTU from the Proxmox bridge — you have to set it explicitly. Without it, large packets on the WAN side hit the VXLAN overhead ceiling and get fragmented. The symptom is exactly what you don't want: everything seems to work until it doesn't, and the failures are inconsistent enough to chase for a while before landing on MTU as the cause.

Step 3 — Set MTU 1400 on the LAN Interface

Interfaces → LAN → MTU 1400. Save and apply.

Same reason as WAN — the LAN side also goes through a vSwitch bridge. Setting it here also lets PfSense clamp TCP MSS correctly in its firewall rules, which prevents large TCP sessions from stalling on connections that cross the MTU boundary.

Step 4 — Configure the LAN IP

If it wasn't set during the console setup, assign the LAN interface:

  • IP: 10.100.100.1
  • Subnet: /23

This is the default gateway for everything in the 10.100.100.0/23 range — VMs in the .100.x pool and cluster nodes in .101.x.

Step 5 — Configure the WAN IP

Assign the WAN interface the first usable IP from your Hetzner additional subnet, with the gateway Hetzner provides for that subnet (visible in Robot under the subnet details).

Step 6 — DHCP for the VM Pool (Optional)

Services → DHCP Server → LAN — enable it, set the range to 10.100.100.2 – 10.100.100.254. That covers the VM pool and deliberately excludes the node addresses in .101.x, which should always be static.

If you'd rather assign VM IPs manually, skip this.

Step 7 — Smoke Test

Spin up a minimal test VM on vmbr_priv and run:

ping -c 4 10.100.100.1     # PfSense LAN
ping -c 4 8.8.8.8          # Through PfSense to the internet
curl -s ifconfig.me        # Should return PfSense's WAN IP, not the node's

PfSense Is Single-Instance — Know the Implication

Right now PfSense runs on one node. If that node goes offline, VM internet access goes with it. The cluster itself stays up — losing one node still satisfies the 2-of-3 quorum, so Proxmox keeps running and the other VMs keep running. But any VM that needs outbound connectivity is cut off until PfSense restarts or the node recovers.

The solution is redundant PfSense with CARP — two PfSense instances sharing a virtual IP, one taking over automatically when the other disappears. That's a future article.