nftables
Nftables
Обзор
Роль для управления правилами и пакетами Nftables.
Вдохновлён ролей брандмауэра Майка Глисона (3 уровня определения правил и шаблонов), спасибо! Надеюсь, я не усложнил его философию... (Я довольно уверен, что теперь усложнил её :D) ^^
Переменные роли
- nft_enabled: Включить или выключить поддержку Nftables [по умолчанию:
true
]. - nft_pkg_state: Состояние новых пакетов
nftables
[по умолчанию:present
]. - nft_old_pkg_list: Список ненужных пакетов для удаления (таких как Iptables,...) [по умолчанию:
iptables
]. - nft_old_pkg_state: Состояние старых пакетов [по умолчанию:
absent
]. - nft_old_pkg_manage: Если старые пакеты должны управляться с помощью этой роли [по умолчанию:
true
]. - nft_conf_dir_path: Директория для хранения различных конфигурационных файлов Nftables [по умолчанию:
/etc/nftables.d
]. - nft_main_conf_path: Основной конфигурационный файл, загружаемый юнитом systemd [по умолчанию:
/etc/nftables.conf
]. - nft_main_conf_content: Шаблон, используемый для генерации предыдущего основного конфигурационного файла [по умолчанию:
etc/nftables.conf.j2
]. - nft_input_conf_path: Входной конфигурационный файл, включаемый в основной конфигурационный файл [по умолчанию:
{{ nft_conf_dir_path }}/filter-input.nft
]. - nft_input_conf_content: Шаблон, используемый для генерации предыдущего входного конфигурационного файла [по умолчанию:
etc/nftables.d/filter-input.nft.j2
]. - nft_output_conf_path: Выходной конфигурационный файл, включаемый в основной конфигурационный файл [по умолчанию:
{{ nft_conf_dir_path }}/filter-output.nft
]. - nft_output_conf_content: Шаблон, используемый для генерации предыдущего выходного конфигурационного файла [по умолчанию:
etc/nftables.d/filter-output.nft.j2
]. - nft_forward_conf_path: Конфигурационный файл перенаправления, включаемый в основной конфигурационный файл [по умолчанию:
{{ nft_conf_dir_path }}/filter-forward.nft
]. - nft_forward_conf_content: Шаблон, используемый для генерации предыдущего конфигурационного файла перенаправления [по умолчанию:
etc/nftables.d/filter-forward.nft.j2
]. - nft_define_conf_path: Файл определения переменных, включаемый в основной конфигурационный файл [по умолчанию:
{{ nft_conf_dir_path }}/defines.nft
]. - nft_define_conf_content: Шаблон, используемый для генерации предыдущего файла определения переменных [по умолчанию:
etc/nftables.d/defines.nft.j2
]. - nft_sets_conf_path: Файл определения наборов и карт, включаемый в основной конфигурационный файл [по умолчанию:
{{ nft_conf_dir_path }}/sets.nft
]. - nft_sets_conf_content: Шаблон, используемый для генерации предыдущего файла определения наборов и карт [по умолчанию:
etc/nftables.d/sets.nft.j2
]. - nft_global_default_rules: Установить правила по умолчанию для цепочки
global
. Другие цепочки будут переходить кglobal
перед применением своих специфических правил. - nft_global_rules: Вы можете добавить правила
global
или переопределить те, что определены параметром nft_global_default_rules для всех хостов. - nft_global_group_rules: Вы можете добавить правила
global
или переопределить те, что определены параметрами nft_global_default_rules и nft_global_rules для группы. - nft_global_host_rules: Хосты также могут добавлять или переопределять все предыдущие правила.
- nft__custom_content: Пользовательский контент (таблицы, включения и т.д.), который необходимо добавить в конфигурацию Nftables [по умолчанию:
''
]. - nft_input_default_rules: Установить правила по умолчанию для цепочки
input
. - nft_input_rules: Вы можете добавить правила
input
или переопределить те, что определены параметром nft_input_default_rules для всех хостов. - nft_input_group_rules: Вы можете добавить правила
input
или переопределить те, что определены параметрами nft_input_default_rules и nft_input_rules для группы. - nft_input_host_rules: Хосты также могут добавлять или переопределять все предыдущие правила
input
. - nft_output_default_rules: Установить правила по умолчанию для цепочки
output
. - nft_output_rules: Вы можете добавить правила
output
или переопределить те, что определены параметром nft_output_default_rules для всех хостов. - nft_output_group_rules: Вы можете добавить правила
output
или переопределить те, что определены параметрами nft_output_default_rules и nft_output_rules для группы. - nft_output_host_rules: Хосты также могут добавлять или переопределять все предыдущие правила
output
. - nft_forward_default_rules: Установить правила по умолчанию для цепочки
forward
. - nft_forward_rules: Вы можете добавить правила
forward
или переопределить те, что определены параметром nft_forward_default_rules для всех хостов. - nft_forward_group_rules: Вы можете добавить правила
forward
или переопределить те, что определены параметрами nft_forward_default_rules и nft_forward_rules для группы. - nft_forward_host_rules: Хосты также могут добавлять или переопределять все предыдущие правила
forward
. - nft__forward_table_manage: Если таблица перенаправления должна управляться [по умолчанию:
False
]. - nft__nat_table_manage: Если таблица NAT должна управляться [по умолчанию:
False
]. - nft__nat_default_prerouting_rules: Установить правила по умолчанию для цепочки
prerouting
таблицы nat. - nft__nat_prerouting_rules: Установить правила для цепочки
prerouting
таблицы nat для всех хостов в инвентаре Ansible. - nft__nat_group_prerouting_rules: Установить правила для цепочки
prerouting
таблицы nat для хостов в конкретной группе инвентаря Ansible. - nft__nat_host_prerouting_rules: Установить правила для цепочки
prerouting
таблицы nat для конкретных хостов в инвентаре Ansible. - nft__nat_prerouting_conf_path: Конфигурационный файл перенаправления, включаемый в основную конфигурацию [по умолчанию:
{{ nft_conf_dir_path }}/nat-prerouting.nft
]. - nft__nat_prerouting_conf_content: Шаблон, используемый для генерации предыдущего конфигурационного файла перенаправления [по умолчанию:
etc/nftables.d/nat-prerouting.nft.j2
]. - nft__nat_default_postrouting_rules: Установить правила по умолчанию для цепочки
postrouting
таблицы nat. - nft__nat_postrouting_rules: Установить правила для цепочки
postrouting
таблицы nat для всех хостов в инвентаре Ansible. - nft__nat_group_postrouting_rules: Установить правила для цепочки
postrouting
таблицы nat для хостов в конкретной группе инвентаря Ansible. - nft__nat_host_postrouting_rules: Установить правила для цепочки
postrouting
таблицы nat для конкретных хостов в инвентаре Ansible. - nft__nat_postrouting_conf_path: Конфигурационный файл постнаправления, включаемый в основную конфигурацию [по умолчанию:
{{ nft_conf_dir_path }}/nat-postrouting.nft
]. - nft__nat_postrouting_conf_content: Шаблон, используемый для генерации предыдущего конфигурационного файла постнаправления [по умолчанию:
etc/nftables.d/nat-postrouting.nft.j2
]. - nft_define_default: Установить переменные по умолчанию, доступные во всех правилах.
- nft_define: Вы можете добавить переменные или переопределить те, что определены nft_define_default для всех хостов.
- nft_define_group: Вы можете добавить переменные или переопределить те, что определены nft_define_default и nft_define для группы.
- nft_define_host: Вы можете добавить или переопределить все предыдущие переменные.
- nft_service_manage: Если служба
nftables
должна управляться с помощью этой роли [по умолчанию:true
]. - nft_service_name: Имя службы
nftables
[по умолчанию:nftables
]. - nft_service_enabled: Установить, чтобы служба
nftables
была доступна при старте [по умолчанию:true
]. - nft__service_protect: Если юнит systemd должен защищать систему и домашнюю директорию [по умолчанию:
true
]. - nft_merged_groups: Если переменные из групп Ansible хостов должны быть объединены [по умолчанию:
false
]. - nft_merged_groups_dir: Словарь, где расположены правила групп nftables, именованные как группы Ansible [по умолчанию:
vars/
]. - nft_debug: Переключение более подробного вывода вкл./выкл. [по умолчанию: 'false'].
Переменные, специфичные для ОС
Пожалуйста, смотрите значения по умолчанию по файлам операционной системы в директории [vars][vars directory].
- nft_pkg_list: Список пакетов для предоставления
nftables
. - nft__bin_location: Путь к исполняемому файлу
nftables
. [по умолчанию:/usr/sbin/nft
]
Шаблоны правил
Словарь nft_templates
содержит библиотеку полезных правил, предназначенных для стандартизации и готовых к использованию в вашем брандмауэре. Например, {{ nft_templates.allow_mdns }}
будет развернуто в следующие правила, охватывающие mDNS для IPv4 и IPv6:
- meta l4proto udp ip6 daddr ff02::fb udp dport mdns counter accept comment "mDNS IPv6 service discovery"
- meta l4proto udp ip daddr 224.0.0.251 udp dport mdns counter accept comment "mDNS IPv4 service discovery"
Предназначенное использование в пользовательских наборах правил:
nft_host_input_rules:
...
010 allow mdns: "{{ nft_templates.allow_mdns }}"
Среди прочего, словарь nft_templates
содержит правила, реализующие полные рекомендации для перенаправления и входящего трафика, как это определено в RFC 4890, RFC 7126 и RFC 9288. Для деталей и примеров смотрите defaults/main.yml.
Словари правил
Каждый тип словарей правил будет объединён, и правила будут применяться в алфавитном порядке ключей (причина использования префиксов от 000 до 999). Таким образом:
- nft_*_default_rules: Определить правила по умолчанию для всех узлов. Вы можете определить это в
group_vars/all
. - nft_*_rules: Можно добавлять правила и переопределять те, что определены nft_*_default_rules. Вы можете определить это в
group_vars/all
. - nft_*_group_rules: Можно добавлять правила и переопределять те, что определены nft_*_default_rules и nft_*_rules. Вы можете определить это в
group_vars/webservers
.- Если
nft_merged_groups
установлен вtrue
, множественные групповые правила из групп ansible также будут объединены.
- Если
- nft_*_host_rules: Можно добавлять правила и переопределять те, что определены nft_*_default_rules, nft_*_group_rules и nft_*_rules. Вы можете определить это в
host_vars/www.local.domain
.
defaults/main.yml
:
# правила
nft_global_default_rules:
005 state management:
- ct state established,related accept
- ct state invalid drop
nft_global_rules: {}
nft_merged_groups: false
nft_merged_groups_dir: vars/
nft_global_group_rules: {}
nft_global_host_rules: {}
nft_input_default_rules:
000 policy:
- type filter hook input priority 0; policy drop;
005 global:
- jump global
010 drop unwanted:
- ip daddr @blackhole counter drop
015 localhost:
- iif lo accept
210 input tcp accepted:
- tcp dport @in_tcp_accept ct state new accept
nft_input_rules: {}
nft_input_group_rules: {}
nft_input_host_rules: {}
nft_output_default_rules:
000 policy:
- type filter hook output priority 0; policy drop;
005 global:
- jump global
015 localhost:
- oif lo accept
050 icmp:
- ip protocol icmp accept
- ip6 nexthdr icmpv6 counter accept
200 output udp accepted:
- udp dport @out_udp_accept ct state new accept
210 output tcp accepted:
- tcp dport @out_tcp_accept ct state new accept
nft_output_rules: {}
nft_output_group_rules: {}
nft_output_host_rules: {}
# определение переменных nft
nft_define_default:
broadcast and multicast:
desc: 'broadcast and multicast'
name: badcast_addr
value: '{ 255.255.255.255, 224.0.0.1, 224.0.0.251 }'
input tcp accepted:
name: in_tcp_accept
value: '{ ssh }'
output tcp accepted:
name: out_tcp_accept
value: '{ http, https, hkp }'
output udp accepted:
name: out_udp_accept
value: '{ bootps, domain, ntp }'
nft_define: {}
nft_define_group: {}
nft_define_host: {}
# наборы и карты
nft_set_default:
blackhole:
- type ipv4_addr;
- elements = $badcast_addr
in_tcp_accept:
- type inet_service; flags interval;
- elements = $in_tcp_accept
out_tcp_accept:
- type inet_service; flags interval;
- elements = $out_tcp_accept
out_udp_accept:
- type inet_service; flags interval;
- elements = $out_udp_accept
nft_set: {}
nft_set_group: {}
nft_set_host: {}
Эти значения по умолчанию сгенерируют следующую конфигурацию:
#!/usr/sbin/nft -f
# Управляется Ansible
# очистка
flush ruleset
include "/etc/nftables.d/defines.nft"
table inet filter {
chain global {
# 000 управление состоянием
ct state established,related accept
ct state invalid drop
}
include "/etc/nftables.d/sets.nft"
include "/etc/nftables.d/filter-input.nft"
include "/etc/nftables.d/filter-output.nft"
}
И вы можете получить все правила и определения, отображая набор правил на хосте: $ nft list ruleset
:
table inet filter {
set blackhole {
type ipv4_addr
elements = { 255.255.255.255, 224.0.0.1, 224.0.0.251}
}
set out_tcp_accept {
type inet_service
flags interval
elements = { http, https, hkp}
}
set out_udp_accept {
type inet_service
flags interval
elements = { domain, bootps, ntp}
}
chain global {
ct state established,related accept
ct state invalid drop
}
chain input {
type filter hook input priority 0; policy drop;
jump global
ip daddr @blackhole counter packets 0 bytes 0 drop
iif "lo" accept
tcp dport @in_tcp_accept ct state new accept
}
chain output {
type filter hook output priority 0; policy drop;
jump global
oif "lo" accept
ip protocol icmp accept
udp dport @out_udp_accept ct state new accept
tcp dport @out_tcp_accept ct state new accept
}
}
Примеры
С плейбуками
Управление Nftables с переменными по умолчанию (нажмите для раскрытия)
- hosts: serverXYZ
roles:
- role: ipr-cnrs.nftables
Добавление нового простого фильтра для входящего трафика (например, 1 порт для UDP/torrent) (нажмите для раскрытия)
- hosts: serverXYZ
vars:
nft_input_rules:
400 input torrent accepted:
- udp dport 6881 ct state new accept
roles:
- role: ipr-cnrs.nftables
- Переменные nft_input_group_rules или nft_input_host_rules также могут быть использованы.
- Вес (
400
) позволяет упорядочивать все объединённые правила (из словарей nft_input_*rules). - Текст, следующий за весом (
input torrent accepted
), является небольшим описанием, которое будет добавлено в качестве комментария в файл nft_input_conf_path на удалённом хосте.
Добавление нового мультипортов фильтра для входящего трафика (например, TCP/http, https, http-alt и т.д.) (нажмите для раскрытия)
- hosts: serverXYZ
vars:
nft_input_rules:
400 input http accepted:
- tcp dport { 80, 443, 8080-8082 } ct state new accept
roles:
- role: ipr-cnrs.nftables
- Переменные nft_input_group_rules или nft_input_host_rules также могут быть использованы.
- Вес (
400
) позволяет упорядочивать все объединённые правила (из словарей nft_input_*rules). - Текст, следующий за весом (
input http accepted
), является небольшим описанием, которое будет добавлено в качестве комментария в файл nft_input_conf_path на удалённом хосте. - В этом случае скобки полезны и определяют анонимный набор. Для одного элемента (порта, IP-адреса и т.д.) скобки избыточны, и определение единичного элемента достаточно.
Добавление нового правила с переменной (нажмите для раскрытия)
Переменные Nftables могут быть полезны, если вы определяете несколько общих правил для всех хостов с такими переменными (вызываемыми с помощью $) и переопределяете значение переменной для некоторых групп или хостов.
- hosts: serverXYZ
vars:
- nft_define_group:
input http accepted:
desc: HTTP and HTTPS
name: in_http_accept
value: '{ 80, 443 }'
nft_input_group_rules:
400 input http accepted:
- tcp dport $in_http_accept ct state new accept
roles:
- role: ipr-cnrs.nftables
- Добавьте новую переменную с define для HTTP портов.
- Добавьте новое правило для входящего трафика и используйте ранее определённую переменную.
- Результат
nft list ruleset
на удаленном хосте будет:table inet filter { … chain input { … tcp dport { http, https } ct state new accept … } … }
- Нет упоминания о переменной
$in_http_accept
.
- Нет упоминания о переменной
- Переменные nft_define или nft_define_host также могут быть использованы.
- Переменные nft_input_rules или nft_input_host_rules также могут быть использованы.
- Вес (
400
) позволяет упорядочивать все объединённые правила (из словарей nft_input_*rules). - Текст, следующий за весом (
input http accepted
), является небольшим описанием, которое будет добавлено в качестве комментария в файл nft_input_conf_path на удалённом хосте.
Добавление нового правила с именованным набором (нажмите для раскрытия)
Довольно похоже на переменные Nftables, именованный набор может быть полезен, если вы определяете несколько общих правил и наборов (например, для всех хостов) и переопределяете только набор в некоторых случаях (например, для группы или некоторых хостов).
В дополнение к переменным, возможно, добавлять содержимое в именованные наборы на лету с хоста без полного переписывания правила.
- hosts: serverXYZ
vars:
nft_set_group:
in_udp_accept:
- type inet_service; flags interval;
- elements = { 6881-6887, 6889 }
nft_input_group_rules:
200 input udp accepted:
- udp dport @in_udp_accept ct state new accept
roles:
- role: ipr-cnrs.nftables
- Добавьте новый именованный набор с помощью словаря nft_set_group (например, для портов торрент).
- Добавьте новое правило для входящего трафика и используйте ранее определённый набор.
- На удалённом хосте, если вы попытаетесь добавить порт к этому набору:
nft add element inet filter in_udp_accept \{ 6999 \}
- Результат
nft list ruleset
на удалённом хосте теперь будет:table inet filter { … set in_udp_accept { type inet_service flags interval elements = { 6881-6887, 6889, 6999 } } chain input { … udp dport @in_udp_accept ct state new accept … } … }
- Переменные nft_set или nft_set_host также могут быть использованы.
- Переменные nft_input_rules или nft_input_host_rules также могут быть использованы.
- Вес (
200
) позволяет упорядочивать все объединённые правила (из словарей nft_input_*rules). - Текст, следующий за весом (
input upd accepted
), является небольшим описанием, которое будет добавлено в качестве комментария в файл nft_input_conf_path на удалённом хосте.
Переопределение правила по умолчанию двумя новыми правилами (нажмите для раскрытия)
- hosts: serverXYZ
vars:
nft_input_host_rules:
050 icmp:
- ip protocol icmp ip saddr != 192.168.0.0/24 counter drop
- ip protocol icmp icmp type echo-request ip length <= 84 counter limit rate 10/minute accept
roles:
- role: ipr-cnrs.nftables
- Получите описание правила из файла
defaults/main.yml
(например,050 icmp
). - Отклоните любой ICMP-запрос, который не поступает из сети 192.168.0.0.
- Убедитесь, что размер запроса меньше или равен 84 байтам и установите ограничение на 10 запросов в минуту.
- Переменные nft_input_rules или nft_input_group_rules также могут быть использованы.
- Вес (
050
) позволяет упорядочивать все объединённые правила (из словарей nft_input_*rules). - Текст, следующий за весом (
icmp
), является небольшим описанием, которое будет добавлено в качестве комментария в файл nft_input_conf_path на удалённом хосте.
Переопределение некоторых правил по умолчанию (нажмите для раскрытия)
- hosts: serverXYZ
vars:
- nft_define:
input tcp accepted:
desc: Custom SSH port and torrent
name: in_tcp_accept
value: '{ 2201, 6881 }'
roles:
- role: ipr-cnrs.nftables
- Получите имя элемента (например,
input tcp accepted
) и имя переменной (например,in_tcp_accept
) из файлаdefaults/main.yml
. - Установите новое значение (например,
'{ 2201, 6881 }'
). - Вы можете добавить атрибут
desc
, который будет установлен в качестве комментария в файл nft_input_conf_path на удалённом хосте.
- Переменные nft_define_group или nft_define_host также могут быть использованы.
Переопределение всех правил по умолчанию (например, для исходящего трафика) (нажмите для раскрытия)
Если правила по умолчанию слишком разрешительные, если вы уже переопределили большинство из них,... В некоторых случаях, я полагаю, может быть интересно переопределить переменную по умолчанию:
- hosts: serverXYZ
vars:
nft_output_default_rules:
000 policy:
- type filter hook output priority 0; policy drop;
005 state management:
- ct state established,related accept
- ct state invalid drop
015 localhost:
- oif lo accept
050 my rule for XXX hosts and services:
- tcp dport 2000 ip saddr { xxx.xxx.xxx.xxx, yyy.yyy.yyy.yyy } ct state new accept
250 reset-ssh: # allow the host to reset SSH connections to avoid 10 min delay from Ansible controller
- tcp sport ssh tcp flags { rst, psh | ack } counter accept
roles:
- role: ipr-cnrs.nftables
- По крайней мере, не забудьте:
- установить политику по умолчанию.
- управлять уже установленным состоянием.
- принимать флаги
rst, psh | ack
для ssh, чтобы избежать 10-минутной задержки при первом запуске этой роли Nftables (смотрите #1).
- Затем добавьте свои собственные правила с нужными весами, чтобы упорядочить все объединенные правила (из словарей nft_output_*rules) и описания.
Удаление правила по умолчанию (нажмите для раскрытия)
- hosts: serverXYZ
vars:
nft_output_host_rules:
210 output tcp accepted:
-
roles:
- role: ipr-cnrs.nftables
- Получите описание правила из файла
defaults/main.yml
(210 output tcp accepted
). - Политика по умолчанию для исходящего трафика (drop) теперь будет применена к портам, определённым в переменной out_tcp_accept. Убедитесь, что вы делаете.
- Правило больше не будет присутствовать в результате
nft list ruleset
, только комментарий останется (210 output tcp accepted
) в файле nft_output_conf_path на удаленном хосте.
- Переменные nft_output_rules или nft_output_group_rules также могут быть использованы.
- Вес (
210
) позволяет упорядочивать все объединённые правила (из словарей nft_output_*rules).
С group_vars и host_vars
Использование правил по умолчанию и разрешение, для first_group, входящего ICMP и подсчёт как ICMP, так и пакетов политики по умолчанию (drop) (нажмите для раскрытия)
group_vars/first_group
:
nft_input_group_rules:
020 icmp:
- ip protocol icmp icmp type echo-request ip length <= 84 counter limit rate 1/minute accept
999 count policy packet:
- counter
Использование объединённых групповых правил из нескольких групп ansible (нажмите для раскрытия)
- Включить возможность объединения переменных группы:
- hosts: serverXYZ vars: nft_merged_groups: true nft_merged_groups_dir: vars/ roles: - role: ipr-cnrs.nftables
- Поместите дополнительные правила в папку "vars", названную в честь групп ansible для serverXYZ:
vars/first_group
:nft_input_group_rules: 020 icmp: - ip protocol icmp icmp type echo-request ip length <= 84 counter limit rate 1/minute accept 999 count policy packet: - counter
vars/second_group
:nft_input_group_rules: 021 LAN: - iif eth0 accept
- Эти наборы правил из двух групп будут объединены, если хост является членом этих групп.
Конфигурация
Эта роль будет:
- Устанавливать
nftables
на систему. - По умолчанию активировать службу
nftables
при старте. - Генерировать файл конфигурации по умолчанию, который включает все последующие файлы и загружается юнитом systemd.
- Генерировать файлы правил входа и выхода, которые включаются в основной конфигурационный файл.
- Генерировать переменные в одном файле и наборы и карты в другом файле.
- Обеспечивать, чтобы
nftables
запускался и включался при загрузке. - (пере)Запускать службу
nftables
при первом запуске или при изменении системных юнитов. - Перезагружать службу
nftables
при следующих запусках, чтобы избежать ситуации, когда хост остаётся без правил брандмауэра из-за неверного синтаксиса.
Интеграция с Fail2ban
Перед Debian Bullseye, юнит systemd для Fail2ban не имел адекватной интеграции с Nftables. Эта роль создаст файл переопределения для юнита fail2ban
, если nft_fail2ban_service_override
не установлен в значение false
. По умолчанию он добавляется, даже если он (ещё) не доступен на хосте. Это обеспечивает:
- Юнит
fail2ban
запускается после юнитаnftables
. - Юнит
fail2ban
перезапускается, когда юнитnftables
перезапускается.
Разработка
Этот исходный код поступает из нашего экземпляра Gitea, а репозиторий Github существует только для возможности отправки роли в Ansible Galaxy…
Но не стесняйтесь отправлять проблемы/PR сюда :)
Спасибо этому хуку, Github автоматически получает обновления от нашего экземпляра Gitea :)
Лицензия
Информация об авторе
Жérémy Gardais
- IPR (Institut de Physique de Rennes)
ansible-galaxy install ipr-cnrs/nftables