Firewall-on-a-stick with pfSense

Generally, a firewall uses multiple network interfaces to define security zones (public, private, dmz, etc.), and building a PC-based firewall requires the installation of multiple network cards in a host computer. But what if you want to use a small form-factor PC like the Intel NUC as your firewall device? Mini PC's are great. They don't take up much space and they produce very little heat or noise. The problem with mini PCs is that they usually only include a single network interface. But that's not an issue if you use pfSense as your firewall and combine it with a VLAN-capable ethernet switch. In routing terms, when we have a switch configured with multiple VLANs and we pass traffic between networks using a single-interface router, we call this "router-on-a-stick". As we'll be doing basically the same thing with a firewall, we'll call this config "firewall-on-a-stick".

For those unfamiliar, pfSense is a firewall distribution based on the FreeBSD operating system. pfSense incorporates advanced networking and firewalling capabilities and uses a straightforward web-based console for configuration and administration. While it can run on dedicated firewall appliances, pfSense is often deployed on commodity x86 and x86-64 PC hardware.

Downloading and installing pfSense is beyond the scope of this article, but you can find all of the relevant documentation available on the project wiki. The installation process is pretty simple and for most users it will involve downloading the installation image, writing it to a USB thumb drive, booting the firewall PC from the thumb drive, and following the prompts to complete the installation. On first boot, the pfSense CLI will walk you through some basic configuration (enough to get you to the web configuration interface).

Required materials

For this setup, you will need two main components: a computer with a single network interface, and an ethernet switch that supports VLANs and 802.1q tagging (also referred to as simply "dot1q"). VLANs allow a single switch to be divided into multiple virtual LANs isolated from one another, and to assign specific ports on the switch to different networks. Dot1q allows multiple VLANs to co-exist on a single port, by tagging ethernet frames with their respective VLAN number.

If you don't already own a VLAN-capable switch that supports 802.1q tagging, the good news is that they have become relatively inexpensive in recent years. For example, you can buy a Cisco SG200-08 8-port gigabit managed switch for less than $90 (at the time of this writing). This layer 2 managed switch supports VLANs and dot1q as well as QoS, and is a decent switch for the purposes of a home network. There are hardware options from other various competitors, at higher and lower price points. I would strongly advise that whatever switch vendor you choose, make sure to purchase a gigabit-capable switch, for reasons I'll discuss next.


As stated previously, most firewalls rely on multiple physical interfaces to define security zones. The firewall routes packets between these interfaces to facilitate connectivity and filters inter-interface communication based on defined rules. In the configuration presented here, the firewall will have multiple virtual interfaces sharing a single physical interface and security zones will be defined using the virtual interfaces. If configured properly, it is my educated opinion that this presents no less of a secure solution than implementing firewall rules using multiple physical interfaces. But as a standard disclaimer, use this configuration at your own risk, I assume no responsibility for loss or damage, etc.

The one major caveat with this configuration concerns network performance. A multi-interface firewall has at its disposal the full bandwidth of each physical interface assigned to a given network. For example, let's say a firewall has a 1Gbps link in DMZ0 and a 1Gbps link in DMZ1, and a backplane capable of processing the full line speed of the network interfaces. If MachineA in DMZ0 copies a file to MachineB in DMZ1, that communication can take place at speeds of up to 1Gbps. MachineA sends packets into the firewall at 1Gbps, and the firewall sends packets to MachineB at 1Gbps.

But if the firewall has a single 1Gbps interface, with a virtual interface in DMZ0 and a virtual interface in DMZ1, the inbound traffic (on DMZ0) shares the same physical interface as the outbound traffic (on DMZ1). In effect, the available bandwidth is one half the total bandwidth of the physical interface. Further, as we add more VLANs and more virtual interfaces to the firewall, we further subdivide the physical interface and the available bandwidth of any given connection is decreased. This is not a linear reduction (an idle VLAN uses no bandwidth), but in the aggregate the more VLANs we add with active traffic the slower the inter-VLAN traffic will become. So there is a scaling issue with this solution.

For most home networks where there may be only a handful of VLANs, this probably doesn't present an issue. The most common case where it might be a problem is if you have a fileserver on one VLAN and client computers on a different VLAN. If these machines were all on the same LAN previously, you will notice that your file copy speeds are now around half as fast as what they used to be. The obvious solution is to plan your VLANs accordingly, and to put high bandwidth services on the same VLAN as the computers accessing them.

Planning your VLANs

In this example I will use four VLANs, but obviously you should tailor your own VLAN config to your specific needs. The key thing to remember is to plan out which VLAN you will use for each specific network ahead of time, and map them out or take good notes. Otherwise you will likely find yourself confused during configuration, or re-doing work to correct missteps.

For this config, I will create four VLANs and assign them to ports on an 8-port switch.

  • VLAN 10 This will be my inside, private network.
  • VLAN 20 This will be a separate VLAN for my wireless access point and connected WiFi devices.
  • VLAN 30 This network will be a DMZ for hosting my home Minecraft server that I share with friends and which is publicly accessible from the Internet.
  • VLAN 99 This will be the outside network shared by the firewall's public interface and my cable modem.

VLAN numbering is arbitrary, and you can assign whatever VLAN numbers you like as long as they are supported by your switch (valid VLAN numbers are between 1 and 4094 on most switches, with 0 and 4095 reserved). However, note that I did not use VLAN 1 in my numbering scheme above. In my switch configuration, I will leave VLAN 1 as the default VLAN. This means that any port which is not configured for a different VLAN will use VLAN 1 as its VLAN by default. By not configuring VLAN 1 to attach to any firewall interface, VLAN 1 becomes an isolated "null" VLAN disconnected from everything else. This ensures that if a switch port with a default configuration is mistakenly connected to a device, that device won't be unintentionally connected to one of my secured networks.

Configuring the switch

Configuration tasks for the switch hardware will vary with vendor and model, but the general concepts are common. You will have two or more untagged "access" ports, and one tagged "trunk" port. An untagged port expects that devices connected to it are not configured for 802.1q and ethernet frames coming into that port will not have 802.1q tags present. The untagged port will add tagging as it passes traffic into the switch's backplane, to associate incoming frames with the VLAN number configured on that port. In contrast, a tagged port expects that devices connected to it are configured to use 802.1q tagging so it does not add tags to inbound ethernet frames. Rather, it uses each frame's existing 802.1q tags to associate that frame to a specific VLAN. The pfSense firewall will be configured to use 802.1q tagging, so we will attach it to a tagged trunk port.

The switch configuration tasks will be something like:

  1. Define the VLANs in your switch. Create each VLAN and assign it a number.
  2. Assign untagged VLANs to your access ports. Decide which devices will plug into each switch port, and which VLAN that device should be attached to. Configure each of these ports with the appropriate VLAN as "untagged".
  3. Configure your trunk port. For the port where you will plug in the pfSense firewall, assign all of your defined VLANs as "tagged".

A diagram may be helpful here:

                99T   99U   30U   20U   10U   10U   10U   10U
            |  +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+  |
            |  | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 |  |
            |  +-^-+ +-^-+ +-^-+ +-^-+ +-^-+ +-^-+ +-^-+ +-^-+  |
                 |     |     |     |     |     |     |     |
                 |     |     |     |     +-----+-----+-----+
                 |     |     |     |              |
                 |     |     |     |              |
+--------------+ |     |     |     |       +--------------+
|    pfSense   |-+     |     |     |       |  computers/  |
|   firewall   |       |     |     |       |   printers   |
+--------------+       |     |     |       +--------------+
+--------------+       |     |     |
|    cable     |-------+     |     |
|    modem     |             |     |
+--------------+             |     |
+--------------+             |     |
|   Minecraft  |-------------+     |
|    server    |                   |
+--------------+                   |
+--------------+                   |
|     WiFi     |-------------------+
| access point |

Fig. 1: The pfSense firewall is connected to the tagged trunk port. All other devices are connected to untagged ports in specific VLANs.

Configuring pfSense

The next task is to configure pfSense to use the VLANs you've defined in your switch, and to create a virtual interfaces associated with each specific VLAN. If you have performed a fresh install of pfSense, the first time you boot up after installation the CLI will guide you through configuring the interfaces:

Valid interfaces are:

em0 c4:04:15:f9:72:61 (up) Intel(R) PRO/1000 Network Connection 7.4.2

Do you want to set up VLANs first?

If you are not going to use VLANs, or only for optional interfaces, you should
say no here and use the webConfigurator to configure VLANs later, if required.

Do you want to set up VLANs now [y|n]?

Answer 'yes' to setup your VLANs. You will add them one by one, and then you will be presented with the configured virtual interfaces:

VLAN interfaces:

em0_vlan99 VLAN tag 99, parent interface em0
em0_vlan10 VLAN tag 10, parent interface em0
em0_vlan20 VLAN tag 20, parent interface em0
em0_vlan30 VLAN tag 30, parent interface em0

Next you'll associate firewall interfaces to each of your virtual interfaces and assign IP addresses, just as you would with a physical interface. If you're unfamiliar with pfSense configuration, refer to the documentation regarding assign interfaces.

WAN (wan) -> em0_vlan99 -> v4/DHCP4:
LAN (lan) -> em0_vlan10 -> v4:
WLAN (opt1) -> em0_vlan20 -> v4:
DMZ (opt2) -> em0_vlan30 -> v4:

Once interface configuration is complete and the firewall reboots you should be able to ping the LAN IP from a computer connected to your inside VLAN, and to connect to the web configuration interface at http://<LAN address>.

If you want to make changes to the VLAN configuration later, you can do so in the web configuration interface. Select Interfaces from the top menu, and click (assign). Under the VLANs tab, you can add or change VLANs (remember to add them on your switch as well, and assign them as tagged VLANs to your firewall's trunk port). Under the Interface assignments tab, you can create new virtual interfaces, change the VLAN assignment for a virtual interface, or delete virtual interfaces.

For all other purposes, virtual interfaces can be configured in the same manner as physical interfaces. Rules are applied under the Firewall/Rules menu, and interface parameters such as addressing are configured under the Interfaces menu.

I hope you've found this information useful. If you have questions or feedback, shoot me an email. Thanks for reading.