Skip to content

Setting iptables: basic Linux firewall

iptables— is the built‑in framework for filtering and managing network traffic in the Linux kernel. It allows flexible control over incoming, outgoing, and transit connections based on rules.

Note

iptables is preinstalled on almost all Linux distributions.
In newer systems (RHEL 8+, Ubuntu 20.04+), the default may be *****nftables****** (the nft command), but iptables remains compatible via the legacy interface iptables-legacy.
For cloud or VPS servers — ****setting** iptables is critically important for security**.


Core Concepts

Three chains (chains)

Chain Purpose
*****INPUT****** Incoming traffic ****to the server**** (SSH, HTTP, etc.)
*****OUTPUT****** Outgoing traffic ****from the server**** (updates, API requests)
*****FORWARD****** Traffic that ****passes through the server**** (only when routing/NAT)

Note

Be careful with INPUT!
Blocking port 22 without permission can disconnect you from the server. Always review rules before applying.

How it works

  1. A packet enters the appropriate chain INPUT, OUTPUT, FORWARD.
  2. Rules are evaluated ****in order**** — as soon as a match is found, the specified action is taken.
  3. If ****no match is found****, the ****default policy**** policy is applied.

Actions (targets)

Action Behavior Recommendation
ACCEPT Allow the packet For trusted services (SSH, HTTP)
DROP Silently drop the packet (no reply) ****Best choice for security**** — hides the existence of the port
REJECT Reject with an ICMP error (e.g., port-unreachable) Use if you need feedback (e.g., for debugging)

Note

Security rule
By default — deny everything, then allow only what is needed.


Basic command syntax

iptables [options] CHAIN [criteria] -j ACTION

Main options:

Option Purpose
-A Append a rule to the end of the chain
-I Insert a rule at the beginning (or at a specific number: -I INPUT 1)
-D Delete a rule (by number or by copying the line)
-L List rules
-F Flush all rules in the chain
-P Set default policy ACCEPT, DROP)

Frequently used criteria:

Option Example Description
-p tcp/udp/icmp -p tcp Protocol
--dport N --dport 22 Destination port
-s IP/MASK -s 192.168.1.5<br-s 203.0.113.0/24 Source (IP or subnet)
-i interface -i eth0 Incoming interface
-m state --state NEW,ESTABLISHED -m state --state NEW Connection state
-m connlimit --connlimit-above 5 Connection limit

Viewing and troubleshooting

Display all rules (readable):

sudo iptables -L -n -v --line-numbers
- -n — do not resolve names (faster); - -v — verbose output; - --line-numbers — show rule numbers (useful for deletion).

View default policies:

sudo iptables -S | grep '^:'
# Or:
sudo iptables -L | head -3

Practical rule examples

# 1. Allow all traffic on loopback
sudo iptables -A INPUT -i lo -j ACCEPT

# 2. Allow already established connections (important!)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 3. Allow SSH (replace 22 with your port if changed!)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 4. Allow HTTP/HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 5. Drop everything else by default
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT   # ← usually allow outbound

2. Access restriction

# Allow MySQL (3306) only from one IP
sudo iptables -A INPUT -s 203.0.113.15 -p tcp --dport 3306 -j ACCEPT

# Block all traffic from a suspicious IP
sudo iptables -A INPUT -s 198.51.100.77 -j DROP

3. Attack protection

# Block malformed/invalid packets
sudo iptables -A INPUT -m state --state INVALID -j DROP

# Protect against SYN‑flood
sudo iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
sudo iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j DROP

# Limit connections to HTTP (no more than 20 concurrent from one IP)
sudo iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 32 -j DROP

4. Logging

# Log attempts to connect to closed ports (first 5 per minute)
sudo iptables -A INPUT -p tcp -m multiport --dports 22,3389,5900 \
  -m limit --limit 5/min -j LOG --log-prefix "PORT-SCAN: " --log-level 4

# Then drop
sudo iptables -A INPUT -p tcp -m multiport --dports 22,3389,5900 -j DROP

Saving rules after reboot

iptables rules are not saved automatically — they only reside in kernel memory.

For RHEL / CentOS 7 and earlier:

sudo /sbin/service iptables save
# or
sudo iptables-save > /etc/sysconfig/iptables

For Debian / Ubuntu:

Install the persistence package:

sudo apt update && sudo apt install iptables-persistent
During installation the system will prompt to save the current rules—choose "Yes".

Update saved rules later:

sudo netfilter-persistent save
# or directly:
sudo iptables-save > /etc/iptables/rules.v4

Note

Before rebooting, verify the rules:

sudo iptables-restore -t < /etc/iptables/rules.v4
The -t flag is only syntax checking, no application.


Removing rules

Delete by number (see --line-numbers):

sudo iptables -D INPUT 3   # delete rule #3 in the INPUT chain

Delete by exact match:

sudo iptables -D INPUT -s 198.51.100.77 -j DROP

Flush a chain:

sudo iptables -F INPUT      # only INPUT
sudo iptables -F            # all chains

Reset default policies:

sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT

Information

  1. Test rules locally or via console (not SSH!), especially when changing INPUT.
  2. Use screen or tmux so you don't lose the session on error.
  3. Consider moving to more modern tools:
  4. ufw — simplified interface for iptables (Ubuntu/Debian); -firewalld — dynamic firewall for RHEL/CentOS; -nftables — the future of the Linux kernel (more efficient and concise syntax).
question_mark
Is there anything I can help you with?
question_mark
AI Assistant ×