Skip to content

Instantly share code, notes, and snippets.

@neko-neko-nyan
Created October 22, 2024 09:47
Show Gist options
  • Save neko-neko-nyan/9bd470bf79b824830ea09592d764479b to your computer and use it in GitHub Desktop.
Save neko-neko-nyan/9bd470bf79b824830ea09592d764479b to your computer and use it in GitHub Desktop.
Параметры nfqws zapret

Параметры nfqws zapret

Глобальные параметры

Параметр Описание Значение по умолчанию
--debug=0 выключить отладку (по умолчанию) 0
--debug, --debug=1 включить отладку в консоль
--debug=syslog включить отладку в syslog
--debug=@<filename> выключить отладку в файл filename
--daemon демонизировать прогу
--pidfile=<filename> сохранить PID в файл
--user=<username> менять uid процесса
--uid=<uid>[:<gid>] менять uid/gid процесса
--qnum=<number> номер очереди nfq Обязательный
--dpi-desync-fwmark=<number> fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. Не меняет fwmark проходящих пакетов 0x40000000
--ctrack-timeouts=S:E:F[:U] таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. 60:300:60:60
--bind-fix4 пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов
--bind-fix6 пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов

Параметры профиля (стратегии)

Профили содержат фильтры и настройки обходчика. Профили нумеруются с 1, МЕЖДУ профилями указывается --new. Специальный профиль 0 (можно увидить в логе --debug) значит, что ни один профиль не подошел и никаких действий не выполняется.

Выбор профиля:

  1. Для каждого профиля с первого по последний (по порядку в командной строке):
  2. Проверяются жесткие фильтры: если жесткий фильтр указан и не совпадает - профиль пропускается.
  3. Если указан фильтр L7 И он не содежит L7 протокол пакета (если протокол еще не известен - проверяется unknown) - профиль пропускается.
  4. Если указан --hostlist-auto - профиль выбирается.
  5. Если не указан ни --hostlist, ни --hostlist-exclude (пустой список эквивалентен его отсутствию) - профиль выбирается.
  6. Если указан имя хоста не известно - профиль пропускается.
  7. Если указан не пустой --hostlist-exclude и имя хоста есть в --hostlist-exclude - профиль пропускается.
  8. Если указан не пустой --hostlist и имя хоста есть в --hostlist - профиль выбирается.
  9. Иначе - профиль пропускается.
  10. Если ни один профиль не подошел - выбирается пустой профиль с номером 0.

Выбор профиля происходит для каждого пакета. Протокол L7 и имя хоста не всегда можно определить сразу. поэтому после определения протокола и/или имени хоста происходит перевыбор профиля. Протокол L7 и имя хоста сохраняется для соединения. Это значит, что действия фазы 0 в начале соединения будут применяться только если они указаны в профиле, в котором есть только жесткие фильтры (либо нет фильтов вообще).

Доп. фильтры не влияют на выбор профиля. Когда профиль уже выбран, если хотя бы один из доп. фильтров не совпадает - никаких действий с пакетом не происходит, пакет пропускается как есть.

Фильтры

Параметр Описание
Жесткие фильтры (Фаза 0)
--filter-l3=ipv4|ipv6 фильтр версии ip
--filter-tcp=[~]port1[-port2] фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp.
--filter-udp=[~]port1[-port2] фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает tcp.
--ipset=<filename> включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip.
--ipset-exclude=<filename> исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip.
Мягкие фильтры
--filter-l7=[http|tls|quic|wireguard|dht|unknown] фильтр протокола L6-L7. поддерживается несколько значений через запятую.
--hostlist=<filename> фильтр хостов из файла. может быть множество листов, они объединяются. пустой обший лист = его отсутствие
--hostlist-exclude=<filename> фильтр хостов не из файла. приоритет выше, чем у --hostlist
--hostlist-auto=<filename> автоматически обнаруживать блокировки и заполнять hostlist (требует перенаправления входящего трафика)
Следующие опции игнорируются, если не указан --hostlist-auto
--hostlist-auto-fail-threshold=<number> сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист
--hostlist-auto-fail-time=<number> все эти ситуации должны быть в пределах указанного количества секунд
--hostlist-auto-retrans-threshold=<number> сколько ретрансмиссий запроса считать блокировкой
--hostlist-auto-debug=<filename> лог положительных решений по autohostlist
Доп. фильтры
--dpi-desync-any-protocol=1 Разрешить работу на фазе 1+ если протокол L7 все еще не известен. По умолчанию пакеты неизвестных протоколов пропускаются как есть, даже если --filter-l7 явно содержит unknown!
--dpi-desync-skip-nosni=0 Не игнорировать QUIC/TLS соединения и их пакеты, если в них нет имени хоста. По умолчанию QUIC и TLS без имени хоста пропускаются как есть
`--dpi-desync-cutoff=[n d
`--dpi-desync-start=[n d

Действия

Параметр Описание
Действия фазы 0
--wsize=<winsize>[:<scale_factor>] менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !)
--wssize=<winsize>[:<scale_factor>] менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0
`--wssize-cutoff=[n d
Действия HTTP (применяются только если протокол L7 - HTTP)
--hostnospace убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
--domcase домен после Host: сделать таким : TeSt.cOm
--hostcase менять регистр заголовка "Host:" по умолчанию на "host:".
--hostspell=HoST точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--dpi-desync=[<mode0>,]<mode>[,<mode2] Указывает режимы десинхронизации DPI (см ниже)

Режим mode0 = synack

В документации по geneva это называется "TCB turnaround". Попытка ввести DPI в заблуждение относительно ролей клиента и сервера.

Поскольку режим нарушает работу NAT, техника может сработать только если между атакующим устройством и DPI нет NAT. Атака не сработает через NAT роутер, но может сработать с него.

Режим mode0 = syndata

Добавляются данные в пакет SYN. Все ОС их игнорируют, если не используется TCP fast open (TFO), а DPI может воспринять, не разобравшись есть там TFO или нет. Оригинальные соединения с TFO не трогаются, поскольку это их точно сломает. Без уточняющего параметра добавляются 16 нулевых байтов.

Параметр Описание
`--dpi-desync-fake-syndata= 0xHEX`

Режим mode = fakeknown, fake

fakeknown = если L7 протокол неизвестен - none (без десинхронизации), иначе - fake. fake - отправить фейковый пакет перед настоящим.

Параметр Описание
`--dpi-desync-fake-http= 0xHEX`
`--dpi-desync-fake-tls= 0xHEX`
`--dpi-desync-fake-unknown= 0xHEX`
`--dpi-desync-fake-quic= 0xHEX`
`--dpi-desync-fake-wireguard= 0xHEX`
`--dpi-desync-fake-dht= 0xHEX`
`--dpi-desync-fake-unknown-udp= 0xHEX`

Режим mode = rst, rstack

Отправляет пакет сброса соединения (RST или RST+ACK).

Режим mode = hopbyhop, destopt, ipfrag1

Режимы десинхронизации hopbyhop, destopt и ipfrag1 относятся только к ipv6 и заключается в добавлении хедера "hop-by-hop options", "destination options" или "fragment" во все пакеты, попадающие под десинхронизацию.

Режим mode2 = disorder, disorder2, split, split2

Эти режимы делят оригинальный пакет на два и отправляют их в следующем порядке:

split:

  1. поддельная 1-я часть пакета, поле данных заполнено нулями
  2. 1-я часть пакета
  3. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз.
  4. 2-я часть пакета

split2: 2. 1-я часть пакета 4. 2-я часть пакета

disorder:

  1. 2-я часть пакета
  2. поддельная 1-я часть пакета, поле данных заполнено нулями
  3. 1-я часть пакета
  4. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз.

disorder2:

  1. 2-я часть пакета
  2. 1-я часть пакета

disorder2 и split2 не предполагают отсылку фейк пакетов, поэтому опции ttl и fooling неактуальны.

Параметр Описание
--dpi-desync-split-http-req=method|host разбивка http request на указанном логическом месте
--dpi-desync-split-tls=sni|sniext разбивка tls client hello на указанном логическом месте
--dpi-desync-split-pos=<1..1500> разбивать пакет на указанной позиции. По умолчанию - 2. Если позиция больше длины пакета, позиция выбирается 1. (предыдущие параметры имеют приоритет над этим)
--dpi-desync-split-seqovl=<int> использовать sequence overlap перед первым отсылаемым оригинальным tcp сегментом
`--dpi-desync-split-seqovl-pattern= 0xHEX`

Режим mode2 = udplen

увеличивает размер udp пакета на указанное в --dpi-desync-udplen-increment количество байтов. Паддинг заполняется нулями по умолчанию, но можно задать свой паттерн.

Параметр Описание
--dpi-desync-udplen-increment=<int> насколько увеличивать длину udp пейлоада
`--dpi-desync-udplen-pattern= 0xHEX`

Режим mode2 = tamper

Режим tamper означает модификацию пакетов известных протоколов особенным для протокола образом. На текущий момент работает только с DHT.

Режим mode2 = ipfrag2

Относится только к ipv6.

Параметр Описание
--dpi-desync-ipfrag-pos-tcp=<int>
--dpi-desync-ipfrag-pos-udp=<int>

Опции

Параметр Описание
--dpi-desync-ttl=<int> установить ttl для десинхронизирующих пакетов
--dpi-desync-ttl6=<int> установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]] режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. delta=0 отключает функцию.
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] переопределение предыдущего параметра для ipv6
--dpi-desync-fooling=<fooling> дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера
--dpi-desync-repeats=<N> посылать каждый десинхронизирующий пакет N раз

fooling = md5sig

Работает не на всех серверах. Пакеты с md5 обычно отбрасывают только linux.

fooling = badsum

Не сработает, если ваше устройство за NAT, который не пропускает пакеты с инвалидной суммой. Наиболее распространенная настройка NAT роутера в Linux их не пропускает. На Linux построено большинство домашних роутеров.

Непропускание обеспечивается так: настройка ядра sysctl по умолчанию net.netfilter.nf_conntrack_checksum=1 заставляет conntrack проверять tcp и udp чексуммы входящих пакетов и выставлять state INVALID для пакетов с инвалидной суммой. Обычно в правилах iptables вставляется правило для дропа пакетов с состоянием INVALID в цепочке FORWARD. Совместное сочетание этих факторов приводит к непрохождению badsum через такой роутер. В openwrt из коробки net.netfilter.nf_conntrack_checksum=0, в других роутерах часто нет, и не всегда это можно изменить. Чтобы nfqws мог работать через роутер, нужно на нем выставить указанное значение sysctl в 0. nfqws на самом роутере будет работать и без этой настройки, потому что чексумма локально созданных пакетов не проверяется никогда. Если роутер за другим NAT, например провайдерским, и он не пропускает invalid packets вы ничего не сможете с этим сделать. Но обычно провайдеры все же пропускают badsum. На некоторых адаптерах/свитчах/драйверах принудительно включен rx-checksum offload, badsum пакеты отсекаются еще до получения в ОС. В этом случае если что-то и можно сделать, то только модифицировать драйвер, что представляется задачей крайне нетривиальной. Установлено, что так себя ведут некоторые роутеры на базе mediatek. badsum пакеты уходят с клиентской ОС, но роутером не видятся в br-lan через tcpdump. При этом если nfqws выполняется на самом роутере, обход может работать. badsum нормально уходят с внешнего интерфейса.

fooling = badseq

Пакеты будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется на sequence numbers. Практика показала, что некоторые DPI не пропускают seq вне определенного окна. Однако, небольшое смещение может вызвать проблемы при существенной потоковой передаче и потере пакетов. Если вы используете --dpi-desync-any-protocol, может понадобится установить badseq increment 0x80000000. Это обеспечит надежную гарантию, что поддельный пакет не вклинится в tcp window на сервере. Так же было замечено, что badseq ломает логику некоторых DPI при анализе http, вызывая зависание соединения. Причем на тех же DPI TLS с badseq работает нормально.

Параметр Описание
`--dpi-desync-badseq-increment=<int 0xHEX>`
`--dpi-desync-badack-increment=<int 0xHEX>`

fooling = datanoack

высылает фейки со снятым tcp флагом ACK. Сервера такое не принимают, а DPI может принять. Эта техника может ломать NAT и не всегда работает с iptables, если используется masquerade, даже с локальной системы (почти всегда на роутерах ipv4). На системах c iptables без masquerade и на nftables работает без ограничений. Экспериментально выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому работает даже с внутренним провайдерским IP. Но linux NAT оно не пройдет, так что за домашним роутером эта техника не сработает, но может сработать с него.

fooling = hopbyhop, hopbyhop2

Только для ipv6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment