Базовая настройка брандмауэра Debian GNU/Linux 10 Buster с помощью nftables

nftables firewall in Debian BusterСогласно документа в Debian Wiki фреймворк nftables представляет собой механизм, используемый ОС Debian 10 Buster по умолчанию для управления встроенного в ядро Linux брандмауэра Netfilter. Nftables может рассматриваться, как современная, более продвинутая и функциональная замена таким инструментам, как iptables, ip6tables, arptables и ebtables.

Установка и запуск nftables

Не смотря на то, что в Debian 10 на данный момент по прежнему доступна утилита iptables, на самом деле она уже работает с фреймворком nftables в режиме совместимости с синтаксисом iptables и ссылается на утилиту iptables-nft.

Debian 10 iptables-nft

Чтобы отказаться от использования режима совместимости и синтаксиса iptables, мы можем использовать родной для nftables инструмент nft. Для этого установим пакет nftables.

# apt-get install nftables

После установки посмотрим на то, какая конфигурация правил nftables используется по умолчанию

# cat /etc/nftables.conf

Debian 10 default nftables config

Как видим, у нас уже описана таблица с именем "filter" семейства inet, предоставляющим возможность использовать правила IPv4/IPv6. В этой таблице созданы три цепочки с хуками netfilter типа input, forward, output. Правила в этих цепочках отсутствуют.

Настраиваем автоматический запуск службы, отвечающей за активацию правил nftables, затем запускаем эту службу:

# systemctl enable nftables
# systemctl start nftables
# systemctl status nftables

Start nftables in Debian 10

Теперь можно переходить к управлению правилами nftables.

Управление правилами nftables

Управление правилами nftables будем выполнять с помощью утилиты nft.

Посмотреть текущий набор активных правил можно командой:

# nft list ruleset

Очистить правила в цепочке "input" таблицы "filter" можно так:

# nft flush chain inet filter input

Полностью очистить набор активных правил можно командой:

# nft flush ruleset

Очистка действующих правил не влияет на загружаемый при старте службы nftables.service конфигурационный файл /etc/nftables.conf

Если нужно, чтобы текущие активные правила nftables попали в стартовую конфигурацию nftables, то достаточно выгрузить их командами типа:

# echo '#!/usr/sbin/nft -f' > /etc/nftables.conf
# echo 'flush ruleset' >> /etc/nftables.conf
# nft list ruleset >> /etc/nftables.conf

То есть внутри конфигурационного файла nftables.conf в первой строке присутствует ссылка на исполняемый файл nft, во второй строке – команда полной очистки текущей конфигурации nftables, а затем идут настроенные нами правила.

Чтобы загрузить в активную конфигурацию nftables набор правил из файла можно выполнить команду типа:

# nft -f /etc/nftables.conf

По аналогии с ранее рассматриваемым iptables, nftables обрабатывает пакеты на основе правил (Rules), которые группируются в цепочки (Chains). Цепочки хранятся в таблицах (Tables).

Правила могут создаваться с использованием следующего синтаксиса:

nft add rule [<family>] <table> <chain> <matches> <statements>
nft insert rule [<family>] <table> <chain> [position <position>] <matches> <statements>
nft replace rule [<family>] <table> <chain> [handle <handle>] <matches> <statements>
nft delete rule [<family>] <table> <chain> [handle <handle>]

Где:

  • family - определяет семейство одним из типов: ip, ip6, arp, bridge, inet, netdev. Описание: #Nftables_families
  • table - указывает на имя таблицы соответствующего семейства <family>
  • chain - указывает на имя цепочки в соответствующей таблице <table>
  • position - номер правила в цепочке <chain>, перед которым будет вставлено добавляемое правило
  • handle - номер правила в цепочке <chain>, которое будет заменено/удалено
  • matches - правило фильтрации пакетов в форматах, описанных в #Matches
  • statements - действие, предпринимаемое с пакетами, подпадающими под правило <matches>. Допускаемые варианты:#Statements

Далее для наглядности рассмотрим несколько простых примеров управления правилами nftables с помощью nft.

Простые примеры правил nftables

Разрешаем ping (сообщения типа echo-request по протоколу ICMP):

# nft add rule filter input icmp type echo-request accept

Разрешаем все пакеты для уже установленных соединений с использованием механизма connection tracking:

# nft add rule filter input ct state established accept

Разрешаем доступ из подсети 192.168.1.0/24 и IP 192.168.0.10 по SSH:

# nft add rule ip filter input ip saddr {192.168.1.0/24, 192.168.0.10} tcp dport 22 accept

Вместо IP в правилах возможно использование доменного имени:

# nft add rule ip filter output ip daddr example.org accept

Запрещаем доступ к 80-му порту:

# nft add rule ip filter input tcp dport 80 drop

Удаляем правило с определённым номером в цепочке "output" таблицы "filter":

# nft delete rule filter output handle 9
Как конвертировать правила iptables

Базовую информацию о конвертации правил можно найти в документе: Moving from iptables to nftables. Можно использовать дополнительные утилиты, такие как iptables-translate и ip6tables-translate, для того чтобы транслировать правила из привычного синтаксиса iptables в новый формат nftables.

Например, команда вида:

# iptables-translate -A INPUT -s 10.1.1.0/24 -i eth0 -p tcp -m state --state NEW -m tcp --dport 22 -m comment --comment "Allow access to SSH-server" -j ACCEPT

вернёт нам указанное в формате iptables правило, транслированное в формат nftables:

nft add rule ip filter INPUT iifname "eth0" ip saddr 10.1.1.0/24 ct state new  tcp dport 22 counter accept comment \"Allow access to SSH-server\"

iptables-translate

Простейший вариант настройки правил nftables

Рассмотрим простейший пример настройки брандмауэра для среднестатистического Linux-сервера в локальной сети предприятия. В рассматриваемом примере настраивается доступ к серверу по протоколу IPv4, а доступ по протоколу IPv6 полностью блокируется. По IPv4 разрешаются входящие подключения по протоколу SSH из сети администраторов (10.1.5.0/24), а также Ping и подключения к веб-серверу из всей сети предприятия (10.1.0.0/13).

Набор команд для наполнения правилами nftables в этом случае может выглядеть примерно следующим образом:

# nft flush ruleset
# nft add table ip FIREWALLIPv4
# nft add chain ip FIREWALLIPv4 INCOMING { type filter hook input priority 0 \; policy drop \; }
# nft add chain ip FIREWALLIPv4 FORWARDING { type filter hook forward priority 0 \; policy drop \; }
# nft add chain ip FIREWALLIPv4 OUTGOING { type filter hook output priority 0 \; policy accept \; }
# nft add rule ip FIREWALLIPv4 INCOMING iifname "lo" counter accept
# nft add rule ip FIREWALLIPv4 INCOMING ct state related,established counter accept
# nft add rule ip FIREWALLIPv4 INCOMING iifname "eth0" ip saddr 10.1.5.0/24 ct state new tcp dport 22 counter accept comment \"Allow access to SSH-server\"
# nft add rule ip FIREWALLIPv4 INCOMING iifname "eth0" ip saddr 10.1.0.0/13 ct state new icmp type echo-request counter accept comment \"Allow ping\"
# nft add rule ip FIREWALLIPv4 INCOMING iifname "eth0" ip saddr 10.1.0.0/13 ct state new tcp dport {80, 443} counter accept comment \"Allow access to Web-server\"
# nft add table ip6 FIREWALLIPv6
# nft add chain ip6 FIREWALLIPv6 INCOMING { type filter hook input priority 0 \; policy drop \; }
# nft add chain ip6 FIREWALLIPv6 FORWARDING { type filter hook forward priority 0 \; policy drop \; }
# nft add chain ip6 FIREWALLIPv6 OUTGOING { type filter hook output priority 0 \; policy accept \; }

Давайте посмотрим, что у нас в итоге получилось в активной конфигурации nftables.

# nft list ruleset

В нашем случае вывод конфигурации будет выглядеть следующим образом:

table ip FIREWALLIPv4 {
        chain INCOMING {
                type filter hook input priority 0; policy drop;
                iifname "lo" counter packets 0 bytes 0 accept
                ct state established,related counter packets 122 bytes 9200 accept
                iifname "eth0" ip saddr 10.1.5.0/24 ct state new tcp dport ssh counter packets 0 bytes 0 accept comment "Allow access to SSH-server"
                iifname "eth0" ip saddr 10.1.0.0/13 ct state new icmp type echo-request counter packets 0 bytes 0 accept comment "Allow ping"
                iifname "eth0" ip saddr 10.1.0.0/13 ct state new tcp dport { http, https } counter packets 0 bytes 0 accept comment "Allow access to Web-server"
        }

        chain FORWARDING {
                type filter hook forward priority 0; policy drop;
        }

        chain OUTGOING {
                type filter hook output priority 0; policy accept;
        }
}
table ip6 FIREWALLIPv6 {
        chain INCOMING {
                type filter hook input priority 0; policy drop;
        }

        chain FORWARDING {
                type filter hook forward priority 0; policy drop;
        }

        chain OUTGOING {
                type filter hook output priority 0; policy accept;
        }
}

Теперь, чтобы сохранить активную конфигурацию в стартовую, достаточно перенаправить вывод команды в конфигурационный файл службы nftables.service.

# echo '#!/usr/sbin/nft -f' > /etc/nftables.conf
# echo 'flush ruleset' >> /etc/nftables.conf
# nft list ruleset >> /etc/nftables.conf

Дополнительные источники информации:

Всего комментариев: 9 Комментировать

  1. Денис /

    Доброго времени суток, спасибо большое за информацию, а то по nftables информации не так много, обрывки

  2. smn /

    А примеры точно верные? Так как описано добавление правила на пинг выдает ошибку. Вот как оно реально срабатывает: nft add rule inet filter input icmp type echo-request accept, другими словами пропущен inet

  3. Иван /

    Да действительно inet не хватает, причём на всех источниках примеры аналогичные стоит debian 10 , где-то нужно и ip убрать .
    nft add rule inet ip filter input ip saddr {192.168.123.0/24, 46.22.4.15} tcp dport 22 accept

    1. Николай /

      Я думаю, лучше закрыть порт 22 и вместо него использовать какой-нибудь "экзотический", например 56473. Это позволит защититься от хакерских атак на сервер. Я на своём сервере так и сделал. Использую Firewalld, поэтому приведу пример для него.
      Выполните команду, например, для CentOS 7:
      # nano /etc/ssh/sshd_config

      В открывшемся файле найдите следующую строку:
      # Port 22

      Закомментируем её и добавим новую строку со случайным номером порта, например, 56473. Номер порта не должен превышать 65535. Также удостоверьтесь, что выбранное вами значение не конфликтует с другими сервисами в системе, например, mysqld использует порт 3306, httpd - 80, ftpd - 21. Рекомендуется выбрать пятизначное значение.
      *** Обязательно!!! На всякий случай, для просмотра уже открытых в системе портов, выполните следующую команду:
      # netstat -tupln | grep LISTEN

      После модификации, участок файла конфигурации SSH должен выглядеть примерно так:
      #Port 22
      Port 56473

      Чтобы SSH-сервер начал слушать новый порт вместо прежнего, его нужно перезапустить:
      # sysremctl restart sshd

      Проверяем на каком порту висит сейчас sshd
      # netstat -tulpn | grep sshd

      Получаем ответ:
      tcp 0 0 0.0.0.0:56473 0.0.0.0:* LISTEN 3586/sshd
      tcp6 0 0 :::56473 :::* ISTEN 3586/sshd

      Видим 56473, значит все в норме.
      После этих манипуляций надо закрыть порт 22 и открыть 56473, для этого сначала выполним команду:
      # firewall-cmd --remove-port=22/tcp --permanent ' закрываем порт 22
      # firewall-cmd --add-port=56473/tcp --permanent ' открываем порт 56473

      Применяем новые настройки Firewall:
      # firewall-cmd --reload

      Перезагружаем компьютер и соединяемся с ним удалённо, через Putty, используя новый порт.

  4. Николай /

    А можно ли установить в Debian 10 Firewalld, я к нему привык и свободно ориентируюсь. А то, сначала IPTables, затем Ferewalld, затем, nftables... Хорошо, если настройки будут аналогичны IPTables, и опять придётся их изучать.

    1. Алексей Максимов / Автор записи

      Можно, так как firewalld может использовать в качестве бакенда как iptables так и nftables

      1. Николай /

        Спасибо. Возможно я верну Debian на домашний сервер, как только закончу его тестирование на десктопе. У меня на нём 5 лет стоял Debian 7 и вполне меня устраивал. А когда закончилась его поддержка, решил обновить сначала до версии 8, а затем до 9 и получил полный облом, система даже не загружалась с выводом сообщения, что не может найти несуществующий раздел /dev/sdi7, /dev/sdh5..., причём при каждой загрузке разный. Перешёл на CentOS 7, но его поддержка скоро закончится, а 8 версию пока не могу настроить, даже не могу подключить ни одного репозитория. Выход один, возвращаться на Debian.

  5. Николай /

    Всё-таки, думаю, до возвращения Debian на домашний сервер, дело не дойдёт. Debian 10 почему-то очень сильно подтормаживает, даже Fedora 31 Plasma, установленная на USB_HDD работает намного быстрее, чем Debian 10 на SATA. К тому же уже практически настроил CentOS 8, его работа на сервере с USB_HDD гораздо быстрее, чем у 7 версии. А Debian тормозит даже в простейших приложениях, например в пасьянсе Aisleriot, я уже отпустил клавишу мышки, а карта перемещается, спустя 0,5 - 2 секунды. Ранее, когда у меня на сервере стоял Debian 7, открытие сетевого ресурса затягивалось от 20 секунд до нескольких минут, абсолютный рекорд открытия папки на сервере составил более 5 минут!

    1. Арс /

      Интересно, в свете когда закопали Центос, что вы используете?

Добавить комментарий