Netfilter: The Linux Packet Processing Framework
In the previous chapter, we followed a packet through the Linux kernel and saw that packet handling is a sequence of decisions, not a single event. One of the most important decision layers in that sequence is netfilter.
Netfilter is the Linux kernel framework that handles packet filtering, NAT, packet mangling, and packet inspection at specific points in the packet path. It is the mechanism behind Linux firewalling and packet rewriting. Tools such as iptables and nftables are user-space interfaces for configuring netfilter, but netfilter itself lives in the kernel.
This chapter focuses on the framework itself: where it sits in the packet path, what it can do, and how to reason about it when troubleshooting.
What Netfilter Is
Netfilter is not a firewall application. It is the in-kernel packet-processing framework that provides hook points where policy can be applied.
At a high level, netfilter allows Linux to:
- inspect packets,
- allow or deny traffic,
- rewrite addresses and ports,
- track flow state,
- and apply policy to traffic entering, leaving, or passing through the host.
The important distinction is:
Netfilter is the kernel framework.
iptablesandnftablesare configuration interfaces for it.
That distinction matters because later chapters will focus on rule syntax, while this chapter focuses on where packet processing happens inside the kernel.
Why Netfilter Matters
A Linux system can route packets and deliver them to sockets without netfilter rules at all. But netfilter adds the packet-policy layer that makes Linux useful as:
- a firewall,
- a router,
- a NAT gateway,
- a container host,
- and a general-purpose packet-control platform.
In practice, netfilter is often invisible until traffic stops working. Then it becomes one of the first places to inspect.
If a packet is:
- arriving but not reaching the application,
- being forwarded unexpectedly,
- translated into a different source or destination address,
- or silently dropped,
netfilter is often part of the explanation.
Netfilter Hooks
Netfilter works by placing hook points at key locations in the packet path. When a packet reaches one of those points, the kernel can pass it through netfilter logic before continuing.
The main hooks are:
PREROUTINGINPUTFORWARDOUTPUTPOSTROUTING
These names describe where the packet is in the kernel pipeline.
PREROUTING
This is one of the first hook points for incoming packets, before the kernel fully decides whether the packet is for the local host or should be forwarded.
It is commonly associated with early packet classification and destination NAT.
INPUT
Packets destined for the local machine pass through this hook before they are delivered to local sockets.
This is where host-level inbound filtering usually matters.
FORWARD
Packets that are not for the local host but are being routed through the machine pass through this hook.
This matters on routers, gateways, and systems with forwarding enabled.
OUTPUT
Packets generated locally by applications or services pass through this hook before they leave the host.
This affects traffic created on the local machine itself.
POSTROUTING
This is one of the last hook points before a packet leaves the system.
It is commonly associated with source NAT and final packet adjustments.
The Netfilter Mental Model
You do not need the internal implementation details to use netfilter effectively. A useful mental model is:
- A packet reaches a hook.
- Netfilter evaluates the applicable rules.
- A rule may allow the packet to continue.
- A rule may drop the packet.
- A rule may rewrite the packet.
- The packet then continues to the next stage.
That is the core pattern.
When you are debugging, the real question is not “is netfilter on?” The real question is:
- which hook saw the packet,
- which rule matched it,
- and what action was taken?
What Netfilter Can Do
Netfilter rules can lead to several kinds of outcomes.
Accept
The packet is allowed to continue through the stack.
Drop
The packet is discarded and does not continue.
Reject
The packet is discarded and the kernel may send a response explaining that it was refused.
Rewrite
Packet headers can be modified, which is how NAT and similar transformations work.
Log or trace
The packet can be recorded for diagnostics or auditing.
These are the practical operations that matter. Everything else is implementation detail.
Netfilter Is Stateful
Netfilter is closely tied to connection tracking, which gives the kernel memory of flows.
That means packets are not always evaluated as isolated events. The kernel can know whether a packet is:
- part of a new flow,
- part of an established flow,
- related to an existing flow,
- or invalid.
This is important because many firewall policies are written around connection state rather than individual packets.
You do not need to master connection tracking in this chapter, but you should already understand that netfilter is not purely stateless.
Netfilter and Packet Direction
A clean way to reason about netfilter is to separate traffic into three categories.
Inbound to a local service
A packet arrives on an interface and is destined for a service on the host.
Typical path:
- packet enters the host,
PREROUTINGis evaluated,- routing decides the packet is local,
INPUTis evaluated,- the packet reaches the socket.
Transit traffic
A packet arrives and must be routed to another host.
Typical path:
- packet enters the host,
PREROUTINGis evaluated,- routing decides the packet must be forwarded,
FORWARDis evaluated,POSTROUTINGis evaluated,- packet leaves the host.
Locally generated traffic
A process on the host sends a packet.
Typical path:
- application creates traffic,
OUTPUTis evaluated,- routing decides where it should go,
POSTROUTINGis evaluated,- packet leaves the host.
This is one of the most practical ways to think about packet handling on Linux.
Netfilter Is Not Routing
Routing and netfilter are related, but they solve different problems.
Routing answers:
- Where should this packet go?
Netfilter answers:
- Should this packet be allowed?
- Should it be rewritten?
- Should it be logged?
A packet can be routed correctly and still be dropped by netfilter.
A packet can also be allowed by netfilter and still fail because routing does not know where to send it.
That distinction is important in troubleshooting.
Netfilter and NAT
NAT is one of netfilter’s major jobs.
When Linux rewrites source or destination addresses or ports, that rewrite is typically happening through netfilter hooks.
Common NAT use cases include:
- allowing private IP ranges to access the internet through one public IP,
- redirecting traffic to another host or service,
- translating container traffic,
- and building gateways or edge devices.
You do not need to implement NAT in this chapter. You only need to know that NAT is not a separate subsystem floating next to Linux networking. It is part of the netfilter pipeline.
Observing Netfilter Without Writing Rules
Because this chapter is about the framework, not rule syntax, the goal is to observe behavior rather than build a firewall.
View the current ruleset
On systems using iptables:
sudo iptables -L -n -v
On systems using nftables:
sudo nft list ruleset
These commands show what is already configured on the machine. They are useful because they let you see how packet-processing policy is represented in the kernel.
Check whether forwarding is enabled
sysctl net.ipv4.ip_forward
If forwarding is disabled, the machine cannot behave as a router for IPv4 traffic.
Watch packets at the interface boundary
tcpdump -i eth0 -nn
This shows whether packets are actually entering or leaving the interface. It does not tell you which netfilter rule acted on them, but it helps you separate “packet never arrived” from “packet arrived and was dropped later.”
Check routing decisions
ip route get 8.8.8.8
This shows the route the kernel would use before netfilter and socket delivery complete the story.
How This Fits Into the Larger Packet Path
Netfilter is not the first thing a packet sees, and it is not the last.
A packet typically passes through this larger sequence:
- NIC and driver receive or send data.
- The kernel builds or consumes the packet object.
- Routing decides where the packet should go.
- Netfilter evaluates policy at relevant hooks.
- Connection tracking may associate the packet with a flow.
- NAT may rewrite packet headers.
- The packet is delivered to a socket or transmitted on an interface.
That is why packet troubleshooting is often layered.
You do not ask only “is the firewall broken?” You ask:
- did the packet arrive,
- did routing choose the right path,
- did netfilter allow it,
- and did the socket receive it?
Common Misunderstandings
“Netfilter is the firewall”
Not quite. Netfilter is the framework. Firewall rules are one use of it.
“iptables and nftables are different kernels”
No. They are different user-space interfaces to the same general kernel packet-processing framework.
“If a packet is on the wire, Linux must have accepted it”
Not necessarily. A packet can be visible on the interface and still be dropped later in the kernel.
“Routing and firewalling are the same thing”
They are separate decisions. Routing selects a path; netfilter enforces policy on that path.
Summary
- Netfilter is the Linux kernel packet-processing framework.
- It provides hooks such as
PREROUTING,INPUT,FORWARD,OUTPUT, andPOSTROUTING. iptablesandnftablesare configuration interfaces, not the framework itself.- Netfilter can accept, drop, reject, log, or rewrite packets.
- It is closely tied to connection tracking and NAT.
- Routing decides where packets go; netfilter decides what is allowed to happen to them.
tcpdump,ip route get,iptables -L -n -v,nft list ruleset, andsysctl net.ipv4.ip_forwardare useful observational tools.
In the next chapter, we will go deeper into the state that makes netfilter powerful: connection tracking.