Сейчас в большинстве популярных дистрибутивов на базе Linux в качестве файрвола по умолчанию используется nftables. Конкретно в Debian начиная с Debian 10 Buster. Пришло время разобраться с его базовой настройкой и использованием.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Введение
Я обычно делаю вот так в нём:
# apt remove --auto-remove nftables # apt purge nftables # apt update # apt install iptables
Но это не может продолжаться вечно. Для какого-нибудь одиночного сервера эти действия просто не нужны. Проще сразу настроить nftables. К тому же у него есть и явные преимущества, про которые я знаю:
- единый конфиг для ipv4 и ipv6;
- более короткий и наглядный синтаксис;
- nftables умеет быстро работать с огромными списками, не нужен ipset;
- экспорт правил в json, удобно для мониторинга.
Я точно помню, что когда-то писал набор стандартных правил для nftables, но благополучно его потерял. Пришлось заново составлять, поэтому и пишу сразу заметку, чтобы не потерять ещё раз. Правила будут для условного веб сервера, где разрешены на вход все соединения на 80 и 443 порты, на порт 10050 zabbix агента разрешены только с zabbix сервера, а на 22-й порт SSH только для списка IP адресов. Всё остальное закрыто на вход. Исходящие соединения сервера разрешены.
Основные команды nftables
Начну с базы, нужной для управления правилами. Смотрим существующий список правил и таблиц:
# nft -a list ruleset # nft list tables
Очистка правил nftables:
# nft flush ruleset
Набор правил nftables для веб сервера
Дальше сразу привожу готовый набор правил. Отдельно отмечу, что в nftables привычные таблицы и цепочки нужно создать отдельно. В iptables они были по умолчанию.
nft add table inet filter nft add chain inet filter input { type filter hook input priority 0\; } nft add rule inet filter input ct state related,established counter accept nft add rule inet filter input iifname "lo" counter accept nft add rule inet filter input ip protocol icmp counter accept nft add rule inet filter input tcp dport {80, 443} counter accept nft add rule inet filter input ip saddr { 192.168.100.0/24, 172.20.0.0/24, 1.1.1.1/32 } tcp dport 22 counter accept nft add rule inet filter input ip saddr 2.2.2.2/32 tcp dport 10050 counter accept nft chain inet filter input { policy drop \; }
Вот и всё, настроили базовый набор правил. Мы создали таблицу filter, добавили цепочку input, закинули туда нужные нам разрешающие правила и в конце изменили политику по умолчанию на drop. Так как никаких других правил нам сейчас не надо, остальные таблицы и цепочки можно не создавать. Осталось только сохранить эти правила и применить их после загрузки сервера.
Автозагрузка правил при запуске сервера
У nftables есть служба, которая при запуске читает файл конфигурации /etc/nftables.conf и применяет правила. Запишем туда наш набор правил для автоматического применения после перезагрузки. Так как мы перезапишем существующую конфигурацию, где в начале стоит очистка всех правил, нам надо отдельно добавить её туда:
# echo "flush ruleset" > /etc/nftables.conf # nft -s list ruleset >> /etc/nftables.conf # systemctl enable nftables.service
Можно перезагружаться и проверять автозагрузку правил nftables.
Ещё полезная команда, которая пригодится в процессе настройки. Удаление правила по номеру:
# nft delete rule inet filter input handle 9
Добавление правила nftables в конкретное место с номером в списке:
# nft add rule inet filter input position 8 tcp dport 22 counter accept
В целом, ничего сложного. Подобным образом настраиваются остальные цепочки output или forward, если нужно. Синтаксис удобнее, чем у iptables. Как-то более наглядно и логично, особенно со списками ip адресов и портов, если они небольшие.
Единственное, что не нашёл пока как делать - как подгружать очень большие списки с ip адресами. Вываливать их в список правил - плохая идея. Надо как-то подключать извне. По идее это описано в sets, но я пока не разбирался.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Добрый день. Я любитель. Хочу арендовать VPS под Debian. Стал разбираться с настройкой firewall. Так как нет уверенных знаний ни в iptables ни в nftables смотрю и туда и сюда. По iptables больше примеров, нашел ваш скрипт. Решил попробовать "перевести" его в nftables с помощью ChatGPT. Оценить правильность не могу, но может Вам будет интересно глянуть :) . Привожу его ниже:
#!/bin/bash
# Внешний интерфейс
export WAN=eth0
export WAN_IP=85.31.203.127
# Локальная сеть
export LAN1=eth1
export LAN1_IP_RANGE=10.1.3.0/24
# Очищаем правила
nft flush ruleset
# Создаем таблицы и цепочки
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
nft add chain inet filter output { type filter hook output priority 0 \; policy drop \; }
nft add table ip nat
nft add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
# Разрешаем localhost и локалку
nft add rule inet filter input iifname lo accept
nft add rule inet filter input iifname $LAN1 accept
nft add rule inet filter output oifname lo accept
nft add rule inet filter output oifname $LAN1 accept
# Разрешаем пинги
nft add rule inet filter input ip protocol icmp icmp type echo-reply accept
nft add rule inet filter input ip protocol icmp icmp type destination-unreachable accept
nft add rule inet filter input ip protocol icmp icmp type time-exceeded accept
nft add rule inet filter input ip protocol icmp icmp type echo-request accept
# Разрешаем исходящие подключения сервера
nft add rule inet filter output oifname $WAN accept
# nft add rule inet filter input iifname $WAN accept
# Разрешаем установленные подключения
nft add rule inet filter input ct state established,related accept
nft add rule inet filter output ct state established,related accept
nft add rule inet filter forward ct state established,related accept
# Отбрасываем неопознанные пакеты
nft add rule inet filter input ct state invalid drop
nft add rule inet filter forward ct state invalid drop
# Отбрасываем нулевые пакеты
nft add rule inet filter input tcp flags == syn && tcp flags == ack drop
# Закрываемся от syn-flood атак
nft add rule inet filter input tcp flags & (syn|ack|fin|rst) == syn limit rate 5/second accept
# Блокируем доступ с указанных адресов
# nft add rule inet filter input ip saddr 84.122.21.197 reject
# Пробрасываем порт в локалку
# nft add rule ip nat prerouting tcp dport 23543 iifname $WAN dnat to 10.1.3.50:3389
# nft add rule inet filter forward iifname $WAN oifname $LAN1 accept
# Разрешаем доступ из локалки наружу
nft add rule inet filter forward iifname $LAN1 oifname $WAN accept
# Закрываем доступ снаружи в локалку
nft add rule inet filter forward iifname $WAN oifname $LAN1 reject
# Включаем NAT
nft add rule ip nat postrouting oifname $WAN ip saddr $LAN1_IP_RANGE masquerade
# Открываем доступ к SSH
nft add rule inet filter input iifname $WAN tcp dport 22 accept
# Открываем доступ к почтовому серверу
nft add rule inet filter input tcp dport {25, 465, 110, 995, 143, 993} accept
# Открываем доступ к web серверу
nft add rule inet filter input tcp dport {80, 443} accept
# Открываем доступ к DNS серверу
# nft add rule inet filter input iifname $WAN udp dport 53 accept
# Включаем логирование
# nft add chain inet filter block_in
# nft add chain inet filter block_out
# nft add chain inet filter block_fw
# nft add rule inet filter input log prefix "--IN--BLOCK" level info
# nft add rule inet filter input drop
# nft add rule inet filter output log prefix "--OUT--BLOCK" level info
# nft add rule inet filter output drop
# nft add rule inet filter forward log prefix "--FW--BLOCK" level info
# nft add rule inet filter forward drop
# Сохраняем правила
nft list ruleset > /etc/nftables.conf
Он работает в итоге? Вы пробовали его? Я не работаю постоянно с nftables, на глаз не могу определить корректность синтаксиса.
Нет, не пробывал :) Я только разбираюсь, мне еще сложнее сказать :)
На тестовой виртуалке проверить - дело 5 минут. Даже быстрее, чем сюда скопировать и написать комментарий. Либо заработает, либо нет. Одно из двух :)
Это хорошо, когда она есть :) Я только начал изучать администрирование :)
Спасибо за статью, все руки не доходили 😅
По поводу множества IP подсунуть у них в документации есть пример с GeoIP.
Я так понял через "include" делается.
https://wiki.nftables.org/wiki-nftables/index.php/GeoIP_matching
Да, всё верно. Я тоже смотрел уже.