К основному содержимому

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.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке