iptables — Firewall Rules

If you like this project, consider supporting me on Buy Me a Coffee ☕️


tags:

iptables is the traditional Linux userspace tool for configuring the kernel's netfilter packet filtering framework. It manages rules for firewalling, NAT, and traffic shaping. While still widely deployed, iptables is considered legacynftables is the modern replacement (available since kernel 3.13+). New deployments should prefer nftables.

📚 Official Docs / Официальная документация: iptables(8) · netfilter.org

[!IMPORTANT] iptables is legacy. For new deployments, use nftables — see the nftables cheatsheet and migration guide.

📘 Basics

Chains & Tables

# filter table: INPUT, FORWARD, OUTPUT
# nat table: PREROUTING, POSTROUTING, OUTPUT
# mangle table: PREROUTING, POSTROUTING, INPUT, OUTPUT, FORWARD

Policy

sudo iptables -P INPUT ACCEPT                 # Allow all input / Разрешить весь входящий
sudo iptables -P INPUT DROP                   # Drop all input / Запретить весь входящий
sudo iptables -P FORWARD DROP                 # Drop all forwarding / Запретить всю пересылку
sudo iptables -P OUTPUT ACCEPT                # Allow all output / Разрешить весь исходящий

🔍 List & View Rules

sudo iptables -L                              # List rules / Список правил
sudo iptables -L -n                           # List without DNS / Без DNS разрешения
sudo iptables -L -v                           # Verbose / Подробный
sudo iptables -L -n -v                        # Numeric verbose / Числа и подробности
sudo iptables -L INPUT                        # List INPUT chain / Список цепочки INPUT
sudo iptables -L OUTPUT                       # List OUTPUT chain / Список цепочки OUTPUT
sudo iptables -L -t nat                       # List NAT table / Список таблицы NAT
sudo iptables -L -t mangle                    # List mangle table / Список таблицы mangle
sudo iptables -L --line-numbers               # Show line numbers / Показать номера строк
sudo iptables -S                              # Show rules as commands / Показать как команды

⬇️ INPUT Chain

Allow Specific Ports

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT  # Allow SSH / Разрешить SSH
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT  # Allow HTTP / Разрешить HTTP
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT # Allow HTTPS / Разрешить HTTPS
sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT # Allow MySQL / Разрешить MySQL
sudo iptables -A INPUT -p tcp --dport 5432 -j ACCEPT # Allow PostgreSQL / Разрешить PostgreSQL
sudo iptables -A INPUT -p tcp --dport 6379 -j ACCEPT # Allow Redis / Разрешить Redis

Allow Port Range

sudo iptables -A INPUT -p tcp --dport 8000:8999 -j ACCEPT  # Ports 8000-8999 / Порты 8000-8999

Allow Specific IP

sudo iptables -A INPUT -s <IP> -j ACCEPT      # Allow from IP / Разрешить с IP
sudo iptables -A INPUT -s <IP>/24 -j ACCEPT   # Allow from subnet / Разрешить с подсети
sudo iptables -A INPUT -s <IP> -p tcp --dport 22 -j ACCEPT  # Allow IP to SSH / Разрешить IP на SSH

Allow Established Connections

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT  # Allow established / Разрешить установленные
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT  # Alternative / Альтернатива

Allow Loopback

sudo iptables -A INPUT -i lo -j ACCEPT        # Allow loopback / Разрешить loopback

Drop/Reject Traffic

sudo iptables -A INPUT -j DROP                # Drop all / Запретить всё
sudo iptables -A INPUT -j REJECT              # Reject all / Отклонить всё
sudo iptables -s <IP> -A INPUT -j DROP        # Drop from IP / Запретить с IP
sudo iptables -A INPUT -p tcp --dport 23 -j DROP  # Drop telnet / Запретить telnet

⬆️ OUTPUT Chain

sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT  # Allow HTTP out / Разрешить HTTP исходящий
sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT # Allow HTTPS out / Разрешить HTTPS исходящий
sudo iptables -A OUTPUT -d <IP> -j DROP       # Block destination IP / Заблокировать IP назначения
sudo iptables -A OUTPUT -m owner --uid-owner <USER> -j ACCEPT  # Allow user / Разрешить пользователю

🔀 FORWARD Chain

sudo iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT  # Forward eth0→eth1 / Пересылка eth0→eth1
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT  # Forward established / Пересылка установленных
sudo iptables -A FORWARD -i wg0 -j ACCEPT     # Forward from VPN / Пересылка с VPN
sudo iptables -A FORWARD -o wg0 -j ACCEPT     # Forward to VPN / Пересылка в VPN

🌐 NAT & Port Forwarding

SNAT (Source NAT) / SNAT (NAT

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  # Masquerade / Маскарад
sudo iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source <PUBLIC_IP>  # Static SNAT / Статический SNAT

DNAT (Destination NAT) / DNAT (NAT

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <INTERNAL_IP>:80  # Port forward / Проброс порта
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination <INTERNAL_IP>:80  # Port redirect / Перенаправление порта

Docker NAT / Docker NAT

sudo iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE  # Docker NAT / Docker NAT

💾 Saving & Restoring

Save Rules

sudo iptables-save > /etc/iptables/rules.v4  # Save IPv4 / Сохранить IPv4
sudo ip6tables-save > /etc/iptables/rules.v6 # Save IPv6 / Сохранить IPv6
sudo iptables-save | sudo tee /etc/iptables/rules.v4  # Alternative / Альтернатива

Restore Rules

sudo iptables-restore < /etc/iptables/rules.v4  # Restore IPv4 / Восстановить IPv4
sudo ip6tables-restore < /etc/iptables/rules.v6  # Restore IPv6 / Восстановить IPv6

Persistent Rules (Debian/Ubuntu)

sudo apt install iptables-persistent         # Install persistence / Установить сохранение
sudo netfilter-persistent save                # Save current rules / Сохранить текущие правила
sudo netfilter-persistent reload              # Reload rules / Перезагрузить правила

Persistent Rules (RHEL/CentOS)

sudo service iptables save                    # Save rules / Сохранить правила
sudo systemctl enable iptables                # Enable on boot / Включить при загрузке

🧩 Common Patterns

Basic Firewall Setup

# Flush existing rules
sudo iptables -F
sudo iptables -X

# Set default policies
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

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

# Allow established
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

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

# Save rules
sudo iptables-save > /etc/iptables/rules.v4

Web Server Firewall

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT   # HTTP
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT  # HTTPS
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set  # SSH rate limit
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

Database Server Firewall

# Allow only from app server
sudo iptables -A INPUT -s <APP_SERVER_IP> -p tcp --dport 3306 -j ACCEPT  # MySQL
sudo iptables -A INPUT -s <APP_SERVER_IP> -p tcp --dport 5432 -j ACCEPT  # PostgreSQL
sudo iptables -A INPUT -p tcp --dport 3306 -j DROP   # Drop other MySQL
sudo iptables -A INPUT -p tcp --dport 5432 -j DROP   # Drop other PostgreSQL

Rate Limiting

# SSH brute force protection
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

# HTTP rate limit
sudo iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

Block Specific Country (using ipset)

sudo ipset create blocklist hash:net          # Create ipset / Создать ipset
sudo ipset add blocklist <COUNTRY_CIDR>       # Add CIDR / Добавить CIDR
sudo iptables -A INPUT -m set --match-set blocklist src -j DROP  # Block / Заблокировать

🔧 Rule Management

Insert Rule

sudo iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT  # Insert at position 1 / Вставить в позицию 1

Delete Rule

sudo iptables -D INPUT -p tcp --dport 22 -j ACCEPT  # Delete by specification / Удалить по спецификации
sudo iptables -D INPUT 1                      # Delete by line number / Удалить по номеру строки

Replace Rule

sudo iptables -R INPUT 1 -p tcp --dport 2222 -j ACCEPT  # Replace rule 1 / Заменить правило 1

Flush Rules

sudo iptables -F                              # Flush all chains / Очистить все цепочки
sudo iptables -F INPUT                        # Flush INPUT chain / Очистить INPUT
sudo iptables -t nat -F                       # Flush NAT table / Очистить таблицу NAT
sudo iptables -X                              # Delete user chains / Удалить пользовательские цепочки

🐛 Troubleshooting

Debug Rules

sudo iptables -L -n -v --line-numbers         # Detailed list / Подробный список
sudo iptables -L -t nat -n -v                 # NAT table / Таблица NAT
sudo iptables -L -t mangle -n -v              # Mangle table / Таблица mangle

Check Packet Counters

sudo iptables -L -n -v                        # View counters / Просмотр счётчиков
sudo iptables -Z                              # Reset counters / Сбросить счётчики

Log Dropped Packets

sudo iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROPPED: " --log-level 4  # Log before drop / Лог перед отбросом
sudo iptables -A INPUT -j DROP                # Drop / Отбросить
sudo journalctl -k | grep IPTABLES            # View logs / Просмотр логов

Test Rule Without Applying

sudo iptables -C INPUT -p tcp --dport 22 -j ACCEPT  # Check if rule exists / Проверить существование правила

IPv6 / IPv6

sudo ip6tables -L -n -v                       # List IPv6 rules / Список IPv6 правил
sudo ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT  # Allow SSH IPv6 / Разрешить SSH IPv6
sudo ip6tables-save > /etc/iptables/rules.v6  # Save IPv6 / Сохранить IPv6

🌟 Real-World Examples

Docker Host Firewall

# Allow Docker containers
sudo iptables -A FORWARD -i docker0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

VPN Server (WireGuard) / VPN

sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Port Knocking

# Advanced port knocking setup
# Requires recent module
sudo iptables -A INPUT -m conntrack --ctstate NEW -m tcp -p tcp --dport 1111 -m recent --set --name KNOCK1
sudo iptables -A INPUT -m conntrack --ctstate NEW -m tcp -p tcp --dport 2222 -m recent --rcheck --seconds 10 --name KNOCK1 -m recent --set --name KNOCK2
sudo iptables -A INPUT -m conntrack --ctstate NEW -m tcp -p tcp --dport 22 -m recent --rcheck --seconds 10 --name KNOCK2 -j ACCEPT

Kubernetes NodePort / Kubernetes NodePort

# Allow Kubernetes NodePort range
sudo iptables -A INPUT -p tcp --dport 30000:32767 -j ACCEPT

Load Balancer

# Round-robin to backends / Round-robin
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -m statistic --mode nth --every 2 --packet 0 -j DNAT --to-destination <BACKEND1>:80
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -m statistic --mode nth --every 2 --packet 1 -j DNAT --to-destination <BACKEND2>:80

💡 Best Practices

Always test rules before saving

Use --line-numbers for easy management

Log dropped packets for debugging

Prefer nftables for new deployments

Keep backup of working rules

Test connectivity after rule changes

🔧 Configuration Files

# /etc/iptables/rules.v4    — IPv4 rules
# /etc/iptables/rules.v6    — IPv6 rules
# /etc/sysconfig/iptables   — RHEL/CentOS rules

📋 Migration to nftables

iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT  # Convert to nftables / Конвертировать в nftables
iptables-restore-translate -f /etc/iptables/rules.v4     # Convert entire ruleset / Конвертировать весь набор

On this page

linux iptables — Linux Packet Filtering 📘 Basics Chains &amp; Tables Policy 🔍 List &amp; View Rules ⬇️ INPUT Chain Allow Specific Ports Allow Port Range Allow Specific IP Allow Established Connections Allow Loopback Drop/Reject Traffic ⬆️ OUTPUT Chain 🔀 FORWARD Chain 🌐 NAT &amp; Port Forwarding SNAT (Source NAT) / SNAT (NAT DNAT (Destination NAT) / DNAT (NAT Docker NAT / Docker NAT 💾 Saving &amp; Restoring Save Rules Restore Rules Persistent Rules (Debian/Ubuntu) Persistent Rules (RHEL/CentOS) 🧩 Common Patterns Basic Firewall Setup Web Server Firewall Database Server Firewall Rate Limiting Block Specific Country (using ipset) 🔧 Rule Management Insert Rule Delete Rule Replace Rule Flush Rules 🐛 Troubleshooting Debug Rules Check Packet Counters Log Dropped Packets Test Rule Without Applying IPv6 / IPv6 🌟 Real-World Examples Docker Host Firewall VPN Server (WireGuard) / VPN Port Knocking Kubernetes NodePort / Kubernetes NodePort Load Balancer 💡 Best Practices Always test rules before saving Use --line-numbers for easy management Log dropped packets for debugging Prefer nftables for new deployments Keep backup of working rules Test connectivity after rule changes 🔧 Configuration Files 📋 Migration to nftables 📚 Documentation Links