Почему файрвол - это минимальная защита, которая нужна каждому серверу
Сервер с публичным IP-адресом попадает под сканирование в первые минуты после включения. Автоматические сканеры перебирают адреса и порты, ищут открытые сервисы и пробуют стандартные комбинации логина и пароля. Файрвол отсекает этот поток на входе: соединение к порту, который вы не разрешили, не доходит до приложения.
Логика фильтрации повторяет принцип любой системы контроля доступа: доступ получают только уполномоченные лица за счёт аутентификации и авторизации, посторонние ограничены. В физической безопасности ту же задачу решают турникеты, карты и биометрия, на сервере её выполняет проверка пакетов по набору правил.
Масштаб фонового шума проверяется за минуту. Оставьте SSH открытым для всего интернета на неделю и посмотрите /var/log/auth.log: записи о неудачных попытках входа идут тысячами в сутки. Каждая такая попытка расходует ресурсы и даёт шанс подобрать слабый пароль.
Файрвол не заменяет остальные меры. Он не спасёт от уязвимости в веб-приложении, к которому открыт доступ, и не защитит от слабого пароля на разрешённом сервисе. Его роль уже, но фундаментальна: сократить число точек входа до списка, которым вы управляете. Это базовый уровень, без которого остальные настройки безопасности теряют смысл.
Работает принцип наименьших привилегий: каждому сервису и пользователю достаётся ровно тот доступ, который нужен для задачи, и ничего сверх. В применении к портам он означает простое правило: открываем только то, что реально слушает сервер.
Принцип «запрещено всё, что не разрешено»: почему это безопасно по умолчанию
Политика default deny (встречается название default drop) блокирует весь входящий трафик и пропускает только то, что вы разрешили явным правилом. Обратный подход default allow разрешает всё, а лишнее закрывается вручную. Разница в том, где возникает ошибка.
При default allow любое забытое правило оставляет сервис открытым для всего интернета. Администратор поставил базу данных, посмотрел на неё, отвлёкся и не вернулся к настройке: порт 5432 или 3306 слушает на внешнем адресе, и это уже не гипотеза, а работающая точка входа. При default deny та же база данных недоступна, пока вы сами не откроете порт, и забывчивость работает в вашу пользу.
Сравнение с дверью уместно. Держать дверь запертой и открывать только тем, кого ждёшь, проще, чем держать её открытой и пытаться никого не впустить. Поверхность атаки при первом варианте состоит из вашего списка разрешений, при втором её размер определяет количество запущенных сервисов во всей системе.
Политика по умолчанию задаётся один раз и дальше работает на вас. В ufw это ufw default deny incoming, в firewalld - зона, у которой не задан target: тогда каждый пакет, не соответствующий ни одному правилу, отклоняется catchall-reject-механизмом firewalld. Синтаксис инструментов разный, логика одна.
Выбираем инструмент: ufw, iptables или firewalld
Все три средства управляют одним и тем же: фильтрацией пакетов в ядре Linux. Отличаются они уровнем абстракции и удобством. Подробное сравнение с примерами правил собрано в статье iptables, nftables и ufw: синтаксис и примеры правил.
ufw: простой старт для начинающих
ufw (Uncomplicated Firewall) входит в состав Ubuntu и обычно предустановлен. На Debian пакет может отсутствовать, тогда его ставят командой sudo apt install ufw. Включение: sudo ufw enable. Проверка: sudo ufw status. ufw - это фреймворк-фронтенд как для iptables, так и для nftables; в Ubuntu бэкенд nftables используется по умолчанию начиная с версии 20.10 (Groovy Gorilla), поэтому отдельно настраивать nftables не нужно. На Ubuntu 20.04 и новее команда iptables фактически тоже работает через бэкенд nftables (iptables-nft), сохраняя привычный синтаксис.
Важная деталь: команда enable сразу применяет политику deny incoming. Если правило для SSH не добавлено, текущая сессия оборвётся при следующем подключении. Правильный порядок действий разобран ниже.
firewalld: зоны и сервисы для CentOS
firewalld используется в RHEL, CentOS, AlmaLinux, Rocky Linux и Fedora и работает поверх nftables, в старых версиях поверх iptables. Вместо отдельных портов здесь оперируют службами и зонами: public, trusted, home, work, drop. Добавление службы: firewall-cmd --add-service=ssh --permanent, затем firewall-cmd --reload. Флаг --permanent сохраняет правило после перезагрузки.
iptables и nftables остаются низкоуровневым инструментом. Синтаксис iptables знаком большинству администраторов, но nftables считается современной заменой: он включён в стандартную ветку ядра Linux начиная с версии 3.13. Для типового веб-сервера на Ubuntu или Debian достаточно ufw, на CentOS и совместимых системах - firewalld. Прямые правила nftables нужны, когда появляются сценарии вроде NAT, маркировки пакетов или фильтрации по большим наборам адресов.
Пошаговая настройка: открываем только SSH, HTTP и HTTPS
Шаг 1. Разрешаем SSH до включения файрвола
SSH - единственный канал управления сервером, и он должен быть разрешён первым. Сначала уточните, на каком порту слушает sshd: sudo ss -tlnp | grep sshd. Если вывод показывает 0.0.0.0:22, порт стандартный. При нестандартном порте, например 2222, открывайте именно его.
sudo ufw allow 22/tcp sudo ufw allow OpenSSH
Обе записи эквивалентны: ufw allow OpenSSH разворачивается в правило для порта 22/tcp. Достаточно одной.
Шаг 2. Открываем порты 80 и 443 для веб-сервера
Порт 80 обслуживает HTTP, порт 443 - HTTPS. Открывайте их, только если на сервере работает Nginx, Apache или другой веб-сервер. Если машина нужна для SSH и внутренних задач, эти порты остаются закрытыми.
sudo ufw allow 80/tcp sudo ufw allow 443/tcp
Для HTTP/3 дополнительно нужен UDP 443: sudo ufw allow 443/udp. HTTP/3 работает поверх QUIC, а QUIC - это транспорт на основе UDP, поэтому без открытого UDP 443 он не заработает. В NGINX для этого используется директива listen 443 quic reuseport. Если QUIC в конфигурации веб-сервера не включён, открывать UDP 443 не требуется. Панели управления вроде Cockpit или Webmin удобнее держать на нестандартном порту с ограничением по IP, детали есть в материале настройка и защита веб-интерфейса сервера.
Шаг 3. Включаем файрвол и смотрим результат
sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw enable sudo ufw status verbose
Для firewalld последовательность та же по смыслу:
sudo firewall-cmd --set-default-zone=public sudo firewall-cmd --add-service=ssh --permanent sudo firewall-cmd --add-service=http --permanent sudo firewall-cmd --add-service=https --permanent sudo firewall-cmd --reload
Как не заблокировать собственное SSH-подключение
Потеря доступа - самая частая авария при первой настройке. Причины две: правило для SSH не добавлено до включения фильтра, либо порт в правиле не совпадает с реальным портом sshd. Обе проверяются заранее.
Меры предосторожности:
- Разрешите SSH до команды enable. Порядок «сначала правило, потом включение» не обсуждается.
- Сверьте порт командой sudo ss -tlnp | grep sshd. Не полагайтесь на память, особенно если конфигурацию менял кто-то другой.
- Откройте вторую сессию SSH до применения правил и не закрывайте её. Проверка идёт в новом окне: если подключение устанавливается, правила корректны.
- Работайте внутри screen или tmux. Если соединение оборвётся, сессия и запущенная команда останутся живы.
- Держите под рукой консольный доступ через панель провайдера: KVM, IPMI, VNC или веб-консоль. Этот канал не зависит от сетевых правил сервера.
- Не меняйте порт SSH и правила файрвола одновременно. Два изменения в одном шаге не дают понять, что именно сломалось.
Что делать, если доступ потерян. Зайдите через консоль провайдера и отключите фильтр: sudo ufw disable. Дальше добавьте правило для SSH и включите файрвол заново. Для firewalld аналогично: sudo systemctl stop firewalld, затем firewall-cmd --add-service=ssh --permanent и запуск службы. Правила iptables, не сохранённые в конфигурацию, сбрасываются при перезагрузке, и это тоже способ вернуть доступ, хотя и грубый.
Ещё один слой - внешний фильтр облака. У AWS, Google Cloud, Yandex Cloud, Selectel доступ регулируют security groups и аналогичные списки на уровне сети. Правило в ufw не поможет, если провайдер блокирует порт раньше. Проверяйте оба уровня. Смежные темы, включая ключи SSH, Fail2Ban и аудит уязвимостей, собраны в руководстве базовая безопасность сервера: UFW, SSH и аудит.
Готовый минимальный набор правил для типового веб-сервера
Шаблон для Ubuntu или Debian с ufw. Подставьте свой порт SSH, если он отличается от 22.
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 enable sudo ufw status verbose
Шаблон для CentOS, AlmaLinux, Rocky Linux, Fedora с firewalld:
sudo firewall-cmd --set-default-zone=public sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload sudo firewall-cmd --list-all
Исходящий трафик оставлен открытым: серверу нужны обновления, DNS, работа с внешними API и репозиториями. Ограничивать его стоит только в изолированных средах, где список внешних назначений известен заранее. Тогда политику меняют на deny для outgoing и добавляют правила под конкретные адреса и порты.
Набор расширяется по мере задач: порт 5432 для PostgreSQL, 3306 для MySQL, 6379 для Redis. Каждый открывается под конкретный источник: sudo ufw allow from 10.0.0.5 to any port 5432 proto tcp. Открывать порт базы данных для всего интернета не нужно никогда.
Проверяем, что файрвол работает
Статус и правила:
- ufw: sudo ufw status verbose показывает политику по умолчанию и список правил.
- iptables: sudo iptables -L -n -v выводит цепочки, адреса и счётчики попавших пакетов.
- firewalld: sudo firewall-cmd --list-all показывает активную зону, службы и порты.
Проверка извне отвечает на главный вопрос: доступен ли порт снаружи. С другой машины выполняют nc -zv 203.0.113.10 22, затем 80 и 443. Успешное соединение даёт строку succeeded, закрытый порт приводит к timeout или connection refused. Разница между ответами информативна: timeout чаще означает блокировку пакетов, refused говорит, что пакет дошёл, но сервис порт не слушает.
Финальная проверка - новое SSH-подключение в отдельном окне терминала. Текущую сессию не закрывайте, пока не убедитесь, что новая устанавливается. Затем перезагрузите сервер командой sudo reboot и посмотрите правила снова: часть конфигураций не переживает перезапуск без сохранения. По умолчанию правила iptables не сохраняются после перезагрузки. Сохранить их можно командой iptables-save, которая записывает текущую конфигурацию в файл, либо пакетом iptables-persistent в Debian и Ubuntu. В Debian 10 и последних версиях Ubuntu у этого пакета есть зависимость netfilter-persistent, а ручное сохранение выполняется командой netfilter-persistent save; правила хранятся в /etc/iptables/rules.v4 для IPv4 и /etc/iptables/rules.v6 для IPv6.
Типичные ошибки новичков и как их избежать
- Включение файрвола без правила для SSH. Решение: сначала allow 22/tcp, потом enable.
- Открытие всего диапазона портов, например sudo ufw allow 1:65535/tcp. Смысл фильтрации исчезает. Открывайте отдельные порты.
- Политика default allow с ручной блокировкой лишнего. Решение: default deny incoming и явные разрешения.
- Правило добавлено, но сервис не запущен или слушает localhost. Проверьте ss -tlnp: адрес 127.0.0.1 означает, что снаружи порт недоступен независимо от файрвола.
- Неверный порядок правил в iptables и nftables. Первое совпавшее правило останавливает обработку, поэтому запреты и разрешения выстраивают в осмысленной последовательности.
- Правила не сохранены. ufw и firewalld хранят конфигурацию на диске, а правила iptables и nftables, добавленные вручную, исчезают после перезагрузки. Для iptables используйте iptables-save или пакет iptables-persistent (в Debian и Ubuntu).
- Правка конфигурации на рабочем сервере без проверки. Прогоняйте набор правил на стенде или в виртуальной машине, особенно если сервер обслуживает продакшн.
Что дальше: расширяем защиту
Минимальный файрвол закрывает сетевой периметр, но не решает задачу безопасности целиком.
fail2ban читает логи и блокирует адреса после нескольких неудачных попыток входа. Он дополняет фильтрацию: файрвол решает, какие порты открыты, fail2ban ограничивает, кто может по ним подключаться. Связка этих инструментов, аудит правил и логирование разобраны в статье файрвол для Linux-сервера: настройка защиты от атак.
Аутентификация по ключам вместо паролей убирает саму возможность подбора. В sshd_config это PasswordAuthentication no, а открытый ключ добавляется в ~/.ssh/authorized_keys. Ограничение по IP ставит второй барьер: sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp пропускает SSH только из доверенной подсети.
Для внутренних сервисов, которые не должны смотреть в интернет, применяют VPN. OpenVPN - бесплатный программный комплекс с открытым исходным кодом, который создаёт защищённые виртуальные сети и шифрованные туннели. Он работает на транспортных протоколах UDP и TCP, использует библиотеку OpenSSL и по умолчанию применяет 256-битное шифрование, поддерживая алгоритмы AES, Blowfish, 3DES, CAST-128 и Camellia. Аутентификация возможна по сертификатам, логину с паролем и сторонним модулям, а соединение проходит через HTTP- и SOCKS-прокси, NAT и сетевые фильтры, поэтому работает почти из любой сети.
Практический вывод для периметра: SSH и панели управления можно не публиковать вовсе, а держать за VPN. Тогда в файрволе остаётся открытым один порт VPN, а остальной доступ идёт внутрь туннеля.
Обновления закрывают уязвимости в уже разрешённых сервисах: sudo apt update && sudo apt upgrade или sudo dnf upgrade. Файрвол ограничивает вход, обновления убирают дыры в том, что вы сознательно открыли. Эти два действия работают вместе, и начинать проще с файрвола: пять команд, проверка извне и повторное подключение по SSH в новом окне.