iptables — класичний інтерфейс до netfilter, підсистеми фільтрації пакетів ядра Linux. Він працює з ланцюжками правил, які перевіряються по порядку згори вниз: щойно пакет збігся з правилом, подальші правила в цьому ланцюжку не перевіряються.
Три основні ланцюжки
Кожен ланцюжок перевіряється окремо і не впливає на рішення інших: дозволивши щось у INPUT, ви не дозволяєте це автоматично в FORWARD. На звичайному веб-сервері, який не пересилає чужий трафік, ланцюжок FORWARD може залишатися закритим повністю — він потрібен лише коли сервер сам виступає шлюзом чи роутером для інших машин.
| Ланцюжок | Коли застосовується | Типове завдання |
|---|---|---|
| INPUT | Пакети, адресовані самому серверу | Дозволити SSH, HTTP, HTTPS; заблокувати решту |
| OUTPUT | Пакети, що виходять із сервера | Зазвичай залишають ACCEPT, якщо сервер не проксує чужий трафік |
| FORWARD | Транзитні пакети через сервер | Актуально для роутерів, VPN-шлюзів і Docker-хостів |
Базові правила iptables
#!/bin/bash
# Очищаємо всі правила
iptables -F
iptables -X
# Політика за замовчуванням: блокувати вхідний трафік
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Дозволяємо loopback
iptables -A INPUT -i lo -j ACCEPT
# Дозволяємо встановлені з'єднання
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSH (замініть 22 на свій порт)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# HTTP і HTTPS
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# ICMP (ping)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
Типові помилки при першому запуску
Забули правило для SSH перед політикою DROP
Якщо виконати iptables -P INPUT DROP раніше, ніж додано правило -A INPUT -p tcp --dport 22 -j ACCEPT, активна SSH-сесія обірветься, а нова не підключиться. На VPS без консолі провайдера це означає повну втрату доступу. Правильний порядок — спочатку додати всі ACCEPT-правила, політику DROP виставляти останньою командою.
Забули дозволити loopback
Без iptables -A INPUT -i lo -j ACCEPT з політикою DROP на INPUT ламаються локальні з'єднання між процесами на самому сервері — наприклад, PHP-FPM більше не зможе достукатися до MySQL через 127.0.0.1, хоча порт зовні ніхто не чіпав.
Захист від сканування портів
# Блокування NMAP SYN сканування
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# Обмеження нових з'єднань (захист від SYN flood)
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
Правило з --state ESTABLISHED,RELATED із базового набору спирається на модуль відстеження з'єднань conntrack, у якого є ліміт розміру таблиці. При масовому скануванні портів чи флуді нових з'єднань таблиця може переповнитися, і в системному лозі з'явиться повідомлення:
kernel: nf_conntrack: table full, dropping packet
Після цього повідомлення нові легітимні з'єднання теж починають обриватися — не лише атакуючі. Ліміт нових з'єднань у правилі вище знижує ризик такого переповнення, але за дійсно великої атаки одного iptables недостатньо: потрібна фільтрація до сервера, на рівні провайдера чи CDN.
Збереження правил
apt install iptables-persistent -y
netfilter-persistent save
# Правила зберігаються в /etc/iptables/rules.v4
Коли одного iptables недостатньо
- Потрібна фільтрація на рівні застосунку (аналіз HTTP-запитів, а не лише портів і IP) — iptables працює на рівні L3/L4, для L7 потрібен WAF на кшталт ModSecurity.
- Багато таблиць і ланцюжків із логікою, що перетинається — сучасні дистрибутиви поступово переходять на nftables, у якого читабельніший синтаксис і один набір таблиць замість окремих утиліт для IPv4 та IPv6.
- Потрібен захист від підбору паролів за фактом невдалих спроб входу — iptables не читає логи застосунків, для цього потрібен Fail2ban поверх нього.
Перевірка, що правила застосувалися
- Виконайте
iptables -L -v -n— переконайтеся, що ланцюжок INPUT містить очікувані правила і політика за замовчуванням дійсно DROP. - З іншого пристрою перевірте закритий порт:
nc -zv ВАША_IP 3306має завершитися відмовою. - Перезавантажте сервер і знову виконайте
iptables -L -v -n— якщо правила зникли, значитьnetfilter-persistent saveне був виконаний або пакетiptables-persistentне встановлений. - Перевірте лічильники пакетів у
iptables -L -v -n: зростаючі значення напроти правила SYN flood підтверджують, що ліміт дійсно фільтрує трафік, а не просто існує в конфігу.
Простіший інтерфейс до тих самих правил — у статті UFW для Ubuntu і Debian, а автоматичне блокування за логами — у розборі налаштування Fail2ban.