Главная / Подводные камни

Подводные камни

Ситуации, в которых UFW ведёт себя не так, как ожидаешь. Прочитайте до того, как они случатся.

Потерял доступ по SSH

Самая частая проблема: UFW включили раньше, чем добавили правило для SSH, или указали не тот порт.

  1. Откройте веб-консоль (VNC) в панели хостинг-провайдера и войдите под root или своим пользователем.
  2. Добавьте правило для SSH или временно выключите файрвол:
bash — в веб-консоли
# вариант 1: открыть SSH (подставьте свой порт)
sudo ufw allow 22/tcp
# вариант 2: выключить UFW целиком
sudo ufw disable

Чтобы это не повторилось, используйте таймер-страховку при каждом серьёзном изменении правил.

Docker обходит UFW

Если запустить контейнер с -p 8080:80, порт 8080 будет доступен из интернета, даже если UFW его не разрешает. Docker добавляет свои правила iptables, и трафик к контейнерам до правил UFW не доходит.

Решение 1. Публиковать порты только на localhost

Самый простой и надёжный путь: контейнер слушает только локальный адрес, а наружу его отдаёт обратный прокси (Nginx, Caddy) через порты 80/443.

bash
docker run -d -p 127.0.0.1:8080:80 nginx
docker-compose.yml
services:
  app:
    image: nginx
    ports:
      - "127.0.0.1:8080:80"

Решение 2. Не публиковать порты вовсе

Если сервисы общаются только между собой, объедините их в общую сеть Docker и уберите ports — снаружи они будут недоступны.

Решение 3. Правила в цепочке DOCKER-USER

Для сложных случаев есть готовые решения, которые встраивают UFW в цепочку DOCKER-USER, например проект ufw-docker на GitHub. Используйте, если понимаете, что он меняет.

Проверить, что торчит наружу:

bash
docker ps --format '{{.Names}}\t{{.Ports}}'
# опасно: 0.0.0.0:8080->80/tcp   безопасно: 127.0.0.1:8080->80/tcp

IPv6

Если у сервера есть IPv6-адрес, а UFW настроен только для IPv4, всё открыто по IPv6. Проверьте настройку:

bash
grep IPV6 /etc/default/ufw
# должно быть: IPV6=yes

Если стоит no — исправьте на yes и перезапустите UFW:

bash
sudo sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
sudo ufw disable && sudo ufw enable

Если включили IPv6 уже после добавления правил, их IPv6-копии могут не появиться. Проверьте sudo ufw status: у каждого правила должна быть строка с (v6). Если её нет — удалите правило и добавьте заново.

Порядок правил

UFW применяет первое совпавшее правило. Пример ошибки:

так не сработает
sudo ufw allow 80/tcp
sudo ufw deny from 198.51.100.7   # добавится в конец: 80-й порт для него открыт
правильно
sudo ufw insert 1 deny from 198.51.100.7

Файрвол провайдера

У многих облаков (AWS, Hetzner, Yandex Cloud, Selectel и др.) есть свой сетевой файрвол — «группы безопасности». Трафик проходит его до UFW. Если порт открыт в UFW, но не открыт в панели провайдера, — он недоступен. И наоборот.

Правило: открывайте порт в обоих местах; закрывать — достаточно в любом.

Смена порта SSH

Порядок важен: сначала открываем новый порт, проверяем вход, только потом закрываем старый.

bash
# 1. открыть новый порт ДО смены
sudo ufw limit 2222/tcp comment 'SSH new'

# 2. в /etc/ssh/sshd_config указать: Port 2222
sudo nano /etc/ssh/sshd_config

# 3a. Ubuntu 22.10+ (SSH через ssh.socket)
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
# 3b. Debian и системы без ssh.socket
sudo systemctl restart ssh

Проверьте вход по новому порту из нового окна: ssh -p 2222 user@сервер. Только после этого удалите старое правило:

bash
sudo ufw status numbered
# удалите правило для 22/tcp и его копию (v6) по номерам
sudo ufw delete 1

Когда limit мешает

ufw limit временно блокирует IP после 6 подключений за 30 секунд. Это мешает инструментам, которые часто открывают новые SSH-сессии: Ansible, CI/CD, скриптам с scp в цикле.

Решение: для этих адресов добавьте обычное allow выше правила limit.

bash
# IP вашего CI-сервера получает доступ без ограничения частоты
sudo ufw insert 1 allow from 198.51.100.30 to any port 22 proto tcp comment 'CI'