Einleitung

A firewall is always good, especially if it is a public server. FreeBSD has had the ‘pf’ firewall from the OpenBSD project, which fulfils the highest requirements, integrated into the base system for years. Quote from the FreeBSD handbook: ‘Firewalls make it possible to filter the incoming and outgoing network traffic of a system. To do this, a firewall uses one or more groups of ‘rules’ to examine incoming network packets and either let them through or block them. The rules of a firewall examine characteristic properties of data packets, including the protocol type, the source and destination addresses and the source and destination ports.’ I can't put it any better than that. In addition to the very simple need for protection, it also regulates access to jails and BHYE VMs in use.

Ziele

The goal is a very simple firewall that allows all outgoing traffic, incoming ping requests and SSH connections and enables NAT for VMs and BHYVE. Everything that is not explicitly allowed is rejected (default block).

NEW: For the very impatient I have a console only section. There are only commands, no explanations.

Last update:

  • 01.12.2024: Initial version

Basic requirements

  • A FreeBSD server is set up and prepared
  • The network card of the host system with access to the LAN network is known, e.g. igb0. The interface must be adapted to your primary network card. The current interface connected to the Internet can be determined with route -n get default | grep 'interface:' | grep -o '[^ ]*$', e.g. bge0 (to mention another example)

PF

The pf firewall is configured via the central /etc/pf.conf file.
All required rules are stored in this file and edited with ee /etc/pf.conf:

# Insert the determined network interface here
ext_if="igb0"

# This causes a TCP RST to be returned for TCP packets and an ICMP UNREACHABLE for other types of packets
set block-policy return

# Will reassemble the fragments, ensuring that all TCP packet information is correct
scrub in on $ext_if all fragment reassemble

# Skip all PF processing on interface lo
set skip on lo

# Tables for later NAT 
table <jails> persist
table <vms> persist
nat on $ext_if from <jails> to any -> ($ext_if:0)
nat on $ext_if from <vms> to any -> ($ext_if:0)
rdr-anchor "rdr/*"

# Incoming traffic is blocked
block in all

# Outgoing traffic is permitted
pass out quick keep state

# Blocking spoofed packets
antispoof for $ext_if inet

# Allows incoming ICMP packets (e.g. ping)
pass in inet proto icmp

# Allows incoming TCP packets on port 22 (SSH)
pass in inet proto tcp from any to any port ssh flags S/SA keep state

The firewall is activated with service pf enable and started with service pf enable. After changes to the rule set, these become active after a service pf reload.

Console

Voilá