iptables: правила firewall для Linux-сервера и шлюза корпоративной сети
Привет! Я, Семёнов Евгений Сергеевич, директор ITFresh. Сегодня хочется поспорить, а заодно расставить точки над «и» по поводу iptables. Нужен ли он вообще, если есть ufw? Стоит ли его учить? За 15 лет в IT я понял одно: без базовых знаний iptables вам не обойтись! Это просто маст-хэв для любого линукс-администратора. Иначе как вы поймете, почему ufw ведет себя именно так? Или попробуйте разобраться с выводом tcpdump на какой-нибудь сложной сети. И самое обидное — будете неделями гадать, куда же делись эти пакеты! Поэтому в этой статье я покажу практический минимум: от самых азов работы с цепочками до готовых, проверенных правил для шлюза с NAT и типового веб-сервера.
Анатомия iptables: таблицы, цепочки, правила
Что же такое iptables? Это, по сути, фронтенд к мощной подсистеме netfilter, которая живет прямо в ядре Linux. Он работает с таблицами, а в каждой таблице — цепочки, и уже в них — упорядоченные правила.
- filter — разрешить/запретить. Цепочки INPUT (входящий трафик), OUTPUT (исходящий), FORWARD (транзитный).
- nat — трансляция адресов. PREROUTING (до маршрутизации), POSTROUTING (после), OUTPUT (локально сгенерированный).
- mangle — модификация заголовков. Используется для TOS, TTL, маркировки.
- raw — обходит conntrack. Редко используется, для очень высокопроизводительных сценариев.
Пакеты через 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 | Любой |
| DNS | 53 tcp/udp | LAN / любой (для публичного) |
| SSH | 22 tcp | Только с офисных IP |
| PostgreSQL | 5432 tcp | Только с сервера приложений |
| VPN (OpenVPN) | 1194 udp | Любой |
| Мониторинг (Node Exporter) | 9100 tcp | Только с Prometheus |
| rsync | 873 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, включающий вот такие правила:
- Что делаем в первую очередь, когда речь идёт о безопасности? Конечно же, закрываем все лишние двери! На INPUT мы безжалостно сбрасываем (DROP) всё, что пытается к нам пробиться извне. Исключение делаем лишь для уже установленных (ESTABLISHED) соединений или тех, что логически их продолжают (RELATED). Это наш базовый принцип — пускать только знакомых.
- VPN-доступ — это важно, ведь нужно как-то безопасно подключаться. Поэтому мы разрешаем (ACCEPT) входящие подключения для OpenVPN, используя стандартный порт 1194 по протоколу UDP. Но без фанатизма: чтобы никто не перегрузил наш канал или не попробовал атаку, мы ставим жёсткий лимит – не более 20 новых подключений в минуту. Безопасность и стабильность прежде всего, разве не так?
- Доступ по SSH (22/tcp) — это хлеб админа, но его нужно защищать по максимуму. Мы разрешаем его только с наших корпоративных IP-адресов. Никто снаружи не сможет даже попробовать подключиться, если его IP не в белом списке. А чтобы уж точно никто не пробился подбором, даже из разрешенных сетей, мы задействуем модуль `recent` — он эффективно пресекает любые попытки брутфорса. Это наш двойной замок.
- Нужно, чтобы пользователи извне попадали на наш внутренний портал? Конечно! Мы настраиваем DNAT: все, кто стучится на внешний адрес по 443/tcp, автоматически перенаправляются на наш внутренний сервер – 10.50.0.100, на тот же порт 443. Так наш внутренний портал доступен из интернета, но при этом скрыт за нашей защитой.
- Как заставить пять разных филиальных сетей выходить в интернет через наш центральный VPN? Очень просто: используем MASQUERADE. Это как дать всем им один общий паспорт при выходе наружу. Все пакеты от этих пяти сетей, проходящие через наш VPN-интерфейс `tun0`, будут маскироваться под IP-адрес нашего шлюза. Так они видят внешний мир, а он их – как единое целое, через защищённый туннель.
- А если что-то пойдёт не так? Для оперативной диагностики мы, конечно же, ведём логи. У нас есть специальная цепочка для логирования событий. Но чтобы не забить диски и не утонуть в мусоре, мы ставим жёсткий лимит – не более 5 записей в лог в минуту. Этого хватает, чтобы увидеть общую картину и выявить проблему, но при этом сохраняет систему от перегрузки. Мы же не хотим превратиться в спам-машину?
И какой же результат? А вот какой: за все 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.
