iptables: правила firewall для Linux-сервера — АйТи Фреш
Москва, Щёлковское шоссе, д. 92, корп. 7 · Пн–Пт 9:00–19:00 · +7 903 729-62-41
· 16 мин чтения

iptables: правила firewall для Linux-сервера и шлюза корпоративной сети

iptables: правила firewall для Linux-сервера и шлюза корпоративной сети

iptables остаётся маст-хэвом для любого линукс-администратора, даже если есть ufw: без базовых знаний не понять, почему ufw ведёт себя именно так, не разобраться с выводом tcpdump на сложной сети, и неделями гадать, куда делись пакеты. Дальше — практический минимум: от азов работы с цепочками до готовых правил для шлюза с NAT и типового веб-сервера.

Анатомия iptables: таблицы, цепочки, правила

Что же такое iptables? Это, по сути, фронтенд к мощной подсистеме netfilter, которая живет прямо в ядре Linux. Он работает с таблицами, а в каждой таблице — цепочки, и уже в них — упорядоченные правила.

Пакеты через iptables идут строго по определенному маршруту. Сначала PREROUTING. Дальше принимается решение о маршрутизации — куда пакету идти. Если это транзитный пакет, то FORWARD; если он предназначен для нашего сервера, то INPUT. Когда сервер генерирует ответ, пакет проходит через OUTPUT, а затем через POSTROUTING. Всё четко и последовательно!

Базовая защита сервера: deny-all

На любом, абсолютно любом боевом сервере, наш первый шаг всегда одинаков: политика DROP по умолчанию. Разрешаем (ACCEPT) только то, что действительно необходимо. Почему так? Потому что 'запретить всё, что не разрешено' в сотни раз безопаснее, чем 'разрешить всё, что не запрещено'. Никаких компромиссов.

#!/bin/bash
# /root/firewall-server.sh

# Очистка
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -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 conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Отбрасываем невалидные пакеты
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# SSH: только с офисных IP
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT

# HTTP/HTTPS с любого
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# ICMP echo — только ограниченно
iptables -A INPUT -p icmp --icmp-type echo-request -m limit \
  --limit 10/sec -j ACCEPT

# Логирование и последующий DROP
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-drop: "

Защита от брутфорса SSH

Хотите альтернативу fail2ban? В iptables есть классный модуль `recent`. Он прямо в ядре отслеживает новые соединения и, если их становится слишком много за короткий промежуток времени, сам блокирует наглеца. Простой и эффективный способ защиты.

# Новое SSH-соединение помечаем
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
  -m recent --set --name SSH --mask 255.255.255.255 --rsource

# Если более 4 новых соединений за 60 секунд — DROP
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
  -m recent --update --seconds 60 --hitcount 4 --name SSH \
  --mask 255.255.255.255 --rsource -j DROP

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

На нашей практике этот подход спасает небольшие VPS-ки от 90% всех автоматических брутфорсеров. И при этом не нужно ставить никаких дополнительных программ типа fail2ban — всё работает прямо из коробки.

Шлюз с NAT для офиса

Представьте типичный кейс: нужно развернуть Linux-шлюз, чтобы раздавать интернет в офис. Внешний интерфейс, допустим, eth0 с реальным публичным IP-адресом. А внутри — eth1 с адресом 10.10.10.1/24. Что потребуется? Для исходящих соединений без SNAT (или masquerade, это одно и то же) точно не обойтись. И, конечно, если у нас есть какие-то внутренние сервисы, то для доступа к ним извне придется настраивать проброс портов — тот самый DNAT.

# Включить маршрутизацию
sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf

# Masquerade исходящего
iptables -t nat -A POSTROUTING -o eth0 -s 10.10.10.0/24 -j MASQUERADE

# Разрешить форвардинг из LAN в интернет
iptables -A FORWARD -i eth1 -o eth0 -s 10.10.10.0/24 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT

# DNAT: публичный 443 → внутренний веб-сервер 10.10.10.50:443
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 \
  -j DNAT --to-destination 10.10.10.50:443

# Разрешить форвардинг для DNAT
iptables -A FORWARD -i eth0 -o eth1 -d 10.10.10.50 \
  -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT

# Hairpin NAT: внутренние клиенты обращаются к публичному IP
iptables -t nat -A POSTROUTING -o eth1 -d 10.10.10.50 \
  -p tcp --dport 443 -j MASQUERADE

Таблица: какие порты открывать на типовых серверах

Роль сервераПортыОткуда
Web (Nginx/Apache)80, 443 tcpЛюбой
Почта (Postfix+Dovecot)25, 465, 587, 993, 995Любой
DNS53 tcp/udpLAN / любой (для публичного)
SSH22 tcpТолько с офисных IP
PostgreSQL5432 tcpТолько с сервера приложений
VPN (OpenVPN)1194 udpЛюбой
Мониторинг (Node Exporter)9100 tcpТолько с Prometheus
rsync873 tcpТолько с бэкап-сервера

Сохранение правил между перезагрузками

Есть нюанс: iptables сам по себе не умеет сохранять правила. Перезагрузили сервер — и всё, правила исчезли! Поэтому на Debian мы обычно ставим `iptables-persistent`. А вот на RHEL-системах, как правило, настраиваем собственный systemd unit, который использует `iptables-save` для сохранения и восстановления конфигурации.

# Debian/Ubuntu
apt install -y iptables-persistent
# При установке спросит — сохранить текущие правила? → Yes
# Правила в /etc/iptables/rules.v4 и rules.v6
# При изменении:
netfilter-persistent save

# Или вручную
iptables-save > /etc/iptables/rules.v4
iptables-restore < /etc/iptables/rules.v4

# RHEL/AlmaLinux
dnf install -y iptables-services
systemctl enable --now iptables
service iptables save

Кейс: защита VPN-шлюза для филиальной сети

В ноябре 2025 года к нам обратилась логистическая компания. У них пять филиалов, а главный офис находится в Москве. Задачу поставили четко: перенести VPN-шлюз на отдельный Linux-сервер, поставить его за файрволом Keenetic, чтобы больше не зависеть от ограничений роутера. Что нужно было сделать? Внешний IP, OpenVPN на 1194/udp, проброс 443/tcp на внутренний веб-портал и, само собой, серьезная защита от брутфорса.

Взяли сервер Dell PowerEdge, накатили Debian 12, установили пару 10G сетевых карт для запаса пропускной способности. Развернули OpenVPN с сертификатами, выпущенными через AD CS клиента, и написали свой скрипт для iptables с такими правилами:

И какой же результат? А вот какой: за все 5 месяцев работы — ни одного успешного брута! Трафик через этот шлюз стабильно держится на впечатляющем уровне: 800 Мбит/с в пиках. А чтобы всегда быть в курсе, что происходит с iptables, мы настроили мониторинг: используем Prometheus в связке с `iptables_exporter`, а все метрики наглядно выводим в Grafana.

Весь проект обошёлся клиенту в 135 000 рублей, и мы справились всего за 4 рабочих дня.

Диагностика: когда правила не работают

Что делать, когда что-то вдруг перестает работать? У меня есть железный чек-лист, по которому я прохожусь каждый раз:

# 1. Показать все правила с нумерацией
iptables -L -v -n --line-numbers

# 2. Счётчики пакетов — пакеты вообще попадают?
iptables -Z && sleep 10 && iptables -L -v -n

# 3. Трассировка пакета через netfilter
iptables -t raw -A PREROUTING -p tcp --dport 443 -j TRACE
tail -f /var/log/syslog | grep TRACE

# 4. conntrack — что видит ядро
conntrack -L | grep 10.10.10.50

# 5. Проверить порты процесса
ss -tlnp | grep :443

Мониторинг и логирование правил

Просто 'DROP пакета' — это, по сути, создание черной дыры. Никогда так не делайте! Я всегда логирую всё, что дропаю, причем с `rate-limit`, чтобы не переполнить syslog. И, конечно, не забываю про метрики: они идут через `iptables_exporter` прямиком в Prometheus, чтобы видеть полную картину.

# Отдельная цепочка для логирования
iptables -N LOGDROP
iptables -A LOGDROP -m limit --limit 5/min \
  -j LOG --log-prefix "IPT-DROP: " --log-level 4
iptables -A LOGDROP -j DROP

# Вместо -j DROP используем -j LOGDROP
iptables -A INPUT -p tcp --dport 3389 -j LOGDROP

# Установка exporter
wget https://github.com/retailnext/iptables_exporter/releases/download/v1.0.0/iptables_exporter-1.0.0.linux-amd64.tar.gz
tar xzf iptables_exporter-*.tar.gz
./iptables_exporter-1.0.0.linux-amd64/iptables_exporter \
  --web.listen-address=:9455

Быстрый справочник команд iptables

Полезно держать под рукой базовый набор ключей для работы с правилами напрямую, без скриптов:

# Просмотр правил с счётчиками и номерами строк
iptables -L INPUT -v --line-numbers
iptables -L -n -v  # все таблицы, без DNS-разрешения

# Добавить правило в конец цепочки
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Вставить правило в начало (позиция 1)
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

# Удалить по номеру строки
iptables -D INPUT 3

# Сбросить все правила в цепочке
iptables -F INPUT

Состояния conntrack и переполнение таблицы

У conntrack четыре основных состояния соединения: NEW — первый пакет нового соединения, ESTABLISHED — соединение установлено (пакеты идут в обе стороны), RELATED — связанное соединение (например, FTP data для FTP control), INVALID — пакет не принадлежит ни одному соединению.

# Просмотр таблицы соединений
conntrack -L
cat /proc/net/nf_conntrack | head -20

# Статистика conntrack
conntrack -S

# Максимум отслеживаемых соединений
cat /proc/sys/net/netfilter/nf_conntrack_max
# По умолчанию ~131072

# Увеличить, если нужно
echo 524288 > /proc/sys/net/netfilter/nf_conntrack_max

На нагруженных серверах с тысячами одновременных соединений переполнение таблицы conntrack — реальная проблема. Симптом: «Connection refused» при наличии свободных портов. Проверяется командой dmesg | grep "nf_conntrack: table full".

Защита от SYN-flood и сканирования портов

Кроме ограничения новых SSH-соединений через модуль recent, стоит закрыть ещё несколько типовых векторов атак на уровне пакетов:

# Защита от SYN flood
iptables -A INPUT -p tcp --syn -m limit --limit 25/second --limit-burst 50 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

# Блокировка NULL-пакетов
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# Блокировка XMAS-пакетов
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# Запрет новых соединений без SYN
iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

FAQ — частые вопросы по iptables

iptables или nftables — что использовать сейчас?
Debian 12 и RHEL 9 уже по умолчанию используют nftables, а iptables-nft является прослойкой-совместимостью. Для новых систем лучше учить nftables, но iptables продолжает работать и будет актуален ещё много лет.
Чем filter отличается от nat?
Filter — фильтрация пакетов (разрешить/запретить), цепочки INPUT/OUTPUT/FORWARD. Nat — трансляция адресов, цепочки PREROUTING/POSTROUTING для DNAT/SNAT. Mangle — модификация заголовков, raw — до conntrack.
Как сохранить правила после перезагрузки?
На Debian: apt install iptables-persistent, правила из /etc/iptables/rules.v4 загружаются при старте. Или iptables-save > rules.v4 + iptables-restore < rules.v4 вручную.
Что такое conntrack?
Механизм отслеживания состояния соединений в ядре Linux. Позволяет писать правила типа ESTABLISHED,RELATED — разрешить ответы на уже установленные соединения, не описывая каждый порт вручную.
Почему после применения правил теряется SSH?
Классическая ошибка: поставили DROP по умолчанию, забыли разрешить порт 22 или ESTABLISHED. Всегда первым правилом INPUT ставьте -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT и -p tcp --dport 22 -j ACCEPT.

Столкнулись с похожей задачей? Обращайтесь — решим

Если у вас происходит что-то из описанного в этой статье — или любая другая проблема с ИТ-инфраструктурой, — обращайтесь в любое время. Мои специалисты и я лично разберём ситуацию, найдём настоящую причину и доведём до решения.

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

📄
Скачайте подробный разбор в PDF Кейсы, статистика, типовые ошибки и чек-лист самопроверки — 12 страниц
Скачать PDF

Подпишитесь на рассылку ITfresh

Кстати, не пропустите! Каждую неделю мы делимся практическими гайдами — это бесценно и для IT-руководителей, и для сисадминов. Мы пишем о безопасности, 1С, сложных миграциях, резервных копиях, и, конечно же, делимся лайфхаками из наших реальных проектов. Подписывайтесь!

Письмо придёт в течение минутыНе нашли его во «Входящих» — загляните в папку «Спам» или «Промоакции» и нажмите «Не спам». Так все следующие выпуски будут приходить прямо в основную почту.
Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.