From 6361a3798a4a7d2e6b6691611b79d7a6d998b078 Mon Sep 17 00:00:00 2001 From: bol-van Date: Thu, 18 Dec 2025 17:26:51 +0300 Subject: [PATCH] update docs --- docs/manual.md | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/docs/manual.md b/docs/manual.md index 197a3a7..f387c7e 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -86,8 +86,7 @@ conntrack отслеживает логическое направление п desync - таблица, содержащая множество параметров обрабатываемого пакета. Прежде всего это диссект - подтаблица `dis`. Информация из записи conntrack - подтаблица `track`. Еще целый ряд параметров, который можно увидеть, выполнив `var_debug(desync)` или просто вызвав готовый инстанс `pktdebug`. -Если идет перепроигрывание задержанных пакетов (replay), LUA инстанс получает информацию о номере части, количестве частей исходного сообщения, позиции текущей части, -reasm или decrypt при наличии. +Если идет перепроигрывание задержанных пакетов (replay), LUA инстанс получает информацию о номере части, количестве частей исходного сообщения, позиции текущей части, reasm или decrypt при наличии. LUA код может использовать глобальное пространство переменных для хранения данных, не относящихся к конкретному обрабатываемому пакету. Ему доступна таблица `desync.track.lua_state`, в которой он может хранить любую информацию, связанную с записью conntrack. При каждом новом пакете потока в LUA выдается одна и та же таблица. @@ -1234,6 +1233,21 @@ ipv6 extension headers и tcp options представляются в форме | kind | [тип опции](https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml) : TCP_KIND_END, TCP_KIND_NOOP, TCP_KIND_MSS, TCP_KIND_SCALE, TCP_KIND_SACK_PERM, TCP_KIND_SACK, TCP_KIND_TS, TCP_KIND_MD5, TCP_KIND_AO, TCP_KIND_FASTOPEN | | data | блок данных опции без kind и length. отсутствует для TCP_KIND_END и TCP_KIND_NOOP | +### Особенности приема многопакетных пейлоадов + +Сборка многопакетного пейлоада называется реасм (reasm - reassemble). +Она производится автоматически C кодом, если встречен пейлоад, требующий сборки, доступен conntrack и не указан запрет на сборку через `--reasm-disable`. +На текущий момент таких пейлоадов 2 - tls_client_hello и quic_initial. Оба могут содержать постквантовую криптографию kyber, которая не помещается в один пакет. + +Для tls_clien_hello производится обычная сборка пейлоадов последовательных tcp сегментов и обьединение их в единый блок reasm_data. + +Для quic_initial отдельные пакеты накапливается во внутреннем буфере, после чего происходит их дешифровка, обьединение и дефрагментация частей разбросанных по пакетам и разным смещениям частей пейлоада (так делает chrome, чтобы заставить всех не упрощать свои алгоритмы, следовать стандартам и уметь корректно собирать пейлоад по частям). + +Пока сборка не финализирована, выполняется накопление пакетов во внутреннем буфере без вызовов LUA. Как только она финализирована, происходит перепроигрывание отдельных частей (replay). В LUA инстансы приходит диссект каждого задержанного пакета, но при этом устанавливаются поля desync.replay=true, desync.replay_piece, desync.replay_count и desync.replay_piece_last. + +В случае стандартной tcp сборки выставляется поле desync.reasm_data, содержащее полный блок собранных данных. В desync.dis.payload по-прежнему возвращаются пейлоады отдельных перепроигрываемых пакетов. Для tcp, если нет replay, desync.reasm_data содержит копию desync.dis.payload. + +При сборке quic desync.reasm_data отсутствует. Вместо него передается поле desync.decrypt_data, содержащее результат дешифровки и дефрагментации всех пейлоадов, входящих в сборку. Для quic reasm_data содержит tls_client_hello без record layer. ### Структура track @@ -2355,6 +2369,24 @@ function payload_check(desync, def) * payload_match_filter проверяет соответствие l7payload списку l7payload_filter или def, если l7payload_filter=nil. Если оба nil - список берется как "known". * payload_check вызывает `payload_match_filter(desync.l7payload, desync.arg.payload, def)` +## Работа с многопакетными пейлоадам + +Обычно идет работа с целым reasm, вместо отдельных его частей. В этом и есть смысл сборки, чтобы не копаться в отдельных пакетах, а разбираться со всем сообщением сразу. + +Стандартный сценарий предполагает работу после приема первой части replay и игнорирование, либо drop остальных частей. Выбор между игнорированием или drop может зависеть от успешности действий с reasm. Например, удалось или не удалось отправить reasm сегментированно. Если удалось - нужно дропнуть все остальные части, потому что иначе они пойдут дублями в оригинальной сегментации. Если возникла какая-то ошибка, сегментированные пакеты отправить не удалось, и при этом дроппнуть все остальное, до адресата не дойдет полное сообщение, начнутся ретрансмиссии, поэтому лучше оставить как есть - так хоть ничего не поломается. + +``` +function replay_first(desync) +function replay_drop_set(desync, v) +function replay_drop(desync) +``` + +* replay_first возвращает true, если текущий диссект не является replay или является его первой частью +* replay_drop_set помечает в desync.track.lua_state boolean признак необходимости "v" дропнуть последующие части replay +* replay_drop возвращает true, если необходимо дропнуть текущую часть replay. Если часть последняя - автоматически снимает признак. + +Функции работают корректно как с реплеем, так и обычными диссектами. Для обычных диссектов replay_first всегда true, replay_drop_set не меняет признак, replay_drop всегда false. + ## Оркестрация В эту группу функций входят функции поддержки процесса оркестрации и прокладки. @@ -2654,9 +2686,9 @@ function multisplit(ctx, desync) * payload фильтр по умолчанию - "known" Multisplit реализует последовательную сегментацию текущего диссекта или реасма с разрезом в определяемых списком маркеров позициях. Опционально поддерживается замена блока данных на произвольный blob и техника seqovl. -Выносится VERDICT_DROP после успешной отправки всех сегментов. +Выносится VERDICT_DROP после успешной отправки всех сегментов, если не указано "nodrop". -Если происходит перепроигрывание (replay) задержанных пакетов и присутствует reasm, то вместо desync.dis.payload берется desync.reasm_data. Нарезание проиходит только при перепроигрывании первой части reasm, по остальным частям выносится VERDICT_DROP, если отсылка была успешна. Поскольку весь reasm уже отправлен нарезанным, нет смысла повторно отправлять его оригинальные части. +Если происходит перепроигрывание (replay) задержанных пакетов и присутствует reasm, то вместо desync.dis.payload берется desync.reasm_data. Нарезание проиходит только при перепроигрывании первой части reasm, по остальным частям выносится VERDICT_DROP, если отсылка была успешна и не указано "nodrop". Поскольку весь reasm уже отправлен нарезанным, нет смысла повторно отправлять его оригинальные части. Может использоваться для отправки произвольных данных, в том числе фейков с заменой текущего пейлоада на произвольный blob. @@ -2691,8 +2723,7 @@ function multidisorder(ctx, desync) Техника seqovl в данном случае работает иначе. Она применятся ко второму в оригинальной очередности (предпоследнему отсылаемому) сегменту. seqovl может быть маркером. Например, можно сделать разрез по midsld, а seqovl сделать "midsld-1". seqovl обязательно должен быть меньше первого сегмента в оригинальной очередности (последнего отсылаемого), иначе эта ситуация распознается и seqovl отменяется. -Смысл seqovl в варианте disorder - в переписывании буфера сокета на принимающем конце. tcp сокет выдает данные в приложение последовательно, в порядке их оригинальной передачи. Если сначала приходит сегмент "спереди", не образующий с уже принятыми данными непрерывной оригинальной последовательности, происходит задержка информации в буфере без выдачи ее приложению. Если далее приходит перекрывающийся по sequence сегмент, то информация из него переписыват уже имеющуюся в буфере. Так ведут себя все системы, кроме Windows, поэтому на Windows серверах эта техника не работает. -Windows сохраняет старую информацию. +Смысл seqovl в варианте disorder - в переписывании буфера сокета на принимающем конце. tcp сокет выдает данные в приложение последовательно, в порядке их оригинальной передачи. Если сначала приходит сегмент "спереди", не образующий с уже принятыми данными непрерывной последовательности, происходит задержка информации в буфере без выдачи ее приложению. Если далее приходит перекрывающийся по sequence сегмент, то информация из него переписыват уже имеющуюся в буфере. Так ведут себя все системы, кроме Windows, поэтому на Windows серверах эта техника не работает. Windows сохраняет старую информацию. К предпоследнему отсылаемому сегменту (2-му по оригинальной очередности) приписывается слева seqovl_pattern размером seqovl (результат ресолвинга маркера), а tcp.th_seq уменьшается на seqovl. @@ -2799,6 +2830,7 @@ function hostfakesplit(ctx, desync) Это специальный "резатель" с замешиванием фейков для пейлоадов, в которых присутствует имя хоста - http_req и tls_client_hello. Двумя основными точкам разреза являются начало имени хоста - маркер "host" и конец имени хоста - маркер "endhost". Дополнительными и опциональными точками разреза являются маркер midhost (должен быть в пределах host..endost) и маркер disorder_after (должен быть больше endhost). При разрезе по disorder_after части отправляются в обратном порядке. +Для фейков необходим фулинг, чтобы они не были приняты сервером. Последовательность отсылки : @@ -2834,7 +2866,7 @@ function tcpseg(ctx, desync) Отсылает часть текущего диссекта, реасма, или произвольного blob, ограниченную двумя маркерами pos с опциональным применением техники seqovl таким же способом, как и в multisplit. Дополнительная сегментация при превышении MSS производится автоматически. -В случае reasm работает только при приеме его первой части. +В случае reasm работает только при приеме его первой части (т.к. работает целиком по reasm, а не отдельным его частям). Вердикт не выносится.