Настройка ufw в Linux: firewall на сервере и основы nftables
Настройка ufw сводится к трём шагам: задать политики по умолчанию (sudo ufw default deny incoming и allow outgoing), разрешить SSH и нужные порты (sudo ufw allow 22/tcp, sudo ufw allow 443/tcp), затем включить firewall командой sudo ufw enable. Правила проверяют через sudo ufw status numbered, а под капотом ufw управляет netfilter через iptables или nftables.
Firewall в Linux решает, какие сетевые пакеты пропустить на сервер, а какие отбросить. Само ядро делает это подсистемой netfilter, а управляют ей утилиты: низкоуровневые iptables и nftables и надстройка ufw (Uncomplicated Firewall). Для большинства серверов на Ubuntu и Debian ufw настройка занимает пять минут: закрыть всё входящее, открыть SSH и порты сервисов, включить. Ниже — пошаговый сценарий, типичные ошибки и минимум nftables, чтобы понимать, что происходит под капотом.
Как устроен firewall в Linux
Фильтрация пакетов живёт в ядре — это netfilter. Он предоставляет точки перехвата (hooks): входящий трафик на сам хост, исходящий, транзитный (forward). Пользовательские утилиты только записывают в ядро правила для этих точек.
| Инструмент | Уровень | Когда использовать |
|---|---|---|
ufw | надстройка, простой синтаксис | одиночный сервер на Ubuntu/Debian, типовые правила |
firewalld | надстройка с зонами | RHEL, Rocky, Fedora |
nftables (nft) | низкий, современный | сложные правила, NAT, наборы адресов |
iptables | низкий, устаревающий | старые системы и скрипты |
Важно: используйте один инструмент управления. Если править правила одновременно через ufw и вручную через iptables, они будут перезаписывать друг друга, и картина станет непредсказуемой.
Установка и проверка ufw
В Ubuntu ufw обычно уже установлен, но выключен. В Debian его ставят отдельно:
$ sudo apt update
$ sudo apt install ufw
$ sudo ufw status
Status: inactive
Статус inactive значит, что правила ufw не применяются. Включать firewall пока рано: сначала разрешим SSH, иначе на удалённом сервере вы отрежете себе доступ.
Пошаговая настройка ufw на сервере
Шаг 1. Политики по умолчанию
Политика по умолчанию — что делать с пакетом, если ни одно правило не подошло. Безопасная схема для сервера: входящее запрещено, исходящее разрешено.
$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow'
Ответы на ваши собственные исходящие соединения проходят автоматически: ufw отслеживает состояние соединений (connection tracking), поэтому открывать порты для ответов не нужно.
Шаг 2. Разрешить SSH
$ sudo ufw allow OpenSSH
Rules updated
Rules updated (v6)
OpenSSH — это профиль приложения. Если SSH слушает нестандартный порт, разрешите его явно: sudo ufw allow 2222/tcp. Проверить, какой порт реально слушает sshd, можно командой sudo ss -tlnp | grep sshd.
Шаг 3. Открыть порты сервисов
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp
Указывайте протокол: без /tcp ufw откроет порт и для TCP, и для UDP, а лишняя открытая дверь ни к чему.
Шаг 4. Включить firewall
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
ufw запустится сразу и будет включаться при каждой загрузке. Не закрывайте текущую SSH-сессию: откройте вторую и убедитесь, что подключение работает.
Шаг 5. Проверить правила
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
Правила для IPv6 ufw создаёт сам, если в /etc/default/ufw стоит IPV6=yes (значение по умолчанию).
Полезно сверять правила с тем, что реально слушает система: sudo ufw show listening выводит открытые сокеты и рядом — правила ufw для них. Порт, который слушается, но не покрыт ни одним правилом, — повод проверить, не забыли ли вы про сервис.
Как открыть порт в ufw: все варианты синтаксиса
Команда ufw allow понимает короткую и полную форму. Короткая удобна для типовых случаев, полная — когда нужно указать источник, интерфейс или адрес назначения.
| Задача | Команда |
|---|---|
| Порт TCP | sudo ufw allow 443/tcp |
| Порт UDP | sudo ufw allow 51820/udp |
| Диапазон портов | sudo ufw allow 6000:6007/tcp |
| По имени сервиса | sudo ufw allow https |
| С одного IP | sudo ufw allow from 203.0.113.10 |
| С подсети на порт | sudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp |
| На интерфейсе | sudo ufw allow in on eth1 to any port 3306 proto tcp |
| Запретить | sudo ufw deny 23/tcp |
| Отклонить с ответом | sudo ufw reject 25/tcp |
Разница между deny и reject: deny молча отбрасывает пакет, и клиент ждёт до таймаута; reject отправляет ответ, что порт закрыт. Для внешнего мира обычно выбирают deny, для внутренних сетей reject удобнее — клиенты сразу видят ошибку.
Доступ к базе данных только с одного сервера
Частая задача: PostgreSQL или MySQL не должны быть видны из интернета, но приложение на соседнем сервере должно подключаться.
$ sudo ufw allow from 10.0.0.5 to any port 5432 proto tcp
Rule added
Порт 5432 остаётся закрытым для всех остальных благодаря политике deny incoming. Дополнительно стоит настроить саму СУБД слушать только внутренний адрес — firewall и настройки сервиса защищают друг друга.
Профили приложений
Пакеты могут класть описания своих портов в /etc/ufw/applications.d/. Список и содержимое профилей:
$ sudo ufw app list
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
$ sudo ufw app info "Nginx Full"
Profile: Nginx Full
Title: Web Server (Nginx, HTTP + HTTPS)
Description: Small, but very powerful and efficient web server
Ports:
80,443/tcp
Разрешить профиль: sudo ufw allow "Nginx Full". Имена с пробелами берите в кавычки. Свой профиль можно описать в INI-формате в том же каталоге и применить командой sudo ufw app update имя.
Как удалить правило ufw
Самый надёжный способ — по номеру:
$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] OpenSSH ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
[ 4] OpenSSH (v6) ALLOW IN Anywhere (v6)
[ 5] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 6] 443/tcp (v6) ALLOW IN Anywhere (v6)
$ sudo ufw delete 2
Deleting:
allow 80/tcp
Proceed with operation (y|n)? y
Rule deleted
После удаления номера сдвигаются, поэтому перед следующим удалением снова выполните status numbered. Второй способ — повторить правило со словом delete: sudo ufw delete allow 80/tcp; он удалит и IPv4-, и IPv6-вариант сразу.
Порядок правил и вставка в начало
ufw проверяет правила сверху вниз, и срабатывает первое подходящее. Поэтому запрет для конкретного адреса должен стоять выше общего разрешения:
$ sudo ufw insert 1 deny from 198.51.100.23
Rule inserted
Если добавить deny обычной командой, он окажется в конце списка после allow 443/tcp и не сработает для этого порта.
Защита SSH от перебора: ufw limit
Правило limit разрешает подключение, но блокирует адрес, который открыл 6 и более соединений за 30 секунд:
$ sudo ufw limit OpenSSH
Rule updated
Это простая защита от массового перебора паролей. Для серьёзной защиты добавьте вход только по ключам и, при желании, fail2ban — он умеет банить адреса через ufw.
Логи ufw
Журналирование включается командой sudo ufw logging on; уровни — low, medium, high, full. Записи попадают в /var/log/ufw.log (через rsyslog) и в журнал ядра:
$ sudo journalctl -k | grep 'UFW BLOCK' | tail -2
Oct 14 10:12:03 web kernel: [UFW BLOCK] IN=eth0 OUT= SRC=45.155.205.1 DST=192.0.2.10 PROTO=TCP SPT=51544 DPT=3389
Oct 14 10:12:09 web kernel: [UFW BLOCK] IN=eth0 OUT= SRC=89.248.165.7 DST=192.0.2.10 PROTO=TCP SPT=40312 DPT=23
Поля SRC и DPT показывают, кто и в какой порт стучался. Если сервис не отвечает, а в логе есть UFW BLOCK с его портом — значит, правило не добавлено.
ufw и Docker: почему порты открыты вопреки правилам
Это самая известная ловушка. Docker при публикации порта (-p 8080:80) сам добавляет правила NAT и цепочку DOCKER, и трафик к контейнеру идёт через forward, минуя входящие правила ufw. В итоге ufw status не показывает порт 8080, а снаружи он доступен.
Варианты решения:
- Публиковать порты только на localhost:
-p 127.0.0.1:8080:80, а наружу отдавать через обратный прокси (nginx). - Добавлять свои правила в цепочку
DOCKER-USER— Docker её не перезаписывает. - Не публиковать порты служебных контейнеров вовсе, а связывать их через сеть Docker.
- Использовать утилиту
ufw-docker, которая добавляет в ufw правила для трафика к контейнерам.
Сброс и отключение
$ sudo ufw disable # выключить, правила сохраняются
$ sudo ufw reset # удалить все правила и выключить
$ sudo ufw reload # перечитать конфигурацию
Перед reset ufw сохраняет копии файлов правил в /etc/ufw/ с суффиксом даты. Сами правила хранятся в /etc/ufw/user.rules и user6.rules — их не правят вручную, только командами.
Основы nftables
nftables — современная замена iptables в ядре Linux. В Debian 10+ и Ubuntu 20.10+ команда iptables по умолчанию работает через слой совместимости iptables-nft, поэтому правила ufw тоже оказываются в nftables. Посмотреть всё, что загружено в ядро:
$ sudo nft list ruleset
Структура nftables: таблица (семейство ip, ip6 или inet для обоих) содержит цепочки, привязанные к точкам netfilter, а цепочки — правила. Минимальный firewall для сервера в файле /etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
ip protocol icmp accept
meta l4proto ipv6-icmp accept
tcp dport { 22, 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Применить и включить при загрузке:
$ sudo nft -c -f /etc/nftables.conf # только проверить синтаксис
$ sudo systemctl enable --now nftables
Правила можно добавлять и на лету, но они пропадут после перезагрузки, если не записать их в файл:
$ sudo nft add rule inet filter input tcp dport 5432 ip saddr 10.0.0.5 accept
$ sudo nft -a list chain inet filter input # -a покажет handle правил
$ sudo nft delete rule inet filter input handle 9
Главное преимущество nftables — наборы ({ 22, 80, 443 }) и одна таблица inet для IPv4 и IPv6. Не запускайте свой nftables.service одновременно с ufw: flush ruleset сотрёт правила ufw.
Типичные ошибки
- Включили ufw без правила для SSH — доступ потерян. Спасает консоль провайдера (VNC/serial):
sudo ufw allow OpenSSHилиsudo ufw disable. - Открыли порт, но сервис недоступен — сервис слушает
127.0.0.1, а не внешний адрес. Проверьтеss -tlnp. - Есть ещё облачный firewall — у многих провайдеров есть группы безопасности; порт нужно открыть и там.
- deny не работает — правило стоит ниже разрешающего; используйте
insert 1.
Итог
Базовая ufw настройка — это default deny incoming, разрешение SSH и портов сервисов, ufw enable и проверка через status numbered. Для точечного доступа используйте правила с from и port, для SSH — limit, а при работе с Docker помните, что он обходит ufw. Когда нужен NAT или сложные наборы правил, переходите на nftables. Защита сервера firewall-ом разобрана на практике в курсе по Linux.
Частые вопросы
Чем ufw отличается от iptables?
ufw — надстройка с простым синтаксисом, которая сама генерирует правила iptables или nftables. iptables и nftables — низкоуровневые инструменты, дающие полный контроль, но требующие больше знаний.
Сохраняются ли правила ufw после перезагрузки?
Да. После sudo ufw enable firewall запускается при загрузке, а правила хранятся в /etc/ufw/user.rules и user6.rules.
Нужно ли открывать порты для исходящих соединений?
При политике allow outgoing — нет. Ответы на исходящие соединения ufw пропускает автоматически благодаря отслеживанию состояния.
Как разрешить ping при включённом ufw?
По умолчанию ufw уже пропускает входящие ICMP echo-request: это правило задано в /etc/ufw/before.rules. Чтобы запретить ping, правило в этом файле меняют с ACCEPT на DROP и выполняют sudo ufw reload.
Есть ли ufw в CentOS и Rocky Linux?
Там штатный инструмент — firewalld с командой firewall-cmd. ufw можно поставить из EPEL, но смешивать его с firewalld не стоит.
Эта тема подробно разобрана с практикой в курсе «Linux: с нуля до уверенного администрирования».
Перейти к курсу