Comprehensive Iptables Tutorial: Essential Commands and Tips for Efficient Network Management

iptables is very powerful, but it has many parameter options, making the learning curve steep. This iptables tutorial summarizes commonly used iptables commands for quick reference in critical moments.

The Four Tables and Five Chains of iptables

The four tables and five chains of iptables refer to the four tables and five chains within iptables. The four tables are:

  1. filter table: Used for filtering packets and controlling network traffic.
  2. nat table: Used for address translation of packets, implementing Network Address Translation (NAT) functionality.
  3. mangle table: Used for modifying packet header information, such as TTL, TOS, etc.
  4. raw table: Used for handling the connection state of packets, processing packets that have not yet established a connection.

The five chains are:

  1. PREROUTING: Processes packets before they enter routing.
  2. INPUT: Processes packets before they enter the local machine.
  3. FORWARD: Processes packets before they are forwarded to other hosts.
  4. OUTPUT: Processes packets before they leave the local machine.
  5. POSTROUTING: Processes packets after they leave routing.

In iptables, you need to use -t to specify the table whose rules you want to view. If not specified, the default is the filter table. For example, to view the rules of the nat table:

 iptables -t nat -L
iptables tutorial

View Detailed Rules of a Table

 iptables -t nat -nvL --line-numbers
iptables tutorial

Displaying line numbers makes it easier to delete specific rules.

Port Forwarding

Enable Kernel Forwarding

 echo "net.ipv4.ip_forward = 1" > > /etc/sysctl.conf
sysctl -p

Local Port Forwarding

Local port forwarding involves only one machine. For example, forwarding external access to port 2222 on the local machine to port 22 on the same machine.

 iptables -t nat -A PREROUTING -p tcp --dport 2222 -j REDIRECT --to-port 22

After adding the above rule, external access is possible, but local access via 127.0.0.1 is not, as local requests do not go through PREROUTING.

Multi-Host Port Forwarding

A’s IP is 192.168.1.2, B’s IP is 192.168.1.1, and A and B are on the same internal network. Now, an external IP (1.2.3.4) wants to access A’s port 22 by accessing B’s port 2222.

 iptables -t nat -A POSTROUTING -d 192.168.1.2 -p tcp --dport 22 -j SNAT --to-source 192.168.1.1

This command is very important! It changes the source address of all TCP traffic returning from machine A to B’s IP address. This needs to be executed regardless of single or multi-port forwarding.

Single Port Forwarding

 iptables -t nat -A PREROUTING -s 1.2.3.4 -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.2:22

The first command redirects all TCP traffic destined for 1.2.3.4 on port 2222 to port 22 on machine A.

Note: Both commands must be executed on machine B, as it is the target of external access.

If you do not want to restrict the source of external access to C, you can omit the -s option.

 iptables -t nat -A PREROUTING  -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.2:22

This allows requests from any external IP to be forwarded.

Multi-Port Forwarding

For the above command, if it is multi-port forwarding, it can be divided into one-to-many and many-to-many scenarios.

Note: According to tests, iptables does not support different mappings for multiple ports of different hosts in a single command. For example, forwarding B’s port 80 to A’s port 8080 and B’s port 443 to A’s port 4443 simultaneously.

One-to-Many Port Forwarding

For example, forwarding all ports from 50000 to 60000 on B to port 443 on A, the command is as follows:

 iptables -t nat -I PREROUTING  -p tcp  -m multiport --dport 50000:60000 -j DNAT --to-destination 192.168.1.2:443

Note: The “–dports” parameter specifies a range of ports, using a colon “:” to indicate the range between the start and end ports.

Many-to-Many Port Forwarding

For example, forwarding all ports from 50000 to 60000 on B to the same range on A, the command is as follows:

 iptables -t nat -I PREROUTING -p tcp -m multiport --dport 50000:60000 -j DNAT --to-destination 192.168.1.2:50000-60000

Of course, multiple ports can also be non-contiguous, such as forwarding ports 80, 443, and 8080 to the same ports on A. Separate the ports with commas “,” and do not specify ports after the IP in the –to-destination parameter.

 iptables -t nat -I PREROUTING -p tcp -m multiport --dport 80,443,8080 -j DNAT --to-destination 192.168.1.2

Note: Use “-” after the –to-destination parameter to indicate the range between the start and end ports.

The Role of MASQUERADE

The role of MASQUERADE is to automatically obtain the current IP address from the server’s network card for NAT, eliminating the need to manually specify the destination IP, thus achieving dynamic SNAT .

 iptables -t nat -A POSTROUTING -d 192.168.1.2 -p tcp --dport 22 -j SNAT --to-source 192.168.1.1

This command can be replaced with the following using MASQUERADE.

 iptables -t nat -A POSTROUTING -d 192.168.1.2 -p tcp --dport 22 -j MASQUERADE

The advantage is that if the IP of machine B changes, there is no need to modify the –to-source parameter, as iptables will automatically replace it, achieving dynamic SNAT.

Adding, Inserting, and Deleting iptables Rules

  • -A Adds a rule at the end of the list
  • -I Inserts a new rule at the top by default
  • -F If no is specified, it clears all rules in the table
  • -D Deletes the specified rule by number

Insert a Rule After the nth Rule

 iptables -I    

For example, to add a rule after the third rule in the POSTROUTING chain of the nat table.

 iptables -t nat -I POSTROUTING 3  

Delete All Rules in a Specific Chain of a Table

iptables -t -F

The table name can be filter, nat, mangle, raw, etc., and the chain name can be INPUT, OUTPUT, FORWARD, etc.

For example, to clear all rules in the INPUT chain of the filter table, use the following command:

 iptables -t filter -F INPUT

Note that this operation is irreversible, and all rules will be deleted.

iptables to Deny Inbound Traffic

Deny Access to a Range of IPs to a Range of Ports

For example, to drop packets from source IP 47.100.0.0/16 to destination ports 40000-60000, the command is as follows:

 iptables -A INPUT -s 47.100.0.0/16 -p tcp --dport 40000:60000 -j DROP

Deny All Requests from a Specific IP

For example, to deny all requests from 47.100.0.1, the command is as follows:

 iptables -A INPUT -s 47.100.0.1 -j DROP

Deny ICMP Traffic from a Range of IPs

For example, to deny all ICMP traffic of type 8 from the IP range 10.8.0.0/16.

 iptables -A INPUT -s 10.8.0.0/16 -p icmp --icmp-type 8 -j DROP

Similarly, for other protocols, you can modify the -p parameter of iptables, which supports TCP, UDP, ICMP, ICMPv6, esp, ah, sctp, udplite, and all protocols.

Restrict Access to Only a Specific IP Range

Whitelist: Allow first, then deny.

For example, to allow only the IP range 192.168.0.0/16 to access the local machine, and deny all other IPs, the command is as follows:

 iptables -I INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -I INPUT -s 0.0.0.0/0 -j DROP

Difference Between REJECT and DROP

REJECT and DROP are two different actions in iptables.

REJECT sends a message back to the source address, informing it that the request was rejected, while DROP silently discards the packet.

iptables -A OUTPUT -m string --string "youtube.com" --algo bm --to 65535 -j DROP

Explanation of the command parameters:

  -m string
 # Specify the module;
 --string "youtube.com"
 # Specify the string to match (domain name, keywords, etc.);
 --algo bm
 # Specify the string matching algorithm (another more complex algorithm is kmp);
 --to 65535
 # Specify the port, here it represents all ports (1-65535);
 -j DROP
 # Specify the action to take when a packet matches, here it is to drop the packet.

iptables Spoofing Source IP

Testing with two hosts in the internal network.

 iptables -t nat -D POSTROUTING -d   -o eth0 -j SNAT --to-source  

Testing shows that it works within the internal network. Note that the spoofed IP by iptables can send packets but cannot receive replies.

The fake-ip.py script and iptables spoofing source IP have the same effect, but testing on a public network host shows that spoofed packets cannot be received.

iptables Limiting Port Concurrency and Request Rate

Installing the ab Benchmarking Tool

 yum install httpd-tools -y

The command is as follows, note that the trailing slash / is essential.

 ab -n 1000 -c 10 http://ip:port/
  • -n Total of 1000 requests
  • -c 10 concurrent requests at a time

Limiting the Request Rate per Minute

 iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --set --name HTTP --rsource
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 60 --hitcount 100 --name HTTP --rsource -j DROP

This rule limits the number of HTTP connections to port 80 to 100 per IP address every 60 seconds. If this limit is exceeded, the connection will be rejected.

Limiting Port Concurrency

Limiting Total Port Concurrency

 iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT

Using the iptables connlimit module to limit the total concurrency on port 80 to no more than 10 connections. If exceeded, the connection is rejected. Note that this limits the total concurrency for all IPs, not per IP.

Limiting Concurrency per IP

 iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 32 -j REJECT --reject-with tcp-reset

--connlimit-mask 32: Specifies a mask of 32, indicating the limit is per single IP’s concurrent connections. The above rule limits the concurrency per single IP. To limit the total concurrency for all IPs, use --connlimit-mask 0.

Negating iptables Rules

Use the ! operator in iptables to negate rules, for example, to block all protocols except TCP.

 iptables -A INPUT ! -p tcp -j DROP

To block all IPs except those in the 192.168.0.0/16 range.

 iptables -A INPUT ! -s 192.16.0.0/16 -j DROP

Making iptables Rules Persistent

By default, iptables rules are lost after a reboot, so they need to be made persistent.

Using iptables-persistent

iptables-persistent is a tool on Debian/Ubuntu systems that automatically loads iptables rules after a reboot. Install it with the following command:

  apt-get install -y iptables-persistent

During installation, you will be prompted to save the current iptables rules. After installation, use the following command to save new iptables rules.

 service netfilter-persistent save

Using iptables-save to Save Rules

 iptables-save >  /etc/iptables.rules

Save the iptables rules to the /etc/iptables.rules file, and use the following command to load them.

 iptables-restore < /etc/iptables.rules

To automatically load iptables rules at system startup, add the above command to the /etc/rc.local file. Commands in this file are executed automatically at each system startup.