How to use a pfSense virtual machine for a DMZ
If you’re starting out in the world of home servers and networking, you’ve probably heard the folk ballads of pfSense the wise, and rightly so. It’s a very powerful, very flexible networking tool that nearly achieves panacea status. It can handle your DNS, it can handle your firewalling, it can handle your routing, and it can do it all for free. You’ve probably also heard that it’s important to have a DMZ (short for de-militarised zone) that separates your web-facing stuff (servers that you want to access from the outside world) from your private stuff (your mum/wife/dog’s laptop, your smart fridge, and so on). And you’ve probably come to the conclusion that you’re going to need to spend a lot of money, because how can you have a DMZ without a separate, dedicated pfSense machine with your DMZ sitting off to one side of it, and your home network sitting on the other?
Well, you know what? You’re wrong. Luckily, I’m here to save you from capitalism and tell you how I did exactly that.
Chances are you’ll have a very basic, typical home network set up at the moment. Something like a WiFi router which everything is connected to, your hypervisor included. This was exactly my situation. For the visual learners, here’s how it looked.
Also, before reading this guide, you should be comfortable with certain terms and tasks. You should understand how LANs (and specifically DHCP) work, and what a virtual bridge is (it’s basically an Ethernet switch but in software instead of hardware). You should also be prepared to look up how to do certain menial things in pfSense, like set DHCP up and edit what IP ranges it offers. It’s not that I’m lazy for not including those, but simply that including them would make this guide even longer.
Finally, I set up all of the following with a 4-port Ethernet PCIe card on my server. That made having a dedicated port for lots of separate things drastically easier. I did say you wouldn’t have to spend a lot of money, and you don’t - 4-port cards are only AU$50, which is way cheaper than a dedicated pfSense box (usually $100+).
pfSense is mainly configured through its web GUI, which is only accessible if you’re on the same network as it. That’s an issue when you’re trying to set it up in a VM, because you’ll often be moving things on and off different sections of your home network and you may not have a connection when you actually need it. To remedy this, I didn’t actually change the layout of my network until the very last second - I set pfSense up with all the settings I wanted, but only actually moved the plugs and cables around when I was sure everything would work. This meant that I could access the web GUI without any trouble.
To do that, I set up my pfSense VM in Proxmox with its own virtual bridge, and assigned that to a separate Ethernet port on my physical server. I then plugged a cable from my router (still running) into that port, and this basically added the pfSense machine to my home network, meaning I could start up the web configurator and actually access it from my home network. I also added the virtual bridge that my hypervisor was using to pfSense (which would eventually be my DMZ), and added another virtual bridge on another dedicated Ethernet port (which would be where I plugged in my actual Internet cable to the outside world). Here’s the diagram.
This bit is pretty easy. What you’ll want to do here is to set up your WAN connection (the actual Internety, ISP bit), your LAN, and your DMZ.
Again, pretty easy. Just set up your WAN here the same way you did on your home router. For me, that’s a PPPoE login with a username and password.
Here, you’ll want to set up a regular network with DHCP. Make sure that you add one static routing (under the DHCP menu in the web GUI) for your WiFI router’s MAC address.
Again, this is a regular network with DHCP. Just make sure that you have a different range of IPs being offered than your LAN. For me, I had my LAN using the 192.168.x.x range, and my DMZ using the 10.0.0.x range. You may want to add a static routing for your hypervisor’s MAC address so that you know where to go to access its web GUI.
Okay, now that you’ve set up pfSense, it’s time to prepare your router for the changeover. All you really need to do is to open your router’s settings (yet another web GUI) and disable DHCP, because DHCP is going to be handled by pfSense now. Also, you’ll want to disable your router’s WAN connection (because the Internet will be handled by pfSense), and you’ll want to assign your router the IP address that you reserved for it in the LAN settings step.
Move the cables
Okay, recall that our (my) network currently looks like this, but has all its settings ready for a new layout.
Because we’ve already set everything up, we don’t need to worry about having any weird spaghetti connections just so we can make sure we can change settings on machines. We can just go straight ahead and set up our new network.
To do that, you’ll want to move your WAN (Internet) cable from your router to the dedicated port on your server that you told pfSense would be your WAN. You won’t need to move the cable from the pfSense LAN port to your router, because it’s actually still useful. You can just imagine that instead of running from the router to pfSense, it now runs from pfSense to the router (because pfSense is now the brains handling DHCP and WAN and such). You will want to remove the cable running from your router to your hypervisor, because otherwise that would put your hypervisor on your LAN. Remember, we actually want it on our DMZ, and we already have a virtual bridge connecting our hypervisor and pfSense which is our DMZ.
All in all, your (my) new setup should look something like this.
Once you’ve done that, you don’t actually need to worry about creating firewall rules to stop traffic between your LAN and your DMZ, because pfSense’s default behaviour is to stop any traffic without an explicit rule allowing that traffic to pass. Naturally, if you have anything you want to expose to the web (like SSH), just set up a NAT rule that opens the port of a machine on your DMZ to the outside world, and voila - the web can talk to your server without eavesdropping on your regular schtuff.
This is a pretty fiddly thing to do, so feel free to email me at ciao dot barilaro dot me for help.
TL;DR: To set up a DMZ with pfSense in a VM, give the VM two virtual bridges (with a dedicated Ethernet port) and also add the virtual bridge your hypervisor is using to it. Set up the former two with a LAN (with DHCP) and WAN, and the latter as a DMZ (with DHCP or static routing). Then, change your router’s settings to disable WAN and DHCP. Then, unplug your old cabling, and run your WAN cable to the dedicated pfSense port, and run a cable from the dedicated LAN port to your router. Your DMZ is already connected by virtual bridge.