I have been interested in setting up my own “home lab”. A “home lab” to me means I will have my own server infrastructure and possibly even non-trivial networking infrastructure in my own home, including separate LANs to keep my publicly facing self-hosted applications separate from my internal wireless network or video game consoles and such.1
I have chosen, for better or for worse, to run my infrastructure on FreeBSD because I feel it is more approachable a UNIX to explore intimately as an enthusiast network infrastructure engineer and relatively junior DevOps person (I recently switched over after a decade being an unremarkable but experienced Software Developer).
warning: these are not incredibly accurate
pfSense: a firewall/router project built off FreeBSD. A linux alternative would be dd-wrt.
FreeBSD: an open source unix clone with a different design philosophy than the more commonly-known Linux.</dd>
Bhyve/Iohyve: Virtualization software native to FreeBSD. This is similar to KVM on Linux.
Firewall: A software or hardware application that filters all network traffic coming it to keep malicious traffic out allow good traffic through.
Network bridge: A device that lets traffic pass through it unadultered. Useful for passing ethernet traffic from one physical media to another.
Network Router and/or Network Gateway: A device that sits as a single point separating an outside network from an “inside”/”private” network. There is a real difference between the two terms but I don’t know what it is.
Network Switch: A switch is a device that, uh, basically is like multiple bridges where traffic from any port can be sent to any other port. I don’t want to explain how it does this, so let’s just say it’s magic because the way switches work are actually hella interesting and fascinating. If you’re a keener, contrast ethernet switches against ethernet hubs.
I have, as most DSL Internet consumers do, a DSL modem and a home router. Unfortunately it does not support VLANs, which will be the building block of how I’ll achieve my aforementioned network separation even if I won’t talk about it in this post. This means I have to replace it with something better. Since I had already invested in a nice beefy server for running VMs on, it made a kind of sense2 to run my router as a Virtual Machine and pick up a nice enterprise-grade switch that could handle VLANs. I obviously need dedicated hardware to plug my networked devices into and out of, but the hardware device known as a router seems to be a combination of that switch hardware plus firewall and routing software, both of which are software and thus virtualizable.
You will need the following hardware to do this:
A diagram of how this will look like from a 3000 ft view is as follows:
Big Bad Internet => Cable/DSL Modem => Ethernet Port 0 on Virtual Machine => pfSense Virtual Machine => Ethernet Port 1 on Virtual Machine => Physical Switch
One of the nice things about having a dedicated hardware firewall is that there is a real physical isolation. With a firewall running in a virtual machine there are the following security concerns if not more:
Anyway, let’s get to it.
Add the following lines to your /etc/sysctl.conf
file, which I guess configures kernel runtimeoptions.
net.link.bridge.pfil_onlyip=0
(This allows non-IP traffic to flow over a bridge interface. I am unsure if this is needed.)net.link.tap.up_on_open=1
(This enables the VM network to be enabled implicitly on demand)Add the following lines to your /etc/loader.conf
, which I guess configures kernel boot-time options.
vmm_load="YES"
(I guess this is some kind of virtualized memory thing)nmdmm_load="YES"
(BHyve uses null modems to communicate over virtualized serial ports to the VMs)if_bridge_load
(I guess this enables bridge interfaces?)if_tap_load
(I guess this enables tap interfaces)Add the following to your /etc/rc.conf
file, which configures system services at startup.
if_bge0="dhcp"
(This enables my first network card but doesn’t configure it on the host OS.)if_bge1="up"
(This enables my second network card. It is important for security reasons for the outside-facing network card to be a passive passthru and not allow IP-based access to the host system)cloned_interfaces="bridge0 bridge1 tap0 tap1"
(This is where we define all our virtual interfaces.)defaultrouter=192.168.1.1
(This is the default address of the pfSense virtual machine)ifconfig_bridge0="inet 192.168.1.2 netmask 255.255.255.0 addm tap0 addm bge0"
(bridge virtual network 0 and my first network port)5ifconfig_bridge1="addm tap1 addm bge1"
(bridge virtual network 1 and my second network port)At this point you’ll want to reboot.
pkg install iohyve
(This is the higher-level VM manager software, the core low-level binary bhyve
is a little involved)iohyve setup pool=<your ZFS partition>
(this primes the bhyve layout)curl -O https://nyifiles.pfsense.org/mirror/downloads/pfSense-CE-2.3.4-RELEASE-amd64.iso.gz
(this was the latest file at time of writing)6gunzip pfSense-CE-2.3.4-RELEASE-amd64.iso.gz
sudo iohyve cpiso ./pfSense-CE-2.3.4-RELEASE-amd64.iso
(this installs the ISO into iohyve’s library of installation software`sudo iohyve create firewall0 4G
(give VM about 4G of disk space)sudo iohyve set firewall0 boot=1 ram=1G tap=tap0,tap1
(most VMs only need one fake network, but we need two here. Also, boot this image on startup. Also, give the VM 1G of RAM)sudo iohyve getall firewall0
(it’s nice to familiarize yourself with the settings of your VM)sudo iohyve isolist
(this is how you see the ISOs you’ve downloaded for installing software)sudo iohyve install firewall0 pfSense-CE-2.3.4-RELEASE-amd64.iso
(this boots up the VM from the CD, as it were)sudo iohyve console firewall0
(this lets you access the machine, where you will configure everything.I found that I had to pick some specific options in order to make sure everything worked.
iohyve start firewall0
to bring it back up)The default IP tends to be 192.168.1.1. The default user/pass combination is user: “admin” and password: “pfsense”, all lowercase.
If you do iohyve list
you should see output as follows:
Guest VMM? Running rcboot? Description
firewall0 YES NO YES <some date>
This indicates that the firewall VM has been provisioned (VMM), isn’t running, but is configured to start when the host machine books.
This is where we configure your pfSense install with real values.
iohyve start firewall0
iohyve console firewall0
At this point, you’re ready to set up your switch and VLANs, which I feel is out of scope and perhaps I’ll write about them later.
An alternative strategy would be to use servers like Digital Ocean and/or Amazon instead of running a bunch of dodgy services from my house. For reasons unexplained I decided to go the self-hosted route :) ↩
The next-next section will point out why the security-minded are having a heart-attack at this statement, don’t worry, wait for it :) ↩
Bridge mode means that the model will act purely as a physical connection between the coax/phoneline signal your telco feeds you and the ethernet connection your computer needs. This is different from the “gateway mode” you normally run routers in, where it does the routing and firewalling for you. ↩
I can sort of get around this via a sneaky virtualization technique called “PCI Device Bypass”. Sadly I could not get it to work, but I’ll write up instructions for it sometime anyway. ↩
My machine has a third ethernet port that I used my old router with while setting this up, and I eventually set up VLANS bypassing this. So I’m kind of guessing here how you’d end up allowing LAN access while letting most traffic pass through. ↩
It occurs to me that maybe you should download this image before mucking with your internet setup, :/ ↩