# Windows ## tpws Запуск tpws возможен только в Linux варианте под **WSL** _(Windows Subsystem for Linux)_. Нативного варианта под Windows нет, поскольку он использует epoll, которого под windows не существует. tpws в режиме socks можно запускать под более-менее современными билдами windows 10 и windows server с установленным WSL. Совсем не обязательно устанавливать дистрибутив убунту, как вам напишут почти в каждой статье про WSL, которую вы найдете в сети. tpws - статический бинарик, ему дистрибутив не нужен. Установить WSL : `dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all` Скопировать на целевую систему `binaries/x86_64/tpws_wsl.tgz`. Выполнить : `wsl --import tpws "%USERPROFILE%\tpws" tpws_wsl.tgz` Запустить : `wsl -d tpws --exec /tpws --uid=1 --no-resolve --socks --bind-addr=127.0.0.1 --port=1080 <параметры_дурения>` Прописать socks `127.0.0.1:1080` в браузер или другую программу. Удаление : `wsl --unregister tpws` > [!NOTE] > Проверено на windows 10 build 19041 (20.04). Возможные проблемы: - Не работают функции `--oob` и `--mss` из-за ограничений реализации WSL. `--disorder` не работает из-за особенностей tcp/ip стека windows. - Может не срабатывать детект RST в autohostlist. - WSL может глючить со splice, приводя к зацикливанию процесса. Может потребоваться `--nosplice`. - Не поддерживается tcp user timeout. Чтобы избавиться от сообщений об ошибке добавляйте : `--local-tcp-user-timeout=0 --remote-tcp-user-timeout=0`. Эти сообщения только информативные, на работу они не влияют. ## winws Это вариант пакетного фильтра nfqws для Windows, построенный на базе windivert. Все функции работоспособны, однако функционал ipset в ядре отсутствует. Он реализован в user mode. Фильтры по большому количеству IP адресов невозможны. Работа с проходящим трафиком, например в случае "расшаривания" соединения, не проверялась и не гарантируется. Для работы с windivert требуются права администратора. Специфические для unix параметры, такие как `--uid`, `--user` и тд, исключены. Все остальные параметры аналогичны nfqws и dvtws. Работа с пакетным фильтром основана на двух действиях : 1) Выделение перенаправляемого трафика в режиме ядра и передача его пакетному фильтру в user mode. 2) Собственно обработка перенаправленных пакетов в пакетном фильтре. В windows отсутствуют встроенные средства для перенаправления трафика, такие как _iptables_, _nftables_, _pf_ или _ipfw_. Поэтому используется сторонний драйвер ядра windivert. Он работает, начиная с windows 7. На системах с включенным secure boot могут быть проблемы из-за подписи драйвера. В этом случае отключите `secureboot` или включите режим `testsigning`. На windows 7, вероятно, будут проблемы с загрузкой windivert. Читайте ниже соответствующий раздел. Задача _iptables_ в **winws** решается внутренними средствами через фильтры windivert. У windivert существует собственный язык фильтров, похожий на язык фильтров wireshark. [Документация по фильтрам windivert.](https://reqrypt.org/windivert-doc.html#filter_language) Чтобы не писать сложные фильтры вручную, предусмотрены различные упрощенные варианты автоматического построения фильтров. ``` --wf-iface=[.] ; числовые индексы интерфейса и суб-интерфейса --wf-l3=ipv4|ipv6 ; фильтр L3 протоколов. по умолчанию включены ipv4 и ipv6. --wf-tcp=[~]port1[-port2] ; фильтр портов для tcp. ~ означает отрицание --wf-udp=[~]port1[-port2] ; фильтр портов для udp. ~ означает отрицание --wf-raw=|@ ; задать напрямую фильтр windivert из параметра или из файла. имени файла предшествует символ @. --wf-save= ; сохранить сконструированный фильтр windivert в файл для последующей правки вручную --ssid-filter=ssid1[,ssid2,ssid3,...] ; включать winws только когда подключена любая из указанных wifi сетей --nlm-filter=net1[,net2,net3,...] ; включать winws только когда подключена любая из указанных сетей NLM --nlm-list[=all] ; вывести список сетей NLM. по умолчанию только подключенных, all - всех. ``` Параметры `--wf-l3`, `--wf-tcp`, `--wf-udp` могут брать несколько значений через запятую. Номера интерфейсов можно узнать так : `netsh int ip show int`. Некоторых типы соединений там не увидеть. В этом случае запускайте **winws** с параметром `--debug` и смотрите IfIdx там. SubInterface используется windivert, но практически всегда **0**, его можно не указывать. Вероятно, он нужен в редких случаях. Конструктор фильтров автоматически включает входящие tcp пакеты с tcp synack и tcp rst для корректной работы функций autottl и autohostlist. При включении autohostlist так же перенаправляются пакеты данных с http redirect с кодами 302 и 307. Всегда добавляется фильтр на исключение не-интернет адресов ipv4 и ipv6. Для сложных нестандартных сценариев могут потребоваться свои фильтры. Логично будет начать со стандартного шаблона, сохраненного через `--wf-save`. Нужно править файл и подсовывать его в параметре `--wf-raw`. Максимальный размер фильтра - **8 Kb**. Можно запускать несколько процессов **winws** с разными стратегиями. Однако, не следует делать пересекающиеся фильтры. В `--ssid-filter` можно через запятую задать неограниченное количество имен wifi сетей (**SSID**). Если задана хотя бы одна сеть, то winws включается только, если подключен указанный **SSID**. Если **SSID** исчезает, winws отключается. Если **SSID** появляется снова, winws включается. Это нужно, чтобы можно было применять раздельное дурение к каждой отдельной wifi сети. Названия сетей должны быть написаны в том регистре, в котором их видит система. Сравнение идет с учетом регистра! При этом нет никаких проверок куда реально идет трафик. Если одновременно подключен, допустим, ethernet, и трафик идет туда, то дурение включается и выключается просто по факту наличия wifi сети, на которую трафик может и не идти. И это может сломать дурение на ethernet. Поэтому полезно так же будет добавить фильтр `--wf-iface` на индекс интерфейса wifi адаптера, чтобы не трогать другой трафик. `--nlm-filter` аналогичен `--ssid-filter`, но работает с именами или GUIDами сетей Network List Manager (NLM). Это те сети, которые вы видите в панели управления в разделе "Центр управления сетями и общим доступом". Под сетью подразумевается не конкретный адаптер, а именно сетевое окружение конкретного подключения. Обычно проверяется mac адрес шлюза. К сети можно подключиться через любой адаптер, и она останется той же самой. Если подключиться, допустим, к разными роутерам по кабелю, то будут разные сети. А если к одному роутеру через 2 разных сетевых карточки на том же компе - будет одна сеть. NLM абстрагирует типы сетевых адаптеров. Он работает как с wifi, так и с ethernet и любыми другими. Поэтому это более универсальный метод, чем **SSID** фильтр. Однако, есть и неприятная сторона. В windows 7 вы легко могли ткнуть на иконку сети и выбрать тип : private или public. Там же вы могли посмотреть список сетей и обьединить их. Чтобы, допустим, вы могли подключаться по кабелю и wifi к одному роутеру, и система эти подключения воспринимала как одну сеть. В следующих версиях windows они эти возможности сильно порезали. Похоже нет встроенных средств полноценно управлять network locations в win10/11. Кое-что есть в **powershell**. Можно поковыряться напрямую в реестре здесь : `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList` Нужно менять ProfileGUID в `Signatures\Unmanaged`. Имена можно поменять в Profiles. Есть кое-какие сторонние утилиты. Кое-что находится, позволяющее посмотреть и удалить network profiles, но не обьединить. Факт, что в ms они это сильно испортили. Движок network list все тот же, и он способен на все то, что было в win7. Можно не бороться с этой проблемой, а просто указывать через запятую те названия сетей или GUIDы, которые выбрала система. Или если у вас только wifi, то использовать `--ssid-filter`. Там хотя бы есть гарантия, что **SSID** соответствуют реальности, а система их не назвала как-то по-своему. Если в путях присутствуют национальные символы, то при вызове winws из `cmd` или `bat` кодировку нужно использовать **OEM**. Для русского языка это 866. Пути с пробелами нужно брать в кавычки. При использовании опции @ кодировка в файле должна быть **UTF-8** без **BOM mark**. Существует неочевидный момент, каcаемый запуска **winws** из cygwin shell\`а. Если в директории, где находится winws, находится копия `cygwin1.dll`, **winws** не запустится. Если нужен запуск под cygwin, то следует удалить или переместить `cygwin1.dll` из `binaries/win64`. Это нужно для работы blockcheck. Из cygwin шелла можно посылать winws сигналы через `kill` точно так же, как в `*nix`. Как получить совместимый с windows 7 и winws cygwin : `curl -O https://www.cygwin.com/setup-x86_64.exe` `setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215` > [!IMPORTANT] > Следует выбрать установку curl. Для сборки из исходников требуется _gcc-core_,_make_,_zlib-devel_. Собирать из директории nfq командой `make cygwin64` или `make cygwin32` для 64 и 32 битных версий соответственно. **winws** требует `cygwin1.dll`, `windivert.dll`, `windivert64.sys` или `windivert32.sys`. Их можно взять из `binaries/win64` и `binaries/win32`. Для _arm64_ windows нет подписанного драйвера windivert и нет cygwin. Однако, эмуляция x64 windows 11 позволяет использовать все, кроме WinDivert64.sys без изменений. Но при этом надо заменить WinDivert64.sys на неподписанную _arm64_ версию и установить режим testsigning. ## Windows 7 и windivert Требования к подписи драйверов windows изменились в 2021 году. Официальные бесплатные обновления windows 7 закончились в 2020. После этого несколько лет продолжали идти платные обновления по программе **ESU**. Именно в этих **ESU** обновлениях находится обновление ядра windows 7, позволяющиее загрузить драйвер _windivert 2.2.2-A_, который идет в поставке zapret. Поэтому варианты следующие : 1) Взять `windivert64.sys` и `windivert.dll` версии _2.2.0-C_ или _2.2.0-D_ отсюда : https://reqrypt.org/download и заменить эти 2 файла. В [zapret-win-bundle](https://github.com/bol-van/zapret-win-bundle) есть отдельных 2 места, где находится **winws** : [_zapret-winws_](https://github.com/bol-van/zapret-win-bundle/tree/master/zapret-winws) и [_blockcheck/zapret/nfq_](https://github.com/bol-van/zapret-win-bundle/tree/master/blockcheck). Надо менять в обоих местах. > [!NOTE] > Этот вариант проверен и должен работать. Тем не менее патч 10 летней давности, который включает SHA256 сигнатуры, все еще необходим. 2) Взломать **ESU** : https://hackandpwn.com/windows-7-esu-patching/ http://www.bifido.net/tweaks-and-scripts/8-extended-security-updates-installer.html и обновить систему 3) Использовать UpdatePack7R2 от simplix : https://blog.simplix.info > [!WARNING] > Но с этим паком есть проблема. Автор из Украины, он очень обиделся на русских. > Если в панели управления стоит регион RU или BY, появляется неприятный диалог. > Чтобы эту проблему обойти, можно поставить временно любой другой регион, потом вернуть. > Так же нет никаких гарантий, что автор не насовал туда какой-то зловредный код. > Использовать на свой страх и риск. Более безопасный вариант - скачать последнюю нормальную довоенную версию : 22.2.10 https://nnmclub.to/forum/viewtopic.php?t=1530323 Ее достаточно, чтобы _windivert 2.2.2-A_ заработал на windows 7. ## blockcheck `blockcheck.sh` написан на _posix shell_ и требует некоторых стандартных утилит _posix_. В windows, естественно, этого нет. Потому просто так запустить `blockcheck.sh` невозможно. Для этого требуется скачать и установить _cygwin_ так , как описано в предыдущем разделе. Следует запустить от имени администратора _cygwin shell_ через `cygwin.bat`. В нем нужно пройти в директорию с zapret. Обратные слэши путей windows нужно удваивать, менять на прямые слэши, либо использовать отображение на unix path. Корректные варианты : - `cd C:\\Users\\vasya` - `cd C:/Users/vasya` - `cd /cygdrive/c/Users/vasya` Существует неочевидный момент, каcаемый запуска **winws** из _cygwin_ шелла. Если в директории, где находится **winws**, есть копия `cygwin1.dll`, **winws** не запустится. Нужно переименовать файл `cygwin1.dll`. Далее все как в _*nix_ : 1 раз `./install_bin.sh` , затем `./blockcheck.sh`. WSL использовать нельзя, это не то же самое. _cygwin_ для обычной работы **winws** не нужен. Однако, хотя такой способ и работает, использование **winws** сильно облегчает [zapret-win-bundle](https://github.com/bol-van/zapret-win-bundle). Там нет проблемы с `cygwin.dll`. ## Автозапуск winws Для запуска **winws** вместе с windows есть 2 варианта. Планировщик задач или службы windows. Можно создавать задачи и управлять ими через консольную программу schtasks. В директории `binaries/win64/winws` подготовлены файлы `task_*.cmd` . В них реализовано создание, удаление, старт и стоп одной копии процесса winws с параметрами из переменной `%WINWS1%`. Исправьте параметры на нужную вам стратегию. Если для разных фильтров применяется разная стратегия, размножьте код для задач _winws1_,_winws2_,_winws3_,_..._ Аналогично настраивается вариант запуска через службы windows. Смотрите `service_*.cmd`. Все батники требуется запускать от имени администратора. Управлять задачами можно так же из графической программы управления планировщиком `taskschd.msc` ## Zapret-win-bundle Можно не возиться с _cygwin_, а взять готовый пакет, включающий в себя _cygwin_ и _blockcheck_ : https://github.com/bol-van/zapret-win-bundle Там сделан максимум удобств для сосредоточения на самом zapret, исключая возню с установкой _cygwin_, заходами в директории, запусками под администратором и прочими сугубо техническими моментами, в которых могут быть ошибки и непонимания, а новичок без базиса знаний может и вовсе запутаться. `/zapret-winws` - здесь все, что нужно для запуска winws в повседневном рабочем режиме. остальное не нужно.\ `/zapret-winws/_CMD_ADMIN.cmd` - получить командную строку cmd в этой директории от имени администратора для тестирования **winws** с параметрами, вводимыми вручную\ `/blockcheck/blockcheck.cmd` - достаточно кликнуть по нему, чтобы пошел _blockcheck_ с записью лога в `blockcheck/blockcheck.log`\ `/cygwin/cygwin.cmd` - запуск среды _cygwin bash_ под текущим пользователем\ `/cygwin/cygwin-admin.cmd` - запуск среды _cygwin bash_ под администратором В среде _cygwin_ уже настроены alias-ы на winws,blockcheck,ip2net,mdig. С путями возиться не нужно! > [!TIP] > Из cygwin можно не только тестировать winws, но и посылать сигналы. > Доступны команды: >- `pidof` >- `kill` >- `killall` >- `pgrep` >- `pkill` Но важно понимать, что таким образом не выйдет посылать сигналы **winws**, запущенному из _zapret-winws_, поскольку там свой `cygwin1.dll`, и они не разделяют общее пространство процессов unix. _zapret-winws_ - это отдельный комплект для повседневного использования, не требующий что-то еще, но и не связанный со _средой cygwin_. Специально для посылки сигналов winws в _zapret-winws_ присутствует killall.exe. Среду cygwin можно использовать для записи в файл дебаг-лога winws. Для этого пользуйтесь командой tee. `winws --debug --wf-tcp=80,443 | tee winws.log` `winws.log` будет в `cygwin/home/<имя_пользователя>` Если у вас windows 7, то блокнот не поймет переводы строк в стиле unix. Воспользуйтесь командой `unix2dos winws.log` > [!CAUTION] > Поскольку 32-битные windows мало востребованы, _zapret-win-bundle_ существует только в варианте для windows _x64/arm64_.