zapret2-mcp 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.1](https://github.com/rcd27/zapret2-mcp/compare/v0.7.0...v0.7.1) (2026-03-28)
4
+
5
+
6
+ ### Features
7
+
8
+ * **knowledge:** deep-wiki, как источник №1 ([5ed5d46](https://github.com/rcd27/zapret2-mcp/commit/5ed5d4637f2be2a5710f60bf8a54ab38eaaddb85))
9
+
10
+ ## [0.7.0](https://github.com/rcd27/zapret2-mcp/compare/v0.6.1...v0.7.0) (2026-03-28)
11
+
12
+
13
+ ### ⚠ BREAKING CHANGES
14
+
15
+ * **retrival:** техника чанков для retrieve логики, чтобы ИИ агенту не жечь токены
16
+
17
+ ### Features
18
+
19
+ * **retrival:** добавлен context для более точного ранжирования чанков ([568e10d](https://github.com/rcd27/zapret2-mcp/commit/568e10dcadf36ca24a4984988fc3398eb171c906))
20
+ * **retrival:** техника чанков для retrieve логики, чтобы ИИ агенту не жечь токены ([e00cd32](https://github.com/rcd27/zapret2-mcp/commit/e00cd32ec82d6dd7cd89c57246524d810d12edf6))
21
+
3
22
  ## [0.6.1](https://github.com/rcd27/zapret2-mcp/compare/v0.6.0...v0.6.1) (2026-03-28)
4
23
 
5
24
 
package/README.md CHANGED
@@ -2,24 +2,24 @@
2
2
 
3
3
  [![CI](https://github.com/rcd27/zapret2-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/rcd27/zapret2-mcp/actions/workflows/ci.yml)
4
4
  [![npm](https://img.shields.io/npm/v/zapret2-mcp)](https://www.npmjs.com/package/zapret2-mcp)
5
- [![Knowledge Base](https://img.shields.io/badge/knowledge_base-27_articles-green)](./knowledge/)
5
+ [![Knowledge Base](https://img.shields.io/badge/knowledge_base-32_articles-green)](./knowledge/)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
7
 
8
8
  База знаний по [zapret2](https://github.com/bol-van/zapret2) (DPI bypass) и [blockcheckw](https://github.com/rcd27/blockcheckw) (сканер стратегий). Работает как [MCP-сервер](https://modelcontextprotocol.io/) для LLM-агентов и как обычная документация.
9
9
 
10
- > **Можно использовать без агентов.** [`knowledge/`](./knowledge/) — 27 статей на русском языке. Открывайте и читайте как обычную документацию, без установки чего-либо.
10
+ > **Можно использовать без агентов.** [`knowledge/`](./knowledge/) — 32 статьи на русском языке. Открывайте и читайте как обычную документацию, без установки чего-либо.
11
11
 
12
12
  ## Что внутри
13
13
 
14
14
  | Раздел | Статей | Темы |
15
15
  |--------|--------|------|
16
- | [strategies/](./knowledge/strategies/) | 8 | TCP segmentation, fake packets, multidisorder, QUIC, circular, Discord, Telegram, orchestration |
17
- | [config/](./knowledge/config/) | 5 | nfqws2 CLI, zapret2 config, UCI, blobs, миграция v1 → v2 |
16
+ | [strategies/](./knowledge/strategies/) | 9 | TCP segmentation, fake packets, Lua scripting, QUIC, circular, Discord, Telegram, orchestration |
17
+ | [config/](./knowledge/config/) | 9 | nfqws2 CLI, zapret2 config, desync profiles, hostlists/ipsets, auto-hostlist, security hardening, UCI, blobs, миграция v1 → v2 |
18
18
  | [troubleshooting/](./knowledge/troubleshooting/) | 5 | Smart TV + YouTube, QUIC, IPv6, FLOWOFFLOAD, конфликты с Podkop |
19
19
  | [tspu/](./knowledge/tspu/) | 4 | Архитектура ТСПУ, DPI engine, методы блокировки, двухстадийная система |
20
20
  | [workflows/](./knowledge/workflows/) | 2 | Установка, поиск стратегии |
21
21
  | [blockcheckw/](./knowledge/blockcheckw/) | 2 | Overview, команды |
22
- | [platforms/](./knowledge/platforms/) | 1 | Поддерживаемые платформы |
22
+ | [platforms/](./knowledge/platforms/) | 1 | Linux, OpenWrt, Windows, FreeBSD, OpenBSD, Android |
23
23
 
24
24
  ## Подключение к LLM-агенту
25
25
 
@@ -90,6 +90,7 @@ npm start
90
90
 
91
91
  ## Источники
92
92
 
93
+ - [deepwiki/zapret2](https://deepwiki.com/bol-van/zapret2) — AI-сгенерированная документация из исходного кода (приоритетный источник)
93
94
  - [zapret2](https://github.com/bol-van/zapret2) — DPI bypass от bol-van
94
95
  - [blockcheckw](https://github.com/rcd27/blockcheckw) — быстрый сканер стратегий
95
96
  - [tspu-docs](https://github.com/DanielLavrushin/tspu-docs) — документация ТСПУ
package/build/index.js CHANGED
@@ -29,9 +29,11 @@ This server does NOT execute commands — it provides knowledge and guidance. Th
29
29
  });
30
30
  server.tool("query-zapret-knowledge", "Search zapret2 and blockcheckw knowledge base by topic. Returns relevant documentation, strategy guides, configuration references, and troubleshooting information.", {
31
31
  topic: z.string().describe("What to search for (e.g. 'split2 strategy', 'blockcheckw scan', 'troubleshooting dns', 'config nfqws2_opt')"),
32
- tokens: z.number().optional().describe("Maximum approximate token count for the response (default: no limit)"),
32
+ tokens: z.number().optional().describe("Maximum approximate token count for the response (default: 4000). Use 0 for unlimited."),
33
+ context: z.string().optional().describe("What you already know or checked (e.g. 'curl OK on router, QUIC disabled, flow_offloading_hw=1'). Helps narrow results by deprioritizing already-covered topics."),
33
34
  }, async (args) => {
34
- const results = index.query(args.topic, args.tokens);
35
+ const tokenLimit = args.tokens === 0 ? undefined : (args.tokens ?? 4000);
36
+ const results = index.query(args.topic, tokenLimit, args.context);
35
37
  if (results.length === 0) {
36
38
  return {
37
39
  content: [
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -15,11 +15,24 @@ export interface KnowledgeEntry {
15
15
  export declare class KnowledgeIndex {
16
16
  private knowledgeDir;
17
17
  private entries;
18
+ private chunks;
18
19
  constructor(knowledgeDir: string);
19
20
  rebuild(): void;
20
- /** Keyword-based search. Returns entries ranked by relevance. */
21
- query(topic: string, maxTokens?: number): KnowledgeEntry[];
21
+ /**
22
+ * Keyword-based search with chunk-level retrieval, intent detection, and context narrowing.
23
+ * @param context - what the agent already knows/checked (used to deprioritize already-covered topics)
24
+ */
25
+ query(topic: string, maxTokens?: number, context?: string): KnowledgeEntry[];
22
26
  /** Get all entries (for listing) */
23
27
  all(): KnowledgeEntry[];
28
+ private assembleResults;
29
+ private detectIntent;
30
+ /**
31
+ * Adjust score based on context (what agent already knows).
32
+ * Chunks heavily overlapping with context get deprioritized.
33
+ * Chunks that add NEW information relative to context get boosted.
34
+ */
35
+ private contextAdjust;
36
+ private intentBoost;
24
37
  private tokenize;
25
38
  }
package/build/indexer.js CHANGED
@@ -27,50 +27,107 @@ function collectMarkdownFiles(dir) {
27
27
  }
28
28
  return files;
29
29
  }
30
+ function splitIntoChunks(entry) {
31
+ const chunks = [];
32
+ const lines = entry.content.split("\n");
33
+ let currentSection = "";
34
+ let currentLines = [];
35
+ let order = 0;
36
+ const flush = () => {
37
+ const content = currentLines.join("\n").trim();
38
+ if (content) {
39
+ chunks.push({
40
+ docPath: entry.path,
41
+ docTitle: entry.title,
42
+ docTags: entry.tags,
43
+ zapret2Version: entry.zapret2Version,
44
+ blockcheckwVersion: entry.blockcheckwVersion,
45
+ sectionTitle: currentSection,
46
+ content,
47
+ order: order++,
48
+ });
49
+ }
50
+ };
51
+ for (const line of lines) {
52
+ if (line.startsWith("## ")) {
53
+ flush();
54
+ currentSection = line.slice(3).trim();
55
+ currentLines = [];
56
+ }
57
+ else {
58
+ currentLines.push(line);
59
+ }
60
+ }
61
+ flush();
62
+ if (chunks.length > 0)
63
+ return chunks;
64
+ return [{
65
+ docPath: entry.path,
66
+ docTitle: entry.title,
67
+ docTags: entry.tags,
68
+ zapret2Version: entry.zapret2Version,
69
+ blockcheckwVersion: entry.blockcheckwVersion,
70
+ sectionTitle: "",
71
+ content: entry.content,
72
+ order: 0,
73
+ }];
74
+ }
30
75
  export class KnowledgeIndex {
31
76
  knowledgeDir;
32
77
  entries = [];
78
+ chunks = [];
33
79
  constructor(knowledgeDir) {
34
80
  this.knowledgeDir = knowledgeDir;
35
81
  this.rebuild();
36
82
  }
37
83
  rebuild() {
38
84
  this.entries = [];
85
+ this.chunks = [];
39
86
  const files = collectMarkdownFiles(this.knowledgeDir);
40
87
  for (const file of files) {
41
88
  const raw = readFileSync(file, "utf-8");
42
89
  const { meta, content } = parseFrontmatter(raw);
43
- this.entries.push({
90
+ const entry = {
44
91
  path: relative(this.knowledgeDir, file),
45
92
  title: meta.title ?? file,
46
93
  tags: (meta.tags ?? "").split(",").map((t) => t.trim()).filter(Boolean),
47
94
  content: content.trim(),
48
95
  zapret2Version: meta["zapret2-version"],
49
96
  blockcheckwVersion: meta["blockcheckw-version"],
50
- });
97
+ };
98
+ this.entries.push(entry);
99
+ this.chunks.push(...splitIntoChunks(entry));
51
100
  }
52
101
  }
53
- /** Keyword-based search. Returns entries ranked by relevance. */
54
- query(topic, maxTokens) {
102
+ /**
103
+ * Keyword-based search with chunk-level retrieval, intent detection, and context narrowing.
104
+ * @param context - what the agent already knows/checked (used to deprioritize already-covered topics)
105
+ */
106
+ query(topic, maxTokens, context) {
55
107
  const keywords = this.tokenize(topic);
56
108
  if (keywords.length === 0)
57
109
  return this.entries;
58
- const scored = [];
59
- for (const entry of this.entries) {
110
+ const intent = this.detectIntent(keywords);
111
+ const contextKeywords = context ? this.tokenize(context) : [];
112
+ const scoredChunks = [];
113
+ for (const chunk of this.chunks) {
60
114
  let score = 0;
61
115
  for (const keyword of keywords) {
62
116
  const kw = keyword.toLowerCase();
63
- // Title match (highest weight)
64
- if (entry.title.toLowerCase().includes(kw))
117
+ // Document title match (highest weight)
118
+ if (chunk.docTitle.toLowerCase().includes(kw))
65
119
  score += 10;
66
- // Tag exact match (high weight)
67
- if (entry.tags.some((t) => t.toLowerCase() === kw))
120
+ // Section title match
121
+ if (chunk.sectionTitle.toLowerCase().includes(kw))
122
+ score += 8;
123
+ // Tag exact match
124
+ if (chunk.docTags.some((t) => t.toLowerCase() === kw))
68
125
  score += 8;
69
126
  // Tag partial match
70
- if (entry.tags.some((t) => t.toLowerCase().includes(kw)))
127
+ if (chunk.docTags.some((t) => t.toLowerCase().includes(kw)))
71
128
  score += 4;
72
129
  // Content match (count occurrences, capped)
73
- const contentLower = entry.content.toLowerCase();
130
+ const contentLower = chunk.content.toLowerCase();
74
131
  let idx = 0;
75
132
  let count = 0;
76
133
  while ((idx = contentLower.indexOf(kw, idx)) !== -1) {
@@ -79,29 +136,130 @@ export class KnowledgeIndex {
79
136
  }
80
137
  score += Math.min(count, 5) * 2;
81
138
  }
139
+ // Intent boost
140
+ score += this.intentBoost(chunk.docPath, intent);
141
+ // Context narrowing: deprioritize chunks that cover already-known topics
142
+ if (contextKeywords.length > 0) {
143
+ score += this.contextAdjust(chunk, contextKeywords);
144
+ }
82
145
  if (score > 0) {
83
- scored.push({ entry, score });
146
+ scoredChunks.push({ chunk, score });
84
147
  }
85
148
  }
86
- scored.sort((a, b) => b.score - a.score);
87
- if (!maxTokens)
88
- return scored.map((s) => s.entry);
89
- // Approximate token limit (1 token ≈ 4 chars)
90
- const charLimit = maxTokens * 4;
149
+ scoredChunks.sort((a, b) => b.score - a.score);
150
+ return this.assembleResults(scoredChunks, maxTokens);
151
+ }
152
+ /** Get all entries (for listing) */
153
+ all() {
154
+ return this.entries;
155
+ }
156
+ assembleResults(scoredChunks, maxTokens) {
157
+ const docOrder = [];
158
+ const docChunks = new Map();
159
+ for (const { chunk } of scoredChunks) {
160
+ const existing = docChunks.get(chunk.docPath);
161
+ if (existing) {
162
+ if (!existing.some((c) => c.order === chunk.order)) {
163
+ existing.push(chunk);
164
+ }
165
+ }
166
+ else {
167
+ docOrder.push(chunk.docPath);
168
+ docChunks.set(chunk.docPath, [chunk]);
169
+ }
170
+ }
171
+ const charLimit = maxTokens ? maxTokens * 4 : undefined;
91
172
  let totalChars = 0;
92
173
  const result = [];
93
- for (const { entry } of scored) {
174
+ for (const path of docOrder) {
175
+ const chunks = docChunks.get(path);
176
+ const parent = this.entries.find((e) => e.path === path);
177
+ const assembledContent = chunks
178
+ .sort((a, b) => a.order - b.order)
179
+ .map((c) => c.sectionTitle ? `## ${c.sectionTitle}\n\n${c.content}` : c.content)
180
+ .join("\n\n");
181
+ const entry = {
182
+ path: parent.path,
183
+ title: parent.title,
184
+ tags: parent.tags,
185
+ content: assembledContent,
186
+ zapret2Version: parent.zapret2Version,
187
+ blockcheckwVersion: parent.blockcheckwVersion,
188
+ };
94
189
  const entryChars = entry.title.length + entry.content.length + 50;
95
- if (totalChars + entryChars > charLimit && result.length > 0)
190
+ if (charLimit && totalChars + entryChars > charLimit && result.length > 0)
96
191
  break;
97
192
  result.push(entry);
98
193
  totalChars += entryChars;
99
194
  }
100
195
  return result;
101
196
  }
102
- /** Get all entries (for listing) */
103
- all() {
104
- return this.entries;
197
+ detectIntent(keywords) {
198
+ const INTENTS = {
199
+ TROUBLESHOOTING: [
200
+ "error", "failed", "problem", "работает", "тормозит",
201
+ "ошибка", "broken", "timeout", "открывается", "fix", "issue",
202
+ "debug", "диагностика", "troubleshoot", "troubleshooting",
203
+ "конфликт", "conflict",
204
+ ],
205
+ REFERENCE: [
206
+ "параметры", "options", "reference", "syntax", "список", "опции",
207
+ "cli", "параметр", "флаг", "flag", "blobs", "blob",
208
+ ],
209
+ HOWTO: [
210
+ "как", "setup", "install", "настроить", "configure", "установка",
211
+ "подключить", "установить", "how", "guide", "workflow", "миграция",
212
+ "migration",
213
+ ],
214
+ };
215
+ let bestIntent = null;
216
+ let bestCount = 0;
217
+ for (const [intent, triggers] of Object.entries(INTENTS)) {
218
+ const count = keywords.filter((kw) => triggers.some((t) => t === kw || kw.includes(t))).length;
219
+ if (count > bestCount) {
220
+ bestCount = count;
221
+ bestIntent = intent;
222
+ }
223
+ }
224
+ return bestIntent;
225
+ }
226
+ /**
227
+ * Adjust score based on context (what agent already knows).
228
+ * Chunks heavily overlapping with context get deprioritized.
229
+ * Chunks that add NEW information relative to context get boosted.
230
+ */
231
+ contextAdjust(chunk, contextKeywords) {
232
+ const chunkText = (chunk.sectionTitle + " " + chunk.content).toLowerCase();
233
+ let overlapCount = 0;
234
+ for (const ckw of contextKeywords) {
235
+ if (chunkText.includes(ckw)) {
236
+ overlapCount++;
237
+ }
238
+ }
239
+ const overlapRatio = contextKeywords.length > 0 ? overlapCount / contextKeywords.length : 0;
240
+ // High overlap (>60% of context keywords found in chunk) → deprioritize
241
+ if (overlapRatio > 0.6)
242
+ return -8;
243
+ // Medium overlap (30-60%) → slight penalty
244
+ if (overlapRatio > 0.3)
245
+ return -3;
246
+ // Low overlap (<30%) → this chunk has new info, slight boost
247
+ return 2;
248
+ }
249
+ intentBoost(docPath, intent) {
250
+ if (!intent)
251
+ return 0;
252
+ const PATH_INTENT_MAP = {
253
+ "troubleshooting/": "TROUBLESHOOTING",
254
+ "config/": "REFERENCE",
255
+ "workflows/": "HOWTO",
256
+ };
257
+ for (const [prefix, matchIntent] of Object.entries(PATH_INTENT_MAP)) {
258
+ if (docPath.startsWith(prefix) && intent === matchIntent) {
259
+ return 5;
260
+ }
261
+ }
262
+ return 0;
105
263
  }
106
264
  tokenize(text) {
107
265
  return text
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ ---
2
+ title: Auto-Hostlist and Failure Detection
3
+ zapret2-version: v0.9.4.5
4
+ tags: auto-hostlist, failure detection, retransmission, rst, redirect, autohostlist, blocking detection
5
+ source: deepwiki/bol-van/zapret2, official-docs
6
+ created: 2026-03-28
7
+ updated: 2026-03-28
8
+ ---
9
+
10
+ # Авто-хостлист и детекция отказов
11
+
12
+ Автоматическое обнаружение заблокированных доменов по паттернам сбоев соединений. Домены, которые повторно не загружаются, автоматически добавляются в хостлист для применения DPI bypass.
13
+
14
+ ## Принцип работы
15
+
16
+ 1. Демон мониторит сетевые соединения на признаки DPI-блокировки
17
+ 2. При обнаружении сбоя увеличивает счётчик для данного домена
18
+ 3. При достижении порога — домен записывается в файл auto-hostlist
19
+ 4. С этого момента к домену применяется стратегия обхода
20
+
21
+ ## Механизмы детекции (C-side)
22
+
23
+ Встроенная детекция активна когда у профиля настроен `hostlist_auto`:
24
+
25
+ | Тип сбоя | Направление | Как определяется |
26
+ |----------|-------------|-----------------|
27
+ | TCP Retransmission | Исходящий | Sequence number ≤ ранее отслеженной позиции |
28
+ | Incoming RST | Входящий | RST-флаг в пределах `hostlist_auto_incoming_maxseq` |
29
+ | HTTP Redirect | Входящий | DPI-редирект (домен в Location не совпадает с оригиналом) |
30
+ | UDP Timeout | Оба | Исходящих ≥ порога И входящих ≤ порога |
31
+
32
+ ### Детекция TCP-ретрансмиссий
33
+
34
+ Функция `is_retransmission()` сравнивает sequence текущего пакета с отслеженной позицией (`ctrack->pos.client.tcp.uppos_prev`). Когда `req_retrans_counter` достигает `hostlist_auto_retrans_threshold` — вызывается `auto_hostlist_failed()`.
35
+
36
+ Опционально: `hostlist_auto_retrans_reset` — отправка spoofed RST для сброса цикла ретрансмиссий.
37
+
38
+ ### Детекция HTTP-редиректов
39
+
40
+ `is_dpi_redirect()` сравнивает домен из заголовка `Location` с оригинальным hostname. Если домены не совпадают — это DPI-редирект.
41
+
42
+ ## Lua-based детекция
43
+
44
+ `standard_failure_detector` в `zapret-auto.lua` зеркалит C-логику со скриптовыми порогами:
45
+ - RST-детекция: проверка TCP reset flag в диапазоне `inseq`
46
+ - HTTP-редирект: через `is_dpi_redirect()`
47
+ - UDP failure: порог исходящих при отсутствии входящих
48
+
49
+ ## Управление состоянием
50
+
51
+ ### Host Records (`hrec`)
52
+ Постоянные счётчики и текущий индекс стратегии для каждого домена.
53
+
54
+ ### Connection Records (`crec`)
55
+ Счётчики ретрансмиссий и защита от дубликатов для каждого соединения.
56
+
57
+ ### Failure Pool (`hostfail_pool`)
58
+ In-memory linked list доменов, ожидающих добавления в хостлист. Каждая запись имеет expiration time для предотвращения застревания.
59
+
60
+ ### Сброс по таймауту
61
+
62
+ `automate_failure_counter()` управляет инкрементом счётчиков с time-based reset. Если интервал между сбоями превышает `maxtime` — счётчик сбрасывается в ноль.
63
+
64
+ ## Процесс добавления в хостлист
65
+
66
+ 1. **Purge**: `HostFailPoolPurge()` — удаление просроченных записей
67
+ 2. **Find/Add**: поиск или создание записи в failure pool
68
+ 3. **Threshold**: `counter >= hostlist_auto_fail_threshold` → обработка
69
+ 4. **Duplicate check**: `HostlistCheck()` — домен не должен уже быть в активных хостлистах
70
+ 5. **Persist**: `append_to_list_file()` — запись домена в файл `--hostlist-auto`
71
+ 6. **In-memory update**: `HostlistPoolAddStrLen()` — немедленное обновление активного пула
72
+
73
+ ## Параметры конфигурации
74
+
75
+ | Параметр CLI | Описание | По умолчанию |
76
+ |-------------|----------|-------------|
77
+ | `--hostlist-auto=<file>` | Путь к файлу auto-hostlist | — |
78
+ | `--hostlist-auto-fail-threshold=<N>` | Количество сбоев для добавления | 3 |
79
+ | `--hostlist-auto-fail-time=<sec>` | Временное окно для подсчёта сбоев | 60 |
80
+ | `--hostlist-auto-retrans-threshold=<N>` | Порог TCP-ретрансмиссий | 3 |
81
+ | `--hostlist-auto-retrans-reset` | Отправка RST для сброса ретрансмиссий | off |
82
+
83
+ ## Пример использования
84
+
85
+ ```
86
+ --name=auto-detect --filter-tcp=443 --filter-l7=tls
87
+ --payload=tls_client_hello
88
+ --hostlist-auto=/opt/zapret2/ipset/auto-blocked.txt
89
+ --hostlist-auto-fail-threshold=3
90
+ --hostlist-auto-fail-time=60
91
+ --lua-desync=fake:blob=fake_default_tls:tcp_md5
92
+ --lua-desync=multisplit:pos=1,midsld
93
+ ```
94
+
95
+ При таком конфиге:
96
+ - Все TLS-соединения на порт 443 мониторятся на сбои
97
+ - После 3 сбоев за 60 секунд домен добавляется в `auto-blocked.txt`
98
+ - Стратегия `fake + multisplit` применяется к доменам из списка
99
+
100
+ ## Интеграция со стратегией ротации
101
+
102
+ Auto-hostlist работает совместно с circular strategy (см. `orchestration.md`):
103
+ - `circular` ротирует стратегии при сбоях
104
+ - `standard_failure_detector` определяет сбои для ротации
105
+ - Если все стратегии исчерпаны — домен считается полностью заблокированным
106
+
107
+ ## Флаг финализации
108
+
109
+ `ctrack->failure_detect_finalized` предотвращает повторную детекцию после того, как исход соединения определён окончательно. Это оптимизация для долгоживущих потоков.
@@ -0,0 +1,118 @@
1
+ ---
2
+ title: Desync Profile System
3
+ zapret2-version: v0.9.4.5
4
+ tags: profiles, desync, new, filter, matching, template, import, lua-desync, l7, l3, l4
5
+ source: deepwiki/bol-van/zapret2, official-docs
6
+ created: 2026-03-28
7
+ updated: 2026-03-28
8
+ ---
9
+
10
+ # Система desync-профилей
11
+
12
+ Профиль — основная единица конфигурации zapret2. Каждый профиль инкапсулирует полную стратегию обхода DPI: правила фильтрации пакетов, целевые хостлисты/IP-диапазоны и цепочку Lua desync-функций.
13
+
14
+ ## Создание профилей
15
+
16
+ Профили создаются через разделитель `--new`:
17
+
18
+ ```
19
+ --name=youtube --filter-tcp=443 --filter-l7=tls
20
+ --payload=tls_client_hello
21
+ --hostlist-domains=youtube.com,googlevideo.com
22
+ --lua-desync=fake:blob=fake_default_tls:tcp_md5
23
+ --lua-desync=multisplit:pos=1,midsld
24
+ --new
25
+ --name=quic --filter-udp=443 --filter-l7=quic
26
+ --payload=quic_initial
27
+ --lua-desync=fake:blob=fake_default_quic:repeats=6
28
+ ```
29
+
30
+ Каждый `--new` начинает новый профиль. Параметры до первого `--new` относятся к первому профилю.
31
+
32
+ ## Многоуровневая фильтрация
33
+
34
+ Профиль содержит каскад фильтров. Пакет проверяется сверху вниз, первый совпавший профиль применяется:
35
+
36
+ | Уровень | Фильтр | Пример |
37
+ |---------|--------|--------|
38
+ | L3 | IPv4/IPv6 | `--filter-ipv4`, `--filter-ipv6` |
39
+ | L4 | Протокол и порты | `--filter-tcp=443`, `--filter-udp=443` |
40
+ | L7 | Прикладной протокол | `--filter-l7=tls,quic,http,mtproto` |
41
+ | IPset | IP-диапазоны | `--ipset=/path/to/ips.txt` |
42
+ | Hostlist | Домены (SNI/Host) | `--hostlist=/path/to/hosts.txt` |
43
+
44
+ ### Порядок сопоставления (matching)
45
+
46
+ 1. L3 → L4 → L7 → IPset → Hostlist
47
+ 2. **Первый совпавший профиль возвращается**
48
+ 3. Если у профиля есть hostlist но hostname ещё неизвестен — сопоставление откладывается до парсинга L7
49
+ 4. Профиль с `hostlist_auto` и известным hostname совпадает немедленно
50
+ 5. Профиль без hostlist совпадает сразу после прохождения L3/L4/L7/IPset
51
+
52
+ ### Кеширование профиля
53
+
54
+ После выбора профиль кешируется в connection tracking (`ctrack->dp`). Кеш сбрасывается при:
55
+ - Обнаружении L7-протокола (первый TLS ClientHello)
56
+ - Извлечении hostname (из SNI или HTTP Host)
57
+
58
+ Это запускает повторный поиск профиля с более специфичными критериями.
59
+
60
+ ## Шаблоны и наследование
61
+
62
+ Шаблоны определяются через `--template` и хранятся отдельно от активных профилей:
63
+
64
+ ```
65
+ --template --name=base-tls --filter-tcp=443 --filter-l7=tls --payload=tls_client_hello
66
+ --new
67
+ --import=base-tls --hostlist=/path/youtube.txt --lua-desync=multisplit:pos=1,midsld
68
+ --new
69
+ --import=base-tls --hostlist=/path/discord.txt --lua-desync=fake:blob=fake_default_tls:tcp_md5
70
+ ```
71
+
72
+ `--import` копирует конфигурацию из шаблона через `dp_copy()`. Копируются **только явно установленные** значения (используются boolean-флаги `b_filter_l3`, `b_filter_l7` и т.д.).
73
+
74
+ ## Цепочка Lua desync-функций
75
+
76
+ Поле `lua_desync` — связный список инстансов функций. Каждый инстанс:
77
+ - Содержит свои аргументы и параметры
78
+ - Может иметь payload-фильтр, ограничивающий выполнение
79
+ - Возвращает вердикт: `VERDICT_PASS`, `VERDICT_MODIFY`, `VERDICT_DROP`
80
+
81
+ Инстансы выполняются последовательно. Вердикты агрегируются: **DROP > MODIFY > PASS**.
82
+
83
+ ```
84
+ # Два инстанса в одном профиле: сначала fake, потом split
85
+ --lua-desync=fake:blob=fake_default_tls:tcp_md5
86
+ --lua-desync=multisplit:pos=1,midsld
87
+ ```
88
+
89
+ ## Именование профилей
90
+
91
+ `--name=` и `--cookie=` — опциональные идентификаторы для отладки и логирования. Имена помогают в диагностике:
92
+
93
+ ```
94
+ --name=youtube --filter-tcp=443 --filter-l7=tls
95
+ --hostlist-domains=youtube.com
96
+ --lua-desync=multisplit:pos=10:seqovl=1
97
+ ```
98
+
99
+ ## Типичные паттерны
100
+
101
+ ### Разные стратегии для разных сервисов
102
+
103
+ ```
104
+ --name=youtube --filter-tcp=443 --filter-l7=tls --payload=tls_client_hello
105
+ --hostlist=/opt/zapret2/ipset/youtube.txt
106
+ --lua-desync=fake:blob=fake_default_tls:tcp_md5:repeats=11
107
+ --lua-desync=multidisorder:pos=1,midsld
108
+ --new
109
+ --name=discord --filter-udp=50000-50100 --filter-l7=quic
110
+ --lua-desync=fake:blob=fake_default_quic:repeats=6
111
+ --new
112
+ --name=other --filter-tcp=443 --filter-l7=tls --payload=tls_client_hello
113
+ --lua-desync=multisplit:pos=2
114
+ ```
115
+
116
+ ### Fallback-профиль
117
+
118
+ Последний профиль без hostlist/ipset работает как catch-all для всего остального трафика.
@@ -0,0 +1,139 @@
1
+ ---
2
+ title: Hostlists and IPsets
3
+ zapret2-version: v0.9.4.5
4
+ tags: hostlist, ipset, filtering, domains, ip, include, exclude, gzip, auto-reload, sighup
5
+ source: deepwiki/bol-van/zapret2, official-docs
6
+ created: 2026-03-28
7
+ updated: 2026-03-28
8
+ ---
9
+
10
+ # Хостлисты и IP-множества (IPsets)
11
+
12
+ Файловые механизмы фильтрации для избирательного применения стратегий обхода DPI. Каждый desync-профиль может ссылаться на несколько хостлистов и ipset-ов для включения (apply) и исключения (exclude).
13
+
14
+ ## Хостлисты
15
+
16
+ ### Формат файла
17
+
18
+ Один домен на строку. Поддерживаются plain text и gzip (`.gz`).
19
+
20
+ ```
21
+ # Комментарий (также ; и / в начале строки)
22
+ example.com # совпадает с example.com и *.example.com
23
+ ^example.com # строгое совпадение: ТОЛЬКО example.com, не субдомены
24
+ youtube.com
25
+ googlevideo.com
26
+ ```
27
+
28
+ - Регистр не важен — все домены приводятся к lowercase при загрузке
29
+ - Пробелы и табы в конце строки обрезаются
30
+
31
+ ### Логика поиска (matching)
32
+
33
+ **Обычная запись** (`example.com`):
34
+ - Рекурсивный поиск по субдоменам: `sub.example.com` → `example.com` → `com`
35
+ - Совпадает, если домен или любой родительский домен есть в списке
36
+
37
+ **Строгая запись** (`^example.com`):
38
+ - Помечается флагом `HOSTLIST_POOL_FLAG_STRICT_MATCH`
39
+ - Совпадает ТОЛЬКО при полном совпадении домена, без рекурсии по субдоменам
40
+
41
+ ### CLI-параметры
42
+
43
+ ```
44
+ --hostlist=/path/to/include.txt # список включения
45
+ --hostlist-exclude=/path/to/exclude.txt # список исключения
46
+ --hostlist-domains=a.com,b.com # inline-домены (без файла)
47
+ --hostlist-auto=/path/to/auto.txt # авто-хостлист (см. auto-hostlist.md)
48
+ ```
49
+
50
+ ## IPsets
51
+
52
+ ### Формат файла
53
+
54
+ IP-адреса и CIDR-подсети, один на строку. IPv4 и IPv6. Поддерживается gzip.
55
+
56
+ ```
57
+ # Комментарий
58
+ 1.2.3.4
59
+ 10.0.0.0/8
60
+ 2001:db8::1
61
+ fd00::/32
62
+ ```
63
+
64
+ ### CLI-параметры
65
+
66
+ ```
67
+ --ipset=/path/to/include-ips.txt # список включения
68
+ --ipset-exclude=/path/to/exclude-ips.txt # список исключения
69
+ ```
70
+
71
+ ### Внутреннее устройство
72
+
73
+ IPset хранит IPv4 и IPv6 пулы отдельно в radix/binary tree для эффективного поиска O(log n).
74
+
75
+ ## Логика include/exclude
76
+
77
+ Порядок проверки детерминирован:
78
+
79
+ 1. **Exclude проверяется первым** — если хост/IP в exclude-списке, пакет отклоняется
80
+ 2. **Include проверяется вторым** — если include-коллекция пуста, пакет проходит (обратная совместимость)
81
+ 3. Если include непуста — пакет должен совпасть хотя бы с одним include-списком
82
+
83
+ Эта логика одинакова для hostlists и ipsets.
84
+
85
+ ## Gzip-поддержка
86
+
87
+ Прозрачная декомпрессия:
88
+ - Magic header `1F 8B` определяет gzip-файл
89
+ - `z_readfile()` декомпрессирует через `zlib` в буфер в памяти
90
+ - Декомпрессированный контент парсится построчно идентично plain text
91
+ - Полезно для больших списков (экономия места на роутерах)
92
+
93
+ ## Авто-перезагрузка (hot reload)
94
+
95
+ Хостлисты и ipset-ы перезагружаются без перезапуска демона:
96
+
97
+ ### Автоматическая детекция изменений
98
+ - `file_mod_signature()` проверяет mtime и размер файла через `stat()`
99
+ - Проверка происходит при обработке пакетов
100
+ - При изменении — файл перезагружается в память
101
+
102
+ ### Ручная перезагрузка
103
+ ```bash
104
+ # Отправить SIGHUP для немедленной перезагрузки всех списков
105
+ kill -HUP $(pidof nfqws2)
106
+ ```
107
+
108
+ ## Скрипты управления списками
109
+
110
+ Директория `ipset/` содержит утилиты для обновления списков из внешних источников:
111
+
112
+ | Скрипт | Назначение |
113
+ |--------|-----------|
114
+ | `def.sh` | Общие утилиты: `zzcat` (прозрачная gzip/plain декомпрессия), `digger` (DNS-резолвинг) |
115
+ | `get_reestr_preresolved.sh` | Загрузка пре-резолвленных IP-списков |
116
+ | `get_antifilter_ipsmart.sh` | Загрузка smart IP-списков |
117
+ | `hup_zapret_daemons()` | Отправка SIGHUP для немедленной перезагрузки |
118
+
119
+ ## Типичные паттерны
120
+
121
+ ### Разные списки для разных профилей
122
+
123
+ ```
124
+ --name=youtube --filter-tcp=443 --filter-l7=tls
125
+ --hostlist=/opt/zapret2/ipset/youtube.txt
126
+ --lua-desync=fake:blob=fake_default_tls:tcp_md5
127
+ --new
128
+ --name=general --filter-tcp=443 --filter-l7=tls
129
+ --hostlist=/opt/zapret2/ipset/general-blocked.txt
130
+ --hostlist-exclude=/opt/zapret2/ipset/whitelist.txt
131
+ --lua-desync=multisplit:pos=2
132
+ ```
133
+
134
+ ### Автообновление списков по cron
135
+
136
+ ```bash
137
+ # /etc/cron.d/zapret-update
138
+ 0 3 * * * root /opt/zapret2/ipset/get_antifilter_ipsmart.sh && kill -HUP $(pidof nfqws2)
139
+ ```
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Миграция стратегий zapret v1 → zapret2 (lua-desync)
3
3
  zapret2-version: v0.9.4.5
4
- tags: migration, v1, v2, lua-desync, dpi-desync, config, conversion
4
+ tags: migration, v1, v2, lua-desync, dpi-desync, config, conversion, profiles, lua
5
5
  source: community
6
6
  created: 2026-03-28
7
7
  updated: 2026-03-28
@@ -0,0 +1,110 @@
1
+ ---
2
+ title: Security Hardening
3
+ zapret2-version: v0.9.4.5
4
+ tags: security, seccomp, capabilities, privilege, droproot, sandbox, hardening, cap_net_admin, daemonize
5
+ source: deepwiki/bol-van/zapret2, official-docs
6
+ created: 2026-03-28
7
+ updated: 2026-03-28
8
+ ---
9
+
10
+ # Security Hardening
11
+
12
+ zapret2 реализует многоуровневую защиту (defense-in-depth) для минимизации поверхности атаки. Все защитные механизмы активируются при инициализации демона, до входа в основной цикл обработки пакетов.
13
+
14
+ ## Seccomp (Linux)
15
+
16
+ BPF-фильтр блокирует опасные системные вызовы на уровне ядра:
17
+
18
+ | Категория | Заблокированные syscall-ы |
19
+ |-----------|--------------------------|
20
+ | Выполнение | `execve`, `execveat` |
21
+ | Файловая система | `chmod`, `fchmod`, `chown`, `fchown` |
22
+ | Структура каталогов | `symlink`, `link`, `mkdir`, `rmdir` |
23
+ | Манипуляция процессами | `ptrace`, `process_vm_readv` |
24
+ | Сигналы | `kill`, `tkill`, `tgkill` |
25
+
26
+ Фильтр устанавливается через `prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER)` и динамически компилируется под текущую архитектуру (x86_64, ARM, MIPS, RISC-V).
27
+
28
+ ## Linux Capabilities
29
+
30
+ После биндинга привилегированных сокетов демон сбрасывает все capabilities, кроме:
31
+ - `CAP_NET_ADMIN` — управление сетевыми параметрами
32
+ - `CAP_NET_RAW` — работа с raw-сокетами
33
+
34
+ Процесс:
35
+ 1. `capget`/`capset` для манипуляции capabilities
36
+ 2. Определение максимальной capability через `/proc/sys/kernel/cap_last_cap`
37
+ 3. `prctl(PR_CAPBSET_DROP, cap)` для каждой ненужной capability
38
+ 4. Финализация без `CAP_SETCAP`
39
+
40
+ ## Сброс привилегий (droproot)
41
+
42
+ Функция `droproot()` — кросс-платформенное понижение привилегий:
43
+
44
+ 1. `prctl(PR_SET_KEEPCAPS, 1L)` — сохранить capabilities при смене UID
45
+ 2. `initgroups()` / `setgroups()` — настройка supplementary groups
46
+ 3. `setgid()` — установка primary group
47
+ 4. `setuid()` — смена пользователя (**необратимая** операция)
48
+
49
+ После `droproot()` цикл обработки пакетов работает с минимальными привилегиями.
50
+
51
+ ## NO_NEW_PRIVS
52
+
53
+ Флаг `prctl(PR_SET_NO_NEW_PRIVS)` запрещает повышение привилегий через `execve()` — критическая защита от цепочек эксплойтов.
54
+
55
+ ## Lua Sandbox
56
+
57
+ - FFI-модуль **отключён** в LuaJIT → невозможен произвольный доступ к памяти
58
+ - Stack guards (`LUA_STACK_GUARD_ENTER/LEAVE`) защищают от corruption при C↔Lua переходах
59
+ - Lua-окружение изолировано от файловой системы и опасных операций
60
+
61
+ ## Daemonization (изоляция процесса)
62
+
63
+ - `fork()` — отсоединение от родительского процесса
64
+ - `setsid()` — создание новой группы процессов
65
+ - `chdir("/")` — освобождение смонтированных файловых систем
66
+ - fd 0, 1, 2 → `/dev/null` — изоляция I/O
67
+
68
+ ## Windows (winws2)
69
+
70
+ Компиляция с security-флагами:
71
+ - **ASLR/DEP**: `--nxcompat`, `--high-entropy-va`
72
+ - **Dynamic base**: `--dynamicbase`
73
+ - **Sandbox**: low integrity level + job object restrictions
74
+ - **Static linking**: защита от DLL injection
75
+
76
+ ## Android
77
+
78
+ - Graceful handling отсутствия `/etc/passwd`
79
+ - Интеграция с `logcat` через `liblog`
80
+ - Статическая линковка (ограничения Bionic libc)
81
+
82
+ ## Порядок инициализации
83
+
84
+ Безопасность применяется в строгом порядке:
85
+
86
+ 1. Парсинг конфигурации
87
+ 2. Проверка привилегий
88
+ 3. Открытие PID-файла (до смены привилегий)
89
+ 4. **Сброс привилегий** (`droproot`)
90
+ 5. Проверка доступности файлов после смены привилегий
91
+ 6. Тестирование Lua-скриптов до активации sandbox
92
+ 7. **Применение seccomp** и capability restrictions
93
+ 8. Инициализация raw-сокетов
94
+ 9. Daemonization
95
+ 10. Регистрация signal handlers
96
+ 11. Инициализация Lua VM в sandbox-окружении
97
+ 12. Инициализация платформенного перехвата пакетов
98
+ 13. **Вход в main event loop** с минимальными привилегиями
99
+
100
+ ## Рекомендации для деплоя
101
+
102
+ - **Всегда** включать droproot до непривилегированного пользователя
103
+ - Настроить права на файлы hostlists/ipsets **до** сброса привилегий
104
+ - Тестировать доступность файлов после смены привилегий
105
+ - Использовать systemd/init-скрипты с правильными security contexts
106
+ - Мониторить reload через SIGHUP для изменений конфигурации
107
+
108
+ ## Философия
109
+
110
+ Компрометация одного слоя (например, escape из Lua sandbox) **не** даёт полный доступ к системе: seccomp фильтрует syscall-ы, capabilities ограничены, привилегии сброшены. Каждый слой работает независимо.
@@ -1,10 +1,11 @@
1
1
  ---
2
2
  title: Supported Platforms
3
3
  zapret2-version: v0.9.4.5
4
- tags: platforms, linux, openwrt, wsl2, windows, macos
5
- source: official-docs
4
+ tags: platforms, linux, openwrt, wsl2, windows, macos, freebsd, openbsd, bsd, dvtws2, winws2, android
5
+ source: deepwiki/bol-van/zapret2, official-docs
6
6
  created: 2026-03-25
7
- updated: 2026-03-25
7
+ updated: 2026-03-28
8
+ revision: 2
8
9
  ---
9
10
 
10
11
  # Поддерживаемые платформы
@@ -30,16 +31,54 @@ Firewall: nftables (предпочтительно) или iptables.
30
31
 
31
32
  ## Windows
32
33
 
33
- Нативно не поддерживается. Причины:
34
- - zapret2 использует NFQUEUE (Linux kernel), Windows использует WinDivert
35
- - Bash-скрипты vs .cmd
36
- - Пути: `/opt/zapret2` vs `C:\zapret`
34
+ Поддерживается через **winws2** (WinDivert-based). Демон `winws2` — нативный Windows-бинарник.
37
35
 
38
- **Решение:** Использовать через WSL2 (Windows Subsystem for Linux):
39
- 1. Установить WSL2 с Ubuntu/Debian
40
- 2. Установить zapret2 как на обычный Linux
41
- 3. Настроить WSL2 для перехвата трафика хоста
36
+ Особенности:
37
+ - Использует WinDivert вместо NFQUEUE для перехвата пакетов
38
+ - Компилируется со статической линковкой зависимостей (защита от DLL injection)
39
+ - Security: ASLR/DEP (`--nxcompat`, `--high-entropy-va`), dynamic base relocation
40
+ - Sandbox: low integrity level + job object restrictions
41
+
42
+ **Альтернатива**: WSL2 (Windows Subsystem for Linux) — установить zapret2 как на обычный Linux.
43
+
44
+ ## FreeBSD
45
+
46
+ Поддерживается через **dvtws2** (DiVerT WorkStation 2). Использует `ipfw` с divert-сокетами.
47
+
48
+ Особенности:
49
+ - Один divert-сокет обслуживает и IPv4, и IPv6
50
+ - Firewall: `ipfw` с divert-правилами
51
+ - Интерфейс определяется из `sockaddr` после `recvfrom()`
52
+ - Совместим с pfSense/OPNsense через специальные скрипты
53
+
54
+ ```
55
+ # Пример ipfw-правила
56
+ ipfw add divert 989 tcp from any to any 443 out
57
+ ```
58
+
59
+ **Ограничения BSD**: нет фильтрации по payload в firewall, нет per-flow kernel filtering, каждый пакет проходит через userspace.
60
+
61
+ ## OpenBSD
62
+
63
+ Поддерживается через **dvtws2**. Использует `pf` с `divert-packet`.
64
+
65
+ Особенности:
66
+ - **Раздельные** divert-сокеты для IPv4 и IPv6 (в отличие от FreeBSD)
67
+ - Firewall: `pf` с правилами `divert-packet`
68
+ - `no state` — чтобы pf не создавал автоматические bidirectional-правила
69
+
70
+ ```
71
+ # Пример pf-правила
72
+ pass out on egress inet proto tcp to port 443 divert-packet port 989 no state
73
+ ```
42
74
 
43
75
  ## macOS
44
76
 
45
- Не поддерживается. macOS не имеет NFQUEUE или аналогичного механизма перехвата пакетов.
77
+ **Не поддерживается.** Apple удалила `ipdivert` из ядра механизм divert-сокетов недоступен, несмотря на BSD-наследие.
78
+
79
+ ## Android
80
+
81
+ Поддерживается (Linux-based). Особенности:
82
+ - Обработка отсутствия `/etc/passwd` для privilege dropping
83
+ - Интеграция с `logcat` через `liblog`
84
+ - Преимущественно статическая линковка (ограничения Bionic libc)
@@ -1,10 +1,11 @@
1
1
  ---
2
2
  title: Fake Packet Strategies
3
3
  zapret2-version: v0.9.4.5
4
- tags: fake, rst, rstack, syndata, fooling, md5sig, badsum, autottl, ttl
5
- source: official-docs
4
+ tags: fake, rst, rstack, syndata, fooling, md5sig, badsum, autottl, ttl, ip6, extension headers, tcp_ts_up, tcp_nop_del, ip_id, ipfrag2, synhide
5
+ source: deepwiki/bol-van/zapret2, official-docs
6
6
  created: 2026-03-25
7
- updated: 2026-03-25
7
+ updated: 2026-03-28
8
+ revision: 2
8
9
  ---
9
10
 
10
11
  # Fake Packets (инъекция пакетов-обманок)
@@ -82,6 +83,53 @@ Fake-пакеты ОБЯЗАНЫ быть отброшены сервером,
82
83
  --dpi-desync-fooling=md5sig,badsum
83
84
  ```
84
85
 
86
+ ## Расширенные fooling-параметры (Lua)
87
+
88
+ В Lua-режиме (`--lua-desync`) доступны дополнительные параметры модификации пакетов.
89
+
90
+ ### IP Layer
91
+
92
+ | Параметр | Описание |
93
+ |----------|----------|
94
+ | `ip_ttl=N` | Установить IPv4 TTL в значение N |
95
+ | `ip6_ttl=N` | Установить IPv6 hop limit в значение N |
96
+ | `ip_autottl=delta,min-max` | Адаптивный TTL: оценка расстояния по входящим TTL (базы 64, 128, 255), применение delta с ограничениями min-max |
97
+ | `ip_id=seq\|rnd\|zero` | Управление IPv4 Identification: `seq` — инкрементальный, `rnd` — случайный, `zero` — нулевой. Опция `ip_id_conn` привязывает счётчик к соединению |
98
+
99
+ ### IPv6 Extension Headers
100
+
101
+ Вставка нестандартных заголовков для сбивания stateful DPI:
102
+
103
+ | Параметр | Заголовок |
104
+ |----------|----------|
105
+ | `ip6_hopbyhop` | Hop-by-Hop Options |
106
+ | `ip6_destopt` | Destination Options |
107
+ | `ip6_routing` | Routing Header |
108
+ | `ip6_ah` | Authentication Header |
109
+
110
+ Система автоматически вызывает `fix_ip6_next()` для корректной цепочки заголовков.
111
+
112
+ ### TCP Layer
113
+
114
+ | Параметр | Описание |
115
+ |----------|----------|
116
+ | `tcp_seq=delta` | Сдвиг TCP sequence number (wraparound-safe) |
117
+ | `tcp_ack=delta` | Сдвиг TCP acknowledgment number |
118
+ | `tcp_flags_set=SYN,ACK,...` | Установить TCP-флаги |
119
+ | `tcp_flags_unset=FIN,RST,...` | Сбросить TCP-флаги |
120
+ | `tcp_ts=delta` | Модификация TCP Timestamp option |
121
+ | `tcp_ts_up` | Переместить Timestamp option в начало списка опций (обходит DPI, которые проверяют timestamp только если он первый) |
122
+ | `tcp_nop_del` | Удалить NOP-padding (0x01) из TCP options, освобождая место в 40-байтном пространстве |
123
+ | `tcp_md5[=hexdata]` | Добавить TCP MD5 Signature (Option 19). По умолчанию — 16 нулевых байт |
124
+
125
+ ### Checksum и фрагментация
126
+
127
+ | Параметр | Описание |
128
+ |----------|----------|
129
+ | `badsum` | Намеренно портит L4 checksum — DPI обрабатывает пакет, стек получателя отбрасывает |
130
+ | `ipfrag2` | Разбивает пакет на 2 IP-фрагмента. TCP: offset 32 байта, UDP: 8 байт. Точка разбиения выравнивается на 8 (требование IP fragmentation) |
131
+ | `ipfrag_disorder` | Отправить второй фрагмент раньше первого для максимального сбоя DPI |
132
+
85
133
  ## Когда использовать
86
134
 
87
135
  - **fake + md5sig** — основная комбинация. Работает против большинства stateful DPI.
@@ -0,0 +1,123 @@
1
+ ---
2
+ title: Lua Scripting System
3
+ zapret2-version: v0.9.4.5
4
+ tags: lua, scripting, lua-desync, zapret-lib, zapret-antidpi, zapret-auto, zapret-obfs, obfuscation, wireguard, ippxor, udp2icmp, synhide
5
+ source: deepwiki/bol-van/zapret2, official-docs
6
+ created: 2026-03-28
7
+ updated: 2026-03-28
8
+ ---
9
+
10
+ # Lua Scripting System
11
+
12
+ Lua-скриптовая система — ядро zapret2. Позволяет гибко программировать стратегии обхода DPI без перекомпиляции C-кода. Разделение: C — перехват и обработка пакетов (производительность), Lua — программируемая логика стратегий (гибкость).
13
+
14
+ ## Архитектура
15
+
16
+ C-демон (nfqws2/dvtws2/winws2):
17
+ 1. Перехватывает пакет через NFQUEUE / divert / WinDivert
18
+ 2. Выполняет dissection и connection tracking
19
+ 3. Вызывает Lua-функции, указанные через `--lua-desync=<function>:param1=val1`
20
+ 4. Lua получает таблицу `desync` с разобранной структурой пакета
21
+
22
+ ### Таблица `desync` (интерфейс C→Lua)
23
+
24
+ | Поле | Содержимое |
25
+ |------|-----------|
26
+ | `dis` | Разобранная L3/L4/payload структура с указателями на слои |
27
+ | `track` | Connection tracking: sequence numbers, счётчики пакетов, позиции |
28
+ | `arg` | Параметры из `--lua-desync` вызова |
29
+ | `l7proto` | Определённый L7-протокол: `tls`, `http`, `quic`, `dtls`, `wireguard` |
30
+ | `reasm_data` | Реассемблированный payload для multi-packet потоков |
31
+
32
+ ## Основные библиотеки
33
+
34
+ ### zapret-lib.lua (утилиты)
35
+
36
+ Фундаментальные функции:
37
+ - **Dissection**: `dissect_tls`, `dissect_http`, `dissect_url` — разбор протоколов
38
+ - **Реконструкция**: `rawsend_dissect_segmented`, `ipfrag2` — отправка модифицированных пакетов
39
+ - **Модификация**: `apply_fooling` — применение fooling-параметров (TTL, checksums, etc.)
40
+
41
+ ### zapret-antidpi.lua (стратегии обхода)
42
+
43
+ Реализация DPI bypass техник:
44
+ - `fake` — отправка пакетов с невалидными checksums/TTL
45
+ - `multisplit` — сегментация payload на несколько частей
46
+ - `multidisorder` — переупорядочивание сегментов
47
+ - `oob` — out-of-band пакеты
48
+ - `syndata` — данные в SYN-пакете
49
+ - `rst` — fake RST для сброса DPI-состояния
50
+
51
+ Параметры поддерживают динамическую подстановку: `#` (длина) и `%` (значение).
52
+
53
+ ### zapret-auto.lua (оркестрация)
54
+
55
+ Управление ротацией стратегий:
56
+ - **`circular`** — ротирует стратегии при сбоях (следующая стратегия при failure)
57
+ - **`repeater`** — повторяет стратегию указанное число раз
58
+ - **`standard_failure_detector`** — мониторинг ретрансмиссий и RST для детекции сбоев
59
+ - Автоматическое переключение стратегий при обнаружении блокировки
60
+
61
+ ### zapret-obfs.lua (обфускация протоколов)
62
+
63
+ Продвинутые техники скрытия трафика:
64
+
65
+ #### WireGuard Obfuscation (wgobfs)
66
+ - Шифрует handshake-сообщения WireGuard (initiation, response, cookie) через AES-GCM
67
+ - Data-пакеты не шифруются (уже зашифрованы WireGuard)
68
+ - Ключ AES-128 генерируется из shared secret через HKDF-SHA256
69
+ - Overhead: 30-46 байт → нужно уменьшить MTU на WireGuard-интерфейсе
70
+ - Параметр `secret=<shared_secret>` (обязательный)
71
+ - Настраиваемый padding: min 0, max 16 байт
72
+
73
+ #### IP Protocol XOR (ippxor)
74
+ - XOR IP protocol number для маскировки под другой протокол
75
+ - Опциональный XOR payload с повторяющимся паттерном
76
+ - Если результат — TCP/UDP/ICMP, пакет переразбирается для корректной L4 dissection
77
+
78
+ #### UDP to ICMP (udp2icmp)
79
+ - Инкапсуляция UDP в ICMP без изменения размера пакета
80
+ - UDP-порты кодируются в ICMP identifier: `sport XOR dport`
81
+ - Client→Server: ICMP_ECHO, Server→Client: ICMP_ECHOREPLY
82
+
83
+ #### TCP Handshake Hiding (synhide)
84
+ - Скрывает TCP three-way handshake убирая SYN-флаг и вставляя magic-маркеры
85
+ - Режимы маркера: `x2` (reserved bits), `urp` (urgent pointer), `opt` (TCP option), `tsecr` (timestamp echo reply)
86
+ - Ghost SYN: пакет с низким TTL для создания NAT-записи без достижения сервера
87
+
88
+ ## C-Lua Integration Bridge
89
+
90
+ Мост в `nfq2/lua.c`:
91
+ - Конвертирует C-структуры (`struct dissect`, `struct t_ctrack`) в Lua-таблицы
92
+ - Экспортирует ~100 C-функций: `rawsend`, `dissect`, криптография (AES-GCM, HKDF, SHA), bitwise-операции
93
+ - Stack guards (`LUA_STACK_GUARD_ENTER/LEAVE`) для предотвращения memory leaks
94
+ - FFI модуль **отключён** в LuaJIT (sandbox)
95
+
96
+ ## Управление производительностью: Cutoff
97
+
98
+ Два механизма для поддержания throughput:
99
+
100
+ | Механизм | Эффект |
101
+ |----------|--------|
102
+ | `instance_cutoff(ctx, [dir])` | Отключает текущий Lua-инстанс для данного соединения |
103
+ | `lua_cutoff(ctx, [dir])` | Отключает ВСЮ Lua-обработку, возврат к чистому C |
104
+
105
+ Применяется после того, как стратегия отработала на нужных пакетах (например, после ClientHello), чтобы не тратить ресурсы на последующие пакеты потока.
106
+
107
+ ## Вызов и конфигурация
108
+
109
+ ```
110
+ --lua-desync=function_name:param1=value1:param2=value2
111
+ ```
112
+
113
+ - Несколько `--lua-desync` в одном профиле — цепочка инстансов
114
+ - Каждый инстанс имеет свои параметры через `arg`
115
+ - Вердикты агрегируются: DROP > MODIFY > PASS
116
+ - Multi-profile через `--new` — каждый профиль со своей цепочкой
117
+
118
+ ## Ключевые свойства
119
+
120
+ - **Stateless design**: каждая Lua-функция получает полный контекст пакета
121
+ - **Reassembly**: поддержка multi-packet протоколов (TLS ClientHello может быть в нескольких TCP-сегментах)
122
+ - **Dynamic substitution**: `#` (длина) и `%` (значение) в параметрах стратегий
123
+ - **Sandboxing**: Lua изолирован от файловой системы, FFI отключён, опасные операции недоступны
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zapret2-mcp",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "MCP knowledge server for zapret2 DPI bypass tool and blockcheckw strategy scanner",
5
5
  "license": "MIT",
6
6
  "author": "Stanislav Zemlyakov",