Инструкция

Настройка ufw в Linux: firewall на сервере и основы nftables

Обновлено: · Skillaria.Top

Настройка 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 понимает короткую и полную форму. Короткая удобна для типовых случаев, полная — когда нужно указать источник, интерфейс или адрес назначения.

ЗадачаКоманда
Порт TCPsudo ufw allow 443/tcp
Порт UDPsudo ufw allow 51820/udp
Диапазон портовsudo ufw allow 6000:6007/tcp
По имени сервисаsudo ufw allow https
С одного IPsudo 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: с нуля до уверенного администрирования».

Перейти к курсу