Information Security 22 min read

Mastering Linux Netfilter: How to Build Custom iptables Rules and NAT

This guide explains Linux's built‑in netfilter firewall framework, its five hook points, the relationship between tables and chains, and how to use iptables (and firewalld) to define, view, modify, and persist traffic‑filtering rules, implement NAT, and create custom chains for advanced network security.

Raymond Ops
Raymond Ops
Raymond Ops
Mastering Linux Netfilter: How to Build Custom iptables Rules and NAT

netfilter introduction

Firewalls are software or hardware that filter traffic between internal and external networks according to defined policies. Linux kernels include the netfilter firewall module, which enables packet filtering, NAT, and connection tracking.

User‑space tools such as iptables and firewalld allow administrators to define rules that are passed to the netfilter framework for packet processing.

netfilter five hooks

Rules defined in user‑space are associated with one of netfilter's five hook functions. When a packet traverses the network stack and reaches a hook point, netfilter processes the packet according to the rules linked to that hook.

These five hook functions are located at different points in the network stack:

netfilter hook diagram
netfilter hook diagram

1. PREROUTING : the first point a packet reaches, before routing decisions.

2. INPUT : handles packets destined for the local system.

3. FORWARD : handles packets that will be routed onward (neither destined for nor originating from the local system).

4. OUTPUT : handles packets generated by the local system before they leave.

5. POSTROUTING : captures packets after routing, just before they exit the system.

iptables

The most common user‑space firewall management tool is iptables ; alternatives include firewalld and nettable .

Before writing filtering rules with iptables, understand three core concepts: rules , chains , and tables .

Rule : a matching strategy composed of match conditions plus an action.

Chain : an ordered list of rules. Packets are examined sequentially until a match is found or the chain ends.

Table : groups chains by functionality (e.g., filtering, NAT).

A packet first enters a specific table, then traverses the chains within that table in order until a matching rule is found or the end is reached.

Default hook‑chain mapping : each of netfilter's five hooks has a default chain with the same name (e.g., the INPUT hook uses the INPUT chain).

filter table : primary packet‑filtering table, containing chains like INPUT, OUTPUT, and FORWARD.

nat table : handles network address translation, associated with PREROUTING and POSTROUTING chains.

mangle table : used for specialized packet modifications; contains all five standard chains.

raw table : configures exceptions to bypass connection tracking; linked to PREROUTING and OUTPUT.

Implementing traffic filtering

Define rules

<code>iptables -t &lt;table&gt; -I| -A &lt;chain&gt; &lt;match conditions&gt; -j &lt;action&gt;</code>

Explanation:

-I

inserts the rule at the beginning of the chain (matched first).

-A

appends the rule to the end of the chain (matched later).

Example: drop all packets from host

10.0.0.11

:

<code>iptables -t filter -I INPUT -s 10.0.0.11 -j DROP</code>

Example: drop packets whose destination is

10.0.0.11

:

<code>iptables -A INPUT -d 10.0.0.11 -j DROP</code>

Match conditions are divided into basic matches (address, interface, protocol) and extended matches (requiring additional modules via

-m

).

Basic address match:

-s

for source,

-d

for destination.

Interface match:

-i

for incoming interface,

-o

for outgoing.

Extended matches include port matching (

multiport

module) and protocol matching (

tcp

,

udp

,

icmp

modules).

Example: block ports 22, 80, 1884, 1883 for source

10.0.0.29

:

<code>iptables -t filter -I INPUT -s 10.0.0.29 -p tcp -m multiport --ports 22,80,1884,1883 -j DROP</code>

Supported actions: ACCEPT (allow), DROP (silently discard), REJECT (reject with notification).

View rules

<code>iptables -t &lt;table&gt; -vnL</code>

Delete rules

Use

-D

with either the rule number or the exact rule specification.

<code>iptables -t filter -D INPUT 1</code>
<code>iptables -t filter -D INPUT -s 10.0.0.11 -j DROP</code>

Flush a chain

Remove all rules from a chain with

-F

(defaults to the

filter

table if none is specified).

<code>iptables -t filter -F INPUT</code>

Change default policy

<code>iptables -P &lt;chain&gt; &lt;policy&gt;</code>

Example: set the default policy of the INPUT chain in the filter table to DROP:

<code>iptables -t filter -P INPUT DROP</code>

Implement black/white lists

Black list: set default policy to ACCEPT and add DROP/REJECT rules for unwanted traffic. White list: set default policy to DROP and add ACCEPT rules for allowed traffic.

Example: allow only ports 22, 80, 8000, 8001, 1883, 1884, 9001, 9100, 9802 for both TCP and UDP:

<code># Ensure current remote connection stays alive
iptables -t filter -I INPUT -s 10.0.0.1 -j ACCEPT
# Change default INPUT policy to DROP
iptables -t filter -P INPUT DROP
# Allow specified ports for TCP
iptables -t filter -A INPUT -m multiport -p tcp --dports 22,8000,8001,80,1883,1884,9001,9100,9802 -j ACCEPT
# Allow specified ports for UDP
iptables -t filter -A INPUT -m multiport -p udp --dports 22,8000,8001,80,1883,1884,9001,9100,9802 -j ACCEPT</code>

Persist rules

Rules added with iptables are lost after a reboot. Save them with

iptables-save

and restore with

iptables-restore

, or create a systemd service.

<code>sudo iptables-save > /path/to/iptables.rules</code>
<code>sudo iptables-restore < /path/to/iptables.rules</code>
<code>[Unit]
Description=Restore iptables rules
After=network.target

[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /path/to/iptables.rules
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target</code>

Implement NAT

NAT (Network Address Translation) translates private IP addresses to public ones and vice versa. It is typically performed by routers, firewalls, or dedicated NAT devices.

Private address ranges:

A class: 10.0.0.0/8

B class: 172.16.0.0/12

C class: 192.168.0.0/16

NAT types:

SNAT : changes the source address (used when internal hosts access the Internet).

DNAT : changes the destination address (used to forward incoming traffic to an internal host).

PNAT/PAT : port‑address translation; modifies both source address and source port, allowing many internal hosts to share a single public IP.

SNAT example

<code># Replace source address for packets leaving the LAN
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j SNAT --to-source 172.18.1.6-172.18.1.9</code>

When the public IP is dynamic, use MASQUERADE:

<code>iptables -t nat -A POSTROUTING -s $LOCALNET ! -d $LOCALNET -j MASQUERADE</code>

DNAT example

<code>iptables -t nat -A PREROUTING -d 10.0.0.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80</code>

PNAT (port redirection) example

<code># Method 1: DNAT to a different port
iptables -t nat -I PREROUTING -d 10.0.0.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080

# Method 2: REDIRECT within the same host
iptables -t nat -A PREROUTING -d 172.16.100.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080</code>

Custom chains

Netfilter provides default chains for each hook, but you can create custom chains and reference them from default chains.

Create a custom chain

<code>iptables -t filter -N IN_WEB</code>

Add rules to the custom chain (e.g., reject ICMP echo requests):

<code>iptables -t filter -I IN_WEB -p icmp --icmp-type 8/0 -j REJECT</code>

Reference the custom chain from a default chain:

<code>iptables -t filter -I INPUT -j IN_WEB</code>

Delete a custom chain

First flush the chain, then remove references, and finally delete it:

<code>iptables -F IN_WEB
iptables -t filter -D INPUT -j IN_WEB
iptables -X IN_WEB</code>
NATNetwork SecurityiptablesnetfilterLinux firewall
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.