До основного вмісту

iptables: налаштування файрвола Linux з нуля

Безпека · 21.02.2025 · 4 хв читання
Ілюстрація до статті «iptables: налаштування файрвола Linux з нуля»

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
⚠️ Перед застосуванням правил перевірте, що дозволили свій SSH-порт, інакше втратите доступ до сервера.
💡 Для простого керування використовуйте UFW — це надбудова над iptables із зручним синтаксисом.

Коли одного iptables недостатньо

  • Потрібна фільтрація на рівні застосунку (аналіз HTTP-запитів, а не лише портів і IP) — iptables працює на рівні L3/L4, для L7 потрібен WAF на кшталт ModSecurity.
  • Багато таблиць і ланцюжків із логікою, що перетинається — сучасні дистрибутиви поступово переходять на nftables, у якого читабельніший синтаксис і один набір таблиць замість окремих утиліт для IPv4 та IPv6.
  • Потрібен захист від підбору паролів за фактом невдалих спроб входу — iptables не читає логи застосунків, для цього потрібен Fail2ban поверх нього.

Перевірка, що правила застосувалися

  1. Виконайте iptables -L -v -n — переконайтеся, що ланцюжок INPUT містить очікувані правила і політика за замовчуванням дійсно DROP.
  2. З іншого пристрою перевірте закритий порт: nc -zv ВАША_IP 3306 має завершитися відмовою.
  3. Перезавантажте сервер і знову виконайте iptables -L -v -n — якщо правила зникли, значить netfilter-persistent save не був виконаний або пакет iptables-persistent не встановлений.
  4. Перевірте лічильники пакетів у iptables -L -v -n: зростаючі значення напроти правила SYN flood підтверджують, що ліміт дійсно фільтрує трафік, а не просто існує в конфігу.

Простіший інтерфейс до тих самих правил — у статті UFW для Ubuntu і Debian, а автоматичне блокування за логами — у розборі налаштування Fail2ban.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці