UFW придуман для того, чтобы фаервол настраивался тремя командами, и с этим он справляется. Проблема в другом: ufw status показывает намерения, а не результат. Правило может стоять в списке и при этом не закрывать ровно ничего — по трём разным причинам, и все три встречаются на реальных серверах регулярно.
Начало, при котором не запираешь себя
Порядок команд имеет значение. Сначала разрешить SSH, потом включать:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable
ufw enable до разрешения SSH обрывает вашу же сессию, и дальше только консоль хостера. Если сервер уже настроен и вы не уверены — держите открытым второе соединение, оно переживёт неудачную правку.
Смотреть надо подробный статус, короткий скрывает политику по умолчанию:
sudo ufw status verbose
Ошибка первая: правило есть, а порт открыт всему миру
Самая частая строка в чужих конфигурациях:
sudo ufw allow 3306
Так открывают MySQL «чтобы подключиться из дома» — и открывают его всему интернету. Правильных вариантов два, и оба лучше:
sudo ufw allow from 203.0.113.25 to any port 3306
или, что надёжнее, вообще не выпускать службу наружу: bind-address = 127.0.0.1 в конфиге MySQL, а доступ извне — через SSH-туннель. Фаервол — второй рубеж; первый в том, чтобы служба не слушала публичный адрес. Правило в UFW можно случайно удалить, а bind-address сам собой не поменяется.
Ошибка вторая: IPv6
Правило вида ufw allow from 203.0.113.25 относится только к IPv4. Если у сервера есть адрес IPv6 — а у большинства VPS он есть и включён — служба остаётся доступной по нему. Хостер выдал адрес, вы про него не помните, сканер про него знает.
Проверьте, что фильтрация v6 вообще включена (IPV6=yes в /etc/default/ufw) и что служба не слушает :: без нужды:
ss -tulpn | grep ':::'
Правила с явным указанием адреса нужно заводить для обеих версий протокола отдельно.
Ошибка третья: Docker
Самая обидная. Docker публикует порты, дописывая собственные правила в цепочки iptables раньше тех, куда пишет UFW. В результате контейнер, запущенный как -p 5432:5432, доступен из интернета, даже если UFW показывает Status: active и политику deny incoming. Фаервол при этом не сломан — до него просто не доходит очередь.
Лечится это не в UFW, а в том, как публикуется порт:
ports:
- "127.0.0.1:5432:5432"
Привязка к локальному адресу — самое простое и надёжное решение. Наружу должно смотреть только то, что действительно обслуживает посетителей: обычно это порты 80 и 443 обратного прокси.
Порядок правил
UFW применяет первое подходящее правило и на этом останавливается. Поэтому запрет, добавленный после разрешения, не сработает: до него дело не дойдёт. Смотрим нумерацию и вставляем в нужное место:
sudo ufw status numbered
sudo ufw insert 1 deny from 198.51.100.0/24
sudo ufw delete 7
Правила удаляются по номеру, но номера сдвигаются после каждого удаления — удаляйте по одному и перечитывайте список.
Проверка снаружи
Локальные команды показывают, что настроено. Что получилось на самом деле, видно только с другой машины:
nmap -Pn -p- 203.0.113.25
nc -zv 203.0.113.25 3306
Достаточно любого другого сервера или домашнего компьютера. Это единственная проверка, которая не врёт, и делать её стоит после каждой заметной перенастройки — особенно после установки чего-то, что «само настраивает сеть»: Docker, панели управления, VPN.
Логи
По умолчанию UFW почти ничего не пишет. Включается так:
sudo ufw logging low
Записи попадают в /var/log/ufw.log — но только если в системе есть rsyslog. На Debian 12 и Ubuntu 24.04 его может не быть, и тогда всё уходит в журнал systemd:
sudo journalctl -k | grep -i '\[UFW'
Пустой /var/log/ufw.log сам по себе ничего не означает — сначала посмотрите в журнал.
Чего ждать от фаервола
UFW закрывает то, что не должно быть доступно. Он не разбирает содержимое запросов к тому, что открыто: порт 443 открыт всем, и всё, что придёт на сайт, придёт беспрепятственно. Это работа других инструментов — WAF на уровне приложения, IDS на уровне трафика. Задача фаервола скромнее и важнее: чтобы список открытых портов совпадал с тем, что вы про него думаете. Как выглядит этот список вместе с активными правилами на одной странице — на демо ниже.