Немного прелюдии о том, как я перешёл на nftables описано -> в этом посте <-, в связи с чем, повторяться не стану и перейду сразу к конфигурации.
Опишем необходимый конфиг для базовый защиты
На момент написания статьи, nftables предустановлен в нашем всеми любимом Debian’е аж с 2014 года, но так как подавляющее большинство лодырей эникеев не торопятся переводить свои дырявые файерволы на пацанский nft, сам сервис, в системе, по дефолту, не стартован и тем более не в автозапуске. Поэтому исправим это
systemctl enable --now nftables
Сами правила располагаются по пути /etc/nftables.conf и редактировать его можно любым удобным текстовым редактором, но мы же не ищем лёгких путей, поэтому будем добавлять правило в консоли. С таким подходом, правило начинает работать мгновенно
После старта и запуска у нас появляются необходимые и полностью пустые цепочки в одной таблице filter, разрешающие абсолютно всё
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
}
chain forward {
type filter hook forward priority 0;
}
chain output {
type filter hook output priority 0;
}
}
Добавим правило, которое будет разрешать уже установленные и связанные с существующим соединения
nft insert rule inet filter input ct state established,related counter accept
Разберём что мы тут наебенили:
nft insert rule - добавит правило в самый верх
inet - семейство протоколов
filter - таблица
input - цепочка
ct state - состояние
established,related - установленные и связанные с существующим соединения
counter - счётчик. Полезно для отладки. Рекомендую всегда добавлять
accept - само правило
Далее запретим всё непонятное, фрагментированное, с левыми флагами, повреждёнными заголовками и прочей аномалией
nft add rule inet filter input ct state invalid counter drop
Отлично! Если у нас это программный маршрутизатор, реализации которых я очень уважаю, в отличии от всяких залупных брендов типа микротиков, цисок, хуавеев и пр, то аналогичные правила необходимо добавить и в цепочку forward
nft insert rule inet filter forward ct state established,related counter accept nft add rule inet filter forward ct state invalid counter drop
Далее разрешим все входящие на интерфейсе loopback
nft add rule inet filter input iif 1 accept
Тут можно заметить некую хитрость. Во-первых рекомендую загуглить разницу между iif и iifname, а во-вторых поясню. В Linux-системах, сетевые интерфейсы, идентифицируются как ключ = значение. Сетевой интерфейс lo всегда имеет первый ключ. Предлагаю проверить это прямо сейчас командой ip a. Можно конечно заменить iif 1 на iifname "lo", но я предпочитаю упарываться 😅 Таким образом мы избавим систему подставлять имена к идентификаторам и выиграем в производительности примерно 0,00001% 🤓
Улыбнулись? Поехали дальше! Разрешим пинги, но...
...но стандартный пинг в windows = 32 байта, а в linux = 64 байта. Возможная корректная длина заголовка ICMP пакета = 29 байт. Почему именно так? За ответами welcome to модель OSI, а сейчас просто доверимся мне 😎
Исходя из вышесказанного, добавим немного защиты от того же возможного DDoS. Максимум передаваемый пакет = 64 байта + заголовок 29 байт = 93 байта. Отлично! Запретим пропускать пинги, размером свыше 93 байта.
nft add rule inet filter input icmp type echo-request meta length 93-65535 counter drop
За ним разрешим пинг
nft add rule inet filter input meta l4proto icmp counter accept
Разрешим подключаться по SSH
nft add rule inet filter input tcp dport 22 accept
Ну и в самом конце отбрасываем всё к хуям и жукам майским
nft add rule inet filter input counter drop
Если после ввода последней команды у вас не отъебнул доступ, значит всё хорошо 😈
Готово! Минимально настроенный файер у нас готов! Дальше уже сами решайте что разрешать, а что запрещать
Для просмотра всех правил используем команду
nft list ruleset
Для просмотра идентификатора правила добавим --handle
nft --handle list ruleset