How Firewalls Work: Packet Filtering, Stateful Inspection, and Beyond

A firewall is a network security device or software that monitors and controls incoming and outgoing network traffic based on a set of defined rules. It acts as a gatekeeper between a trusted internal network and untrusted external networks like the internet, deciding which packets are allowed to pass and which are dropped or rejected. Firewalls are one of the oldest and most fundamental security mechanisms in networking, and nearly every device connected to the internet today sits behind at least one.

But "firewall" is a broad term. The technology has evolved dramatically since the first packet-filtering routers of the late 1980s. Modern firewalls range from simple iptables rulesets on a Linux server to cloud-native security groups in AWS, from stateful connection-tracking engines in the kernel to application-layer gateways that inspect the contents of HTTP requests. Understanding how each type works, and where each fits in a defense-in-depth strategy, is essential for anyone who touches networking infrastructure.

This article covers the full spectrum: from the raw packet filtering that happens at the network layer, through stateful inspection and connection tracking, to application-layer firewalls, NAT interaction, network zone architecture, next-generation firewalls, and cloud-native security models.

Packet Filtering: The Foundation

The simplest form of firewalling is packet filtering. A packet-filtering firewall examines each packet independently, looking only at the packet's header fields, and makes a binary decision: accept or drop. There is no memory of previous packets, no understanding of connections, and no inspection of payload data. Each packet is evaluated in isolation against a ruleset.

The header fields available for filtering at the network and transport layers include:

A packet filter processes rules in order from top to bottom. When a packet matches a rule, the action specified by that rule (ACCEPT, DROP, or REJECT) is taken and no further rules are evaluated. If no rule matches, a default policy applies. This last-match-loses, first-match-wins approach means that rule ordering is critical -- a misplaced rule can negate an entire security policy.

iptables: The Classic Linux Firewall

For decades, iptables has been the standard packet-filtering tool on Linux systems. It interfaces with the Netfilter framework in the Linux kernel, which provides hook points where packets can be intercepted and processed. iptables organizes rules into tables (filter, nat, mangle, raw) and chains (INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING).

The filter table is where standard firewall rules live. Its three built-in chains handle different packet flows:

A typical iptables ruleset for a web server looks like this:

# Set default policies -- drop everything by default
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow established and related connections (stateful rule)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT

# Allow SSH from specific management subnet
iptables -A INPUT -p tcp --dport 22 -s 10.0.1.0/24 -j ACCEPT

# Allow HTTP and HTTPS from anywhere
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Allow ICMP ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Log and drop everything else
iptables -A INPUT -j LOG --log-prefix "DROPPED: "
iptables -A INPUT -j DROP

Even this "simple" ruleset already uses stateful inspection (the conntrack module), which we will cover in detail shortly. Without that rule, you would need to explicitly allow return traffic for every outbound connection -- an error-prone and insecure approach.

nftables: The Modern Replacement

nftables is the successor to iptables, introduced in Linux kernel 3.13 (2014) and now the default firewall framework in most modern distributions. It replaces the separate iptables, ip6tables, arptables, and ebtables tools with a single unified framework. The key improvements include:

The equivalent nftables configuration looks cleaner:

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        ct state established,related accept
        iif lo accept

        tcp dport 22 ip saddr 10.0.1.0/24 accept
        tcp dport { 80, 443 } accept
        icmp type echo-request accept

        log prefix "DROPPED: " drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Note the inet address family, which handles both IPv4 and IPv6 in a single table. In iptables, you would need separate rules for iptables and ip6tables, a common source of security gaps where IPv6 traffic is accidentally left unfiltered.

Stateful Inspection: Connection Tracking

Pure packet filtering has a fundamental limitation: it has no concept of a connection. It sees each packet as an isolated event. This creates problems for protocols like TCP, where a client initiates a connection with a SYN packet and the server responds with a SYN-ACK. A packet filter must either allow all incoming SYN-ACK packets (dangerous -- an attacker can send crafted SYN-ACKs) or block them (breaking all outbound TCP connections).

Stateful inspection solves this by tracking connections. The firewall maintains a connection table (also called a state table) that records every active connection passing through it. When a new outbound TCP connection is initiated, the firewall records the source IP, source port, destination IP, destination port, and protocol. When a return packet arrives, the firewall checks whether it belongs to a known connection. If it does, the packet is allowed without needing to match any explicit rule.

Stateful Firewall: Connection Tracking Client 10.0.1.50:49152 Stateful Firewall Inspects + tracks connections conntrack table in kernel Server 93.184.216.34:443 SYN SYN (allowed) SYN-ACK SYN-ACK (tracked) Connection Table (conntrack) Proto Src IP Src Port Dst IP Dst Port State TTL TCP 10.0.1.50 49152 93.184.216.34 443 ESTABLISHED 432000 TCP 10.0.1.50 49153 1.1.1.1 53 SYN_SENT 120 UDP 10.0.1.50 51234 8.8.8.8 53 ASSURED 180 Attacker 198.51.100.1 Firewall No matching connection Spoofed SYN-ACK DROPPED --- Outbound (new/allowed) --- Return (tracked) --- Unsolicited (dropped) Return packets matching tracked connections are automatically accepted. Packets with no matching connection entry are dropped by default policy.

How Linux Connection Tracking Works

Linux's conntrack subsystem (part of Netfilter) is the connection-tracking engine used by both iptables and nftables. It maintains a hash table in kernel memory, keyed by the 5-tuple (protocol, source IP, source port, destination IP, destination port). Every packet passing through the firewall is checked against this table.

The conntrack system classifies packets into several states:

You can inspect the connection table on a Linux system using conntrack -L or by reading /proc/net/nf_conntrack:

$ conntrack -L
tcp   6 431999 ESTABLISHED src=10.0.1.50 dst=93.184.216.34 \
    sport=49152 dport=443 src=93.184.216.34 dst=10.0.1.50 \
    sport=443 dport=49152 [ASSURED] mark=0 use=1
udp  17 28 src=10.0.1.50 dst=8.8.8.8 sport=51234 dport=53 \
    src=8.8.8.8 dst=10.0.1.50 sport=53 dport=51234 [ASSURED] mark=0 use=1

Each entry shows both the original direction (client to server) and the reply direction (server to client). The [ASSURED] flag means traffic has been seen in both directions, so the entry will not be dropped early under memory pressure.

Conntrack Table Sizing and Performance

The conntrack table has a finite size, configured via nf_conntrack_max (default is typically 65536 or 262144 depending on available RAM). When the table is full, new connections are dropped -- a common cause of mysterious connection failures on busy firewalls or NAT gateways. On high-traffic systems, you may need to increase this limit significantly:

# View current limit and usage
sysctl net.netfilter.nf_conntrack_max
sysctl net.netfilter.nf_conntrack_count

# Increase limit
sysctl -w net.netfilter.nf_conntrack_max=1048576

Each conntrack entry consumes roughly 300-400 bytes of kernel memory. A table with 1 million entries uses about 300-400 MB of RAM. For systems handling millions of concurrent connections (such as a large load balancer or CDN edge node), conntrack can become a bottleneck. Some high-performance setups disable connection tracking entirely on forwarding paths and rely on stateless packet filtering, trading security granularity for throughput.

Stateful Tracking for UDP and ICMP

TCP has explicit connection lifecycle events (SYN, FIN, RST), making stateful tracking natural. But UDP and ICMP are connectionless protocols. The conntrack system handles them through heuristics:

For UDP, conntrack creates a state entry when the first outbound packet is seen. If a reply packet arrives from the same remote IP and port within a timeout period (typically 30 seconds for unreplied, 180 seconds for assured), the connection is considered established. This allows DNS queries (UDP port 53), NTP requests, and other UDP-based protocols to work transparently through a stateful firewall.

For ICMP, conntrack tracks request/reply pairs. An outbound echo request (ping) creates a state entry, and the corresponding echo reply is matched and allowed back through. ICMP error messages (destination unreachable, time exceeded, etc.) are matched to the connection that triggered them using the embedded original packet header in the ICMP payload -- this is the RELATED state in action.

Application-Layer Gateways and Deep Packet Inspection

Packet filtering and stateful inspection operate at layers 3 and 4 of the OSI model -- they see IP addresses, ports, and connection state, but they do not understand the application data inside the packets. An application-layer gateway (ALG), also called an application-level firewall or proxy firewall, operates at layer 7 and understands application protocols.

An ALG terminates the client's connection, inspects the application-layer data, and opens a new connection to the destination server on behalf of the client. This allows it to enforce policies that packet filters cannot:

The trade-off is performance. An ALG must parse and understand application-layer protocols, which is far more computationally expensive than checking packet headers. It also introduces latency because the firewall acts as a proxy -- the client connects to the firewall, not directly to the server. In return, it provides far deeper security enforcement.

Web Application Firewalls (WAF)

A Web Application Firewall is a specialized ALG focused on HTTP/HTTPS traffic. WAFs inspect the full HTTP request and response, including headers, URL parameters, POST bodies, cookies, and JSON/XML payloads. They enforce rules designed to prevent common web application attacks:

Popular WAF solutions include ModSecurity (open-source, runs as an Apache/Nginx module), Cloudflare WAF (cloud-based, inspects traffic at the CDN edge), and AWS WAF (integrated with Application Load Balancers). Many WAFs use the OWASP Core Rule Set (CRS), a community-maintained set of over 200 rules targeting the OWASP Top 10 vulnerabilities.

Firewalls and NAT: Two Sides of the Same Coin

Network Address Translation (NAT) and stateful firewalling are deeply intertwined. In Linux, both are implemented by the same Netfilter/conntrack subsystem. NAT rewrites packet headers (changing source or destination IP addresses and ports), and it relies on the connection table to translate return traffic back to the original addresses.

There are two primary NAT modes relevant to firewalling:

Source NAT (SNAT/Masquerade) rewrites the source address of outbound packets. This is what your home router does: it replaces your private IP address (e.g., 192.168.1.100) with its public IP address, allowing multiple private-network devices to share a single public IP. The firewall's conntrack table records the original source address and port so that return traffic can be translated back.

Destination NAT (DNAT/Port Forwarding) rewrites the destination address of inbound packets. This is used to expose internal services to the internet. For example, forwarding port 443 on the firewall's public IP to an internal web server at 10.0.1.10:443. In iptables:

# DNAT: forward inbound port 443 to internal server
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 10.0.1.10:443

# Must also allow the forwarded traffic in the filter table
iptables -A FORWARD -p tcp -d 10.0.1.10 --dport 443 -j ACCEPT

NAT provides a degree of implicit security because hosts behind a NAT gateway are not directly addressable from the internet. However, NAT is not a firewall. It was designed to address IPv4 address exhaustion, not to provide security. A NAT gateway without explicit firewall rules will still forward DNAT'd traffic to internal hosts, and a misconfigured port forward can expose vulnerable services. With IPv6, where every device can have a globally routable address, NAT's implicit protection disappears entirely -- explicit firewall rules become the only defense.

Network Zones and the DMZ

A firewall does not simply divide the world into "inside" and "outside." Real-world network architectures use multiple security zones, each with different trust levels and different rules governing traffic between them. The most common zones are:

The critical principle in zone-based architecture is that the DMZ protects the LAN. If an attacker compromises a web server in the DMZ, the firewall rules prevent that compromised server from reaching internal resources. Traffic flows are tightly controlled:

Network Zone Architecture with DMZ Internet Untrusted zone External clients Attackers, bots Firewall (External) Allow 80, 443 DMZ Semi-trusted zone Web servers (HTTPS) DNS, mail servers Firewall (Internal) Strict rules LAN Trusted zone Workstations Internal databases Zone Traffic Policy From To Policy Internet DMZ Allow HTTP/HTTPS only Internet LAN DENY all (no direct access) DMZ LAN Allow DB port only (3306/5432) LAN DMZ Allow SSH for management LAN Internet Allow (outbound NAT) DMZ Internet Allow DNS, NTP, updates only

In a dual-firewall architecture, the external firewall sits between the internet and the DMZ, while the internal firewall sits between the DMZ and the LAN. Using two separate firewalls (ideally from different vendors) means that a vulnerability in one firewall product does not compromise both perimeters. In smaller deployments, a single firewall with three or more network interfaces achieves a similar zone separation.

Firewall Rule Ordering and Optimization

Firewall rules are evaluated sequentially. The order in which rules appear in a chain determines both the security posture and the performance of the firewall. Several principles govern effective rule ordering:

First Match Wins

In iptables and nftables, the first matching rule determines the action for a packet. This has critical implications. Consider these two rule orderings:

# Order A (CORRECT): specific deny before general allow
iptables -A INPUT -p tcp --dport 443 -s 198.51.100.0/24 -j DROP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Order B (WRONG): general allow before specific deny
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -s 198.51.100.0/24 -j DROP  # Never reached!

In Order B, the DROP rule is dead code -- every packet to port 443 matches the ACCEPT rule first, including traffic from the blocked subnet. This class of bug is one of the most common firewall misconfiguration errors.

Performance Optimization

On a firewall processing millions of packets per second, rule ordering affects throughput. The conntrack state-match rule should always be first:

# THIS RULE MUST BE FIRST
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

This single rule handles the vast majority of traffic on any busy firewall. Once a connection is established, all subsequent packets in that connection match this rule on the first check, skipping every other rule in the chain. Without this optimization, every packet in an established connection would traverse the entire ruleset.

After the conntrack rule, additional ordering principles include:

Default Policies: Allow vs. Deny

There are two fundamental approaches to default policies:

Default deny (allowlist): the default policy is DROP, and rules explicitly ACCEPT permitted traffic. This is the secure approach -- any traffic not explicitly allowed is blocked. If you forget a rule, the traffic is denied. All production firewall deployments should use this model.

Default allow (blocklist): the default policy is ACCEPT, and rules explicitly DROP prohibited traffic. This is insecure by design -- any traffic you forget to block is allowed. It is useful only for temporary debugging or in environments where availability takes absolute priority over security (rare in practice).

Next-Generation Firewalls (NGFW)

The term next-generation firewall (NGFW) was coined by Gartner around 2009 to describe firewalls that integrate capabilities beyond basic stateful packet filtering. An NGFW combines traditional firewalling with additional security functions in a single appliance or software platform:

Deep Packet Inspection (DPI)

DPI goes beyond looking at packet headers. It examines the payload data of packets to identify the application protocol being used, regardless of the port number. Traditional firewalls assume that port 80 means HTTP and port 443 means HTTPS, but applications routinely use non-standard ports, and attackers intentionally tunnel malicious traffic over allowed ports.

A DPI engine can identify that a connection on port 443 is actually carrying BitTorrent traffic, not HTTPS. It can detect that traffic on port 80 is a WebSocket connection being used for command-and-control communication. It does this by matching patterns in the packet payload against a database of application signatures -- specific byte sequences, handshake patterns, or protocol-level behaviors that uniquely identify each application.

DPI is computationally expensive. Inspecting every byte of payload requires significant CPU and memory resources, and it can introduce latency. For TLS-encrypted traffic, DPI requires either TLS interception (the firewall acts as a man-in-the-middle, decrypting and re-encrypting traffic using its own CA certificate installed on client machines) or analysis of TLS metadata (SNI field, JA3/JA4 fingerprints, certificate details) without decrypting the payload.

Intrusion Prevention System (IPS)

An integrated IPS analyzes traffic in real-time against a database of known attack signatures and behavioral anomalies. Unlike a standalone IDS (Intrusion Detection System) that merely alerts, an IPS actively blocks detected threats. Signature-based detection matches traffic against patterns of known exploits (e.g., specific buffer overflow payloads, SQL injection strings, malware download patterns). Anomaly-based detection establishes baselines of "normal" traffic and flags deviations -- sudden spikes in outbound DNS queries might indicate DNS exfiltration, or an unusual volume of SYN packets could signal a SYN flood attack.

Popular IPS/IDS engines include Snort (open-source, maintained by Cisco), Suricata (open-source, multi-threaded, developed by OISF), and proprietary engines in commercial NGFWs from Palo Alto Networks, Fortinet, and Check Point. Suricata can process over 10 Gbps on modern hardware using kernel bypass techniques like DPDK (Data Plane Development Kit) or AF_PACKET.

Application Awareness and User Identity

NGFWs can write rules based on the application rather than the port. Instead of "allow TCP port 443," the rule becomes "allow HTTPS but block Tor, block BitTorrent, allow Slack, restrict YouTube to low quality." This application-awareness is powered by DPI signatures and protocol decoders.

User-identity integration allows rules like "engineers can SSH to production servers, but marketing cannot." The firewall integrates with directory services (Active Directory, LDAP) to associate IP addresses or authenticated sessions with user identities, enabling role-based access control at the network layer.

Threat Intelligence Feeds

NGFWs subscribe to real-time threat intelligence feeds that provide lists of known-malicious IP addresses, domains, URLs, and file hashes. When traffic matches an entry in these feeds, it is automatically blocked or flagged. The feeds are continuously updated as new threats are discovered, providing protection against zero-day malware, phishing campaigns, and command-and-control infrastructure.

Cloud Firewalls and Security Groups

Cloud computing has introduced new firewall models that differ fundamentally from traditional network firewalls. Instead of a physical or virtual appliance sitting at a network choke point, cloud firewalls are distributed across the infrastructure and enforced at the hypervisor or virtual network level.

AWS Security Groups

An AWS Security Group acts as a virtual firewall for EC2 instances. It controls inbound and outbound traffic at the instance level. Key characteristics distinguish it from traditional firewalls:

A typical AWS security group configuration for a web server:

# Inbound rules
Type          Protocol    Port    Source
HTTPS         TCP         443     0.0.0.0/0           (public access)
HTTP          TCP         80      0.0.0.0/0           (redirect to HTTPS)
SSH           TCP         22      sg-bastion-host     (from bastion only)
Custom TCP    TCP         8080    sg-load-balancer    (health checks)

# Outbound rules
Type          Protocol    Port    Destination
All traffic   All         All     0.0.0.0/0           (default: allow all outbound)

Network ACLs (NACLs)

AWS also provides Network ACLs that operate at the subnet level. NACLs are stateless -- you must explicitly allow both inbound and outbound traffic, including return traffic on ephemeral ports. They support both ALLOW and DENY rules, and rules are evaluated in numbered order (lowest first). NACLs provide a secondary layer of defense that operates independently of security groups.

Google Cloud Firewall Rules and Azure NSGs

Google Cloud Platform uses VPC Firewall Rules that are conceptually similar to AWS security groups but with differences: rules can be ALLOW or DENY, they apply to an entire VPC network (not individual instances), and they use network tags or service accounts for targeting. Azure Network Security Groups (NSGs) combine features of both security groups and NACLs: they support ALLOW and DENY rules, they are stateful, and they can be applied at both the subnet level and the network interface level.

Kubernetes Network Policies

Container orchestration platforms like Kubernetes introduce yet another firewall model. Network Policies are Kubernetes resources that control traffic between pods (containers) within a cluster. By default, all pods in a Kubernetes cluster can communicate with all other pods -- network policies restrict this.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-server
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: web-frontend
    ports:
    - protocol: TCP
      port: 8080

This policy allows only pods labeled app: web-frontend to reach pods labeled app: api-server on port 8080. All other ingress traffic to the API server pods is denied. Network policies are enforced by the Container Network Interface (CNI) plugin -- Calico, Cilium, and Weave Net all support network policies, each with different implementation approaches (Cilium uses eBPF for high-performance enforcement).

eBPF and the Future of Kernel-Level Firewalling

eBPF (extended Berkeley Packet Filter) is fundamentally changing how packet processing works in the Linux kernel. Instead of using the Netfilter hook-and-chain architecture that iptables and nftables rely on, eBPF allows custom programs to be loaded directly into the kernel and attached to network hooks at various points in the network stack.

The key advantage is performance. eBPF programs run in a sandboxed virtual machine inside the kernel, with JIT compilation to native machine code. They can process packets before they enter the full network stack, bypassing conntrack and the Netfilter chains entirely when appropriate. This makes eBPF-based firewalls significantly faster for high-throughput workloads.

Cilium, a popular Kubernetes networking project, replaces kube-proxy and traditional iptables rules with eBPF programs. On a Kubernetes node running thousands of services with tens of thousands of iptables rules (one for each Service/endpoint combination), the linear rule traversal becomes a measurable bottleneck. Cilium's eBPF maps provide O(1) lookups regardless of the number of rules.

XDP (eXpress Data Path) is an eBPF hook that processes packets at the earliest possible point -- in the network driver itself, before the kernel allocates a socket buffer. XDP programs can drop, redirect, or modify packets at line rate. This is commonly used for DDoS mitigation: an XDP program can drop known-malicious traffic at 100 Gbps without consuming CPU cycles on socket buffer allocation or routing lookups.

Firewall Architectures: Defense in Depth

No single firewall technology provides complete protection. Modern security architectures layer multiple types of firewalls at different points in the network stack:

Each layer catches threats that the others miss. A perimeter firewall might allow HTTPS traffic that contains a SQL injection payload; the WAF catches it. A security group might allow pod-to-pod traffic that violates application-level constraints; a Kubernetes network policy enforces it. The host firewall ensures that even if every other layer fails, the server itself rejects unauthorized connections.

Common Firewall Pitfalls

Despite their ubiquity, firewalls are frequently misconfigured. Some of the most dangerous mistakes include:

Firewalls and BGP: Protecting the Routing Infrastructure

For networks operating their own autonomous system, firewalls play a critical role in protecting the BGP routing infrastructure itself. BGP sessions run on TCP port 179, and unauthorized BGP connections could allow an attacker to inject false routes (a BGP hijack) or disrupt existing sessions.

Standard practice includes:

See It in Action

Firewalls protect networks at every layer, but the underlying routing is visible through BGP. Use the looking glass to explore the networks behind major firewall vendors and cloud platforms:

Every connection to this page passed through multiple firewalls: your device's host firewall, your router's NAT and packet filter, your ISP's infrastructure ACLs, and Cloudflare's edge WAF. Look up any IP address or AS number in the looking glass to see the AS path your traffic traverses -- and consider how many firewalls guard each hop along the way.

See BGP routing data in real time

Open Looking Glass
More Articles
How TLS/HTTPS Works: Securing the Internet's Traffic
Certificate Transparency: How CT Logs Secure the Web's PKI
What is Cross-Site Scripting (XSS)?
What is Cross-Site Request Forgery (CSRF)?
What is Server-Side Request Forgery (SSRF)?
What is SQL Injection?