Firewall Lab with OpenBSD

User documentation

  • Last Updated: 01/05/2022


In this lab, you will be working with OpenBSD. OpenBSD is a Unix based operating system. This means that it has many similarities and differences to other Unix based systems like Debian. Most base commands in OpenBSD are the same in Debian, and the file systems and other features related to IPs and routing are somewhat different. Additionally, OpenBSD has its own way of routing protocols, and packages and ports are sent to /usr/local. Although OpenBSD doesn't use the same exact services that Linux services use, it has the same functionality. OpenBSD is also security-oriented; so, it can be used for implementing firewalls, securing network packets, etc. On OpenBSD, you will not be creating bird or ISC-DHCP servers.


Console into spokes 1, 2, and 3 and check to see if they can ping each other. Make sure they’re all using OSPF and have the appropriate neighbors before moving on to the next steps.

Download the fw-lab.img and fw-lab.xml files and store them in /data. Shut down all the VMs that are currently running, except for the spokes.

Choose 2 vlans for the firewall. Make sure one is connected to the hub and the other is connected to the internet. We'll be using vlan104 and vlan11 in this scenario. Enter vlan11 as your first interface and vlan104 as your second. In our case, our external interface is vio0, and our internal interface is vio1, which is connected to the router. Later on, we'll connect vio0 to dhcp and give vio1 an external ip address.

Edit fw-lab.xml, changing the src file (devices) path, vmbrs, interfaces, and slots as necessary.

Now, define a vm using the fw-lab.xml file, start fw-lab, and console into it.

To change the hostname, edit /etc/myname.

Configuring Firewall

Run ship. You should see two interfaces (vio0 and vio1). Edit /etc/hostname.vio0 and /etc/hostname.vio1. Make vio0 dhcp (simply write dhcp) and change vio1's inet ( NONE).

If you're unsure about the subnet of the router/hub, go back into the neatrack and console into spoke1, ssh into the hub/router, and type ip route. The subnet of the router in this case is /30.

Now, restart the interfaces by entering the following commands:
sh /etc/netstart vio0
sh /etc/netstart vio1

Try to ping out to the internet (

/etc/interfacedb.txt is a file used for organizational purposes when running ‘ship’. Insert or edit the vlans to ensure that vio0 is your WAN interface (vlan11) and vio1 is your LAN interface (vlan104). For vio0, write '11:wan_uplink' and '104:lan' for vio1.

        'vio0' => '11:wan',
        'vio1' => '104:lan',

Now, console into one of the spokes. Try pinging the hub and the other vlans.

If you cannot ping the hub, check to see if your switch/router is on and all cables are plugged in.

Now console back into fw-lab and type "route show" to check your routes. You'll notice that on our spokes, there is a default route, but no route to go to our hub. We can fix this by adding static routes in order to test pinging to the internet. To add static routes to the firewall, run the commands:

route add
route add

However, a route added with a single command will not still be there after rebooting the firewall. To make sure that these routes save after a reboot edit /etc/hostname.vio1 (lan interface). Add static routes to all of the networks under the hub in this file. Make sure the next step it set to the the hub ( from the firewall.
Example: !route add

Also, instead of writing out the full netmask next to the IP address, you could just write /30, /24, etc. depending on the subnet.

Make sure that the firewall is able to ping all of the spokes' LANs and vice versa.

At the moment, the Cisco Router(hub) is communicating with the spokes about routes through OSPF, while the Cisco Router(hub) and firewall are communicating through static routing. In the next part of the lab we will be making the entire network communicate with OSPF, including the firewall. While static routes may work well for communications between the firewall and router in this scenario, this doesn't mean that static routes are the best choice. OSPF does the same basic job as static routing, but it is much more efficient when setting up and expanding networks. For example, if you were to add another firewall to this network with static routing, then you would have to add all of the static routes all over again. If you used OSPF to add another firewall, then you would just need to quickly set up OSPF on the firewall and it would be able to communicate with all the other devices on the network.

NAT Tables

Imagine that you had a device on your private network that wanted to connect to the internet. Your private IP cannot directly connect to the internet. In order to allow your private network to connect to a public network, a NAT (network address translation) table would be needed.

NAT tables work by translating a private IP address into a public IP address. So, the packets coming from your private network would change their source IP (originally the private IP) to the router's public IP. Then, the router would add a new row in the NAT table that would map the private IP to its destination address (the public IP). Now, your device can connect to the public network.

We're now going to create a NAT table for our LAN's IPs.

Go back into fw-lab and create the firewall rules by editing /etc/pf.conf. Delete the extra "ext_if" line if more than one are there. Move the "fwip external IP" line below the "ext_if vio0" line and save and exit.

Run "fws" to restart the firewall.

Your firewall should have automatically obtained an IP via dhcp on its WAN interface.
Add that IP address’s subnet to /opt/shared/pf/noc.conf. For example, if your firewall’s WAN IP is with subnet mask, you would insert “”.

In /etc/pf.conf, set $fwip to its WAN IP address, ext_if to its external interface, int_if to its internal interface, and lan to its LAN subnet ( These macros that don’t actually configure the firewall, but are useful for editing the firewall rules without having to change the IP in multiple places.

In /etc/pf.conf, confirm that NAT (##outbound NAT) says

“match out on $ext_if from $lan nat-to $fwip”.

Once done, restart the firewall again. If set up correctly, you should be able to ping the internet from the firewall's LAN IP and the cisco router's WAN IP.

To ping the internet using the firewall's LAN ip, do

ping -I <source IP> <destination IP>

Afterwards, try pinging the internet from the Cisco router. You'll want to make sure that the cisco router(hub) has a static default route to the firewall.

ip route

Back inside the firewall, create a new table by editing "/opt/shared/pf/lan.conf." List all of the IPs for all of the LANs that you want to include (the screenshot below is an example but is not what you should enter!). Any pings with a source address in the listed ranges will be NATted and consequently get internet, so be sure to include all of them.

Now go back to your /etc/pf.conf file. Add this line where the tables are defined:

table <lan>           persist file "/opt/scripts/pf/lan.conf" 

At the bottom, change the "match out" lan to use the table instead of the macro:

match out on $ext_if from <lan> nat-to $fwip

Save the file, and restart the firewall.

Test your connections again by pinging from your spoke's LAN to the internet.

Setting up OSPF from the Cisco Router to the Firewall

Remove the default static route to the internet off of the router. Make sure the router isn't advertising that it has the route to

Then, go into the sub interface for vlan104 on the router and run the following commands:

ip ospf cost 100
ip ospf hello-interval 6

Now, OSPF will be listening on vlan104.

Create a loopback address on the firewall by editing /etc/hostname.lo1. Inside this file, type the following command:

inet <loopback ip> <subnet mask> NONE

Run "sh /etc/netstart lo1" to initialize the interface. If that doesn't work, try changing the file permissions to 700 by typing "chmod 700 /etc/hostname.lo1."

If you cannot remember the loopback, be sure to check the spokes and bird routers.

Then, run ship to make sure the loopback works.

Go into /etc/ospfd.conf. Inside this file, type the following:

router-id <loopback>
fib-update yes
    interface "vio1"{
         hello-interval 6
         router-dead-time 24
         metric 100

Now, we have to change the file permissions for ospfd.conf.

ls -al /etc/ospfd.conf

This command lists the file permissions for the owner, users in the same group as the owner, and everyone else (global). We only want to give the owner read and write permissions and everyone else no permissions for security reasons. To do this, we type:

chmod 600 /etc/ospfd.conf

Now, we need to edit /etc/rc.conf.local and add the following:

ospfd_flags = "" 

It's important to set the ospfd_flags to "" because it allows the daemon to run at its default. If NO was defined instead, the daemon would not run at all.

Run "/etc/rc.d/ospfd start."

Afterwards, we need to go through and delete all the static route off the firewall. To list all the current routes, type "ospfctl show rib."

Try to ping, the external ip of the firewall (in this case, and (Firewall's loopback address) from a spoke's LAN.

These pings should be successful, however pinging the firewall's loopback address is only working since it is going through the default route to get to the firewall, and the firewall isn't actually advertising that it has the route to the loopback address over ospf. While this might work for simple networks, it would become a problem for larger networks with two or more firewalls since only one is going to have the default route. We want to make sure that loopback is included inside ospf. So, to make the firewall advertise its loopback through ospf, edit /etc/ospfd.conf and add "redistribute default" right above the line that contains area Then add the following inside of area

interface "lo1" {
   metric 100

To put these changes into effect, restart ospf with the command "/etc/rc.d/ospfd.conf restart".
Now ping from spoke1's LAN (

Now delete the static LAN macro in pf.conf and restart the Firewall.

Now test by pinging around the various devices. Important connections to test from the LAN of a spoke are to the internet, the firewall's loopback address, and the external ip of the firewall.

Firewall Rules

You can now mess around with the firewall rules. Firewall rules tell you what traffic is allowed or not allowed based on some criteria in order to protect your network. You can create firewall rules by using certain keywords. For example, "block" denies traffic from traveling to a specific destination.

Additionally, it's important to remember that "the last matching rule wins." For example, if you had a block rule that prevented traffic from going out to from a specific IP address but then had an allow rule below that permitted all traffic to reach, the latter would be carried out. However, quick rules are an exception to this as they are prioritized and can override other existing rules.

Here are a couple of sample rules that you can add to pf.conf:

##blocks all traffic going out to
block out quick on $ext_if from any to

Note: In order to test the "block" rule, change "any" to <lan> and make <lan> only contain spoke1's LAN. Then, ping from spoke1 and spoke2's LAN.

##port redirection to ssh into the spokes
pass in quick on $ext_if proto tcp from <noc> to $fwip port 1000 rdr-to port 22

Note: Remember to restart the firewall after you add the rules.

Note: In order to use redirection with ssh you must specify which port you are trying to ssh to. Example to go with the port redirection above:

ssh -p 1000 admin@

Note: When trying to ssh into the Cisco router the computer will sometimes give you an error initially and a list of ciphers. This happens because the Cisco router has older software that has trouble working with your newer ssh software. To get around this, simply add "-c <insert cipher here>" between the port number and the username.

Now that you SSH enabled on your spokes, you should start SSHing into the spokes. Up until this point, you were consoling into each spoke with "virsh console <VM>" which limits to only allowing one person at a time to be in the spoke. SSHing will allow more than one person to be in a spoke and really you should start SSHing into them anyway because it lessens the dependency on a console connection.


routes1.png (27.1 KB) routes1.png Ritika Allada, 07/13/2020 04:04 PM
lanconf.png (11.8 KB) lanconf.png Ritika Allada, 07/14/2020 12:07 PM
opt-shared-pf-noc-conf.PNG (4.3 KB) opt-shared-pf-noc-conf.PNG Chloe Martin, 08/09/2021 03:31 PM