Брандмауэр на VPS: UFW для Ubuntu и Debian, firewalld для AlmaLinux

Закрываем всё, кроме нужных портов, разрешаем SSH только со своего IP и разбираемся, почему Docker обходит UFW.

6 ноября 2026 г.·2 мин чтения·ufw, firewalld, docker

Брандмауэр решает, какие входящие соединения сервер примет, а какие молча отбросит. Снаружи должны быть видны только те сервисы, которыми вы действительно пользуетесь. Обычно это:

  • SSH — порт 22 или ваш, если меняли;
  • сайт — 80 и 443;
  • VPN или прокси — порты конкретной программы.

Всё остальное — базы данных, панели, Redis, служебные порты приложений — наружу торчать не должно.

Сначала разрешите SSH, потом включайте брандмауэр. Если включить с пустым списком правил, текущая сессия, скорее всего, выживет, а следующая уже не подключится. Выполняйте команды строго по порядку.

Ubuntu и Debian: UFW

sudo apt update
sudo apt install -y 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 enable
sudo ufw status verbose

Вывод ufw status verbose: активен, входящие запрещены, открыты 22, 80 и 443

На вопрос о возможном обрыве SSH при включении отвечайте y: порт 22 уже разрешён.

Полезные команды:

sudo ufw status numbered                 # правила с номерами
sudo ufw delete 3                        # удалить правило №3
sudo ufw allow 8080/tcp                  # открыть ещё порт
sudo ufw limit 22/tcp                    # не больше 6 подключений за 30 с с одного IP
sudo ufw disable                         # выключить (правила сохраняются)

ufw limit — простейшая защита от перебора без fail2ban: после шести попыток за полминуты IP временно блокируется.

AlmaLinux, Rocky, CentOS: firewalld

sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --list-all

SSH в зоне public обычно разрешён по умолчанию, убедитесь в этом по выводу. Добавьте веб:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Произвольный порт:

sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

Без --permanent правило живёт до перезагрузки; без --reload постоянное правило не применяется сразу. Нужны оба.

SSH только с вашего IP

Самая сильная мера: порт 22 не виден никому, кроме вас. Свой адрес узнайте любым сервисом вроде «мой IP».

Только при постоянном IP. У домашних и мобильных провайдеров адрес меняется, и однажды вы окажетесь снаружи. Если не уверены — пропустите этот раздел и ограничьтесь ufw limit и fail2ban.

UFW:

sudo ufw allow from ВАШ_IP to any port 22 proto tcp
sudo ufw delete allow 22/tcp
sudo ufw status

firewalld:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="ВАШ_IP" port port="22" protocol="tcp" accept'
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload

Docker обходит UFW

Важная ловушка. Когда контейнер публикует порт через -p 8080:80 или ports: в Compose, Docker добавляет собственные правила iptables, и они срабатывают раньше UFW. Порт будет открыт на весь интернет, хотя в ufw status его нет.

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

docker run -d -p 127.0.0.1:8080:80 nginx

В Compose — "127.0.0.1:8080:80". Наружу выходят только 80 и 443 обратного прокси. Базы данных (MySQL, PostgreSQL, Redis) внутри одного Compose-проекта вообще не нуждаются в публикации портов: контейнеры видят друг друга по именам сервисов.

Проверить, что реально слушает сервер:

sudo ss -tlnp

ss -tlnp показывает, какие порты слушает сервер и какие процессы

Строки с 0.0.0.0:ПОРТ и [::]:ПОРТ открыты миру, 127.0.0.1:ПОРТ — только локально.

Если отрезали себе доступ

Зайдите через консоль в кабинете tanaka.host и временно выключите брандмауэр:

sudo ufw disable                    # UFW
sudo systemctl stop firewalld       # firewalld

Поправьте правила и включите обратно. Следующий шаг — автообновления и fail2ban.