Home Network Virtualized pfSense Install

Circuit Guy
46 min readAug 2, 2020

Migrating from consumer grade OpenWRT / LEDE to a real network for my IoT home. The complete guide and tutorial. Last Updated March 2021.

I had a few challenges and surprises along the way, spent literally hundreds of hours learning everything, and decided to create the guide I wish I had. I approach everything here with an eye towards a non-expert. You’ll note that I share screenshots of the GUI instead of decidedly unfriendly edit your config file until it looks like mine. Once you have the hardware available and the basic planning done, it should be possible to set all of this up in just a single afternoon.

Here’s the end goal: An easy to set up enterprise-grade solution for my home

To get one of the questions out of the way for users questioning the security of virtualizing your firewall — if an exploit becomes available that lets an attacker break out of a VM over the internet, they’re going to be too busy trolling the likes of Google, Amazon, Facebook, and governments all around the world to worry about your home network. The only ‘real’ risk is if you make a misconfiguration, but frankly, that’s pretty hard to do and this guide highlights those steps.

The benefits — I can use the hardware for other things including for other network appliances like deep packet inspection. When I get that up and running and am confident enough that I got it ‘right’, I’ll share here.

Why?

I’ve been running OpenWRT on consumer hardware for years, but it just kept letting me down. Over the years, I’ve accumulated a lot of IoT network ‘junk’ and my Linksys router with OpenWRT was failing under the load.

The solution: PfSense

I’m also segregating my devices into VLANS. I can put the devices I trust on one VLAN, and give them one-way access to everything. The devices I don’t trust are also on their own network, but the damage they can do is fairly limited. Hack into my IoT light bulb? Annoying, sure, but at least it’s not on a network with my credit card numbers.

I’ve done this with OpenWRT for years, but again, the hardware and software stack was just getting crushed under the weight of my network. Time for an upgrade!

VERY brief network crash course

<Begin Tutorial> — jump down to <End Tutorial> if you want.

Skip this section if you want. Really, this is everything I wish I knew as an amateur before embarking on this journey. I mean, I had a pretty good idea of basic IP addresses, DNS and the like. However, the CIDR notation, IPv6 prefix allocation and the like was all new to me.

IP Address 101

It’s almost trivia, but “the internet” and IP addresses aren’t really synonymous (somebody could theoretically start a duplicate internet). ICANN is the benevolent multi-national organization that sets up the rules for the internet. Among these rules: Public IP addresses are assigned by “RIR” Regional Internet Registries. Your ISP pays for a ‘bank’ of IP addresses it’s allowed to use.

Public IP addresses can be used to identify ‘where’ you are, or at least down to your ISP. Every time an ISP buys an IP address, this is registered in a database (accessible through an internet whois search). This goes for both IPv4 and (the first few parts of) IPv6 addresses. Now — it’ll be obvious later in this tutorial, but addresses like 192.168.xxx can NOT uniquely identify you.

Gateway and Subnets

Subnets are a polite suggestion for what devices can talk to other devices and work in a peer-to-peer fashion.

You’ll typically see subnet masks of 255.255.0.0 or 255.255.255.0. There’s something referred to as CIDR notation for how many bits the submask is. The 255.255.0.0 example is 16 bits, or CIDR /16, 255.255.255.0 is /24. For the 10.5.xxx.xxx IP range with mask 255.255.0.0 or /16, valid IPs range from 10.5.0.1 through 10.5.255.254, or 65,534 devices. You’ll see three notations pretty commonly: /8 or 255.0.0.0 allows the last 3 ranges to be valid IPs for a whopping 16,777,214 devices, /16 is 255.255.0.0 (what I just covered), and /24 is 255.255.255.0 which allows 254 devices.

When your PC encounters an IP outside of its subnet, it assumes peer-to-peer communication is not possible and has to go through a gateway. One weird “gotcha” with networking. Without complex workarounds, you can have any number of IP addresses, but only one gateway. Again, when you get an IP not in your subnet, you ask your gateway (after this tutorial, your pfSense box) to route your data for you. Every gateway itself has a list of clients it serves (theoretically everything in its subnet) and a gateway above it. Three things can happen with a request, 1) a gateway (acting as a firewall) can reject the packet if it doesn’t meet the rules set 2) the gateway will forward ‘down’ either directly into the destination or into another gateway if the subnet is within its domain or 3) the gateway will forward the request ‘up’ until a gateway is found to forward back ‘down’ towards the destination.

Network Address Translation (NAT)

When you’re on any internet-connected network, you’re probably not actually directly connected to the internet. You have a local IP address (for home users, very likely something like 192.168.1.103), assigned to you by your home router. Millions of devices around the world probably have that same IP address, it’s not public and only people on the home side of your router can find your IP address. The router itself is the only true internet-connected device and has a public internet-accessible IP address.

When you send or receive data over the internet your router performs NAT (Network Address Translation) and communicates with the internet as the ‘only’ device with your IP address. When it receives a response from the internet, it translates the data and routes it to your home computer and every other device on the LAN.

It’s somewhat uncommon, but your router may also be behind another router from your ISP (carrier grade NAT). This is referred to as double-NAT and greatly restricts anything beyond very basic remote server / local client access from working — the ISP won’t allow you to poke holes in their firewall for peer-to-peer traffic like multiplayer video games.

IPv6

Quick aside: This guide is going to set you up to be IPv6-compatible and safe from the get-go. I hated running into ‘the internet’ telling you to just disable IPv6 and move on with your life because it’s too hard. Continuing to use IPv4 as your primary internet use in this day and age is like dumping your used motor oil into the local creek justifying yourself as a trivial part of the pollution problem. IPv4 is a finite resource and we’re almost tapped out. /rant

IPv4 is 32 bits, which allows 4 billion unique IP addresses (not all publicly routable). Not sure if you’re counting, but there are almost 8 billion people. You’re in the privileged 50% if your home network has its own IP address especially considering all the IP addresses owned by governments, corporations, and all the other entities.

IPv6 by comparison is a whopping 128 bits. That number is on the order of 10³⁸. For comparison, the Earth is 10²⁷ grams. You could convert every gram of dust on the Earth into a computer and give it its own IP address. If that wasn’t enough, you could assign every gram of all the solar system and sun itself (10³³ grams) an IP address 100 thousand times over.

The point is — there’s enough addresses that every device on your LAN can get its own publicly accessible IP address if you allow it to.

Also, that whole NAT thing isn’t even built in to the spec. IPv6 clients can talk directly to one another (if allowed by your firewall).

I have no idea why this information is so hard to find, but here’s what an IPv6 IP address looks like and why you care:

The [brackets] are added by me.

  • 2001:0db8:85a3:0000:0000:8a2e:0370:7334
  • [2001:0db8:85a3]:[0000]:[0000:8a2e:0370:7334]
  • [Public Routing]:[Subnet]*:[Unique Device ID]

Each number is hex, or 4 bits. The first 48 bits is the “public” information about routing the IP address. This is the part that ICANN, RIRs, and your ISP directly control and give to you.

The next 16 bits were a huge stumbling block for me. This is equivalent to the subnet in IPv6, except your ISP doesn’t automatically give it all to you. In the end, if my explanation isn’t good enough, the best document I could find was a best practice RFC 6177. There’s a weird quirk in IPv6 where subnets can’t be split into anything smaller than /64 (see RFC 5375), and /64 is the default your ISP gives you, meaning all of your equipment is on one subnet (see VLANs below for why this is an issue). However, there’s a mechanism to request a larger subnet from your ISP (most home ISPs seem to allow at least /60) which implies there are 4 bits on top of your ‘one’ /64 subnet — or 16 subnets. The other common recommendation is /56 which gives 256 subnets and /48 for a business which gives 65,536 subnets. Note that ISPs themselves are given allocations of /32 (4 billion — or, put another way every ISP is easily given an allocation allowance equal to the entirety of IPv4 in just a single globally-routable address).

Given that, I’m going to change the figure above a bit.

  • [2001:0db8:85a3]:[00][00]:[0000:8a2e:0370:7334]
  • [Public Routing]:[ISP Subnet][ISP/Your Subnet]:[Unique Device ID]

In the tutorial below, I’m recommending you request a /56, which means you get the last two hex digits as your subnet within the 4th bracket : section, i.e. you can pick 00 through FF, for 256 subnets. I also cover what happens if you need to fall back to a /60, which gives you access to only the last entry or 0:F.

Finally, the last 64 bits are unique to your device “interface identifier”. You can think of it like a MAC address, it can be changed, it’s semi-unique, and devices may randomly re-generate them.

Firewalls

Your router provides another very important firewall function. It prevents willy-nilly access to devices on your local network. This is how you or your company can have a file server on the local network ‘intranet’ accessible to all computers on WiFi, but it remains protected and inaccessible from the rest of the internet.

PfSense (and most modern firewalls) are stateful, meaning that once communication is requested, a response is allowed. This means that Google can’t get access to your computer. However, if you go to Google’s webpage, Google is free to send a response.

VLANs

I covered this a little bit earlier, but a VLAN is just a Virtual LAN. You can think of it as a virtual ethernet cable. VLANs even use terms like ‘tagged’, meaning that a packet is given an additional VLAN header that describes which virtual cable its traveling on. The advantage is that your firewall can really really separate out this VLAN traffic. Your switches and anything with access to a VLAN Trunk- (an actual ethernet cable or interface with multiple VLANs on it) has to be a trusted device.

<End Tutorial>

Plan your network

I can’t believe how much IoT and internet device cruft I’ve collected! One thing I don’t have is non-internet home automation devices (well, I do, but they’re behind Z-Wave). An ‘island’ that can’t access the internet but can be connected to from your home devices is certainly reasonable.

The network setup I’m using is below. The arrows show the direction that communication can be initiated. Note that connections are not automatically bi-directional, this stateful firewall feature allows some devices to recognize another only if spoken to first. For example, my personal devices can see other personal devices, the IoT devices, the servers, and the internet. The IoT devices can only see the servers and the internet.

In my planning, note that I made two IoT networks that appear virtually identical. For those of you who don’t know what those devices are, the 3D Printer (Octoprint / Octopi) is a Raspberry Pi connected to a webcam and a device that can quite literally burn my house down, the TeslaUSB is a Raspberry Pi that stores video of everywhere I’ve driven for the past week or so (and uploads it to my NAS on the server network), and the washing machine is… probably not the most likely thing to be patched and maintained by the manufacturer but should be a very low-internet use device. By putting them in their own VLAN I can monitor and throttle their bandwidth use. More importantly (thanks to WiFi client isolate features) they can’t see each other or anything but the internet (which they need a trivial amount of) or the fairly well-hardened servers.

One important point — you’ll need a separate WiFi SSID for each WiFi connected VLAN. Luckily the WiFi APs can be ‘trusted’ with the VLAN and can broadcast multiple SSIDs.

Next, pick your VLAN numbers. My suggestion is to use 2–255. There’s also a really good argument to use 2–99 so that your VLAN in hex for IPv6 reads in decimal. Get creative. Everybody on the internet seems to use 10,20,30,… I went with random prime numbers myself (5, 47, 89, 113, 181), where higher numbers are more restrictive. For maximum device compatibility, you should stay within 2–1001. You shouldn’t use ‘1’ because you’ll get made fun of by the security people on the internet (doesn’t really matter for your home network, but in a corporate environment ‘1’ is the default for most switches, so a new device automatically lets VLAN 1 out). I would also recommend keeping in the range of 2–255 so you can make your IP addresses match your VLAN and make it easier on yourself.

Your New Router Hardware

You have two options here (1) buy a small form factor fanless PC or (2) buy a good server-grade network card and put it into an existing server chassis.

I went the fanless PC route with a good Intel processor, a lot of networking ports, 16 GB of RAM, and a 128 GB SSD. This article is from 2020, and I know that doesn’t sound like much in this day and age. However, in this case, it’s waaay more than enough. The pfSense VM only gets a small fraction of that. I basically bought for value, a smaller HDD or RAM stick is only a few bucks cheaper.

My actual hardware, sitting on a dusty shelf, complete with disorganized cables. I hopefully won’t have to touch this baby for a few more years

Option 1: Fanless

Please consider supporting Netgate (the company that makes and supports pfSense). Their products are reasonably priced and really a no-brainer if you’re running a small business where down-time costs money and you need it to work. Unfortunately, for me as a home hobbyist, it wasn’t quite worth it.

I ended up going with this PC, a 6-NIC Intel i5 with passive cooling. I also purchased a 128 GB SSD and 16 GB of RAM. Honestly, I was really on the fence about some of the Protectli products. They have better BIOS features and (probably) better support, but I just couldn’t quite justify the price increase and/or performance downgrade compared to the off-brands.

In retrospective, the i5 was totally worth it if not overkill, 16 GB of RAM is still plenty, but the 128 GB SSD is really holding me back. I would strongly recommend getting 512 GB or more to comfortably hold a few VMs and snapshots in local storage.

Option 2: Home Server

If you’re upgrading a home server, my honest recommendation is a server-grade Intel 4-port NIC. Deals on Amazon aren’t too hard to find. Otherwise, go with used stock on eBay to save a few bucks. You really want something intended for server use to reliably work day in and out for years. Pick Intel because their Linux support is much better than Realtek or any other vendor that I could find in my research. You really want at least 3 ports for this to work — one management, one WAN, and one LAN. Intel has 4-port cards for virtually the same cost as one-port cards, so use them. Finally, there’s tons of very good used cards floating around from companies who are upgrading their networks to 10 GbE and scrapping their old stock.

Other Stuff:

  • Label Maker — Help future you not get wires crossed.
  • You’ll end up doing a lot of network switching back and forth. I found some of this easier to do on my thin laptop that didn’t have an ethernet port. If you’re in the same boat, find a cheap USB — ethernet adapter and a spare ethernet cord.

Personal PC Software

This is the software you need on your ‘real’ computer. You know — the one with a keyboard and monitor.

Use a password manager!

Use a password manager for all of this. This is security 101, and really important for a computer you’re going to directly connect to the big bad internet. My personal favorite is Bitwarden (works on all devices, and I can share passwords with my S.O.), but any password manager you’re comfortable with will work. Since you’ll very rarely have to type this password in (normally you can copy-paste it), If typable is more your style, Bitwarden can also generate an equally strong XKCD-like password phrase like jukebox-defiant-ascertain-modulator — just flip your options from “password” to “passphrase” in the generate section.

Remember that whole trust the devices on your network thing? Yeah — reasonable level of trust includes insanely-difficult passwords for the things that are really important.

For ‘software’ installation, this is really just a Chrome or Firefox add-on.

ISO flashing tool

You’ll need something to turn an ISO into a bootable USB drive.

Windows has two really good options:

  1. Balena Etcher
  2. Rufus

Ubuntu: Launch “Make Startup Disk”. I had to then rename my downloaded .iso to a .img file for the tool to recognize it as appropriate for a USB drive.

Install Proxmox Server OS

One of the eventual regrets from many pfsense users is that they didn’t immediately virtualize their install. I have other plans for this box (OpenHab and a deep packet inspection tool for starters), and so went with a VM from the start.

Before writing this tutorial, I played with quite a few VM solutions before settling on Proxmox. Proxmox is a Debian/Ubuntu derivative OS dedicated to serving VMs.

Without going into too much detail,I really like that it’s designed for “headless” web interface out of the box. This is important for something that’s going to sit on a shelf with no keyboard or monitor. Some of the other solutions really sucked here getting remote access to work right. It’s also designed for VMs from the ground up. I really almost went with another Linux distro running a VM host app. This was much easier — I wish I had started here.

Step 1: Download and flash Proxmox to a USB stick

Proxmox Virtual Environment OS can be downloaded here:

https://www.proxmox.com/en/downloads/category/iso-images-pve

Flash it to a USB key using some of the software recommended above under ISO Flashing Tool.

Step 2: Plug in your new server

You’ll need to plug in a keyboard and mouse temporarily to install the OS.

Optional but recommended: Pick a network port that you plan to tie to your server VLAN and use for remote management. Plug that port into your router during installation.

Remember: I’m recommending at least 3 ports. One for the internet / WAN, one for VLANs to go to your downstream switch, and one for direct connection / management. This is the one for direct connection, you’ll need it (or keyboard / monitor) if pfSense ever goes down for some reason and you need to access this Proxmox VM host. If you went the Intel NIC route on a motherboard that already has built-in ethernet, it would be totally fine to use your motherboard built-in port for this.

Step 3: Install the OS

Give it a strong password! The pfSense VM (later) should have a different equally-strong password.

Tip: If you’re using gmail (most, but not all support this), consider adding an extension to your email so you can better sort and filter it. For example change YourEmail@gmail.com to YourEmal+Proxmox@gmail.com.

The Proxmox installer assumes and requires a static IP address. If you have it plugged in to your network during install, it will get an IP via DHCP and then offer that one up — don’t use that address. You should pick an address that is easy to remember and outside your router’s DHCP pool.

Write down or remember this IP address.

Start working on your server remotely

From now on, you shouldn’t need the video and keyboard attached to the Proxmox box. Feel free to put it on the shelf or networking cabinet where you’re going to keep it.

Log in through the web portal

You’ll need to open your web browser and navigate to https://<Proxmox IP>:8006

You’ll get the “Potential Security Risk Ahead” warning because the encryption key isn’t signed. Choose the “Advanced -> Continue Anyway” option.

Continue your login as root and the password you picked earlier.

The “You do not have a valid subscription” warning can be dismissed. This is the Proxmox paid support service (i.e. Redhat model for corporations).

Welcome to your new Proxmox installation!

IF you want to get rid of the subscription warning, this one-liner disables it. You can choose your server, “>_ Shell” and run the following.

sed -i.backup "s/data.status !== 'Active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service
Optional — Disable the startup warning

After running the command, you can refresh your browser and the message shouldn’t appear.

If something goes wrong, that command will save a backup of your original /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js as proxmoxlib.js.backup.

Take a look at the network config

This will become important later, and is where your installation might differ from mine. Note: If you went with the two-port option, you won’t be able to have a dedicated management port. My ‘final final’ config is near the end of the article.

The default Proxmox install creates a “Linux Bridge”, assigns the fixed IP address there, and bonds it to the NIC you picked. I have 6 ports, with the last one being bridged for the management interface.

My default network config

First thing’s first — make a backup of your known-working (you can log in!) network config. If you ever lose the ability to log in with the web terminal, you’ll have to connect a keyboard and monitor and copy your backup back. In the left sidebar or top-right corner, select “>_ Shell” and run the following:

cp /etc/network/interfaces /etc/network/interfaces.bak.CleanInstall

Next, we’re going to enable “OVS” or “Open vSwitch”. Go into the “>_ Shell” and run:

apt update
apt install openvswitch-switch

From here, you’re going to want to make your basic choices.

In my case, I’m going to choose to configure my 6 available ports in the following way:

  1. WAN
  2. VLAN Trunk (to downstream switches / wireless APs)
  3. VLAN Trunk
  4. Home PC VLAN
  5. Server VLAN
  6. Proxmox management interface (Changed later in this guide as part of wrapping up, follow those directions if you don’t have a dedicated management port available)

The only part you really don’t want to mess up is to assign your WAN port to one and only one place — your pfSense VM. Create a new “Linux Bridge” and type in the name of your WAN port in the “Bridge ports” section (vmbr1 in my screenshot). Note: Linux bridge for WAN, OVS bridge for everything else. This also helps to make sure they’re very clearly separated.

Next, create a new “OVS Bridge” — this is going to be your VLAN trunk. In my case, this is vmbr2. Under “Bridge Ports” type in the name(s) of all the LAN ports (in my case enp2s0-enp6s0).

Next, create one “OVS IntPort” for each VLAN you want the server to be able to access, including if you want the server to be able to route the VLAN to a physical port. Under “VLAN Tag” type in the VLAN you want. Here’s mine for VLAN 5. I created one VLAN 5 so I could tag the ports and plug PCs in, and another VLAN 47 for the actual server. If you want to give the server an IP address on a VLAN, type in the IP address and netmask (I cover this later, but recommend /16). In this case, I chose to give it an IP address on VLAN 47 as well as the management interface (again, if you don’t have a spare port, this is the only way you can access it after configuring your managed switch — I’d recommend doing that later).

The “vlan5” OVS port. Important: “VLAN Tag”

Finally, for each port that you don’t want to be a VLAN trunk, open the port setting and type in a “Tag”.

Tagging Port 4 to VLAN5

Since I have a spare NIC for the management interface, I’m going to also bridge my management interface (for now) to the pfSense LAN. If you only have two ports, you should tag your management interface bridge from the VLAN trunk bridge and configure your downstream switch with the right VLAN. Scroll down later in this document where I set that up and do it now.

Set the gateway for your new 10.x address (see the tutorial on Gateways above for ‘why’), and leave it blank for the default management interface if you have multiple IPs. This will allow your Proxmox server to respond across VLANs using the pfSense VM to route the traffic. Note that when you remove this 192.168.x.x gateway, you’ll have to be on 192.168.x.x yourself (which you probably are).

Here’s my final configuration after reboot

OPTIONAL: Leave a VLAN untagged on a trunk port. There are a few places where this is basically required. If you only have one LAN port, this allows you to connect a normal PC without VLAN awareness and access your firewall. Another is for switch management. Ubiquiti and other switches require an untagged VLAN for configuration (note — or they use VLAN 1, which is why you shouldn’t). To do this, edit the OVS port, and add a VLAN Tag and type in the ‘OVS options’ vlan_mode=native-untagged.

OPTIONAL — Leave one VLAN untagged on your trunk. Example here is leaving VLAN ‘1’ untagged on the trunk. Any packets on VLAN1 exit untagged, and any packets put on without a VLAN tag get tagged as VLAN1. If you plug in a ‘normal’ non-VLAN aware PC, it’ll automatically see VLAN 1 and nothing else.

Note: The rest of this tutorial does not use this optional tagging, but I did change to this after creating this tutorial. I’ll add a follow-on later.

You’ll have to hit “Apply Configuration” and then “Reboot” for the changes to take effect. Go ahead and do that now.

Install pfSense

Finally: Download a pfSense ISO https://www.pfsense.org/download/

From the Proxmox web portal, under your local storage, upload the ISO.

Click on the “Create VM” button.

I’m going to run through my settings real quick and call out the important changes:

General: Nothing special, just the name
OS: Important — Select “Other” and give it your pfSense ISO
System: Prefer “VirtIO” for controller
Hard Disk: Important — Pick VirtIO. I provisioned 8 GB
CPU: Important — pick ‘Host’ Type. I provisioned 2 cores (likely overkill on the Intel processors)

Note: If for some reason you want to run the pfSense VM on multiple hosts with different hardware, pick the ‘kvm64’ and set the ‘aes’ CPU flags if all of your hardware supports it. You can check to see if your hardware supports it by running “grep ‘ aes ‘ /proc/cpuinfo” in the console. If you get a wall of text, aes is supported.

Memory: Nothing special. I provisioned 1 GB

When you get to the network screen, just skip it “No network device” since it only lets you select one and you’ll want at least 2.

Go ahead and finish the setup.

Now, go into the “Hardware” settings for your new VM and add all the network bridges it needs (WAN and LAN at a minimum). It’s important to pick VirtIO for speed and turn off the firewall, because, well, pfSense is the firewall. Note: By default the firewall isn’t configured, but just in case… still don’t want it for the pfSense VM.

If you’re following along 1:1, I set net0 to the WAN Bridge, net1 to the VLAN trunk. All with VirtIO hardware. Make a temporary note and check it twice.

My final network and hardware config

Finally, disable the “Use tablet for pointer” in the “options” just below hardware. This is recommended to reduce the load on the system (which doesn’t have a mouse/GUI).

Disable the mouse

Configure pfSense

Click the “Start” button and tab over to the Console. You should see pfSense starting.

pfSense is booting!

All the defaults are fine — just next, yes, ok until it’s restarted. You’ll get to a few options on the first boot.

Select ‘no’ for VLANs (for now — it’s easier to set up later in the GUI).

No VLANs — Yet

For WAN/LAN connection, cross-check your notes from the previous step and your “Hardware” settings of the VM with your Proxmox networks. In my case WAN is vtnet0, LAN is vtnet1.

Type in your network configuration. Mine is shown here.

Just so you know, the install and boot sequence “freezes” longer than I thought it should in some spots. Everything is fine. Just be patient.

Configuration so far

Once setup is finished, toggle into the Hardware again, and for CD/DVD Drive pick “Do not use any media”. You won’t need the CD image after installation, and if you ever delete the ISO file, Proxmox ‘silently’ refuses to start the VM. Ask me how I know… By the way, if your VM ever won’t start for some reason, tab into the Proxmox “>_ Shell” and run qm start ###, for example qm start 100 for my pfSenseWAN VM.

Remove the virtual media from Proxmox

This is also a good time to adjust the startup order under your VM “Options”. You probably want your router/firewall pfSense VM to start up before any future VMs.

Next we’re going to set up the very basics of Proxmox and put it in-between our local PC and our local router (i.e. double-NAT) while we do the rest of the configuration. After that’s working, we’re going to swap places and configure our router (running OpenWRT in my case) as a managed switch.

Picking the LAN IP Range

I’m going to choose to match my VLAN IDs to IP address ranges (again — no reason other than clarity and my sanity). The biggest range of IP addresses available for a LAN is the 10.x.x.x range (take a look if you work in a large office — very very likely that your computer’s IP is 10.x).

Take a look at your notes for your VLAN IDs. For reference, mine are: 5, 47, 89, 113, 181. I’m going to give VLAN 5 the 10.5.xxx.xxx IP range, VLAN 47 is going to get 10.47.xxx.xxx, and so on.

The netmask: Since my first two digits of IP are fixed, my netmask is going to be 255.255.0.0 (also the /16 notation). For the 10.5.xxx.xxx IP range with mask 255.255.0.0, valid IPs range from 10.5.0.1 through 10.5.255.254, or 65,534 devices. Again, I’m advocating for /16 so I can reserve some areas for static IPs and some for DHCP.

Now, choose to (2) set interface(s) IP addresses. You’ll want to set your LAN IP address. I’m going to start off with the ‘trusted’ VLAN and give my pfsense firewall / DHCP server the .0.1 address (usually convention, but definitely not required) i.e. 10.5.0.1 in my case, again with the /16 subnet notation.

Set your LAN Static IP and Subnet Mask

Continuing, skip IPv6 for now — we’ll get back to it in the ‘Bonus’ section near the end.

You will want to enable the DHCP server. In my case, the first valid IP could be as low as 10.5.0.2. I’m going to go ahead and (somewhat arbitrarily) let my DHCP server work in the upper half, starting at 10.5.128.1 and assigning IPs all the way to 10.5.255.254.

Choose ‘no’ for reverting the web portal to http.

Finishing up the DHCP server on pfSense

Now, go perform the physical switcheroo. You’ll want to connect the Proxmox / pfSense box between your router and your computer. Plug the ‘WAN’ port of the proxmox box into a spare ethernet port, and plug your computer into the ‘LAN’ port of the Proxmox box.

If everything went right, your PC should immediately get a new IP address in the 10.x range you configured, and the internet should work.

Once that’s verified, navigate to the pfSense IP you configured. In my case: https://10.5.0.1

Success! Proxmox is communicating

Go through the same “Advanced” — Continue thing.

The default password is going to be admin//pfsense.

Logging in. Default username // password is admin // pfsense

Just run through the setup wizard with the defaults, making sure you give it a strong password that’s different from your Proxmox box (just in case!) and go ahead and check for updates.

Next, the official pfSense documentation advises you to turn off some of the “hardware offload” features since we’re running in a VM. Go to System -> Advanced -> Networking Tab.

Disable all Network-Related Hardware Acceleration — Important since we’re actually connected to a virtual bridge

While you’re in this tab, set up two important IPv6 settings: 1) Make sure you have “Allow IPv6” set, and 2) Do not generate local IPv6 DNS entries. Not generating DNS entries tends to make all of your local LAN-LAN communication default to IPv4 (which should be totally fine!), but still allows IPv6 for the internet.

Change IPv6 Options

Next, enable AES support if your hardware supports it. From the home page, check to see if you have this line AES-NI CPU Crypto: Yes (inactive).

Do you have AES-NI Support?

If so, go to System -> Advanced -> Miscellaneous tab and enable AES-NI CPU-based Acceleration.

Enable AES-NI if supported

Temporary Rules You’ll Have to Revert Later

Since we’re currently debugging behind our LAN, we want to allow our development PC to access the rest of the network. Navigate to Interfaces -> WAN and uncheck the “Block private networks and loopback addresses”. After you save, pfSense will prompt you to ‘apply changes’.

Interfaces -> WAN. Until we’re actually connected to the WAN, let’s allow local addresses

Quick note: I mentioned double-NAT or carrier grade NAT before. If your ISP gives you an IP address of 192.168.x, 172.16.x-172.31.x, or 10.x. you’re behind your ISP’s private network and might have to leave this feature off with little other choice.

When we configure VLANs, we’re going to lose access to the pfSense box since we’re directly plugged into it and we don’t really want to deal with VLANs directly on our development PC, assuming we even can. To work around this, we’re going to enable a dangerous setting — allow access to pfSense admin through the WAN port. Make sure you don’t forget to disable this when you plug it into the real internet. In case you do forget, at least you set a strong pfSense password, right? Right?

Go to Firewall -> Rules -> WAN. Add a new rule at the top. Select action -> Pass. Destination Port Range -> HTTPS. Fill in whatever description makes you remember to delete it. When you’re done, it should look similar to the one below. Hit Apply Changes.

Since our WAN port is still on the local network, allow access to the web GUI

To make sure this worked, we’re going to plug our PC into the same router pfSense is currently on. Take note of of the IP address in the main page of pfSense. NOTE: If you’re willing to forego internet access on your development computer, give your WAN a static IP and connect directly to it on your development PC.

Take a note of the ‘WAN’ IP address

You should be able to access your pfSense web interface by that IP address when plugged in to either the LAN port from pfSense or into another LAN port on the router while pfSense is connected to it. Make sure it’s working while your PC is plugged in to the router alongside pfSense.

Finally — VLAN configuration in pfSense

Go to Interfaces -> Assignments -> VLAN tab. Click the “Add” button and begin adding your VLANs. You’ll want everything assigned to LAN. Priority is optional, and can be used later for packet prioritization and QoS. I’d suggest leaving it the default for now and configuring it later if/when you get around to QoS.

Here are my VLANs

In order for the VLANs to do anything useful, we have to start adding them to the LAN and configuring your firewall rules.

Go back to the “Interface Assignments” main tab and click ‘Add’ until all your VLANs appear.

First go into your LAN interface and set IPv4 Configuration to “None” and Save.

Remove IPv4 from the VLAN Trunk

You’ll want to hit “Apply Changes” immediately.

Then go into each interface and make a few key changes. 1) Change the description to something more useful. I went with (for example) LAN5 for VLAN 5. 2) Set each VLAN to have a Static IPv4. 3) Set the IPv4 Address to the range you want. Again, for VLAN 5, I’m choosing 10.5.0.1. VLAN 47 would be 10.47.0.1, etc. 4) Set your netmask (right of IPv4 Address) to your chosen config (again, I recommend /16).

My Configuration for VLAN 5

Repeat this for all VLANs, and hit “Apply Changes” on the last one.

Once your VLANs are complete, you should “Delete” the base “LAN” interface, leaving only the VLANs.

When you’re all finished, your interfaces should look something like this.

Network Interface Assignments — Completed Double-check on this screen that every VLAN is available, is assigned to your LAN vtnet, and the ‘base’ non-VLAN tagged LAN is unconfigured

Now, go to Services -> DHCP Server. Click on each interface, choose to “Enable” the server, and pick the range. My setup is for DHCP range is going to be 10.<VLAN>.128.1 to 10.<VLAN>.255.254. That way I can put static IPs anywhere in the .0.X through .127.X range.

Note — we’ll go back to IPv6 later.

DHCP Settings for my VLAN 5

Save and repeat this configuration for all VLANs. Tab through and double-check that you got all the settings right.

Not obvious (gah — these are the little things that take sooo long when you’re doing this for the first time), but you have to restart the DHCP service for it to work. Click the little ‘restart’ icon in the top-right corner.

Restart DHCP When Finished

VLAN Firewall Rules

Right now your VLANs are like virtually ethernet cables strung across the floor, there’s no rules for how they’re plugged in to anything, and they shouldn’t really do anything. This is also where the real power of VLANs becomes apparent. This is how you isolate and manage traffic.

Quick basics about the pfSense firewall — by default, if there’s no accept rule, it won’t happen. Earlier on when we added a rule to the WAN to allow access to the web GUI, we had to do that because nothing allowed it to happen. This means that by default, all traffic from the WAN got discarded. If you tab over to the LAN, there will be a default rule that allows LAN to ANY, meaning that the LAN could access the internet (or really anything). Also important, the firewall is stateful, meaning that once a connection is established, two-way comms are allowed. This allows you to (for example) send out a request for a web page, and then actually see the response.

Additionally, rules are evaluated in order, first by the ‘Interface’ rules (this allows, for example, your DHCP server we just set up to actually work), then the firewall page ‘Floating’ rules, top-to-bottom, then the specific interface. The first match wins. For example, if you put an “Allow all” rule as the first thing in the firewall, no other rules will get evaluated. This means your order of operation should always be deny followed by allow. Finally, there are two types of deny rules: Block and Reject. Block silently discards packets, and Reject sends a response. For example, this is the difference between pinging a host and getting a timeout a few seconds later vs an immediate ‘host not found’. In general when there’s a very low-trust network (such as the internet) you should block packets “la la la — I can’t hear you” vs leaking information that invites an attacker to keep trying. On the other hand, if a rule is likely to be triggered on a higher-trust internal network, you should consider reject so that the user (probably you in this case) gets immediate feedback.

First thing first, we’re going to update some of the default DNS settings. Navigate to Services -> DNS Resolver, scroll near the bottom and check the three useful non-default “DHCP Registration”, “Static DHCP”, and “OpenVPN Clients”. These settings allow you to ping a computer by host name. Click save, then apply.

Enable the pfSense DNS server to use host names

This setting allows you to access pfSense (or any other PC on your network) by it’s host name.

What registering DHCP host names does (after a restart)

Interestingly, allowing access to “the internet” without allowing access to “everything” is somewhat complicated in pfSense. The easiest way I’ve found to do this is to create a list of all LAN IPs and create a rule that says “everything that’s not a LAN IP must be the internet”.

To do this, navigate to Firewall -> Aliases, and create a new alias. Name it something like “LAN_IPs” and give it a useful description. The important part is to create the three ‘networks’ with the correct subnet mask. If you want to follow along, here are my settings in text for you to copy-paste, enter them, save, and apply changes:

Name: LAN_IPs
Description: List of LAN addresses from RFC 1918 and RFC 4193
Type: Network(s)
Networks (Name / Mask) Description:
192.168.0.0 / 16 192.168.xxx Private LAN Addresses
172.16.0.0 / 12 172.16.xxx-172.31.xxx Private LAN Addresses
10.0.0.0 / 8 10.x Private LAN Addresses
127.0.0.0 / 8 127.x Loopback addresses
fc00:: / 7 IPv6 Unique Local Addresses
Firewall Alias for LAN_IPs

Finally, one more ‘Alias’ really helps simplify your rules. Go to Interfaces -> Assignments, Interface Groups tab and add all your VLANs to a “Local” group. This lets you make rules that apply globally to each VLAN. I chose not to, but this would also be the place to make groups like “internet access” if you find it convenient and don’t want to repeat yourself.

Make a new “Local” Interface Group

Next, you’ll want to set up the global rules for all of your Local interfaces.

The lower rule is fairly important and allows pings to this firewall. My rules allow ‘this’ firewall to act as a domain server and reject DNS from other sources. Navigate to Firewall -> Rules -> Local tab and implement these rules as you see fit. The * in the rule stands for ‘any’. Note that my reject rule is useful only as a ‘suggestion’ to not use other DNS servers and is helpful in (for example) making sure Android clients can access local network PCs by host name. Note that malicious actors (or legitimate users!) can use DNS over HTTPS to get around this rule (it’s a major pain point for corporate network admins and fascist countries alike who try to restrict internet access).

My final Local Rules — Make this Firewall the only DNS server and Allow Pings

Next, tab into the WAN interface and configure the following rules. Note that I took this screenshot later and so have the “Dangerous WAN access” rule disabled.

Basically, these rules prevent anything coming from a “LAN” to appear from the internet interface (it’s probably bogus traffic) and allow IPv6 ICMP, which is required to actually get your IPv6 negotiation working (this was another ridiculous pain point and part of why I made this tutorial). Note that this does allow anybody on the internet to (IPv6) ping any PC down into your network. It’s a little uncomfortable, but it’s how IPv6 works. Note that I do NOT have an IPv4 ICMP rule. This means my firewall will not respond to IPv4 pings. That’s fine/good with me. IPv4 is routinely port-scanned and takes only a few hours for a PC to run through. IPv6 is so large it isn’t happening unless somebody knows exactly which device they’re looking for (i.e. prior communication was established).

My Final WAN Configuration

Go take a look at your planning diagram and figure out which VLANs need access to which elements.

Here’s a refresher on my planning diagram (Note some bi-directional arrows)

Go into your Firewall -> Rules and tab over into each configuration and allow the rules you want.

Important: Make sure you set a rule that explicitly allows SSH and HTTPS ports to “This Firewall” from any networks you want to do configuration on. In my case VLAN 5. This prevents you from locking yourself out.

For internet, you’ll want to select destination: (Invert Match) LAN_IPs. This says that any packet from a VLAN is allowed to make it to the internet. Note you can / should copy-paste rules to the other VLANs to make your life easier.

Enable Internet Access

Create all your generic VLAN routing rules this way (make use of the ‘Copy’ button on the firewall rules page). Then ‘Apply Changes’ when you’re done. Here are all of my rules:

The VLAN with the most access is VLAN5. It has the anti-lockout rule, allows access to the internet, access to all but the guest VLAN, and access to my upstream cable modem at 192.168.100.1.

LAN 5, Trusted PCs. Allow configuration access to the firewall, access to most VLANs, and upstream access to the cable modem

The next few VLANs are much easier and allow access to only the internet, and an increasingly small group of other VLANs. Note that these are all basic permissive rules. The ‘Trusted Devices’ can access basically anything (except for the guest network), while the far other end is the guests on VLAN 181 who can only see the internet.

VLAN 47: Internet Access and 2 VLANs
VLAN 89: Internet and Server VLAN only

VLAN 113 is identical to VLAN 89 and not shown.

VLAN 181 — Guest Network, Internet Access

Connecting to your managed switch

If you’re following along, you should be able to plug in directly to the tagged “Local PC” port and get a valid IP address. If you went with the 2-port device route, you’ll have to configure your switch VLANs on the switch to be able to test.

Success! From my VLAN 5 system, I get a 10.5.x address, and can access the web portal at 10.5.0.1

Now — let’s get the managed switch up and running. For my managed switch and wireless AP, I’m going to use my Linksys routers running OpenWrt. However, I’m going to eventually upgrade to Ubiquiti for the real pro-sumer. This really sounds like an ad, but it’s not. If you’re not sold on the benefits, it’s comparably priced to a ‘normal’ WiFi router (Ubiquiti managed switch + wireless AP is pretty close to my now ~$200 Linksys WRT3200ACM), is designed for small business use, and has power-over-ethernet to allow access points or IP cameras to be installed anywhere you can get an ethernet cable.

Fortunately, the concepts of OpenWrt configuration transfer to any managed switch or router out there. If you’re not running a ‘real’ managed switch, you should really switch to something like OpenWRT or DD-WRT. The OEM firmware just doesn’t cut it for all the reasons I ranted about in the beginning of this post.

If, like me, you’re using a router instead of a managed switch, try not to use the WAN port for anything important / fast. The reason being the WAN port is sometimes configured as a completely separate NIC and the CPU is required to be ‘in the loop’ routing all traffic (normally a benefit when the device is working as a firewall!). The CPU in this router may struggle to hit the gigabit speeds of the NIC while software packet-forwarding. Now — all that said, I’m going to tie the ‘WAN’ port to VLAN 5 intending to use it for trusted PCs / management, but nothing I’m going to use daily.

Here I am with a “factory fresh” OpenWRT image on a Linksys WRT3200ACM

Configure your switch VLANs

Navigate to Network -> Switch and take a look at this configuration.

My ‘Switch’ Configuration in OpenWRT on a Linksys Router

The default for OpenWRT is to use two VLANs ‘1’ and ‘2’ (btw — remember when security people said not to use default VLAN 1 — this is why) for LAN, and WAN respectively. The ‘tagged’ and ‘untagged’ notation was covered just a little bit in the previous parts of this tutorial. Going a little more in-depth, a ‘tagged’ interface means that traffic from that VLAN is marked / tagged as coming from that VLAN. In this case, it’s tagged only on the CPU so that the CPU ‘knows’ where it came from for purposes of firewalling it. “Untagged” by comparison means that any VLAN tags are stripped from that port, i.e. so the clients aren’t aware of the VLAN existence. Again, this default configuration strips all tags (if they exist) from the LAN and WAN, re-tags them for the CPU / firewall, and strips them off on the way out. Pretty standard, and what we’ve done so far for everything but our ‘trunk’ port.

I’m going to leave my PC plugged in to the switch on the LAN 4 port, and plug the trunk port from my pfSense / Proxmox box on port 1.

Potential landmine with dual CPU Linksys routers (WRT1200AC, WRT1900AC, WRT1900ACS, WRT3200ACM, WRT32X): Don’t tag both CPUs on a VLAN. You’ll end up with very high packet loss, possibly high enough you’ll lock yourself out of SSH or the web interface. From the research I’ve done, it appears you can tag a CPU to give it exclusive access to a network, and it handles ‘all’ the loads of that network. Easy enough where there’s a default LAN / WAN — one CPU per network. In my case, I’m dedicating one CPU to VLAN 5, and letting the other CPU handle the other network traffic. I’m not sure if this makes a difference. Somebody more knowledgeable please fill me in!

Configure this and hit ‘Save’, but do not apply yet. Note my IP address change, I took this screenshot after following this and the next step. Yours should still be the default (192.168.1.1) on this screen.

Tag all VLANs you want access to per interface. Leave CPUs and VLAN trunks “tagged” (equivalent to VLAN Aware) and leave single-VLAN ports “untagged” to strip the VLAN tags on data going out

Now, tab over to Network -> Interfaces and delete everything. Then create a new interfaces for each VLAN and edit it with the following settings:

Protocol: Either “unmanaged” or “Static IPv4”. Pick unmanaged if you don’t want the AP to have an IP address on that network. It will still pass traffic, but will just be invisible.

Static IPv4 address: something that would be appropriate for the VLAN you want the swith to be accessible on. In my case, I’m going to put it on VLAN 5 and give it a static 10.5.0.2 address with netmask /16 (or 255.255.0.0).

Gateway: Your pfSense box (in my case 10.5.0.1)

Then Physical Settings: Bridge Interfaces, and pick your VLAN you want the IP to be on. In my case, eth0.5. I also selected ‘eth1’ consistent with the above screenshot to allow the former ‘WAN’ port to be software-bridged to VLAN 5.

Then DHCP Server: “Ignore”.

My new OpenWrt “LAN” IP Settings (Note: I took this screenshot after the next step, the IP should still be the old 192.168.1.1)
My OpenWrt Bridge Settings
OpenWRT — Turn off DHCP
This is what is should look like when you’re done (again — my IP address is ‘wrong’ since I took the screenshots after the next step)

Finally, go to System -> Startup and disable the following three items from starting up (don’t need them, they just burn CPU cycles and potentially get in your way): dnsmasq, firewall, odhcpd.

Disable DHCP Server, DNS Server, and Firewall from booting

Now, hit “Save and Apply” and try to access the router from its new static IP address (you may have to re-enable your ethernet to get a new IP address). You should be on the VLAN network, and have access at the new address. Note for OpenWRT if you don’t do this in 90 seconds, it should revert your old settings automatically to prevent you from getting locked out.

If your switch isn’t back up in 60 seconds or so, just power cycle it (I think the hardware reconfiguration of the switch doesn’t always work correctly without a power cycle).

Once you’re successfully logged in with that new IP address, the “No password set!” warning should really be bothering you. Go create a totally different strong password in your password manager for this device.

Yet another totally unique one-off password

Optional: Plug into the internet now

If you went the two-port Proxmox route, this should be the first time you can communicate with both devices at once. Either way, now is the time to undo our mods. Go disable WAN access to your pfSense web interface / SSH. At this point, you’re safe enough to plug into the internet if you want.

Configuring Managed APs

In this case, I’m going to continue my OpenWRT config and add WiFi to the VLANs that need them.

Just create a new WiFi SSID as usual, select “Access Point” mode, and ‘bridge’ to the network (VLAN) you want. WPA2-PSK security is “the standard” and is supported by almost every device I’ve seen. Store your SSIDs and (unique per SSID!) passwords in Bitwarden. Especially for the less-trusted networks, use the “Isolate Clients” feature to force client-client traffic into the firewall (advanced settings in OpenWRT).

Bridge the WiFI to the VLAN you want

Optional: Adjust your WiFi signal strength

By the way, the best advice I’ve seen for mixed (2.4 GHz and 5 GHz) networks is to use the same SSID for both networks so that devices seamlessly roam and adjust the 2.4 GHz network transmit power to be at least 6 dB below the 5 GHz network so that the 5 GHz network is stronger and preferred by default since it’s faster. Additionally, you want to keep your 2.4 GHz WiFi strength as low as reasonable to avoid interfering with your neighbors and needlessly broadcasting your signal to the entire neighborhood — unless you plan on using your WiFi from the next block over.

TLDR if you want to copy my settings:

  • 5 GHz WiFi: 23 dBM, 199 mW
  • 2.4 GHz Wifi: 14 dBM, 25 mW

Note: Don’t enable the 1000 mW broadcast. It’s just silly and is meant for AP<-> AP communication over long distances. Your cell phone sure as heck won’t broadcast back at 1 Watt.

Here’s the best way to adjust signal strength in my experience. I have two APs to cover my entire house (one in the basement, one in the garage). I turned the 5 GHz power all the way up and looked at the signal to noise ratio from near-ish to the router. The signal stayed 20–30 dB above the noise, which was pretty good. Note: some APs are really bad with high transmit powers, and cutting it in half to get a better SNR is always good! Check to see if cutting power gets you a consistent SNR of at least 20 dB and stick with that one. By comparison my 2.4 GHz WiFi gets a SNR of 60+ which is fantastic.

Then I installed a WiFi strength / speed meter (WiFiman on Android) and found the worst area of my house where I expected the basement AP to be the strongest signal and 5 GHz speeds were still acceptable. The WiFiman app will show you the signal strength for both the 5 GHz and 2.4 GHz signal with the same name. I then just kept dropping the 2.4 GHz signal strength on the router until it was slightly lower than the 5 GHz signal at that location.

Edit after the fact — I had to bump the 2.4 GHz signal up a bit from the original method (my TLDR values are accurate though) since 2.4 GHz wasn’t quite good enough at the far corners. However, walking around the house with both APs active, the 5 GHz signal is stronger in most places, neither AP ever drops below the ‘yellow’ anywhere I’d expect to use WiFi, and my signal is significantly stronger than my neighbor’s within my house, but quickly drops off when you leave my property.

Finishing touches

Configuring Proxmox Management Interface to use VLAN

Now that you have a managed switch set up, you should be able to access your original Proxmox VE server through it’s VLAN address (mine was https://10.47.1.1:8006) and all is right with the world.

If you wanted, it would be reasonable to break the management bridge and just rely on VLANs from here on out.

Here’s a screenshot of my new (final) config. I deleted the original management bridge with the 192.168.2.x address, added enp6s0 to the OVS bridge, and assigned it to VLAN 47 (my server port). Finally, I added that URL to Bitwarden so I won’t forget it :).

Getting IPv6 Working “Correctly”

Again, this was one of the most challenging aspects of this whole thing. I really couldn’t find a good all-in-one tutorial and hope this helps you!

I already covered the firewall rules, but the first thing is to allow IPv6 ICMP packets through.

Next, go to Interfaces -> WAN and enabled IPv6 Configuration Type -> DHCP6, then scroll down and select “DHCPv6 Prefix Delegation Size” of 56. I covered this in the tutorial section, but this allows you to allocate 256 different subnets (remember how I recommended < 256 VLANs) and hand them out to your VLANs. Also choose the next check mark to “send the prefix hint”.

Important: IPv6 On multiple VLANs requires you to pull a /56 prefix delegation (could be smaller, but most ISPs seem to allow this one) and the prefix hint.

Note my “Debug” checkmark. Completely optional, but I spent a lot of time debugging making this tutorial.

At this point, after saving, I’m pretty sure you have to reboot pfSense to reliably get a new IPv6 negotation from your ISP.

Here’s how you’ll know it was successful. Tab over into your first VLAN and choose “IPv6 Configuration Type -> Track Interface”.

Make your VLANs “Track Interface” for IPv6

Then scroll down, and choose interface source as WAN. Since you requested a /56 prefix, you’ll have 256 subnets available, or 0 to FF. I’m doing the same thing for my VLANs in IPv6 as I did in IPv4 and assigning their VLAN ID to the prefix. In my case (decimal = 0xHEX): 5 = 0x05, 47 = 0x2F, 89=0x59, 113 = 0x71, and 181 = 0xB5.

LAN 5 DHCPv6 Configuration. Track WAN Interface, Previx ID of 0x05.

Once you’re done and saved (and given a minute or two for the network IPv6 negotiation to occur), you should have IPv6 addresses for all of your interfaces visible on the “front page” dashboard of pfSense.

Goal: IPv6 on all interfaces

IF this doesn’t work, here are your next debug steps:

  1. Reboot the WAN interface. Go to WAN, disable, save. Then enable, save, apply changes. Wait a minute for interface to reboot.
  2. Set one of your VLANs to prefix zero and make sure it gets an IP address.
  3. If zero gets an IP address, move all VLANs to prefixs between 0 and F.

What those debug steps do. Reboot is obvious. If you can get prefixes between 0 and F, it means your ISP only allows a prefix delegation of /60. Go ahead and change your WAN “DHCPv6 Prefix Delegation Size” to “60”. IF you want to call and complain because you have more than 16 VLANs you’re welcome to try.

If you can only get prefix of “0” to work, it means your ISP is limiting you to /64. Unfortunately, there’s not much you can do. Only one of your VLANs can get native IPv6 and your ISP is running afoul of the RFC 6177 best practice, specifically “it should be easy for an end site to obtain address space to number multiple subnets (i.e., a block larger than a single /64)”. Seriously — call, ask, be kind, you might actually get somewhere. Remember, there’s plenty of IPv6 room to go around and the sys admins are nerds themselves, they understand that you want to learn and grow.

If all of this works, you should get an IPv6 address on your PC, and the standard IPv6 test sites should pass.

For example, ipv6.google.com and https://ipv6-test.com/

IPv6 100% Working!

In addition, I verified through http://ipv6-test.com/pingtest/ that my actual computer’s IPv6 address was showing up, not my router’s, and that sure enough — pings to my router are silently timing out, but IPv6 pings to my PC behind my network are working.

Success! ipv6-test.com is showing that I can directly ping my PC fast the firewall in IPv6 only

Finishing Touches: Safer DNS

This section covers how to use Cloudflare’s DNS. It’s a 3rd-party audited fast and privacy-guaranteed DNS resolver. We’re going to set up an encrypted connection to their servers for all the DNS resolution in pfSense and the rest of your network.

DNS (Domain Name Resolution) is how you turn a domain name into an IP address. Unfortunately, DNS traffic isn’t encrypted and the default for most people is to go ask your ISP, which hands a private company that knows your name and address all the websites you visit. At best, they have no incentive to protect your privacy. At worst, they can legally sell the data for targetted ads, blackmail, you name it. Really, there’s no reason to trust them given that our ISPs are lobbying against encrypted DNS, have been caught using their DNS to serve advertisements and tracking cookies, and charge extra to not track you. Wow.

I actually really want to give a shout-out to pfSense here. By default they ignore your WAN connection DNS servers and go straight to the internet root servers. This is a fantastic step in the right direction. By default, just running pfSense, you’re better than 99% of the users out there. However, even if you don’t use the ISP’s DNS resolver, since default DNS traffic is unencrypted, it’s easy for them to ‘skim’ the data anyway.

Just getting this out of the way- but this is NOT sufficient to “really ” hide your tracks, but I don’t really have anything too valuable to hide and am treating this more like home security — make your house just a little bit less tempting than your neighbor’s.

Tab over to System-> General Setup. Add the following DNS servers from Cloudflare with “cloudflare-dns.com” as the host name:

  • 1.1.1.1
  • 1.0.0.1
  • 2606:4700:4700::1111
  • 2606:4700:4700::1001

Go ahead and uncheck the “Allow DNS Server to be overriden by DHCP/PPP on WAN” (this is only used for the firewall, not your clients — again belt and suspenders).

Add in CloudFlare’s Servers

Save and apply changes.

Then navigate to Services->DNS Resolver. For options: allow it to respond to incoming SSL/TLS queries (i.e. allow encrypted DNS on the LAN / WiFi), choose to “Enable Forwarding Mode”, and “Use SSL/TLS for outgoing DNS Queries to Forwarding Servers”.

Your settings should look like the following:

Complete DNS Settings Page

Save and apply changes.

Check that it’s working in pfSense:

In pfSense, navigate to Diagnostics -> DNS Lookup and run a query.

pfSense success — using Cloudlare’s DNS

Finishing Touches: UPnP

Remember that whole NAT problem and port forwarding thing? One of the “problems” with a firewall is it does exactly what it’s supposed to — prevent clients from establishing communication with each other. Sometimes peer-to-peer communication is desirable instead of going through a server (audio video chat is the big one). In particular, these firewall ‘holes’ are almost absolutely required if you’re using game consoles like Xbox or Playstation for peer-to-peer gaming and voice chat. The solution is UPnP or “Universal Plug and Play”.

Enabling UPnP is definitely a security vs usability trade-off. A lot of security exports abhore it since it allows devices to request internet-facing ports to be opened for them to use. There have been some pretty infamous UPnP vulnerabilties in consumer-grade routers (again — don’t do that) where they allowed UPnP requests to come from the internet instead of internal networks. The way I see it, if you allow HTML / HTTPS web traffic to a device, you’re already trusting it with “anything” a bad actor could do. UPnP is a pretty minor additionally vulnerability if properly configured as pfSense does.

All that said, I want my video game consoles to work. Navigate to Services -> UPnP and NAT-PMP.

I enabled all services for LAN 5 (main PCs) and LAN 113 (Guests) only. Important: DO NOT SELECT WAN as an interface — you don’t want to Netgear yourself.

Enable UPnP for the PC networks only

For gaming consoles in particular, you’ll have to make one more change. By default pfSense randomizes the outbound port when doing NAT to prevent “fingerprinting” of the applications behind the firewall. My PS4s in particular don’t like this and you’ll find endless threads of people complaining that uPnP doesn’t work. Point them here!

Navigate to Firewall -> NAT, Outbound tab.

Click the “Manual Output NAT rule generation” and Save.

Select Manual Output NAT Rule Generation

Select the rules for “Source” as you see fit. In my case, I’m allowing ALL. You can restrict to problematic hosts like your PS4s if you want. Select “Static Port” under port range.

Create a new rule and allow “Static Port”

My new rule is shown on top of the auto-created rules. The “Static Port” column has a check-mark vs with a tooltip of “Keep Source Port Static” vs the crossing arrows icon with a tooltip of “Randomize Source Port.”

New rule for static source port for outbound NAT

Make a backup

You should set up a backup solution in Proxmox. Note that backing up Proxmox itself is going to be somewhat hardware dependent, so “just restoring it” isn’t going to work if you move it to a different PC. Now — pfSense itself should come along pretty easily since it only has two network ports and no ‘real’ hardware dependence.

However, for now, we have a working VM, and the pfSense VM has the minimally-required customization. That’s part of the point of making it a VM. Back it up manually for now.

Hop into your Proxmox setup, navigate to your pfSense box, Backup, and choose Backup Now.

Make a quick backup in Proxmox

There’s no way to easily download the VM, but your very next step should be to set up your Proxmox backups (this tutorial is already too long). In my case, I just added an NFS share to Proxmox / Synology in the Proxmox “Datacenter” tab and configured the built-in Proxmox backup to make weekly backups of it.

Done!

I hope this helped you out. Please leave comments if something isn’t clear. I know this was long and winding, but my goal is for you to be able to get all this working and understand why with significantly less than the hundreds of tabs and dozens of hours I spent on it. :) This is really powerful technology and something I really wish was more accessible to the amateur home enthusiast.

--

--