· 16 мин чтения

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

Семёнов Евгений Сергеевич, директор АйТи Фреш. iptables — это тот инструмент, о котором спорят «нужно учить или хватит ufw». За 15 лет работы я убедился: базовый iptables должен знать каждый линукс-администратор. Без него вы не поймёте, как работает ufw, не прочитаете вывод tcpdump на сложной сети и не сможете разобраться, почему пакеты не доходят. В этой статье дам практический минимум — от понимания цепочек до готовых правил для шлюза с NAT и веб-сервера.

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

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

Пакет проходит по цепочкам в определённом порядке: PREROUTING → решение о маршрутизации → FORWARD (если транзит) или INPUT (если локальный) → OUTPUT (для ответов) → POSTROUTING.

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

На любом боевом сервере я всегда начинаю с политики DROP по умолчанию и явных ACCEPT только для нужного. Deny-all безопаснее allow-all даже на 100 раз.

#!/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 можно использовать модуль recent в iptables — прямо в ядре считает новые соединения и блокирует при превышении.

# Новое 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 по умолчанию не сохраняет правила — после reboot всё чисто. На 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 клиент — логистическая компания с 5 филиалами, центральный офис в Москве. Стояла задача: вынести VPN-шлюз на отдельный Linux-сервер за файрволом Keenetic, чтобы не зависеть от ограничений роутера. Внешний IP, OpenVPN на 1194/udp, перенаправление 443/tcp на внутренний веб-портал, защита от брутфорса.

Собрали Debian 12 на Dell PowerEdge, 2 × 10G NIC, развернули 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

Настроим firewall и сетевую безопасность

Настраиваем iptables/nftables на Linux-серверах и шлюзах: корпоративные шлюзы с NAT и VPN, защита публичных серверов, проброс портов, защита от брутфорса. От 2 рабочих дней.

Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш

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

iptables или nftables — что использовать в 2026?
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.

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

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

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