---
date: 2026-07-17
tags:
  - zapret
  - zapret2
  - nfqws2
  - filter
  - profile
  - l7
aliases:
  - Фильтры профиля
  - --filter
  - filter-l3
  - filter-l7
  - Типы фильтров
link: https://github.com/bol-van/zapret2/blob/master/docs/manual.md
---
# 🧯 Фильтры профиля в Zapret 2

> [!info] О чём заметка
> Что такое фильтры [[profile|профиля]] в [[Zapret2/Zapret2|Zapret 2]], как по ним выбирается, какой профиль будет обрабатывать пакет, и какие бывают фильтры: по версии IP, портам, ICMP, номеру IP-протокола, L7-протоколу, спискам IP/доменов, а также внутрипрофильные `dir`/`payload`. Не путать с начальными фильтрами захвата [[wf|WinDivert/nftables]] — те решают, какой трафик вообще попадёт в `nfqws2`, а эти — что с ним делать дальше. Где выбор профиля стоит в общем конвейере, см. [[схема обработки трафика]].

## TL;DR

- **Профиль** = набор фильтров (кому он адресован) + действия ([[desync|`--lua-desync`]]). Профили разделяются флагом `--new`.
- Пакет проверяется по профилям **строго по порядку, сверху вниз**; при первом совпадении фильтров выбирается этот профиль, поиск прекращается. Не подошёл никто — берётся скрытый профиль по умолчанию `no_action` (ничего не делает; подробнее — [[exclusions]]).
- Внутри одного профиля все фильтры работают по логике **И** (пакет должен пройти все).
- Фильтры: `--filter-l3` (версия IP), `--filter-tcp`/`--filter-udp` (порты), `--filter-icmp` (тип/код), `--filter-ipp` (номер IP-протокола), `--filter-l7` (протокол потока), плюс списки [[ipset]] и [[hostlist]].
- Почти все фильтры принимают **несколько значений через запятую**, а `~` означает инверсию.

---

## Что такое фильтр профиля

[[profile|Профиль]] в Zapret 2 состоит из двух половин: **фильтры** — кому этот профиль адресован, и **действия** ([[desync|`--lua-desync`]]-инстансы) — что делать с подошедшими пакетами. Фильтры отвечают на вопрос «этот пакет — мой?».

> [!warning] Это не фильтры захвата WinDivert/nftables
> Есть два разных уровня отбора. Сначала [[wf|фильтр захвата]] (`--wf-*` на Windows, правила nftables/iptables на Linux) решает, какие пакеты вообще «завернуть» из ядра в `nfqws2` — это грубое сито ради экономии. И только потом фильтры профиля (эта заметка) выбирают, какой именно профиль и стратегия обработают уже захваченный пакет. Если пакет не прошёл фильтр захвата, до профилей он даже не дойдёт.

## Как выбирается профиль

Профили в командной строке разделяются флагом `--new`. Порядок принципиален:

1. Пакет проверяется по профилям **сверху вниз**, от первого к последнему.
2. При **первом** же совпадении всех фильтров профиля выбирается этот профиль, и дальнейший поиск прекращается.
3. Если не подошёл ни один профиль — применяется **скрытый профиль по умолчанию** `no_action` (служебный номер 0): движок сам дописывает его последним в список при запуске, действий в нём нет, поэтому с пакетом ничего не происходит (подробнее о нём — в [[exclusions|заметке об исключениях]]).

Внутри одного профиля несколько разных фильтров объединяются логикой **И**: пакет должен удовлетворить их всем одновременно (например, `--filter-tcp=443` **и** `--filter-l7=tls`). А вот несколько значений внутри одного фильтра — это логика **ИЛИ** (`--filter-tcp=80,443` — порт 80 или 443).

> [!note] Выбранный профиль кэшируется
> Чтобы не искать профиль заново на каждый пакет, `nfqws2` запоминает выбор в записи потока (conntrack). Пересмотр возможен максимум дважды за поток — при распознавании L7-протокола и при обнаружении имени хоста (подробнее — [[схема обработки трафика]]).

---

## Фильтры профиля

Ниже — все фильтры выбора профиля. Почти все принимают список значений через запятую и поддерживают инверсию (`~` перед значением — «всё, кроме»), а `*` означает «любое».

| Фильтр | Что отбирает | Синтаксис |
|:-------|:-------------|:----------|
| `--filter-l3` | версия IP-протокола | `ipv4` или `ipv6` (можно оба через запятую) |
| `--filter-tcp` | порты TCP | `[~]port[-port]` или `*`, через запятую |
| `--filter-udp` | порты UDP | `[~]port[-port]` или `*`, через запятую |
| `--filter-icmp` | тип и код ICMP | `type[:code]` или `*`, через запятую |
| `--filter-ipp` | номер «сырого» IP-протокола | `proto` или `*`, через запятую |
| `--filter-l7` | протокол потока (L6/L7) | `proto[,proto,…]` |
| `--filter-ssid` | имя Wi-Fi-сети (не на всех платформах) | `ssid[,ssid,…]` |

### `--filter-l3` — версия IP

Отбирает пакеты по версии IP-протокола.

```bash
--filter-l3=ipv4           # только IPv4
--filter-l3=ipv6           # только IPv6
--filter-l3=ipv4,ipv6      # оба (эквивалент «не фильтровать по версии»)
```

### `--filter-tcp` и `--filter-udp` — порты

Отбирают по TCP- или UDP-портам. Фильтруется и порт источника, и порт назначения. Поддерживаются: одиночный порт, диапазон `port1-port2`, инверсия `~port`, и `*` (все порты). Несколько значений — через запятую.

```bash
--filter-tcp=80,443        # порт 80 или 443
--filter-tcp=1000-2000     # диапазон 1000–2000
--filter-tcp=~443          # все TCP-порты, КРОМЕ 443
--filter-tcp=*             # все TCP-порты
--filter-udp=443           # QUIC (UDP/443)
```

> [!important] Указание только TCP отключает UDP (и наоборот)
> Если в профиле задан `--filter-tcp`, но нет `--filter-udp`, то UDP этим профилем не обрабатывается вовсе (и симметрично наоборот). Чтобы профиль работал с обоими транспортами, укажите оба фильтра (при необходимости с `*`).

### `--filter-icmp` — тип и код ICMP

Отбирает ICMP-пакеты по типу и, опционально, коду: формат `type[:code]`. Если код не указан — подходит **любой** код этого типа. Значения — через запятую, `*` — любой ICMP.

```bash
--filter-icmp=3            # ICMP type 3 (destination unreachable), любой code
--filter-icmp=3:4,11       # type 3 code 4, или type 11 (любой code)
--filter-icmp=*            # любой ICMP
```

### `--filter-ipp` — номер IP-протокола (raw IP)

Отбирает пакеты по номеру IP-протокола для «сырых» протоколов, которые не являются TCP/UDP/ICMP (см. про raw IP в [[структура desync и диссекта]]). Значения — номера протоколов через запятую или `*`.

```bash
--filter-ipp=47            # GRE (протокол 47)
--filter-ipp=50,51         # ESP и AH (IPsec)
--filter-ipp=*             # любой raw IP-протокол
```

### `--filter-l7` — протокол потока

Отбирает по **протоколу потока** — ярлыку, который `nfqws2` вешает на всё соединение, распознав его сигнатурно (`http`, `tls`, `quic`, `wireguard`, `mtproto`, `dns`, `stun`, `discord`, `dht`, `xmpp`, `dtls`, `bt`, `utp_bt`). Плюс спецзначения: `all` — любой, `known` — любой распознанный (не `empty`/`unknown`), `unknown` — нераспознанный.

```bash
--filter-l7=tls            # только TLS/HTTPS
--filter-l7=tls,http       # TLS или HTTP
--filter-l7=quic           # только QUIC (HTTP/3)
--filter-l7=known          # любой распознанный протокол
```

> [!note] Протокол потока vs тип payload
> `--filter-l7` смотрит на протокол **всего соединения**, а не на тип отдельного пакета. Разница между «протоколом потока» и «типом payload конкретного пакета», полная таблица распознаваемых протоколов и особые ICMP-типы (`ipv4`/`ipv6`/`icmp`) подробно разобраны в [[payload]] — чтобы не дублировать, здесь только суть.

### `--filter-ssid` — Wi-Fi-сеть

Ограничивает профиль конкретными Wi-Fi-сетями по их SSID (доступно не на всех платформах). Список — через запятую.

```bash
--filter-ssid=MyHomeWiFi,OfficeNetwork
```

---

## Списки IP и доменов

Кроме фильтров по заголовкам, профиль отбирают по спискам адресов и доменов — [[ipset]] (списки IP) и [[hostlist]] (списки доменов). У обоих есть исключающие варианты `--hostlist-exclude`/`--ipset-exclude` («профиль срабатывает для всех, кроме…») — именно на них строятся [[exclusions|исключения]] в пресетах. Полное описание списков встроено ниже.

![[ipset]]

![[hostlist]]

---

## Внутрипрофильные фильтры инстанса: `dir` и `payload`

Кроме фильтров выбора профиля, есть более тонкие фильтры **внутри** профиля — они ограничивают не весь профиль, а отдельные [[desync|`--lua-desync`]]-инстансы. Их можно задавать сколько угодно, и после определения они действуют на все последующие инстансы до переопределения. Главный смысл — отсеять лишнее на быстрой стороне C-кода, не доходя до вызова Lua.

**`dir` — направление пакета.** Строка `in`, `out` или `any` (по умолчанию `out`). На стороне Lua её проверяют функции `direction_check` (соответствует ли направление фильтру) и `direction_cutoff_opposite` (отключить инстанс от противоположного направления). Так, `dir=out` — только исходящие (от клиента к серверу), `dir=in` — только входящие, `dir=any` — оба.

**`payload` — тип содержимого пакета.** Список типов payload через запятую (со спецзначениями `all`/`known` и инверсией `~`), проверяется функциями `payload_match_filter`/`payload_check`. Это тот же механизм, что и профильный `--payload`, но на уровне отдельного инстанса. Полный разбор типов payload и их фильтрации — в [[payload]] (там же — почему по умолчанию `known`).

```bash
# оба фильтра действуют на идущий следом инстанс
--payload=tls_client_hello --lua-desync=fake:blob=fake_default_tls:dir=out
```

> [!note] Диапазонные фильтры in/out-range
> Есть и третий вид внутрипрофильных фильтров — `--in-range`/`--out-range`, отбирающие пакеты по их позиции в потоке (какие по счёту). Они разобраны в отдельной заметке [[out-range]].

---

## Комбинированные примеры

### Базовая фильтрация HTTP/HTTPS

```bash
nfqws2 \
  --filter-tcp=80,443 \
  --filter-l7=http,tls \
  --lua-desync=fake:blob=fake_default_tls
```

### QUIC с hostlist

```bash
nfqws2 \
  --filter-udp=443 \
  --filter-l7=quic \
  --hostlist=/path/to/youtube.txt \
  --lua-desync=fake:blob=fake_default_quic:repeats=6
```

### Мультипрофиль: разные фильтры → разные стратегии

```bash
nfqws2 \
  --filter-tcp=80 --filter-l7=http \
  --hostlist=/path/to/list1.txt \
  --lua-desync=multisplit \
  --new \
  --filter-tcp=443 --filter-l7=tls \
  --hostlist-exclude=/path/to/exclude.txt \
  --lua-desync=fake:blob=fake_default_tls \
  --new \
  --filter-udp=443 --filter-l7=quic \
  --lua-desync=fake:blob=fake_default_quic
```

### IP-фильтрация через ipset

```bash
nfqws2 \
  --filter-tcp=443 \
  --ipset=/path/to/blocked_ips.txt \
  --ipset-exclude-ip=192.168.0.0/16,10.0.0.0/8 \
  --lua-desync=fake:blob=fake_default_tls
```

---

## Важные особенности

1. **Порядок профилей решает всё** — выбирается первый совпавший сверху; более узкие профили ставьте выше более общих.
2. **Внутри профиля — логика И**, несколько значений одного фильтра — логика ИЛИ.
3. **TCP/UDP взаимоисключение** — указание только TCP-фильтра отключает UDP, и наоборот.
4. **Инверсия `~` и `*`** поддерживаются в портовых и большинстве фильтров.
5. **Поддомены в hostlist включаются автоматически** (см. [[hostlist]]).
6. **Несколько файлов** `--ipset`/`--hostlist` допустимы; файлы могут быть сжаты gzip.
7. **Каждый профиль (`--new`) имеет свои фильтры** — они не наследуются между профилями.

---

## 📚 См. также

- [[profile|Профиль]] — блок, к которому относятся эти фильтры; как перебирать стратегии
- [[preset|Пресет]] — файл стратегии целиком (набор профилей)
- [[wf|Фильтры захвата WinDivert/nftables]] — грубое сито до профилей
- [[payload|Тип payload]] — полная таблица распознаваемых протоколов и разница «поток vs пакет»
- [[out-range|Диапазонные фильтры in/out-range]] — отбор по позиции пакета в потоке
- [[desync|Механизм --lua-desync]] — действия, которые фильтры адресуют
- [[схема обработки трафика|Схема обработки трафика]] — где выбор профиля стоит в конвейере
- [[ipset]] · [[hostlist]] — списки IP и доменов
- [[exclusions|Исключения]] — профиль `pass` и exclude-списки: два способа пустить трафик мимо дурения
- 🔗 [Официальная документация (docs/manual.md)](https://github.com/bol-van/zapret2/blob/master/docs/manual.md) — первоисточник

---

> [!quote] 🤖 Эти статьи открыты — можно обучать на них ИИ
> При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование и скачивание всего репозитория одним zip-архивом доступны в Forgejo: [исходник этой заметки](https://git.zapret.moe/zapretdiscordyoutube/todo/src/branch/main/Zapret2/filter.md) · [весь репозиторий](https://git.zapret.moe/zapretdiscordyoutube/todo/src/branch/main).
