Файрвол для Linux-сервера: настройка защиты от атак в 2026 году | AdminWiki

Файрвол для Linux-сервера: настройка защиты от атак в 2026 году

17 сентября 2026 15 мин. чтения

Почему файрвол - первый рубеж обороны Linux-сервера

Публичный IP-адрес начинают сканировать в первые минуты после появления в сети. Полный перебор 65535 TCP-портов занимает у автоматического сканера меньше минуты, а распределённые ботнеты проверяют десятки тысяч адресов параллельно. Сервер с открытым 22-м портом собирает от сотен до нескольких тысяч попыток входа в сутки. Файрвол отбрасывает этот трафик в ядре, до передачи данных приложению, поэтому CPU и диск не расходуются на обработку заведомо мусорных соединений.

Открытый порт даёт злоумышленнику готовый интерфейс к сервису. Redis на 6379 без пароля позволяет через CONFIG SET dir и dbfilename записать файл в произвольный каталог и положить свой SSH-ключ в /root/.ssh/authorized_keys. MongoDB на 27017 без аутентификации отдаёт содержимое всей базы. Docker API на 2375 разрешает запустить контейнер с примонтированным корнем хоста. Одно правило с policy drop закрывает все три сценария сразу.

Сервер за NAT тоже нуждается в фильтрации. Проброс портов на роутере часто шире, чем требуется: открыли 443 наружу, а заодно пробросили 8080 на отладочную панель. Конфигурация обратного прокси меняется, и внутренний сервис неожиданно начинает отвечать на внешнем интерфейсе. Файрвол на хосте ограничивает горизонтальное перемещение: получив доступ к одной машине, атакующий не подключится к PostgreSQL на соседней по 5432.

Отдельный сценарий, который почти всегда упускают, - исходящий трафик. Цепочка output по умолчанию разрешает всё, и вредонос, попавший на хост, свободно скачивает полезную нагрузку и отправляет украденные данные на управляющий сервер. Ограничение исходящих соединений по подсетям и портам сужает окно для атакующего заметно сильнее, чем один лишь фильтр входящих пакетов.

Выбор инструмента: nftables, iptables, ufw или firewalld

Четыре инструмента делят рынок, и три из них пишут правила в один движок ядра. Разница в уровне абстракции и в том, кто управляет цепочками: вы, демон или Docker.

ИнструментУровеньГде применяетсяСильные стороныОграничения
nftablesподсистема ядра, Linux 3.13+ (2014)Debian 10+, Ubuntu 20.04+, RHEL 8+, Arch, openSUSEсеты и map, атомарная замена всего набора одной командой, единый синтаксис для IPv4, IPv6 и bridgeвыше порог входа, чем у ufw
iptablesфронтенд xtablesстарые скрипты и образы, RHEL 7огромное количество примеров и готовых решенийв RHEL 9, Debian 11+ и Ubuntu 20.04+ команда iptables ссылается на iptables-nft, старый движок остался как iptables-legacy
ufwнадстройка над nftablesUbuntu, Debian, простые VPSрабочий конфиг из четырёх команд, профили приложений, встроенный limit против брутфорсане покрывает сложные задачи: сеты, mark, NAT, тонкие цепочки
firewalldнадстройка с зонамиRHEL, Fedora, CentOS Stream, Rocky, AlmaLinuxзоны, разделение runtime и permanent, rich rules, D-Bus API для автоматизациизоны путают новичков, правила по умолчанию не переживают перезагрузку без runtime-to-permanent

Практическое правило выбора: для нового сервера с веб-стеком берите nftables напрямую, если планируете сеты, NAT и логирование с лимитами; берите ufw, если нужен минимум правил и быстрый результат. В RHEL-семействе разумнее работать через firewalld: он использует backend nftables, и результат виден в nft list ruleset. iptables оставляйте там, где конфигурация уже написана, проверена и нет ресурса на миграцию. Подробные примеры для всех трёх инструментов собраны в материале о сравнении iptables, nftables и ufw, включая безопасную настройку по SSH без потери доступа.

Два инструмента одновременно не запускают. ufw и firewalld конфликтуют за цепочки, а Docker вставляет свои правила независимо от обоих. Проверьте, кто уже управляет набором правил, командой nft list ruleset и выводом systemctl status ufw firewalld.

Базовая политика deny all: пошаговая настройка

Схема одинакова для любого инструмента: политика по умолчанию drop, затем точечные разрешения. До первого запуска проверьте три вещи: на каком порту слушает SSH (ss -tlnp | grep sshd), есть ли доступ к консоли провайдера через VNC или KVM, установлены ли tmux или screen.

Откройте вторую SSH-сессию и не закрывайте её до конца работ. Поставьте отложенный откат правил на случай ошибки: echo "nft -f /etc/nftables.backup" | at now + 10 minutes. Простой способ быстро выйти из блокировки, если вы отрезали себя от сервера.

Настройка nftables с нуля

Файл /etc/nftables.conf с минимальным рабочим набором для веб-сервера:

#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority filter; policy drop;
        ct state invalid drop
        ct state established,related accept
        iif lo accept
        ip protocol icmp icmp type { echo-request, destination-unreachable, time-exceeded } accept
        ip6 nexthdr ipv6-icmp accept
        tcp dport { 22, 80, 443 } accept
        ip saddr 10.0.0.0/24 tcp dport { 3306, 5432 } accept
        limit rate 5/minute log prefix "nft-drop: " level warn
    }

    chain forward {
        type filter hook forward priority filter; policy drop;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}
  • flush ruleset очищает все таблицы, включая созданные Docker и fail2ban. На работающей системе сначала сохраните текущий набор: nft list ruleset > /root/nft-backup-$(date +%F).nft.
  • ct state established,related accept пропускает ответные пакеты уже открытых сессий. Без этой строки перестанут работать исходящие запросы: ответы серверов не пройдут политику drop.
  • iif lo accept нужен локальным сервисам, которые ходят друг к другу через loopback.
  • ICMP: echo-request оставляет ping для диагностики, destination-unreachable и time-exceeded нужны для обнаружения MTU на пути. Полный запрет ICMP ломает часть сетевых сценариев.
  • Сет { 22, 80, 443 } вместо трёх правил экономит проходы по цепочке: nftables проверяет набор за одно обращение.
  • ip saddr 10.0.0.0/24 ограничивает базы данных внутренней подсетью. Порт 5432 наружу закрыт даже при работающем PostgreSQL.
  • limit rate 5/minute log записывает отброшенные пакеты, не давая сканеру залить диск логами.

Применение и проверка синтаксиса выполняются двумя командами:

nft -c -f /etc/nftables.conf   # проверка без применения
nft -f /etc/nftables.conf      # применение
systemctl enable --now nftables
nft list ruleset

Юнит nftables.service читает /etc/nftables.conf при загрузке, поэтому правила переживают перезагрузку. Для старого стека iptables потребуется пакет iptables-persistent и команда netfilter-persistent save.

Цепочка forward с политикой drop отключает транзит трафика. Если сервер работает шлюзом или публикует контейнеры с пробросом портов, понадобятся отдельные правила DNAT и FORWARD: эту часть разбирает руководство по маршрутизации и NAT в Linux.

Важная оговорка про Docker: опубликованный порт вида -p 8080:80 создаёт DNAT в таблице nat и попадает в цепочку DOCKER, минуя filter INPUT. Правило policy drop его не остановит. Публикуйте порты только на loopback (-p 127.0.0.1:8080:80) и проксируйте через Nginx, либо используйте ufw-docker для синхронизации цепочек.

Настройка ufw для типовых сервисов

Последовательность команд для Ubuntu или Debian:

sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw limit 22/tcp
sudo ufw enable
sudo ufw status verbose
  • default deny incoming задаёт политику drop для входящих, allow outgoing оставляет исходящие открытыми. Для строгого периметра политику output меняют на deny и разрешают нужные направления точечно.
  • ufw limit 22/tcp включает встроенную защиту от брутфорса: адрес блокируется на время, если открывает больше 6 соединений за 30 секунд. Профиль OpenSSH подключается командой sudo ufw allow OpenSSH.
  • IPv6 в ufw включён по умолчанию (IPV6=yes в /etc/default/ufw). Проверьте значение, иначе правила будут действовать только для IPv4.

Проверка состояния показывает правила вместе с политиками: sudo ufw status verbose и sudo ufw status numbered для удаления правил по номеру. Docker обходит ufw так же, как и nftables, по причине DNAT в цепочке DOCKER. Решения те же: ufw-docker или публикация портов только на 127.0.0.1.

Разрешение портов для баз данных: ограничение по IP

Порты 3306 (MySQL, MariaDB), 5432 (PostgreSQL), 6379 (Redis), 27017 (MongoDB), 9200 (Elasticsearch), 11434 (Ollama) не должны отвечать из публичной сети. Redis и MongoDB исторически лидируют по числу взломов из-за аутентификации, отключённой по умолчанию. С 2025 года сканеры активно ищут открытые эндпоинты инференса языковых моделей: чужой сервер бесплатно считает запросы неизвестных пользователей.

Правило для nftables внутри таблицы inet filter:

ip saddr 10.0.0.0/24 tcp dport { 3306, 5432, 6379 } accept
ip saddr 10.0.0.0/24 udp dport 6379 accept

Аналог для ufw:

sudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 6379 proto tcp

Ограничение по адресу надёжнее пароля, потому что отсекает попытки подбора до уровня приложения. Дополнительно закройте bind-address в конфигурации СУБД: для PostgreSQL параметр listen_addresses, для MySQL и MariaDB bind-address, для Redis bind и protected-mode yes. Если серверы живут в облаке, приватный интерфейс между ними и консольный доступ настраиваются на этапе создания: например, Timeweb Cloud выдаёт приватную сеть, трафик по которой не выходит в публичный сегмент, и VNC-консоль для аварийного доступа. Для распределённых команд альтернатива приватной сети - WireGuard: порт БД слушает только на интерфейсе туннеля.

Защита SSH от брутфорса с помощью fail2ban

Файрвол пропускает 22-й порт для всех адресов, поэтому подбор пароля продолжается на уровне демона SSH. fail2ban читает логи, находит серии неудачных входов и временно банит адрес правилом в файрволе.

Установка: sudo apt install fail2ban в Debian и Ubuntu, sudo dnf install fail2ban в RHEL и Fedora. Файл /etc/fail2ban/jail.conf редактировать не нужно: пакет перезапишет его при обновлении. Все изменения вносите в /etc/fail2ban/jail.local:

[DEFAULT]
backend = systemd
bantime = 1h
findtime = 10m
maxretry = 5
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1w
ignoreip = 127.0.0.1/8 ::1 203.0.113.10/32

[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 4
findtime = 10m
  • bantime задаёт срок бана, findtime - окно, в котором считаются неудачные попытки, maxretry - их порог.
  • bantime.increment = true с множителем factor удваивает срок при повторных нарушениях с того же адреса, maxtime ограничивает рост одной неделей. Повторный бан на час уже не помогает ботам.
  • ignoreip защищает ваш адрес и адреса систем мониторинга. Ошибка в этом параметре приводит к самоблокировке: проверяйте его до перезапуска службы.
  • backend = systemd читает журнал journald вместо файла /var/log/auth.log. В свежих сборках без rsyslog это единственный рабочий вариант.
  • banaction по умолчанию в Debian и Ubuntu равен iptables-multiport, что на современных системах пишет правила через iptables-nft. На хосте с чистым nftables укажите banaction = nftables-multiport, при работе через ufw - banaction = ufw.

Проверка и управление:

sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.77
sudo tail -f /var/log/fail2ban.log

Команда fail2ban-client status sshd показывает счётчик банов, список заблокированных адресов и файл журнала. Проверьте, что правила действительно появились в файрволе: nft list ruleset | grep f2b или iptables -L -n | grep f2b.

fail2ban закрывает подбор пароля, но не заменяет настройку самого SSH. Отключите вход по паролю (PasswordAuthentication no) и прямой вход root, оставив вход только по ключам. Остальные шаги по усилению демона и управлению sudo разобраны в материале о базовой безопасности сервера в 2026.

Аудит правил файрвола: чек-лист и тестирование

Аудит занимает 10-15 минут и отвечает на три вопроса: стоит ли политика drop на входе, нет ли лишних открытых портов, переживут ли правила перезагрузку.

  1. Выгрузите текущий набор: nft list ruleset, iptables -L -n -v, ufw status verbose, firewall-cmd --list-all. Для firewalld отдельно проверьте постоянные правила: firewall-cmd --list-all --permanent.
  2. Найдите строку политики: policy drop для nftables, Chain INPUT (policy DROP) для iptables, Default: deny (incoming) для ufw. Политика accept на входе обнуляет смысл остальных правил.
  3. Сверьте разрешённые порты со списком слушающих сокетов: ss -tulpn. Всё, что слушает 0.0.0.0 или :: и не должно быть публичным, переносите на 127.0.0.1 или закрывайте правилом.
  4. Проверьте IPv6 отдельно. Цепочка в таблице inet покрывает оба стека, а таблица ip6 filter их не видит: nft list table ip6 filter. Для iptables используйте ip6tables -L -n -v.
  5. Перезагрузите сервер и повторите шаг 1. Правила, живущие только в памяти, исчезают: для nftables нужен systemctl enable nftables, для iptables - пакет iptables-persistent с командой netfilter-persistent save, для firewalld - firewall-cmd --runtime-to-permanent.
  6. Проверьте цепочки fail2ban: они появляются после первого срабатывания фильтра. Пустая цепочка f2b при активном брутфорсе означает, что фильтр не читает журнал или указан неверный logpath.
  7. Отсканируйте периметр с внешнего хоста: nmap -sT -Pn -p- адрес_сервера. Сканирование выполняется только по своим системам или с письменного разрешения владельца инфраструктуры. Для быстрой проверки отдельного порта достаточно nc -zv адрес порт.
  8. Сравните результат сканирования с ожидаемым списком сервисов. Каждый лишний открытый порт - либо ошибка правила, либо сервис, который слушает слишком широко.

Проверка без риска для рабочей среды строится на трёх привычках. Первая: конфигурация хранится в git, перед применением выполняется синтаксическая проверка nft -c -f /etc/nftables.conf или ufw --dry-run. Вторая: изменения сначала тестируются на копии сервера в виртуалке или контейнере. Третья: держите открытой консоль провайдера и отложенный откат через at. Повторяйте аудит после каждого изменения инфраструктуры: новый сервис, новый контейнер, смена порта. Расширенный набор проверок и автоматический аудит уязвимостей через Lynis и OpenSCAP собраны в руководстве по hardening и аудиту Linux-сервера.

Логирование и мониторинг событий безопасности

Без журналов вы не узнаете, что ночью кто-то перебрал 40000 портов и получил три отказа в SSH. Логирование настраивается в том же инструменте, что фильтрует трафик.

Для nftables правило логирования ставится последним в цепочке, перед неявным drop:

limit rate 5/minute log prefix "nft-drop: " level warn
limit rate 5/minute log prefix "nft-drop: " level warn tcp flags syn log flags all

Записи уходят в кольцевой буфер ядра, оттуда в journald и rsyslog. Смотреть их удобно так: journalctl -k -f, dmesg -w, grep nft-drop /var/log/kern.log. Для отдельного файла нужен ulogd2 с плагином NFLOG, который принимает пакеты логирования по netlink.

Для ufw логирование включается командой sudo ufw logging on (уровни low, medium, high), записи попадают в /var/log/ufw.log. Для iptables цель LOG ставится до DROP, потому что LOG не завершает обработку пакета:

iptables -A INPUT -j LOG --log-prefix "iptables-drop: " --log-level 4
iptables -A INPUT -j DROP
  • fail2ban пишет в /var/log/fail2ban.log: срабатывания фильтров, баны, разбаны. Настройте logrotate для этого файла, иначе при активном сканировании он вырастет до гигабайтов за неделю.
  • Оповещения строятся на счётчиках: fail2ban-client status sshd, число записей nft-drop за час, всплеск кодов 401 и 403 в логах Nginx. Пороговые значения отправляйте в систему мониторинга.
  • Анализ веб-логов удобно вести через goaccess: он разбирает access.log и показывает источники подозрительного трафика.

Логирование с лимитом обязательно. Одна сканирующая подсеть генерирует десятки тысяч отброшенных пакетов в минуту, и запись каждого из них загружает диск и процессор сильнее, чем сама фильтрация. Для разбора больших выгрузок можно подключить языковую модель через API: AiTunnel даёт единый ключ к десяткам моделей с оплатой в рублях, и скрипт отправляет подозрительные строки на суммаризацию вместо ручного просмотра.

Типичные ошибки при настройке файрвола и как их избежать

  1. deny all до проверки SSH-порта. Политика drop применяется мгновенно, и доступ теряется вместе с сервером. Решение: вторая сессия, консоль провайдера и отложенный откат командой at.
  2. Неверный порядок правил. В nftables и iptables правила проверяются сверху вниз, первое совпадение определяет судьбу пакета. Правило drop, поставленное выше разрешающего, блокирует нужный сервис. Логирующее правило оставляйте последним.
  3. Правила не сохраняются после перезагрузки. Для nftables нужен systemctl enable nftables, для iptables - netfilter-persistent save, для firewalld - firewall-cmd --runtime-to-permanent. Правило, добавленное через --permanent без reload, не работает до перезапуска службы.
  4. Конфликт с Docker. Контейнер, опубликованный как -p 8080:80, доступен из интернета даже при policy drop, потому что DNAT выполняется в таблице nat до фильтрации на входе. Решения: ufw-docker, публикация на 127.0.0.1 с обратным прокси, отключение iptables у демона Docker с ручным описанием правил.
  5. Открытые порты баз данных. MySQL, PostgreSQL, Redis и MongoDB не должны отвечать из публичной сети никогда. Ограничение по ip saddr или from в ufw закрывает вектор целиком.
  6. Забытый IPv6. Многие VPS получают IPv6 по умолчанию, сервисы слушают на ::, а правила написаны только для IPv4. Проверяйте ss -tulpn и таблицу ip6.
  7. Нет журналов и оповещений. Файрвол без логов молча отбрасывает атаки, и о компрометации узнают от провайдера. Логирование с лимитом и счётчики банов закрывают этот пробел.
  8. Самоблокировка fail2ban. Офисный NAT-адрес или адрес VPN легко попадает под бан при опечатке в пароле. ignoreip с вашей подсетью и адресом мониторинга обязателен.
  9. Смена порта SSH без правки правил. Перенос демона на нестандартный порт без обновления набора правил отрезает доступ. Меняйте порт и правило одним окном обслуживания.
  10. flush ruleset в проде. Команда стирает все таблицы, включая цепочки Docker, fail2ban и NAT. Перед ручной правкой сохраняйте снимок: nft list ruleset > backup.nft.

Ещё одна ошибка встречается реже, но стоит дороже остальных: приложение слушает на 0.0.0.0 при том, что правило разрешает доступ только доверенной подсети. Файрвол спасает до первой ошибки в правилах, поэтому bind на 127.0.0.1 оставляйте вторым слоем защиты. Полный набор политик по доступу, sudo и мандатному контролю разобран в руководстве по политике безопасности Linux-сервера.

Что изменилось в 2026 году: актуальные рекомендации

nftables стал стандартом де-факто: он используется в Ubuntu 20.04 и новее, Debian 10 и новее, RHEL 8 и новее, openSUSE. В RHEL 9 и Ubuntu команда iptables ссылается на iptables-nft, а старый движок остался только как iptables-legacy в устаревших образах. Новые возможности появляются именно в nftables: именованные сеты, verdict maps, динамическое наполнение наборов из скриптов.

firewalld версии 2.x работает поверх nftables и добавил политики (policies) для описания правил между зонами, что упрощает сегментацию хоста с несколькими сетевыми интерфейсами. fail2ban 1.1 закрывает типовые задачи защиты SSH. Как альтернатива набирает популярность CrowdSec: сценарии в виде collections, обмен репутацией адресов между установками и бан через bouncer на уровне nftables.

Сместились и цели атак. Кроме Redis, MongoDB и Docker API на 2375, сканеры массово ищут открытые панели управления и эндпоинты инференса моделей на 11434. В Kubernetes защита узла не покрывает поды: трафик между ними идёт по overlay-сети и не проходит через filter INPUT хоста. Эту зону закрывают NetworkPolicy и CNI с реализацией на eBPF, например Cilium, а классические правила хоста остаются защитой самого узла и его служебных портов.

Управление правилами переходит в код. Набор из /etc/nftables.conf хранится в git, проверяется в CI командой nft -c -f, применяется через Ansible (community.general.ufw, ansible.posix.firewalld) или Terraform-провайдеры облака. Откат на предыдущую версию занимает одну команду, и это снимает главный страх при работе с периметром продакшена.

Начните с двух действий сегодня: выгрузите текущий набор правил в git (nft list ruleset > rules.nft) и сверьте его с выводом ss -tulpn. Это даст реальную картину периметра быстрее, чем любая теория, и покажет, какие порты закрывать первыми.

Поделиться:
Сохранить гайд? В закладки браузера