# nftables: базовый набор правил

Индекс LLMS: [llms.txt](/llms.txt)

---

> [!NOTE]
> Все команды проверены на Debian/Ubuntu с пакетом `nftables` и на RHEL/CentOS 8+. На старых системах может потребоваться `apt install nftables` или `yum install nftables`.

nftables пришёл на смену iptables, но документация по базовому набору правил часто разрознена. Вот конспект, который использую сам, когда поднимаю файрволл на новой машине.

## Создание таблицы inet filter

Таблица семейства `inet` объединяет IPv4 и IPv6 в одном пространстве имён. Это предпочтительный подход, если на хосте оба стека активны.

```bash
nft add table inet filter
```

Если таблица уже существует, команда вернёт ошибку. Чтобы избежать дублирования при повторном запуске скрипта:

```bash
nft 'add table inet filter' 2>/dev/null || true
```

Для полного сброса текущего набора правил перед загрузкой своего набора:

```bash
nft flush ruleset
```

> [!WARNING]
> `flush ruleset` удаляет **все** правила мгновенно. На продакшен-машине выполняйте это только из консоли, не через удалённый сессию без fallback.

## Цепочки input и forward

Цепочки привязываются к таблице и определяют точку входа трафика. Для базового файрволла нужны `input` (трафик к самому хосту) и `forward` (проходящий через хост).

```bash
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 \; }
```

Ключевые части в фигурных скобках:

| Компонент | Значение |
|---|---|
| `type filter` | Тип цепочки, стандартный для фильтрации |
| `hook input` / `hook forward` | Точка перехвата в сетевом стеке |
| `priority 0` | Приоритет обработки |
| `policy drop` | Политика по умолчанию — отбрасывать |

Синтаксис требует экранирования точек с запятой внутри строки или использования одинарных кавычек, как показано выше.

> [!TIP]
> Если нужно разрешить установленные соединения, добавьте цепочку `output` с политикой `accept` или используйте коннект-трекинг в правилах `input`.

## Базовые правила для input

После создания цепочки с политикой `drop` нужно явно разрешить необходимый трафик. Типичный минимум:

```bash
# Разрешить loopback
nft add rule inet filter input iif lo accept

# Разрешить установленные и связанные соединения
nft add rule inet filter input ct state established,related accept

# Разрешить SSH (порт 22)
nft add rule inet filter input tcp dport 22 accept

# Разрешить ping (ICMP echo request)
nft add rule inet filter input ip protocol icmp icmp type echo-request accept
nft add rule inet filter input ip6 nexthdr icmpv6 icmpv6 type echo-request accept
```

Каждое правило добавляется в конец цепочки. Порядок важен: `accept` для loopback и established-трафика должен стоять раньше правил с более узкими критериями.

Для логирования отброшенных пакетов перед политикой `drop` (опционально, но полезно для диагностики):

```bash
nft add rule inet filter input log prefix "nft-drop: " level warn
```

> [!NOTE]
> Логирование добавляет накладные расходы. На высоконагруженных интерфейсах используйте лимиты: `limit rate 10/second`.

## Базовые правила для forward

Цепочка `forward` нужна, если хост работает как маршрутизатор или NAT-шлюз. Минимальный набор:

```bash
# Разрешить установленные соединения
nft add rule inet filter forward ct state established,related accept

# Разрешить forwarding между конкретными интерфейсами (пример)
nft add rule inet filter forward iifname "eth0" oifname "eth1" accept
```

Если хост не выполняет маршрутизацию, цепочку `forward` можно оставить с политикой `drop` без дополнительных правил.

Для включения IP-forwarding на уровне ядра (если ещё не сделано):

```bash
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1
```

## Просмотр и управление правилами

После настройки проверяем текущий набор:

```bash
nft list table inet filter
nft list chain inet filter input
nft list ruleset
```

`list ruleset` выводит полный конфиг, который можно сохранить и использовать как скрипт загрузки.

Удаление конкретного правила по номеру в цепочке:

```bash
nft delete rule inet filter input handle <handle-number>
```

Номер `handle` виден в выводе `nft list ruleset -a`.

Для удаления всей цепочки:

```bash
nft delete chain inet filter input
```

Цепочку можно удалить только если она пуста. Для полного удаления таблицы сначала удалите все цепочки внутри неё.

Сохранение правил в файл для загрузки при перезагрузке:

```bash
nft list ruleset > /etc/nftables.conf
```

На системах с systemd включите автозагрузку:

```bash
systemctl enable nftables
systemctl start nftables
```

> [!WARNING]
> Если `/etc/nftables.conf` не существует или пуст, сервис не загрузит правила. Создайте файл вручную перед включением сервиса.
