Building a FreeBSD router part 1

By Roger, Sun 11 October 2020, in category Software

FreeBSD, install, router

During the last couple of years I tried a lot of different routers. To start with the router provided by my ISP. First a Fritzbox 7360 with DSL support and later a 7490 for use with fiber. But in the meantime I already started using my own routers. I tried PFSense, it had a problem with DPCP-PD at that time, OPNSense, it broke after an update and M0n0wall, one of my favourite! But the last one has stoped development in 2014. I ended up using an Edgerouter X. Very cool one, but somehow limited in possibilities.

That made me think. How hard can it be to build your own router? I have seen a lot of crapy routers in my life. It couln't be that hard...

Base OS

The first question, which OS? FreeBSD of course! I was thinking of using OpenBSD, but that was a little too far out of my comfort zone. I took my old small ESX host containing 16GB of ram and a 300GB harddisk, knowing it was probably enough for a router. I'm not going to tell you how to install FreeBSD, but it's basically next, next, finish work. Format your harddisk with ZFS because that can save you a lot of trouble later.

There are some things you have to know about FreeBSD. There is a difference between OS and additional installed software. The OS is master of the / and the additional software reside in /usr/local. So the program bash can be found in /usr/local/bin/ and sudoers in /usr/local/etc/. That's somehow different than most Linux distributions.

Most of the configuration of the OS is done in /etc/rc.conf.

Configure the LAN interfaces

First let's configure the interfaces in /etc/rc.conf. There are two physical interfaces. For the internet I used re0 and for my internal network re1. On my internal interface I needed some VLANs, one for my workstations, one for my DMZ, or IOT as some call it today, and one for my guests. First the inside world.

hostname="router.example.org"

ifconfig_re1="inet 192.168.0.1/24"
vlans_re1="wks iot guests"
create_args_wks="vlan 11"
ifconfig_wks="inet 192.168.1.1/24"
create_args_dmz="vlan 12"
ifconfig_dmz="inet 192.168.2.1/24"
create_args_guests="vlan 13"
ifconfig_guests="inet 192.168.3.1/24"

That the outside world. I'm using XS4All and they use VLAN 6 with PPPOE. I replaced /etc/ppp/ppp.conf with the below config. The authname and authkey doesn't matter.

:::toml
default:
  set log Phase tun command

xs4all_ftth:
  set device PPPoE:xs4all
  set authname xs4all@xs4all.nl
  set authkey 1234
  set dial
  set login
  add default HISADDR

And changed /etc/rc.conf:

ifconfig_re0="up"
vlans_re0="xs4all"
create_args_xs4all="vlan 6 up"

# Start PPPoE connection
ppp_enable="YES"
ppp_mode="ddial"
ppp_profile="xs4all_ftth"

Reboot and you got a system capable of using the internet and the internal network, but without any routing or services.

DHCP server

The internal network need some control of the IP adresses. Let's install the OpenBSD DHCP server.

:::bash
pkg install dhcpd

And make a config file in /usr/local/etc/dhcpd.conf for the three networks and a static entry as an example:

:::toml
authoritative;
default-lease-time 86400;
max-lease-time 1036800;

# WKS
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.100 192.168.1.200;
  option domain-name-servers 192.168.1.1;
  option domain-name "wks.example.org";
  option domain-search "wks.example.org", "dmz.example.org", "example.org";
  option routers 192.168.1.1;
  option subnet-mask 255.255.255.0;
  option broadcast-address 192.168.1.255;
}

# DMZ
subnet 192.168.2.0 netmask 255.255.255.0 {
  range 192.168.2.100 192.168.2.200;
  option domain-name-servers 192.168.2.1;
  option domain-name "dmz.example.org";
  option routers 192.168.2.1;
  option subnet-mask 255.255.255.0;
  option broadcast-address 192.168.2.255;
}

# Guests
subnet 192.168.3.0 netmask 255.255.255.0 {
  range 192.168.3.10 192.168.3.250;
  option domain-name-servers 192.168.3.1;
  option domain-name "guests.example.org";
  option routers 192.168.3.1;
  option subnet-mask 255.255.255.0;
  option broadcast-address 192.168.3.255;
}

host myhost {
  hardware ethernet CC:00:FF:FF:EE:EE;
  fixed-address 192.168.1.10;
}

And as last, enable the DHCP server in /etc/rc.conf:

:::bash
dhcpd_enable="YES"

Thats everything needed for the networking part of a router. Next time, we will take a look at the routing and firewalling.

Read the other parts of the story:

Part 1 - Part 2 - Part 3