Согласно документа в Debian Wiki фреймворк nftables представляет собой механизм, используемый ОС Debian 10 Buster по умолчанию для управления встроенного в ядро Linux брандмауэра Netfilter. Nftables может рассматриваться, как современная, более продвинутая и функциональная замена таким инструментам, как iptables, ip6tables, arptables и ebtables.
Установка и запуск nftables
Не смотря на то, что в Debian 10 на данный момент по прежнему доступна утилита iptables, на самом деле она уже работает с фреймворком nftables в режиме совместимости с синтаксисом iptables и ссылается на утилиту iptables-nft.
Чтобы отказаться от использования режима совместимости и синтаксиса iptables, мы можем использовать родной для nftables инструмент nft. Для этого установим пакет nftables.
# apt-get install nftables
После установки посмотрим на то, какая конфигурация правил nftables используется по умолчанию
# cat /etc/nftables.conf
Как видим, у нас уже описана таблица с именем "filter" семейства inet, предоставляющим возможность использовать правила IPv4/IPv6. В этой таблице созданы три цепочки с хуками netfilter типа input, forward, output. Правила в этих цепочках отсутствуют.
Настраиваем автоматический запуск службы, отвечающей за активацию правил nftables, затем запускаем эту службу:
# systemctl enable nftables
# systemctl start nftables
# systemctl status nftables
Теперь можно переходить к управлению правилами 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\"
Простейший вариант настройки правил 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
Дополнительные источники информации:
Доброго времени суток, спасибо большое за информацию, а то по nftables информации не так много, обрывки
А примеры точно верные? Так как описано добавление правила на пинг выдает ошибку. Вот как оно реально срабатывает: nft add rule inet filter input icmp type echo-request accept, другими словами пропущен inet
Да действительно 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
Я думаю, лучше закрыть порт 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, используя новый порт.
А можно ли установить в Debian 10 Firewalld, я к нему привык и свободно ориентируюсь. А то, сначала IPTables, затем Ferewalld, затем, nftables... Хорошо, если настройки будут аналогичны IPTables, и опять придётся их изучать.
Можно, так как firewalld может использовать в качестве бакенда как iptables так и nftables
Спасибо. Возможно я верну Debian на домашний сервер, как только закончу его тестирование на десктопе. У меня на нём 5 лет стоял Debian 7 и вполне меня устраивал. А когда закончилась его поддержка, решил обновить сначала до версии 8, а затем до 9 и получил полный облом, система даже не загружалась с выводом сообщения, что не может найти несуществующий раздел /dev/sdi7, /dev/sdh5..., причём при каждой загрузке разный. Перешёл на CentOS 7, но его поддержка скоро закончится, а 8 версию пока не могу настроить, даже не могу подключить ни одного репозитория. Выход один, возвращаться на Debian.
Всё-таки, думаю, до возвращения 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 минут!
Интересно, в свете когда закопали Центос, что вы используете?