linux vs. freebsd firewalls

FreeBSD – Linux and FreeBSD Firewalls – Part 1

Linux vs. FreeBSD

Linux and FreeBSD Firewalls – The Ultimate Guide

Part 1

When it comes to choosing a firewall technology for your operating system, the options can be overwhelming. This is particularly true for Linux and FreeBSD, which offer multiple choices. In this article, we’ll take a closer look at four of the most popular firewall options for both systems: iptables, nftables, ipfw, and pf, to help you make an informed decision.

So here’s our contribution to the effort, this article is essentially your four-way comparison of iptables, nftables, IPFW and PF 

Firewalls act as network filters, allowing some packets to flow while blocking others. This decision is usually based factors such as the packet’s source and destination address, which side initiated the network connection, and network port numbers. The Linux and FreeBSD firewalls are stateful, which means that they can also remember details of past packets to track ongoing connections. 

Firewalls are commonly used to protect systems that share a network link with untrusted systems—but they can also be useful to block unwanted outgoing network connections initiated by badly behaved software (or users!) on your own system.

Linux Firewall Technologies

On Linux, nftables is iptables’ successor, rather than a competing alternative. However iptables remains relevant – it is widely deployed, and nftables includes a compatibility layer for iptables commands. Many people have experience in using it along with the ip6tables, arptables and ebtables variants. 

Aside from dropping the duplication for IPv6, arp and bridging, nftables was designed to be faster at handling rules. The option letters used for rules with iptables have been replaced by a more intuitive syntax inspired by tcpdump(1) and, incidentally, more similar to the syntax used by the FreeBSD firewalls. 

In addition, you may come across firewalld on Redhat derivative distributions and UFW on Ubuntu. These aren’t actually separate firewall platforms; they’re an abstraction layer for the underlying firewall—typically iptables, although firewalld now supports an nftables back end also. 

You might also be interested in

Maximizing your FreeBSD performance starts with understanding its current state.

A FreeBSD performance audit can help you identify areas for improvement and optimize your systems.

These firewall abstraction layers provide a simpler view to cover common use cases. Even if you use firewalld, UFW or other abstraction layers such as that of OpenWRT, it can be useful to have a basic understanding of the underlying firewall to debug complicated cases.

FreeBSD Firewall Technologies

This article started out by making it clear that the war between *NIX OSes is largely pointless. Understanding the differences between distributions and making the right choice is very likely the only argument worth having. So instead of demonizing (yep, we learned straight into that one!), we’re going to talk about how to leverage what FreeBSD has to offer.

FreeBSD’s PF firewall is the basis of several widely-used network appliance / router distributions—most notably, pfSense and its competing fork, opnSense. (It’s worth pointing out the difference between OpenBSD and FreeBSD PF, because the latter has substantially diverged, including enough differences in rule syntax to make copying and pasting between the two unwise.)

The PF firewall enjoys a reputation for being fast and secure with intuitive syntax, while also offering powerful features like pfsync (which synchronizes state between two firewalls).

Actions Applied to Packages

When configuring a firewall, the first step is to decide on the default policy. Typically, best practice is “default deny”—meaning all packets will be dropped unless a rule specifically allows them in. For those who prefer the opposite approach, a default allow policy allows packets to pass unless a rule specifically drops them.


Before processing any rules, iptables first divides IP packets up into the INPUT, OUTPUT and FORWARD chains. These correspond to packets received on the network, outgoing packets generated on this system, and packets that the system is routing on behalf of other systems.

Each chain may have its own default policy—making it possible, for example, to be default deny on incoming packets but default allow on outgoing packets. Within each chain, rules are processed sequentially, and any matching rule can change the final verdict on whether to drop or accept the packet. 

In addition to INPUT, OUTPUT, and FORWARD iptables offers the PREROUTING and POSTROUTING chains. These exist to handle tasks such as defragmentation and IP masquerading (NAT). Note that a packet can be accepted on one chain only to be rejected later. To express more complex logic, the action for a rule can consist of a jump to a user-defined chain.


Nftables has chains much like iptables—but nftables chains can be attached to hooks where “input”, “output” and “forward” are the names of hooks. Where you have multiple chains attached to the same hook, a priority ordering can be defined. 

Similarly to iptables, a chain has a default policy of either accept or drop associated with it. While chains act as containers for rules, there are also tables which act as containers for chains. Tables are associated with an address family such as ip, ip6, arp and bridge thus allowing nftables to be a replacement for all of iptables, ip6tables, arptables and ebtables.


IPFW uses a simple numbered list of rules where the numbers define the ordering, and the first matching rule can determine the outcome for a particular packet. For complex logic there are jump and call actions which take rule numbers as their target. This is rather like programming in BASIC and is simple and effective for firewalls of small to moderate size. 

IPFW’s default policy is determined by the net.inet.ip.fw.default_to_accept loader tunable in /boot/loader.conf. The value of this tunable is reflected by either an allow or deny rule with number 65535 which places it last after all other rules. 


PF is a default allow firewall which applies rules in the order they appear in the configuration file but—in contrast to ipfw—the last matching rule determines the outcome. However, because the last rule matches, you can effectively make a pf firewall default deny by starting with “block all” on the very first line—meaning that only packets matched in later rules will be allowed to pass. 

You can also mark a rule with the word quick, which means that if that rule matches, it determines whether the packet is blocked or passed and PF will cease matching the packet against further rules.

Common Functionality

Aside from pronouncing a verdict to drop or accept packets, all the firewalls support a wealth of other actions. This includes functionality such as logging and counting packets, saving state to track connections, applying traffic shaping, or changing to way the packet is routed.

Rule Syntax

Let’s show a rule to demonstrate the basic syntax differences and to give you a feel for what rules look like with the different firewalls. We’ll start with a rule to permit incoming connections on a mail server that has services running on TCP ports 25 (SMTP), 110 (POP3) and 143 (IMAP).


We’re concerned with incoming packets so we’ll specify the INPUT chain for iptables. There is a -p option for matching the protocol, in this case TCP. For all but the most basic rules we need to enable an extension, in this case multiport for matching the destination port numbers. Lastly, we use a jump to specify a target (ACCEPT).

  iptables -A INPUT -p tcp -m multiport --dports 25,110,143 -j ACCEPT

In a fully unconfigured state, nftables lacks any tables or chains—so we first need to create a table (named “filter”) and a chain (named “input”) to which we can add our rule. “inet” refers to the address family. 

  nft add table inet filter
  nft add chain inet filter input \{ type filter hook input priority 0 \; policy drop \; \}

With these in place the nftables rule contains the same basic elements as for iptables.

  nft add rule inet filter input tcp dport '{25, 110, 143}' accept

In our IPFW example, we provide a rule number for the rule explicitly. The specific number used is not meaningful beyond process order; in our example, the use of rule #420 simply means “after 1-419″ and “before 421 and up.” If we leave the rule number out, the rule will simply be given a new number and added to the end of the ruleset. The action of allow comes first, followed by the address family (tcp), and then a from directive to match the source and destination address of the packet. We then list port numbers and the word “in” denotes an incoming packet, serving much the same purpose as using the INPUT chain on Linux. 

The consistent structure in the initial part of IPFW rules helps with clarity when viewing a large number of rules, since leading common elements align vertically. More unusual rule options come last, can be ordered flexibly, and are always preceded by an identifying word such as “dst-port” rather than being implicit.

  ipfw add 420 allow tcp from any to me 25,110,143 in

PF uses the word “pass” to denote packets that are accepted. Otherwise, the rule resembles that for IPFW closely enough that the explanation of individual elements need not be repeated. Because PF uses a configuration file, there is no shell quoting for the braces as in earlier examples.

  pass in proto tcp from any to any port {25, 110, 143}

Miscellaneous Syntactical Issues

Given that rules as a whole either do or don’t match based on several aspects of a packet, they can be viewed as boolean algebra expressions. Adding refinements to a rule by matching further aspects of a packet acts logically as a conjunction, or AND operation. 

Where lists are given, such as for the port numbers in these examples, these are matched logically as an OR. Otherwise, it is often necessary to add an additional rule to achieve an OR operation. 

For negations, iptables allows options to be preceded by an exclamation mark. For PF, an exclamation mark is used before the matched value, e.g. “from ! {,, }”. IPFW uses they keyword “not” in a similar manner, and for nftables it is !=. (Note that exclamation marks need to be quoted in some shells.)

The rules in this example apply to services running on a local system. When opening network ports on a device that is doing routing, it is worth being aware that, while ports are often associated with particular applications, e.g. TCP port 22 for ssh and UDP port 53 for DNS, someone with malicious intent can tunnel anything they like such as a reverse shell over any port. There are approaches to restrict or detect this such as only exposing access via application layer proxy servers or running Intrusion Detection Systems or doing Deep Packet Inspection as part of the filtering. 

Look Out for Part 2

In part 2, we’ll go ahead and further discuss the implementation of FreeBSD and Linux firewalls by touching on egress actions, listing rules and viewing counters and just some general useful tips on how to go beyond a basic implementation.

Other FreeBSD vs. Linux Resources

We’ve written quite a bit in the past about making the right choice between the two operating systems. So here are some useful reads when trying to make a choice between FreeBSD and Linux:

1.) FreeBSD vs Linux – Which Operating System to use for OpenZFS

In December 2020, the OpenZFS project completed unifying the OpenZFS codebase between the FreeBSD and Linux platforms. This helps ensure cross-compatibility between the two—but there are still some implementation and even a few feature differences worth paying attention to. This write-up goes over the remaining OpenZFS differences, to help anyone on the fence decide which OS to use beneath our favorite filesystem.

2.) FreeBSD vs. Linux – Networking At A Glance

Network is incredibly important in every infrastructure, and network configuration differences can be pretty challenging between different OSes. This article covers several network technologies where Linux and FreeBSD have equivalent but different implementations and how to work with them. 

3.) FreeBSD vs. Linux – Virtualization Showdown with bhyve and KVM

Although the bhyve management ecosystem is currently quite limited in comparison to Linux’s KVM, its performance is already quite impressive.  For storage-heavy workloads, the benefit of bhyve’s emulated NVMe controller is difficult to overstate—it produced massive throughput improvements that even a long-time KVM fan simply cannot ignore. 

4.) FreeBSD vs. Linux – Package Management

Package managers on various Unix distributions make it easy for system administrators to manage the software installed on the operating system. Packages are an easy, straightforward way to install software that avoids time-consuming configure, compile, install sequences. The popularity of package managers permeates all Unix distributions. Yet there are subtle differences in the approach that Linux vs. FreeBSD take in handling packages. How does Linux compare to FreeBSD’s way of managing packages?

If you’re looking to migrate from a Linux-based environment to FreeBSD, how would you go about it?

5.) Easily Migrating from Linux to FreeBSD

If you are already experienced with Linux, FreeBSD should feel very familiar. The operating systems have a lot in common, due both to their Unix heritage and many shared modern components. Much of what may be unfamiliar to a Linux user adopting FreeBSD is also inconsistent between Linux distributions themselves. This article covers some of the conceptual differences between Linux and FreeBSD, and go on to contrast some aspects of the basic system utilities and the differing views of hardware given by the two systems.

6.) Linux and FreeBSD Firewalls – The Ultimate Guide

If you’re looking to understand security at its most basic level in FreeBSD vs. Linux there’s no better way to start than with how firewalls are being implemented in the two different environments. Take a deeper dive in this two-part article series and understand how different firewalls are implemented in FreeBSD and Linux and what the advantages to them are.

You might also be interested in

Get more out of your FreeBSD development

Kernel development is crucial to many companies. If you have a FreeBSD implementation or you’re looking at scoping out work for the future, our team can help you further enable your efforts.

Tell us what you think!