-
Notifications
You must be signed in to change notification settings - Fork 132
/
Copy pathREADME.md
309 lines (237 loc) · 15.7 KB
/
README.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
Implementation of some DPI bypass methods.
The program is a local SOCKS proxy server.
Usage example:
```
ciadpi --disorder 1 --auto=torst --tlsrec 1+s
ciadpi --fake -1 --ttl 8
```
------
### Описание аргументов
```
-i, --ip <ip>
Прослушиваемый IP, по умолчанию 0.0.0.0
-p, --port <num>
Прослушиваемый порт, по умолчанию 1080
-E, --transparent
Запуск в режиме прозрачного прокси, SOCKS работать не будет
-c, --max-conn <count>
Максимальное количество клиентских подключений, по умолчанию 512
-I, --conn-ip <ip>
Адрес, к которому будут привязаны исходящие соединения, по умолчанию ::
При указании IPv4 адреса запросы на IPv6 будут отклоняться
-b, --buf-size <size>
Максимальный размер данных, получаемых и отправляемых за один вызов recv/send
Размер указывается в байтах, по умолчанию равен 16384
-g, --def-ttl <num>
Значение TTL для всех исходящий соединений
Может быть полезен для обхода обнаружения нестандартного/уменьшенного TTL
-N, --no-domain
Отбрасывать запросы, если в качестве адреса указан домен
Т.к. резолвинг выполняется синхронно, то он может замедлить или даже заморозить работу
-U, --no-udp
Не проксировать UDP
-F, --tfo
Включает TCP Fast Open
Если сервер его поддерживает, то первый пакет будет отправлен сразу вместе с SYN
Поддерживается только в Linux (4.11+)
-A, --auto <t,r,s,n>
Автоматический режим
Если произошло событие, похожее на блокировку или поломку,
то будут применены параметры обхода, следующие за данной опцией
Возможные события:
torst : Вышло время ожидания или сервер сбросил подключение после первого запроса
redirect: HTTP Redirect с Location, домен которого не совпадает с исходящим
ssl_err : В ответ на ClientHello не пришел ServerHello или SH содержит некорректный session_id
none : Предыдущая группа пропущена, например из-за ограничения по доменам или протоколам
-L, --auto-mode <0|1>
0: кешировать IP только если имеется возможность переподключиться
1: кешировать IP также в том случае, если:
torst - таймаут/соединение сброшено во время обмена пакетами (т.е. уже после первых данных от сервера)
ssl_err - совершился лишь один круг обмена данными (запрос-ответ/запрос-ответ-запрос)
-u, --cache-ttl <sec>
Время жизни значения в кеше, по умолчанию 100800 (28 часов)
-T, --timeout <sec>
Таймаут ожидания первого ответа от сервера в секундах
В Linux переводится в миллисекунды, поэтому можно указать дробное число
-K, --proto <t,h,u>
Белый список протоколов: tls,http,udp
-H, --hosts <file|:string>
Ограничить область действия параметров списком доменов
Домены должны быть разделены новой строкой или пробелом
-V, --pf <port[-portr]>
Ограничитель по портам
-R, --round <num[-numr]>
К каким/какому запросу применять запутывание
-s, --split <pos_t>
Разбить запрос по указанной позиции
Позиция имеет вид offset[:repeats:skip][+flag1[flag2]]
Флаги:
+s: добавить смещение SNI
+h: добавить смещение Host
+n: нулевое смещение
Дополнительные флаги:
+e: конец; +m: середина
Примеры:
0+sm - разбить запрос в середине SNI
1:3:5 - разбить по позициям 1, 6 и 11
Ключ можно указывать несколько раз, чтобы разбить запрос по нескольким позициям
Если offset отрицательный и не имеет флагов, то к нему прибавляется размер пакета
-d, --disorder <pos_t>
Подобен --split, но части отправляются в обратном порядке
-o, --oob <pos_t>
Подобен --split, но часть отсылается как OOB данные
-q, --disoob <pos_t>
Подобен --disorder, но часть отсылается как OOB данные
-f, --fake <pos_t>
Подобен --disorder, только перед отправкой первого куска отправляется часть поддельного
Количество байт отправляемого из фейка равно рамеру разбиваемой части
-t, --ttl <num>
TTL для поддельного пакета, по умолчанию 8
Необходимо подобрать такое значение, чтобы пакет не дошел до сервера, но был обработан DPI
-k, --ip-opt[=file|:str]
Установить опции для фейкового IP пакета
Существенно снизит вероятность, что пакет дойдет до сервера
Стоит учесть, что до DPI он также может не дойти
В Windows поддержка может быть отключена
-S, --md5sig
Установить опцию TCP MD5 Signature для фейкового пакета
Большинство серверов (в основном на Linux) отбрасывают пакеты с данной опцией
Поддерживается только в Linux, может быть выключен в некоторых сборках ядра (< 3.9, Android)
-O, --fake-offset <n>
Сместить начало фейковых данных на n байт
-l, --fake-data <file|:str>
Указать свои поддельные пакеты
-e, --oob-data <char>
Байт, отсылаемый вне основного потока, по умолчанию 'a'
-n, --tls-sni <str>
Изменить SNI в fake пакете на указанный
-M, --mod-http <h[,d,r]>
Всякие манипуляции с HTTP пакетом, можно комбинировать
hcsmix:
"Host: name" -> "hOsT: name"
dcsmix:
"Host: name" -> "Host: NaMe"
rmspace:
"Host: name" -> "Host:name\t"
-r, --tlsrec <pos_t>
Разделить ClientHello на отдельные записи по указанному смещению
Можно указывать несколько раз
-a, --udp-fake <count>
Количество фейковых UDP пакетов
-Y, --drop-sack
Игнорировать SACK, вынуждая ядро переотправить уже доставленные пакеты
```
------
### Подробнее
`--split`
Разбивает запрос на части. Пример на запросе в 30 байт:
- Параметры: `--split 3 --split 7`
- Порядок отправки: 1-3, 3-7, 7-30
Позиции следует указывать в порядке возрастания.
------
`--disorder`
Часть, попадающая под disorder, будет отправлена с TTL=1, т.е. фактически не будет никуда доставлена.
ОС узнает об этом лишь после отсылки последующей части, когда сервер сообщит о потере с помощью SACK.
Системе придется отослать предыдущий пакет заново, тем самым нарушив обычный порядок.
- Параметры: `--disorder 7`
- Порядок отправки: 7-30, 1-7
Вышесказанное распространяется только на Linux.
В Windows выполняется полная ретрансмиссия:
- Параметры: `--disorder 7`
- Порядок отправки: 7-30, 1-30
Поэтому желательно использовать ещё и `split`:
- Параметры: `--split 7 --disorder 23`
- Порядок отправки: 1-7, 23-30, 7-30
На практике оптимально использовать:
* Linux: `--disorder 1`
* Windows: `--split 1+s --disorder 3+s`
------
`--fake`
- Параметры: `--fake 7`
- Порядок отправки: 1-7 фейк, 7-30 оригинал, 1-7 оригинал
Данные в первой части запроса заменяются на поддельные.
Эта часть должна пройти через DPI, но не дойти до сервера.
А раз часть не дойдет, то ОС отправит ее снова, тем самым изменив порядок подобно `disorder`.
Для того, чтобы фейк не дошел до сервера, есть опции `ttl`, `ip-opt` и `md5sig`.
TTL необходимо подбирать такой, чтобы пакет прошел через все DPI, но не дошел до сервера.
Для Linux есть md5sig. Он устанавливает опцию TCP MD5 Signature, что не дает пакету быть принятым многими серверами.
К сожалению, md5sig работает не во всех сборках.
Для Windows есть еще один способ избежать обработки фейка сервером.
Это комбинирование `fake` с `disorder`:
- Параметры: `--disorder 1 --fake 7`
- Порядок отправки: 2-7 фейк, 7-30 оригинал, 1-30 оригинал
Если поддельный пакет и дойдет до сервера, то он будет перезаписан из-за полной ретрансмисси.
На практике оптимально использовать:
* Linux: `--fake -1 --md5sig`
* Windows: `--disorder 1 --fake -1`
------
`--oob`
TCP может отсылать данные вне основного потока, используя флаг URG, однако лишь 1 байт в пакете.
Все данные в таком пакете будут доставлены приложению, кроме последнего байта, который и является внеканальным:
- Параметры: `--oob 3`
- Отправка: 1-4 с флагом URG (1-3 данные запроса + 4-й байт, который будет усечен), 3-30
Этот байт желательно помещать в SNI: `--oob 3+s`
------
`--disoob`
Схож с `--disorder`, но часть отправляется с OOB байтом:
- Параметры: `--disoob 3`
- Отправка: 3-30, 1-4 с флагом URG (1-3 данные запроса + 4-й байт, который будет усечен)
При использовании с `--fake` или `--disorder` можно получить пакет, где OOB байт будет находиться на месте разбиения:
- Параметры: `--disoob 3 --disorder 7`
- Отправка: 3-30, 1-8 с флагом URG (1-3 + байт который будет усечен + 4-8)
------
`--tlsrec`
Одну TLS запись можно разбить на несколько, немного переделав заголовок.
На месте разбиения вставляется новый заголовок, увеличивая размер запроса на 5 байт.
Этот заголовок можно поместить в середину SNI, не давая возможность DPI правильно его прочитать:
`--tlsrec 3+s`
Хоть `tlsrec` и `oob` запутывают DPI, они также могут запутать всякие мидлбоксы, которые не поддерживают полноценный стек TCP/TLS.
Из-за этого их следует использовать вместе с `--auto`:
`--auto=torst --timeout 3 --tlsrec 3+s`
В примере `tlsrec` будет применяться лишь в случаях, когда сброшено подключение или вышел таймаут, т.е. когда, скорее всего, произошла блокировка.
Можно наоборот - отменять tlsrec, если сервер сбрасывает подключение или откидывает пакет:
`--tlsrec 3+s --auto=torst --timeout 3`
------
`--auto`, `--hosts`
Параметр `auto` делит опции на группы.
Для каждого запроса они обходятся слева на право.
Сначала проверяется триггер, указанный в `auto`, затем `pf`, `proto` и `hosts`.
Можно указывать несколько групп опций, раделяя их данным параметром.
Параметры, которые идут ниже `--timeout` в help-тексте (кроме `tls-sni`), можно вынести в отдельную группу.
------
#### Примеры:
```
--fake -1 --ttl 10 --auto=ssl_err --fake -1 --ttl 5
```
По умолчанию использовать `fake` с ttl=10, в случае ошибки использовать `fake` с ttl=5
```
--hosts list.txt --disorder 3 --auto=none
```
Применять запутывание только для доменов из list.txt
```
--hosts list.txt --auto=none --disorder 3
```
Не применять запутывание для доменов из list.txt
```
--auto=torst --hosts list.txt --disorder 3
```
По умолчанию ничего не делать, использовать disorder при условии, что произошла блокировка и домен входит в list.txt.
```
--proto=http,tls --disorder 3 --auto=none
```
Запутывать только HTTP и TLS
```
--proto=http --fake -1 --fake-data=':GET /...' --auto=none --fake -1
```
Переопределить фейковый пакет для HTTP
------
### Сборка
Для сборки понадобится:
`make`, `gcc/clang` для Linux, `mingw` для Windows
* Linux: `make`
* Windows: `make windows CC=x86_64-w64-mingw32-gcc`
------
### Дополнительная информация о DPI, источники идей
* https://github.com/bol-van/zapret/blob/master/docs/readme.txt
* https://geneva.cs.umd.edu/papers/geneva_ccs19.pdf
* https://habr.com/ru/post/335436