Initial commit: zapret-discord-youtube-linux v1.9.8c-linux

This commit is contained in:
2026-05-10 19:06:04 +04:00
commit 80e0a116e1
40 changed files with 2599 additions and 0 deletions

18
.gitignore vendored Normal file
View File

@@ -0,0 +1,18 @@
# Build artifacts
bin/
*.tmp
*.log
# User data (auto-created on first run)
lists/*-user.txt
.service/installed_strategy
.service/game_filter_enabled
.service/ipset_filter_*
.service/check_updates_enabled
# Build dirs
/tmp/zapret-build-*
# OS files
.DS_Store
Thumbs.db

1
.service/version.txt Normal file
View File

@@ -0,0 +1 @@
LOCAL_VERSION="1.9.8c-linux"

206
README.md Normal file
View File

@@ -0,0 +1,206 @@
# Zapret for Linux (Discord + YouTube)
Linux-аналог популярного репозитория [Flowseal/zapret-discord-youtube](https://github.com/Flowseal/zapret-discord-youtube) для обхода DPI (Deep Packet Inspection) на Linux.
## Требования
- Linux (Ubuntu/Debian, Arch/Manjaro, Fedora и др.)
- `iptables` или `nftables`
- Ядерный модуль `nfnetlink_queue`
- `curl`, `git`, `make`, `gcc`
- `sudo` или root-доступ
## Быстрый старт
```bash
# 1. Клонировать репозиторий
cd /opt
sudo git clone https://github.com/YOUR_USERNAME/zapret-discord-youtube-linux.git zapret
sudo chown -R $(whoami) zapret
cd zapret
# 2. ОДИН СКРИПТ — всё сделает автоматически:
# установка, сборка, тест, подбор стратегии, systemd-сервис
sudo ./install.sh
```
Готово! После этого сервис работает и будет автозапускаться.
---
## Полная инструкция (если нужно по шагам)
```bash
# Установка и настройка
sudo ./setup.sh # зависимости + сборка nfqws
# Автоподбор стратегии
sudo ./autotest.sh # интерактивный режим
sudo ./autotest.sh --auto # автоматический (сразу ставит в systemd)
# Обновление в будущем
sudo ./update.sh # проверить версию, обновить, пересобрать
sudo ./update.sh --full-auto # форсировать: пересобрать + перетестить
```
### autotest.sh — автоподбор стратегии (Step 3 автоматизирован!)
```bash
sudo ./autotest.sh
```
**Что делает:**
1. Последовательно запускает каждую стратегию (от самой популярной к редким)
2. Проверяет доступность YouTube и Discord через `curl`
3. Останавливает стратегию и переходит к следующей, если не работает
4. Когда находит рабочую — предлагает установить в systemd
**Автоматический режим (без вопросов):**
```bash
sudo ./autotest.sh --auto
```
**Ручной режим:** тестирует, показывает результат, ждёт подтверждения для установки.
| Параметр | Описание |
|----------|----------|
| `--auto` или `-a` | Найти рабочую стратегию и сразу установить в systemd |
| без параметров | Интерактивный режим с меню |
## Структура проекта
```
.
├── bin/ # nfqws + fake-пакеты
├── lib/
│ └── functions.sh # Общие функции (firewall, цвета)
├── lists/
│ ├── list-general.txt # Основные домены (Discord, Cloudflare, etc.)
│ ├── list-google.txt # Google/YouTube домены
│ ├── list-exclude.txt # Исключения (Twitch, VK, банки...)
│ ├── ipset-all.txt # IP-диапазоны
│ └── ipset-exclude.txt # IP-исключения
├── utils/
│ ├── test_zapret.sh # Тесты доступности сайтов
│ └── targets.txt # Список тестовых URL
├── systemd/
│ └── zapret.service # systemd unit
├── .service/
│ ├── version.txt # Текущая версия
│ ├── installed_strategy # Установленная стратегия
│ ├── game_filter_enabled # Флаг game filter
│ └── check_updates_enabled # Флаг автообновления
├── general*.sh # Скрипты стратегий
├── autotest.sh # Автоподбор рабочей стратегии
├── install.sh # Полный установщик: setup + build + autotest + systemd
├── run_strategy.sh # Единый запускатель стратегий
├── service.sh # Меню управления (аналог service.bat)
├── setup.sh # Начальная настройка
├── install_nfqws.sh # Сборка nfqws из bol-van/zapret
└── update.sh # Автообновление: проверка → сборка → тест → установка
```
## Стратегии (general*.sh)
Каждый `general*.sh` — это обёртка над `run_strategy.sh` с нужным параметром:
| Файл | Стратегия | Описание |
|------|-----------|----------|
| `general.sh` | `general` | Standard multisplit |
| `general_ALT.sh` | `ALT` | Fake fakedsplit + ts fooling |
| `general_ALT2.sh` | `ALT2` | Multisplit pos=2 |
| `general_ALT3.sh` | `ALT3` | Hostfakesplit (Google/ya.ru) |
| `general_ALT4.sh` | `ALT4` | Fake multisplit + badseq |
| `general_ALT5.sh` | `ALT5` | **NOT RECOMMENDED** syndata multidisorder |
| `general_ALT6.sh` | `ALT6` | Uniform split-seqovl=681 |
| `general_ALT7.sh` | `ALT7` | Multisplit + syndata |
| `general_ALT8.sh` | `ALT8` | Fake + badseq-increment=2 |
| `general_ALT9.sh` | `ALT9` | Hostfakesplit (ozon.ru) |
| `general_ALT10.sh` | `ALT10` | Fake + ts fooling |
| `general_ALT11.sh` | `ALT11` | Fake multisplit + max_ru pattern |
| `general_FAKE_TLS_AUTO.sh` | `FAKE_TLS_AUTO` | FAKE TLS multidisorder |
| `general_FAKE_TLS_AUTO_ALT.sh` | `FAKE_TLS_AUTO_ALT` | FAKE TLS fakedsplit |
| `general_FAKE_TLS_AUTO_ALT2.sh` | `FAKE_TLS_AUTO_ALT2` | FAKE TLS multisplit badseq |
| `general_FAKE_TLS_AUTO_ALT3.sh` | `FAKE_TLS_AUTO_ALT3` | FAKE TLS + 4pda pattern |
| `general_SIMPLE_FAKE.sh` | `SIMPLE_FAKE` | Simple fake |
| `general_SIMPLE_FAKE_ALT.sh` | `SIMPLE_FAKE_ALT` | Simple fakedsplit |
| `general_SIMPLE_FAKE_ALT2.sh` | `SIMPLE_FAKE_ALT2` | Simple hostfakesplit |
**Как подобрать рабочую стратегию:** запускайте разные `general*.sh` и проверяйте открывается ли Discord/YouTube. Когда найдёте рабочую — установите через `service.sh``Install Service`.
## service.sh — меню управления
Аналог `service.bat` из Windows-версии:
```
:: SERVICE
1. Install Service — выбор стратегии + systemd unit
2. Remove Services — удаление unit + остановка nfqws
3. Check Status — проверка nfqws и firewall rules
:: SETTINGS
4. Game Filter — вкл/выкл обход для UDP/TCP портов >1024
5. IPSet Filter — none / loaded / any
6. Auto-Update Check — вкл/выкл автообновление
:: UPDATES
7. Update IPSet List — обновить ipset-all.txt
8. Update Hosts File — показать новые записи hosts
9. Check for Updates — проверить версию на GitHub
:: TOOLS
10. Run Diagnostics — проверка зависимостей, модулей, DNS
11. Run Tests — тест сайтов или DPI checker
```
## Автообновление (update.sh)
```bash
# Интерактивный режим — проверяет версию, предлагает обновить,
# скачивает новые списки, пересобирает nfqws, перезапускает сервис
sudo ./update.sh
# Автоматический режим (для cron / systemd timer)
sudo ./update.sh --auto
```
### systemd таймер для автообновления
```bash
sudo cp systemd/zapret-update.timer /etc/systemd/system/
sudo cp systemd/zapret-update.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now zapret-update.timer
```
## Установка в автозагрузку (systemd)
```bash
sudo cp systemd/zapret.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable zapret.service
sudo systemctl start zapret.service
```
## Пользовательские списки
При первом запуске автоматически создаются:
- `lists/list-general-user.txt` — добавляйте свои домены
- `lists/list-exclude-user.txt` — домены-исключения
- `lists/ipset-exclude-user.txt` — IP-исключения
## Secure DNS
Рекомендуется включить DNS-over-HTTPS:
- **Chrome**: `chrome://settings/security` → Secure DNS
- **Firefox**: `about:preferences#privacy` → DNS-over-HTTPS
- **Система (systemd-resolved)**: `resolvectl dns eth0 1.1.1.1`
## Лицензия
MIT License — аналогично оригинальному проекту.
## Благодарности
- [bol-van](https://github.com/bol-van) — оригинальный разработчик zapret
- [Flowseal](https://github.com/Flowseal) — Windows-обёртка и стратегии

257
autotest.sh Normal file
View File

@@ -0,0 +1,257 @@
#!/bin/bash
# autotest.sh - Automatic strategy tester
# Iterates through all strategies, checks connectivity, suggests installation
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
# Test targets (must be accessible when bypass works)
TEST_URLS=(
"https://www.youtube.com|YouTube"
"https://discord.com|Discord"
"https://discordapp.com|DiscordApp"
)
# Strategy order (most common first)
STRATEGIES=(
general.sh
general_ALT.sh
general_ALT2.sh
general_ALT3.sh
general_ALT4.sh
general_ALT6.sh
general_ALT7.sh
general_ALT8.sh
general_ALT9.sh
general_ALT10.sh
general_ALT11.sh
general_FAKE_TLS_AUTO.sh
general_FAKE_TLS_AUTO_ALT.sh
general_FAKE_TLS_AUTO_ALT2.sh
general_FAKE_TLS_AUTO_ALT3.sh
general_SIMPLE_FAKE.sh
general_SIMPLE_FAKE_ALT.sh
general_SIMPLE_FAKE_ALT2.sh
general_ALT5.sh # NOT RECOMMENDED, last
)
# Test a single URL
test_url() {
local url="$1"
local timeout=8
local code
code=$(curl -o /dev/null -s -w "%{http_code}" --max-time "$timeout" -L "$url" 2>/dev/null)
if [[ "$code" == "200" ]] || [[ "$code" == "301" ]] || [[ "$code" == "302" ]] || [[ "$code" == "307" ]]; then
return 0
fi
return 1
}
# Test all targets for a strategy
test_strategy() {
local passed=0
local total=${#TEST_URLS[@]}
echo " [*] Testing connectivity..."
for entry in "${TEST_URLS[@]}"; do
IFS='|' read -r url name <<< "$entry"
if test_url "$url"; then
echo " $(print_green "[OK]") $name"
((passed++))
else
echo " $(print_red "[FAIL]") $name"
fi
done
echo " [*] Result: $passed/$total passed"
if [[ "$passed" -eq "$total" ]]; then
return 0
fi
return 1
}
# Run a strategy with timeout
run_strategy_test() {
local strategy="$1"
local strategy_path="$SCRIPT_DIR/$strategy"
local strategy_name="${strategy%.sh}"
echo ""
echo "=============================================="
echo " Testing: $strategy_name"
echo " $(describe_strategy "$strategy_path")"
echo "=============================================="
# Check if strategy file exists
if [[ ! -f "$strategy_path" ]]; then
print_yellow " [!] Strategy file not found, skipping..."
return 1
fi
# Start strategy in background
echo " [*] Starting $strategy_name..."
sudo "$strategy_path" >/dev/null 2>&1 &
local nfqws_pid=$!
# Wait for nfqws to initialize
sleep 3
# Check if nfqws actually started
if ! pgrep -f "nfqws.*qnum=$NFQUEUE_NUM" >/dev/null 2>&1; then
print_yellow " [!] nfqws did not start for $strategy_name, skipping..."
cleanup_firewall >/dev/null 2>&1 || true
return 1
fi
# Run connectivity tests
local success=0
if test_strategy; then
success=1
fi
# Stop strategy
echo " [*] Stopping $strategy_name..."
cleanup_firewall >/dev/null 2&1 || true
sleep 1
if [[ "$success" -eq 1 ]]; then
return 0
fi
return 1
}
# Main autotest logic
main() {
local auto_install="${1:-}"
echo ""
echo "=============================================="
echo " Zapret Auto-Test v$LOCAL_VERSION"
echo " Will test ${#STRATEGIES[@]} strategies"
echo "=============================================="
echo ""
# Check prerequisites
if [[ "$EUID" -ne 0 ]]; then
print_red "[!] This script must be run as root (or with sudo)"
echo " sudo ./autotest.sh"
exit 1
fi
check_nfqws || {
echo ""
echo "[*] nfqws not found. Building first..."
bash "$SCRIPT_DIR/install_nfqws.sh"
}
echo "[*] Test targets:"
for entry in "${TEST_URLS[@]}"; do
IFS='|' read -r url name <<< "$entry"
echo " - $name ($url)"
done
echo ""
if [[ "$auto_install" != "--auto" ]]; then
read -rp "Press Enter to start testing... or Ctrl+C to cancel"
fi
# Ensure clean state
cleanup_firewall >/dev/null 2>&1 || true
sleep 1
local working_strategy=""
local working_desc=""
for strat in "${STRATEGIES[@]}"; do
if run_strategy_test "$strat"; then
working_strategy="$strat"
working_desc="$(describe_strategy "$SCRIPT_DIR/$strat")"
break
fi
done
echo ""
echo "=============================================="
if [[ -n "$working_strategy" ]]; then
print_green " WORKING STRATEGY FOUND!"
print_green " Strategy: ${working_strategy%.sh}"
print_green " Desc: $working_desc"
echo "=============================================="
echo ""
if [[ "$auto_install" == "--auto" ]]; then
echo "[*] Auto-installing to systemd..."
# Write strategy marker directly
mkdir -p "$SCRIPT_DIR/.service"
echo "${working_strategy%.sh}" > "$SCRIPT_DIR/.service/installed_strategy"
local service_path="$SYSTEMD_DIR/zapret.service"
cat > "$service_path" <<EOF
[Unit]
Description=Zapret DPI bypass (strategy: ${working_strategy%.sh})
After=network.target
[Service]
Type=simple
ExecStart=$SCRIPT_DIR/$working_strategy
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
cp "$service_path" /etc/systemd/system/zapret.service
systemctl daemon-reload
systemctl enable zapret.service
systemctl start zapret.service
print_green "[OK] Installed and started!"
echo ""
systemctl status zapret --no-pager
else
echo "[*] Next steps:"
echo " 1. Test in browser: open youtube.com and discord.com"
echo " 2. If everything works, install it:"
echo ""
echo " sudo ./service.sh"
echo " → 1. Install Service"
echo " → Choose: ${working_strategy%.sh}"
echo ""
read -rp "Install this strategy to systemd now? [Y/n]: " ans
if [[ "${ans:-Y}" == [yY]* ]]; then
bash "$SCRIPT_DIR/service.sh" >&1 &
# The service.sh menu will handle installation
fi
fi
else
print_red " NO WORKING STRATEGY FOUND"
echo "=============================================="
echo ""
echo "[*] Suggestions:"
echo " - Try adding custom domains to lists/list-general-user.txt"
echo " - Check that Secure DNS is enabled"
echo " - Try modifying strategy parameters manually in run_strategy.sh"
echo " - Check diagnostics: sudo ./service.sh → 10. Run Diagnostics"
fi
echo ""
echo "[*] Auto-test complete."
echo ""
}
# Entry point
case "${1:-interactive}" in
--auto|-a)
main --auto
;;
interactive|"")
main interactive
;;
*)
echo "Usage: sudo ./autotest.sh [--auto|-a]"
exit 1
;;
esac

4
general.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
# general.sh wrapper - Standard multisplit strategy
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" general

4
general_ALT.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
# general_ALT.sh wrapper
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT

3
general_ALT10.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT10

3
general_ALT11.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT11

3
general_ALT2.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT2

3
general_ALT3.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT3

3
general_ALT4.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT4

3
general_ALT5.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT5

3
general_ALT6.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT6

3
general_ALT7.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT7

3
general_ALT8.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT8

3
general_ALT9.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" ALT9

3
general_FAKE_TLS_AUTO.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" FAKE_TLS_AUTO

View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" FAKE_TLS_AUTO_ALT

View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" FAKE_TLS_AUTO_ALT2

View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" FAKE_TLS_AUTO_ALT3

3
general_SIMPLE_FAKE.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" SIMPLE_FAKE

View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" SIMPLE_FAKE_ALT

View File

@@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/run_strategy.sh" SIMPLE_FAKE_ALT2

77
install.sh Normal file
View File

@@ -0,0 +1,77 @@
#!/bin/bash
# install.sh - One-shot installer: setup + build + autotest + systemd install
# Run once after cloning the repository.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
if [[ "$EUID" -ne 0 ]]; then
print_red "[!] This script must be run as root (or with sudo)"
echo " sudo ./install.sh"
exit 1
fi
echo ""
echo "=============================================="
echo " Zapret for Linux - Full Installer"
echo "=============================================="
echo ""
echo " This will:"
echo " 1. Install dependencies (git, make, gcc, curl)"
echo " 2. Build nfqws binary from source"
echo " 3. Run autotest to find working strategy"
echo " 4. Install systemd service for auto-start"
echo ""
read -rp "Continue? [Y/n]: " ans
if [[ "${ans:-Y}" != [yY]* ]]; then
echo "Aborted."
exit 0
fi
# Step 1: Setup
echo ""
echo "[*] Step 1/4: Running setup..."
bash "$SCRIPT_DIR/setup.sh"
# Step 2: Build (done inside setup, but verify)
echo ""
echo "[*] Step 2/4: Verifying build..."
check_nfqws || {
print_red "[!] nfqws not found after setup. Trying to rebuild..."
bash "$SCRIPT_DIR/install_nfqws.sh"
}
# Step 3: Auto-test
echo ""
echo "[*] Step 3/4: Auto-testing strategies..."
bash "$SCRIPT_DIR/autotest.sh" --auto
# Step 4: Done
echo ""
print_green "=============================================="
print_green " Installation Complete!"
print_green "=============================================="
echo ""
if command -v systemctl >/dev/null 2>&1; then
echo "[*] Service status:"
systemctl status zapret --no-pager 2>/dev/null || true
echo ""
echo "Commands:"
echo " sudo systemctl status zapret # check status"
echo " sudo systemctl stop zapret # stop"
echo " sudo systemctl start zapret # start"
echo " sudo systemctl restart zapret # restart"
echo " sudo journalctl -u zapret -f # view logs"
else
echo "[*] systemd not found. To start manually:"
echo " sudo ./general.sh (or any other strategy)"
fi
echo ""
echo "[*] To update in the future:"
echo " sudo ./update.sh # check for new version + rebuild"
echo " sudo ./update.sh --full-auto # force rebuild + re-test"
echo ""

118
install_nfqws.sh Normal file
View File

@@ -0,0 +1,118 @@
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BIN_DIR="$SCRIPT_DIR/bin"
BUILD_DIR="/tmp/zapret-build-$$"
echo "=============================================="
echo " Zapret Builder for Linux"
echo " Target: nfqws binary"
echo "=============================================="
echo ""
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO="$ID"
else
DISTRO="unknown"
fi
echo "[*] Detected distro: $DISTRO"
echo "[*] Installing build dependencies..."
install_deps() {
case "$DISTRO" in
ubuntu|debian|linuxmint|pop|zorin|kubuntu|xubuntu|lubuntu)
sudo apt-get update
sudo apt-get install -y git make gcc curl iptables nftables libnetfilter-queue-dev libcap-dev build-essential
;;
arch|manjaro|endeavouros|garuda|artix|arcolinux|blackarch)
if command -v pacman >/dev/null 2>&1; then
sudo pacman -Syu --noconfirm git make gcc curl iptables nftables libnetfilter_queue libcap
elif command -v yay >/dev/null 2>&1; then
yay -Syu --noconfirm git make gcc curl iptables nftables libnetfilter_queue libcap
elif command -v paru >/dev/null 2>&1; then
paru -Syu --noconfirm git make gcc curl iptables nftables libnetfilter_queue libcap
fi
;;
fedora|rhel|centos|almalinux|rocky)
sudo dnf install -y git make gcc curl iptables nftables libnetfilter_queue-devel libcap-devel
;;
alpine)
sudo apk add --no-cache git make gcc curl iptables nftables libnetfilter_queue-dev libcap-dev linux-headers
;;
*)
echo "[!] Unknown/unsupported distro: $DISTRO"
echo " Required packages: git, make, gcc, libnetfilter_queue (dev), curl"
read -rp "Continue anyway? [y/N]: " ans
if [[ "$ans" != [yY]* ]]; then
exit 1
fi
;;
esac
}
install_deps
echo ""
echo "[*] Cloning bol-van/zapret..."
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
if ! git clone --depth=1 https://github.com/bol-van/zapret.git; then
echo "[!] Failed to clone repository. Check your internet connection."
exit 1
fi
cd zapret
echo "[*] Building nfqws..."
if ! make -C nfq; then
echo "[!] Build failed!"
echo " Check that you have all dependencies installed."
exit 1
fi
if [ ! -f "$BUILD_DIR/zapret/nfq/nfqws" ]; then
echo "[!] Build failed: nfqws not found after compilation"
exit 1
fi
mkdir -p "$BIN_DIR"
cp "$BUILD_DIR/zapret/nfq/nfqws" "$BIN_DIR/"
chmod +x "$BIN_DIR/nfqws"
echo ""
echo "[*] Installing fake packet binaries..."
FAKE_BIN_URL="https://github.com/bol-van/zapret/raw/master/files/fake"
for f in quic_initial_www_google_com.bin quic_initial_dbankcloud_ru.bin tls_clienthello_www_google_com.bin tls_clienthello_4pda_to.bin tls_clienthello_max_ru.bin stun.bin; do
if curl -sfL "$FAKE_BIN_URL/$f" -o "$BIN_DIR/$f" 2>/dev/null; then
echo " [OK] $f"
else
echo " [SKIP] $f (will try to find local alternatives)"
fi
done
echo ""
echo "[*] Setting capabilities (optional, allows running without root)..."
if command -v setcap >/dev/null 2>&1; then
sudo setcap cap_net_admin,cap_net_raw+eip "$BIN_DIR/nfqws" 2>/dev/null || true
echo " [OK] cap_net_admin,cap_net_raw set on nfqws"
fi
echo ""
echo "[*] Cleanup..."
cd "$SCRIPT_DIR"
rm -rf "$BUILD_DIR"
echo ""
echo "=============================================="
echo " Build complete!"
echo " Binary: $BIN_DIR/nfqws"
echo "=============================================="
echo ""
echo "Next steps:"
echo " 1. Run './service.sh' to manage strategies"
echo " 2. Or run any './general*.sh' script directly"
echo ""

216
lib/functions.sh Normal file
View File

@@ -0,0 +1,216 @@
#!/bin/bash
# Common functions for zapret-discord-youtube Linux
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
BIN_DIR="$SCRIPT_DIR/bin"
LISTS_DIR="$SCRIPT_DIR/lists"
UTILS_DIR="$SCRIPT_DIR/utils"
SYSTEMD_DIR="$SCRIPT_DIR/systemd"
LOCAL_VERSION="1.9.8c-linux"
NFT_TABLE="zapret"
NFQUEUE_NUM=200
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
print_green() { echo -e "${GREEN}$1${NC}"; }
print_red() { echo -e "${RED}$1${NC}"; }
print_yellow(){ echo -e "${YELLOW}$1${NC}"; }
print_cyan() { echo -e "${CYAN}$1${NC}"; }
# Detect package manager
detect_distro() {
if [ -f /etc/os-release ]; then
. /etc/os-release
echo "$ID"
else
echo "unknown"
fi
}
# iptables wrapper with -w support
iptables_cmd() {
if iptables -w -L -n -t mangle >/dev/null 2>&1; then
iptables -w "$@"
else
iptables "$@"
fi
}
ip6tables_cmd() {
if ip6tables -w -L -n -t mangle >/dev/null 2>&1; then
ip6tables -w "$@"
else
ip6tables "$@"
fi
}
nft_supports() {
nft list tables >/dev/null 2>&1
}
load_user_lists() {
if [[ ! -f "$LISTS_DIR/ipset-exclude-user.txt" ]]; then
echo "203.0.113.113/32" > "$LISTS_DIR/ipset-exclude-user.txt"
fi
if [[ ! -f "$LISTS_DIR/list-general-user.txt" ]]; then
echo "domain.example.abc" > "$LISTS_DIR/list-general-user.txt"
fi
if [[ ! -f "$LISTS_DIR/list-exclude-user.txt" ]]; then
echo "domain.example.abc" > "$LISTS_DIR/list-exclude-user.txt"
fi
}
get_game_filter() {
if [[ -f "$SCRIPT_DIR/.service/game_filter_enabled" ]]; then
GameFilter="enabled"
GameFilterTCP="1024:65535"
GameFilterUDP="1024:65535"
else
GameFilter="disabled"
GameFilterTCP=""
GameFilterUDP=""
fi
}
describe_strategy() {
local name
name=$(basename "$1")
case "$name" in
general.sh) echo "Standard multisplit strategy";;
general_ALT.sh) echo "Fake fakedsplit with ts fooling";;
general_ALT2.sh) echo "Multisplit with split-pos=2";;
general_ALT3.sh) echo "Hostfake split (Google/ya.ru)";;
general_ALT4.sh) echo "Fake multisplit with badseq";;
general_ALT5.sh) echo "NOT RECOMMENDED: syndata multidisorder";;
general_ALT6.sh) echo "Uniform split-seqovl=681";;
general_ALT7.sh) echo "Multisplit + syndata";;
general_ALT8.sh) echo "Fake with badseq-increment=2";;
general_ALT9.sh) echo "Hostfakesplit (ozon.ru)";;
general_ALT10.sh) echo "Fake with ts fooling";;
general_ALT11.sh) echo "Fake multisplit with max_ru pattern";;
general_FAKE_TLS_AUTO.sh) echo "FAKE TLS AUTO multidisorder";;
general_FAKE_TLS_AUTO_ALT.sh) echo "FAKE TLS fakedsplit";;
general_FAKE_TLS_AUTO_ALT2.sh) echo "FAKE TLS multisplit badseq";;
general_FAKE_TLS_AUTO_ALT3.sh) echo "FAKE TLS with 4pda pattern";;
general_SIMPLE_FAKE.sh) echo "Simple fake strategy";;
general_SIMPLE_FAKE_ALT.sh) echo "Simple fakedsplit";;
general_SIMPLE_FAKE_ALT2.sh) echo "Simple hostfakesplit";;
*) echo "Custom strategy";;
esac
}
check_nfqws() {
if [[ ! -x "$BIN_DIR/nfqws" ]]; then
echo ""
print_red "ERROR: nfqws binary not found!"
echo ""
echo "Please build it first:"
echo " ./install_nfqws.sh"
echo ""
return 1
fi
return 0
}
tcp_enable_timestamps() {
if [[ -w /proc/sys/net/ipv4/tcp_timestamps ]]; then
echo 1 > /proc/sys/net/ipv4/tcp_timestamps 2>/dev/null || true
fi
}
setup_firewall() {
local tcp_ports="80,443,2053,2083,2087,2096,8443"
local udp_ports="443,19294:19344,50000:50100"
get_game_filter
if [[ -n "$GameFilterTCP" ]]; then
tcp_ports="${tcp_ports},${GameFilterTCP}"
fi
if [[ -n "$GameFilterUDP" ]]; then
udp_ports="${udp_ports},${GameFilterUDP}"
fi
if nft_supports; then
print_cyan "[*] Using nftables..."
nft add table ip $NFT_TABLE 2>/dev/null || true
nft add chain ip $NFT_TABLE postrouting '{ type filter hook postrouting priority mangle; policy accept; }' 2>/dev/null || nft flush chain ip $NFT_TABLE postrouting 2>/dev/null || true
IFS=',' read -ra TCP_P <<< "$tcp_ports"
for port in "${TCP_P[@]}"; do
nft add rule ip $NFT_TABLE postrouting tcp dport "$port" counter queue num $NFQUEUE_NUM 2>/dev/null || true
done
IFS=',' read -ra UDP_P <<< "$udp_ports"
for port in "${UDP_P[@]}"; do
nft add rule ip $NFT_TABLE postrouting udp dport "$port" counter queue num $NFQUEUE_NUM 2>/dev/null || true
done
else
print_cyan "[*] Using iptables..."
IFS=',' read -ra TCP_P <<< "$tcp_ports"
for port in "${TCP_P[@]}"; do
iptables_cmd -t mangle -C POSTROUTING -p tcp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM" 2>/dev/null || \
iptables_cmd -t mangle -I POSTROUTING -p tcp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM"
done
IFS=',' read -ra UDP_P <<< "$udp_ports"
for port in "${UDP_P[@]}"; do
iptables_cmd -t mangle -C POSTROUTING -p udp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM" 2>/dev/null || \
iptables_cmd -t mangle -I POSTROUTING -p udp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM"
done
fi
}
cleanup_firewall() {
echo "[*] Removing firewall rules..."
pkill -f "nfqws.*qnum=$NFQUEUE_NUM" 2>/dev/null || true
sleep 1
if nft list table ip $NFT_TABLE >/dev/null 2>&1; then
nft delete table ip $NFT_TABLE 2>/dev/null || true
fi
local ports=(80 443 2053 2083 2087 2096 8443 "1024:65535")
for port in "${ports[@]}"; do
while iptables_cmd -t mangle -C POSTROUTING -p tcp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM" 2>/dev/null; do
iptables_cmd -t mangle -D POSTROUTING -p tcp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM" 2>/dev/null || break
done
while iptables_cmd -t mangle -C POSTROUTING -p udp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM" 2>/dev/null; do
iptables_cmd -t mangle -D POSTROUTING -p udp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM" 2>/dev/null || break
done
done
for port in 19294:19344 50000:50100; do
while iptables_cmd -t mangle -C POSTROUTING -p udp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM" 2>/dev/null; do
iptables_cmd -t mangle -D POSTROUTING -p udp --dport "$port" -j NFQUEUE --queue-num "$NFQUEUE_NUM" 2>/dev/null || break
done
done
}
run_nfqws() {
local strategy_file="$1"
shift
check_nfqws || return 1
tcp_enable_timestamps
load_user_lists
get_game_filter
if pgrep -f "nfqws.*qnum=$NFQUEUE_NUM" >/dev/null 2>&1; then
print_yellow "WARNING: nfqws is already running. Stopping existing instance..."
cleanup_firewall
sleep 1
fi
setup_firewall
local strat_name
strat_name=$(basename "$strategy_file")
echo ""
print_cyan "[*] Starting strategy: $strat_name"
print_cyan "[*] $(describe_strategy "$strategy_file")"
echo ""
"$BIN_DIR/nfqws" --qnum=$NFQUEUE_NUM "$@"
}

1
lists/ipset-all.txt Normal file
View File

@@ -0,0 +1 @@
203.0.113.113/32

11
lists/ipset-exclude.txt Normal file
View File

@@ -0,0 +1,11 @@
0.0.0.0/8
10.0.0.0/8
127.0.0.0/8
172.16.0.0/12
192.168.0.0/16
169.254.0.0/16
224.0.0.0/4
100.64.0.0/10
::1
fc00::/7
fe80::/10

91
lists/list-exclude.txt Normal file
View File

@@ -0,0 +1,91 @@
pusher.com
live-video.net
ttvnw.net
twitch.tv
mail.ru
citilink.ru
yandex.com
nvidia.com
donationalerts.com
vk.com
yandex.kz
mts.ru
multimc.org
ya.ru
dns-shop.ru
habr.com
3dnews.ru
microsoft.com
microsoftonline.com
live.com
minecraft.net
xboxlive.com
akamaitechnologies.com
msi.com
2ip.ru
yandex.ru
boosty.to
tanki.su
lesta.ru
korabli.su
tanksblitz.ru
reg.ru
epicgames.dev
epicgames.com
unrealengine.com
riotgames.com
riotcdn.net
leagueoflegends.com
playvalorant.com
marketplace.visualstudio.com
gosuslugi.ru
gov.ru
nalog.ru
spb.ru
mos.ru
yandex.net
vk.ru
vk.me
vkvideo.ru
ok.ru
mycdn.me
okcdn.ru
odkl.ru
wb.ru
geobasket.ru
paywb.com
rwb.ru
wb-basket.ru
wbbasket.ru
wbpay.ru
wibes.ru
wildberries.ru
ozon.by
ozon.com
ozon.com.by
ozon.com.kz
ozon.kz
ozon.ru
ozon.tm
ozone.ru
ozonru.me
ozonusercontent.com
alfabank.ru
gazprombank.ru
gpb.ru
dbo-dengi.online
mtsdengi.ru
psbank.ru
bankline.ru
rosbank.ru
abr.ru
rshb.ru
sber.ru
sberbank.com
sberbank.ru
cdn-tinkoff.ru
tbank-online.com
tbank.ru
tochka-tech.com
tochka.com
vtb.ru

49
lists/list-general.txt Normal file
View File

@@ -0,0 +1,49 @@
cloudflare-ech.com
encryptedsni.com
cloudflareaccess.com
cloudflareapps.com
cloudflarebolt.com
cloudflareclient.com
cloudflareinsights.com
cloudflareok.com
cloudflarepartners.com
cloudflareportal.com
cloudflarepreview.com
cloudflareresolve.com
cloudflaressl.com
cloudflarestatus.com
cloudflarestorage.com
cloudflarestream.com
cloudflaretest.com
cloudfront.net
dis.gd
discord-attachments-uploads-prd.storage.googleapis.com
discord.app
discord.co
discord.com
discord.design
discord.dev
discord.gift
discord.gifts
discord.gg
discord.media
discord.new
discord.store
discord.status
discord-activities.com
discordactivities.com
discordapp.com
discordapp.net
discordcdn.com
discordmerch.com
discordpartygames.com
discordsays.com
discordsez.com
discordstatus.com
frankerfacez.com
ffzap.com
betterttv.net
7tv.app
7tv.io
localizeapi.com
klipy.com

18
lists/list-google.txt Normal file
View File

@@ -0,0 +1,18 @@
yt3.ggpht.com
yt4.ggpht.com
yt3.googleusercontent.com
googlevideo.com
jnn-pa.googleapis.com
stable.dl2.discordapp.net
wide-youtube.l.google.com
youtube-nocookie.com
youtube-ui.l.google.com
youtube.com
youtubeembeddedplayer.googleapis.com
youtubekids.com
youtubei.googleapis.com
youtu.be
yt-video-upload.l.google.com
ytimg.com
ytimg.l.google.com
play.google.com

356
run_strategy.sh Normal file
View File

@@ -0,0 +1,356 @@
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
STRATEGY="${1:-general}"
# Load settings
bash "$SCRIPT_DIR/service.sh" status_zapret >/dev/null 2>&1 || true
bash "$SCRIPT_DIR/service.sh" check_updates >/dev/null 2>&1 || true
bash "$SCRIPT_DIR/service.sh" load_game_filter >/dev/null 2>&1 || true
bash "$SCRIPT_DIR/service.sh" load_user_lists >/dev/null 2>&1 || true
load_user_lists
get_game_filter
# Build dynamic game filter args
TCP_GAME=""
UDP_GAME=""
[[ -n "$GameFilterTCP" ]] && TCP_GAME="--filter-tcp=$GameFilterTCP"
[[ -n "$GameFilterUDP" ]] && UDP_GAME="--filter-udp=$GameFilterUDP"
# Common rule 1: UDP 443 general
RULE1=(
--filter-udp=443
--hostlist="$LISTS_DIR/list-general.txt"
--hostlist="$LISTS_DIR/list-general-user.txt"
--hostlist-exclude="$LISTS_DIR/list-exclude.txt"
--hostlist-exclude="$LISTS_DIR/list-exclude-user.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt"
)
# Common rule 2: UDP discord/stun
RULE2=(
--filter-udp=19294-19344,50000-50100
--filter-l7=discord,stun
)
# Common rule 6: UDP 443 ipset-all
RULE6=(
--filter-udp=443
--ipset="$LISTS_DIR/ipset-all.txt"
--hostlist-exclude="$LISTS_DIR/list-exclude.txt"
--hostlist-exclude="$LISTS_DIR/list-exclude-user.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt"
)
# Common rule 9: UDP game filter
RULE9=()
if [[ -n "$UDP_GAME" ]]; then
RULE9+=("$UDP_GAME")
fi
RULE9+=(
--ipset="$LISTS_DIR/ipset-all.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude.txt"
--ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt"
)
# Parse strategy-specific args
case "$STRATEGY" in
general)
# Rule 3
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
# Rule 4
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
# Rule 5
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_4pda_to.bin")
# Rule 6 extra
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
# Rule 7
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_4pda_to.bin")
# Rule 8
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-seqovl=568 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_4pda_to.bin")
# Rule 9 extra
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n3)
;;
ALT2)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-seqovl=652 --dpi-desync-split-pos=2 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT3)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fooling=ts)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fooling=ts)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n4)
;;
ALT4)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=1000 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT5)
RULE3=(--filter-l3=ipv4 --filter-tcp=80,443,2053,2083,2087,2096,8443 --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=syndata,multidisorder)
RULE4=()
RULE5=()
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=()
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=syndata,multidisorder --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4)
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=14 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n3)
;;
ALT6)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT7)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=multisplit --dpi-desync-split-pos=2,sniext+1 --dpi-desync-split-seqovl=679 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=multisplit --dpi-desync-split-pos=2,sniext+1 --dpi-desync-split-seqovl=679 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=multisplit --dpi-desync-split-pos=2,sniext+1 --dpi-desync-split-seqovl=679 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=syndata)
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=syndata --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4)
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT8)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fake-tls-mod=none --dpi-desync-repeats=6 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT9)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=www.google.com)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=www.google.com)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-fooling=ts,md5sig --dpi-desync-hostfakesplit-mod=host=ozon.ru)
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru)
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=4 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru)
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT10)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=12 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
ALT11)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=664 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=664 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-split-seqovl=664 --dpi-desync-split-pos=1 --dpi-desync-fooling=ts --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_max_ru.bin" --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n4)
;;
FAKE_TLS_AUTO)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multidisorder --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badseq --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
FAKE_TLS_AUTO_ALT)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,fakedsplit --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,fakedsplit --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=2 --dpi-desync-repeats=8 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
FAKE_TLS_AUTO_ALT2)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,multisplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-split-seqovl=681 --dpi-desync-split-pos=1 --dpi-desync-fooling=badseq --dpi-desync-badseq-increment=10000000 --dpi-desync-repeats=8 --dpi-desync-split-seqovl-pattern="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
FAKE_TLS_AUTO_ALT3)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,hostfakesplit --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n4 --dpi-desync-fake-tls-mod=rnd,dupsid,sni=ya.ru --dpi-desync-hostfakesplit-mod=host=ya.ru,altorder=1 --dpi-desync-fooling=ts --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_4pda_to.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
SIMPLE_FAKE)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
SIMPLE_FAKE_ALT)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_www_google_com.bin" --dpi-desync-fake-tls-mod=none)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=fake,fakedsplit --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-fakedsplit-pattern=0x00 --dpi-desync-fake-tls="$BIN_DIR/stun.bin" --dpi-desync-fake-tls="$BIN_DIR/tls_clienthello_4pda_to.bin" --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
SIMPLE_FAKE_ALT2)
RULE3=(--filter-tcp=2053,2083,2087,2096,8443 --hostlist-domains=discord.media --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fake-tls-mod=none)
RULE4=(--filter-tcp=443 --hostlist="$LISTS_DIR/list-google.txt" --ip-id=zero --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=www.google.com,altorder=1 --dpi-desync-fake-tls-mod=none)
RULE5=(--filter-tcp=80,443 --hostlist="$LISTS_DIR/list-general.txt" --hostlist="$LISTS_DIR/list-general-user.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru,altorder=1 --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE6+=(--dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
RULE7=(--filter-tcp=80,443,8443 --ipset="$LISTS_DIR/ipset-all.txt" --hostlist-exclude="$LISTS_DIR/list-exclude.txt" --hostlist-exclude="$LISTS_DIR/list-exclude-user.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru,altorder=1 --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE8=()
[[ -n "$TCP_GAME" ]] && RULE8+=("$TCP_GAME")
RULE8+=(--ipset="$LISTS_DIR/ipset-all.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude.txt" --ipset-exclude="$LISTS_DIR/ipset-exclude-user.txt" --dpi-desync=hostfakesplit --dpi-desync-repeats=6 --dpi-desync-any-protocol=1 --dpi-desync-cutoff=n3 --dpi-desync-fooling=ts --dpi-desync-hostfakesplit-mod=host=ozon.ru,altorder=1 --dpi-desync-fake-tls-mod=none --dpi-desync-fake-http="$BIN_DIR/tls_clienthello_max_ru.bin")
RULE9+=(--dpi-desync=fake --dpi-desync-repeats=10 --dpi-desync-any-protocol=1 --dpi-desync-fake-unknown-udp="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-cutoff=n2)
;;
*)
echo "Unknown strategy: $STRATEGY"
echo "Valid strategies: general, ALT, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9, ALT10, ALT11, FAKE_TLS_AUTO, FAKE_TLS_AUTO_ALT, FAKE_TLS_AUTO_ALT2, FAKE_TLS_AUTO_ALT3, SIMPLE_FAKE, SIMPLE_FAKE_ALT, SIMPLE_FAKE_ALT2"
exit 1
;;
esac
# Build final args
FINAL_ARGS=()
# Rule 1: UDP 443 general
FINAL_ARGS+=("${RULE1[@]}")
FINAL_ARGS+=(--dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic="$BIN_DIR/quic_initial_www_google_com.bin")
FINAL_ARGS+=(--new)
# Rule 2: UDP discord/stun
FINAL_ARGS+=("${RULE2[@]}")
FINAL_ARGS+=(--dpi-desync=fake --dpi-desync-fake-discord="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-fake-stun="$BIN_DIR/quic_initial_dbankcloud_ru.bin" --dpi-desync-repeats=6)
FINAL_ARGS+=(--new)
# Rule 3
if [[ ${#RULE3[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE3[@]}")
FINAL_ARGS+=(--new)
fi
# Rule 4
if [[ ${#RULE4[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE4[@]}")
FINAL_ARGS+=(--new)
fi
# Rule 5
if [[ ${#RULE5[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE5[@]}")
FINAL_ARGS+=(--new)
fi
# Rule 6
FINAL_ARGS+=("${RULE6[@]}")
FINAL_ARGS+=(--new)
# Rule 7
if [[ ${#RULE7[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE7[@]}")
FINAL_ARGS+=(--new)
fi
# Rule 8
if [[ ${#RULE8[@]} -gt 0 ]]; then
FINAL_ARGS+=("${RULE8[@]}")
FINAL_ARGS+=(--new)
fi
# Rule 9
FINAL_ARGS+=("${RULE9[@]}")
run_nfqws "$0" "${FINAL_ARGS[@]}"

547
service.sh Normal file
View File

@@ -0,0 +1,547 @@
#!/bin/bash
# service.sh - Zapret Service Manager for Linux
# Analogous to service.bat on Windows
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
# ============================================
# External commands (called from general*.sh)
# ============================================
if [[ "$1" == "status_zapret" ]]; then
check_nfqws >/dev/null 2>&1 || true
tcp_enable_timestamps
exit 0
fi
if [[ "$1" == "check_updates" ]]; then
if [[ "${2:-}" != "soft" ]]; then
bash "$0" check_updates soft >&1 &
exit 0
else
check_for_updates soft
exit 0
fi
fi
if [[ "$1" == "load_game_filter" ]]; then
get_game_filter
exit 0
fi
if [[ "$1" == "load_user_lists" ]]; then
load_user_lists
exit 0
fi
# ============================================
# MENU
# ============================================
show_menu() {
local ipset_status game_filter_status check_updates_status current_strategy
ipset_status=$(ipset_switch_status)
game_filter_status=$(game_switch_status)
check_updates_status=$(check_updates_switch_status)
current_strategy=$(get_strategy_name)
echo ""
echo " ZAPRET SERVICE MANAGER v$LOCAL_VERSION"
echo " $current_strategy"
echo " ----------------------------------------"
echo ""
echo " :: SERVICE"
echo " 1. Install Service"
echo " 2. Remove Services"
echo " 3. Check Status"
echo ""
echo " :: SETTINGS"
echo " 4. Game Filter [$game_filter_status]"
echo " 5. IPSet Filter [$ipset_status]"
echo " 6. Auto-Update Check [$check_updates_status]"
echo ""
echo " :: UPDATES"
echo " 7. Update IPSet List"
echo " 8. Update Hosts File"
echo " 9. Check for Updates"
echo ""
echo " :: TOOLS"
echo " 10. Run Diagnostics"
echo " 11. Run Tests"
echo ""
echo " ----------------------------------------"
echo " 0. Exit"
echo ""
}
# ============================================
# STATUS HELPERS
# ============================================
get_strategy_name() {
if [[ -f "$SCRIPT_DIR/.service/installed_strategy" ]]; then
local strat
strat=$(cat "$SCRIPT_DIR/.service/installed_strategy")
echo "Current strategy: $strat"
else
echo "No service installed"
fi
}
ipset_switch_status() {
if [[ -f "$SCRIPT_DIR/.service/ipset_filter_any" ]]; then
echo "any"
elif [[ -f "$SCRIPT_DIR/.service/ipset_filter_loaded" ]]; then
echo "loaded"
else
echo "none"
fi
}
game_switch_status() {
if [[ -f "$SCRIPT_DIR/.service/game_filter_enabled" ]]; then
echo "enabled"
else
echo "disabled"
fi
}
check_updates_switch_status() {
if [[ -f "$SCRIPT_DIR/.service/check_updates_enabled" ]]; then
echo "enabled"
else
echo "disabled"
fi
}
# ============================================
# SERVICE INSTALL
# ============================================
service_install() {
echo ""
echo "[*] Pick one of the strategies:"
echo ""
local files=()
local i=1
while IFS= read -r -d '' f; do
local name
name=$(basename "$f")
[[ "$name" == service.sh ]] && continue
[[ "$name" == run_strategy.sh ]] && continue
[[ "$name" == install_nfqws.sh ]] && continue
[[ "$name" == lib ]] && continue
files+=("$f")
local desc
desc=$(describe_strategy "$f")
printf " %2d. %-35s %s\n" "$i" "$name" "$desc"
((i++))
done <<< "$(find "$SCRIPT_DIR" -maxdepth 1 -type f -name '*.sh' -print0 | sort -z)"
echo ""
read -rp " Input file index (number): " choice
if [[ -z "$choice" ]]; then
echo "The choice is empty, exiting..."
return
fi
local selected="${files[$((choice-1))]}"
if [[ -z "$selected" ]]; then
echo "Invalid choice, exiting..."
return
fi
local strategy_name
strategy_name=$(basename "$selected" .sh)
echo ""
echo "[*] Installing strategy: $strategy_name"
# Stop any existing service
bash "$0" remove_services >/dev/null 2>&1 || true
# Write strategy marker
mkdir -p "$SCRIPT_DIR/.service"
echo "$strategy_name" > "$SCRIPT_DIR/.service/installed_strategy"
# Create systemd service file
local service_path="$SYSTEMD_DIR/zapret.service"
cat > "$service_path" <<EOF
[Unit]
Description=Zapret DPI bypass (strategy: $strategy_name)
After=network.target
[Service]
Type=simple
ExecStart=$selected
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
# Install and enable
if command -v systemctl >/dev/null 2>&1; then
sudo cp "$service_path" /etc/systemd/system/zapret.service
sudo systemctl daemon-reload
sudo systemctl enable zapret.service
sudo systemctl start zapret.service
echo ""
print_green "[OK] Service installed and started."
echo " Strategy: $strategy_name"
echo " systemd: /etc/systemd/system/zapret.service"
else
echo ""
print_yellow "[!] systemctl not found. Service file created but not installed automatically."
echo " To start manually: $selected"
fi
read -rp "Press Enter to continue..."
}
# ============================================
# SERVICE REMOVE
# ============================================
service_remove() {
echo ""
echo "[*] Removing services..."
# Stop systemd service
if command -v systemctl >/dev/null 2>&1; then
sudo systemctl stop zapret.service 2>/dev/null || true
sudo systemctl disable zapret.service 2>/dev/null || true
sudo rm -f /etc/systemd/system/zapret.service
sudo systemctl daemon-reload
fi
# Kill nfqws
pkill -f "nfqws.*qnum=$NFQUEUE_NUM" 2>/dev/null || true
sleep 1
# Cleanup firewall
cleanup_firewall
# Remove markers
rm -f "$SCRIPT_DIR/.service/installed_strategy"
echo ""
print_green "[OK] Services removed."
read -rp "Press Enter to continue..."
}
# ============================================
# SERVICE STATUS
# ============================================
service_status() {
echo ""
echo "[*] Service Status"
echo ""
# Check systemd
if command -v systemctl >/dev/null 2>&1; then
if systemctl is-active zapret.service >/dev/null 2>&1; then
print_green "zapret.service is RUNNING."
else
print_red "zapret.service is NOT running."
fi
fi
# Check nfqws process
if pgrep -f "nfqws.*qnum=$NFQUEUE_NUM" >/dev/null 2>&1; then
print_green "nfqws process is RUNNING."
else
print_red "nfqws process is NOT running."
fi
# Check iptables/nftables rules
if nft list table ip $NFT_TABLE >/dev/null 2>&1; then
print_green "nftables rules are LOADED."
elif iptables -t mangle -L -n 2>/dev/null | grep -q "NFQUEUE"; then
print_green "iptables rules are LOADED."
else
print_red "No firewall rules found."
fi
# Show strategy
local strat
strat=$(get_strategy_name)
echo ""
echo "Strategy: $strat"
echo ""
read -rp "Press Enter to continue..."
}
# ============================================
# GAME FILTER SWITCH
# ============================================
game_switch() {
echo ""
if [[ -f "$SCRIPT_DIR/.service/game_filter_enabled" ]]; then
rm -f "$SCRIPT_DIR/.service/game_filter_enabled"
echo "[*] Game Filter: DISABLED"
echo " (Restart strategy to apply)"
else
touch "$SCRIPT_DIR/.service/game_filter_enabled"
echo "[*] Game Filter: ENABLED"
echo " (Restart strategy to apply)"
fi
read -rp "Press Enter to continue..."
}
# ============================================
# IPSET FILTER SWITCH
# ============================================
ipset_switch() {
echo ""
echo "[*] IPSet Filter options:"
echo " 1. none - no IPs checked"
echo " 2. loaded - check against ipset-all.txt"
echo " 3. any - any IP goes through filter"
echo ""
read -rp " Select option (1-3): " choice
rm -f "$SCRIPT_DIR/.service/ipset_filter_none"
rm -f "$SCRIPT_DIR/.service/ipset_filter_loaded"
rm -f "$SCRIPT_DIR/.service/ipset_filter_any"
case "$choice" in
1) touch "$SCRIPT_DIR/.service/ipset_filter_none" ;;
2) touch "$SCRIPT_DIR/.service/ipset_filter_loaded" ;;
3) touch "$SCRIPT_DIR/.service/ipset_filter_any" ;;
*) echo "Invalid choice"; return ;;
esac
echo "[*] IPSet filter updated. (Restart strategy to apply)"
read -rp "Press Enter to continue..."
}
# ============================================
# AUTO-UPDATE SWITCH
# ============================================
check_updates_switch() {
echo ""
if [[ -f "$SCRIPT_DIR/.service/check_updates_enabled" ]]; then
rm -f "$SCRIPT_DIR/.service/check_updates_enabled"
echo "[*] Auto-Update Check: DISABLED"
else
touch "$SCRIPT_DIR/.service/check_updates_enabled"
echo "[*] Auto-Update Check: ENABLED"
fi
read -rp "Press Enter to continue..."
}
# ============================================
# UPDATE IPSET LIST
# ============================================
ipset_update() {
echo ""
echo "[*] Updating IPSet list..."
local url="https://raw.githubusercontent.com/Flowseal/zapret-discord-youtube/main/.service/ipset-all.txt"
if curl -sfL "$url" -o "$LISTS_DIR/ipset-all.txt.new" 2>/dev/null; then
mv "$LISTS_DIR/ipset-all.txt.new" "$LISTS_DIR/ipset-all.txt"
print_green "[OK] ipset-all.txt updated."
else
print_red "[!] Failed to update ipset-all.txt"
echo " (URL may be unavailable)"
fi
read -rp "Press Enter to continue..."
}
# ============================================
# UPDATE HOSTS FILE
# ============================================
hosts_update() {
echo ""
echo "[*] Updating hosts file..."
local hosts_url="https://raw.githubusercontent.com/Flowseal/zapret-discord-youtube/main/.service/hosts.txt"
local temp_hosts="/tmp/zapret_hosts_$$.txt"
if curl -sfL "$hosts_url" -o "$temp_hosts" 2>/dev/null; then
echo ""
echo "[*] New hosts entries:"
cat "$temp_hosts"
echo ""
echo "[*] To apply, add these lines to your /etc/hosts manually:"
echo " sudo nano /etc/hosts"
echo ""
rm -f "$temp_hosts"
else
print_red "[!] Failed to fetch hosts file"
fi
read -rp "Press Enter to continue..."
}
# ============================================
# CHECK FOR UPDATES
# ============================================
check_for_updates() {
local mode="${1:-interactive}"
local github_version_url="https://raw.githubusercontent.com/Flowseal/zapret-discord-youtube/main/.service/version.txt"
local github_release_url="https://github.com/Flowseal/zapret-discord-youtube/releases/latest"
local github_version
github_version=$(curl -sfL "$github_version_url" 2>/dev/null | head -n1 | tr -d '[:space:]')
if [[ -z "$github_version" ]]; then
echo "Warning: failed to fetch the latest version."
if [[ "$mode" == "interactive" ]]; then
read -rp "Press Enter to continue..."
fi
return
fi
if [[ "$LOCAL_VERSION" == "$github_version" ]]; then
echo "Latest version installed: $LOCAL_VERSION"
if [[ "$mode" == "interactive" ]]; then
read -rp "Press Enter to continue..."
fi
return
fi
echo ""
echo "New version available: $github_version"
echo "Your version: $LOCAL_VERSION"
echo "Release page: $github_release_url"
echo ""
if [[ "$mode" == "interactive" ]]; then
read -rp "Open download page? [Y/n]: " ans
if [[ "${ans:-Y}" == [yY]* ]]; then
if command -v xdg-open >/dev/null 2>&1; then
xdg-open "$github_release_url"
elif command -v gnome-open >/dev/null 2>&1; then
gnome-open "$github_release_url"
else
echo "Please open: $github_release_url"
fi
fi
read -rp "Press Enter to continue..."
fi
}
# ============================================
# DIAGNOSTICS
# ============================================
service_diagnostics() {
echo ""
echo "[*] Running Diagnostics"
echo ""
# Check root/sudo
if [[ "$EUID" -ne 0 ]]; then
print_yellow "[!] Not running as root. Some checks may fail."
fi
# Check nfqws
if [[ -x "$BIN_DIR/nfqws" ]]; then
print_green "[OK] nfqws binary found"
else
print_red "[FAIL] nfqws binary NOT found"
echo " Run: ./install_nfqws.sh"
fi
# Check iptables/nftables
if command -v iptables >/dev/null 2>&1; then
print_green "[OK] iptables found"
else
print_red "[FAIL] iptables NOT found"
fi
if command -v nft >/dev/null 2>&1; then
print_green "[OK] nftables (nft) found"
else
print_yellow "[WARN] nftables (nft) NOT found"
fi
# Check kernel modules
if lsmod | grep -q "nfnetlink_queue"; then
print_green "[OK] nfnetlink_queue module loaded"
else
print_yellow "[WARN] nfnetlink_queue module not loaded"
echo " Try: sudo modprobe nfnetlink_queue"
fi
# Check Secure DNS (systemd-resolved)
if command -v resolvectl >/dev/null 2>&1; then
echo ""
echo "[*] DNS settings:"
resolvectl status 2>/dev/null | head -n 20 || true
fi
# Check for conflicting processes
echo ""
echo "[*] Checking for conflicting processes..."
if pgrep -f "goodbye-dpi\|byedpi\|zapret-win" >/dev/null 2>&1; then
print_yellow "[!] Another DPI bypass tool may be running"
else
print_green "[OK] No conflicting processes found"
fi
# Offer to clear Discord cache
echo ""
read -rp "Clear Discord cache? [y/N]: " ans
if [[ "$ans" == [yY]* ]]; then
local discord_cache="$HOME/.config/discord/Cache"
if [[ -d "$discord_cache" ]]; then
rm -rf "$discord_cache"/* 2>/dev/null || true
print_green "[OK] Discord cache cleared."
else
print_yellow "[!] Discord cache directory not found."
fi
fi
echo ""
read -rp "Press Enter to continue..."
}
# ============================================
# RUN TESTS
# ============================================
run_tests() {
echo ""
echo "[*] Running Tests"
echo ""
echo " 1. Standard tests (check common sites)"
echo " 2. DPI checkers (Cloudflare, Amazon, etc.)"
echo ""
read -rp " Select option (1-2): " choice
case "$choice" in
1) bash "$UTILS_DIR/test_zapret.sh" standard ;;
2) bash "$UTILS_DIR/test_zapret.sh" dpi ;;
*) echo "Invalid choice" ;;
esac
read -rp "Press Enter to continue..."
}
# ============================================
# MAIN LOOP
# ============================================
main() {
while true; do
clear 2>/dev/null || true
show_menu
read -rp " Select option (0-11): " menu_choice
case "$menu_choice" in
1) service_install ;;
2) service_remove ;;
3) service_status ;;
4) game_switch ;;
5) ipset_switch ;;
6) check_updates_switch ;;
7) ipset_update ;;
8) hosts_update ;;
9) check_for_updates ;;
10) service_diagnostics ;;
11) run_tests ;;
0) echo "Goodbye!"; exit 0 ;;
*) echo "Invalid option" ; sleep 1 ;;
esac
done
}
main

124
setup.sh Normal file
View File

@@ -0,0 +1,124 @@
#!/bin/bash
# setup.sh - Initial setup for zapret-discord-youtube Linux
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "=============================================="
echo " Zapret for Linux - Setup"
echo "=============================================="
echo ""
# Make all scripts executable
echo "[*] Setting executable permissions..."
chmod +x "$SCRIPT_DIR"/*.sh
chmod +x "$SCRIPT_DIR"/lib/*.sh
chmod +x "$SCRIPT_DIR"/utils/*.sh
print_green "[OK] Permissions set."
# Detect distro
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO="$ID"
else
DISTRO="unknown"
fi
echo ""
echo "[*] Detected distro: $DISTRO"
# Check dependencies
echo ""
echo "[*] Checking dependencies..."
missing=()
if ! command -v curl >/dev/null 2>&1; then
missing+=("curl")
fi
if ! command -v git >/dev/null 2>&1; then
missing+=("git")
fi
if ! command -v make >/dev/null 2>&1; then
missing+=("make")
fi
if ! command -v gcc >/dev/null 2>&1; then
missing+=("gcc")
fi
if [[ ${#missing[@]} -gt 0 ]]; then
print_red "[!] Missing packages: ${missing[*]}"
echo "[*] Attempting to install..."
case "$DISTRO" in
ubuntu|debian|linuxmint|pop)
sudo apt-get update
sudo apt-get install -y curl git make gcc build-essential
;;
arch|manjaro)
sudo pacman -Syu --noconfirm curl git make gcc
;;
fedora)
sudo dnf install -y curl git make gcc
;;
*)
print_red "[!] Please install manually: ${missing[*]}"
exit 1
;;
esac
else
print_green "[OK] All basic dependencies present."
fi
# Check nfnetlink_queue module
echo ""
echo "[*] Checking kernel module nfnetlink_queue..."
if ! lsmod | grep -q "nfnetlink_queue"; then
print_yellow "[!] nfnetlink_queue not loaded. Loading..."
sudo modprobe nfnetlink_queue 2>/dev/null || {
print_red "[!] Failed to load nfnetlink_queue."
echo " Install: linux-headers + libnetfilter_queue"
}
else
print_green "[OK] nfnetlink_queue is loaded."
fi
# Build nfqws
echo ""
if [[ ! -x "$SCRIPT_DIR/bin/nfqws" ]]; then
echo "[*] nfqws binary not found. Starting build..."
bash "$SCRIPT_DIR/install_nfqws.sh"
else
echo "[*] nfqws already built."
fi
# Create user lists if missing
echo ""
echo "[*] Creating user lists..."
mkdir -p "$SCRIPT_DIR/.service"
[[ ! -f "$SCRIPT_DIR/lists/list-general-user.txt" ]] && echo "domain.example.abc" > "$SCRIPT_DIR/lists/list-general-user.txt"
[[ ! -f "$SCRIPT_DIR/lists/list-exclude-user.txt" ]] && echo "domain.example.abc" > "$SCRIPT_DIR/lists/list-exclude-user.txt"
[[ ! -f "$SCRIPT_DIR/lists/ipset-exclude-user.txt" ]] && echo "203.0.113.113/32" > "$SCRIPT_DIR/lists/ipset-exclude-user.txt"
print_green "[OK] User lists ready."
# Offer to install systemd service
echo ""
if command -v systemctl >/dev/null 2>&1; then
read -rp "Install systemd service for auto-start? [y/N]: " ans
if [[ "$ans" == [yY]* ]]; then
bash "$SCRIPT_DIR/service.sh" && true || true
fi
else
print_yellow "[!] systemctl not found. Skipping systemd setup."
fi
echo ""
print_green "=============================================="
print_green " Setup complete!"
print_green "=============================================="
echo ""
echo "Quick start:"
echo " 1. Test manually: sudo ./general.sh"
echo " 2. Manage service: sudo ./service.sh"
echo " 3. Auto-update: sudo ./update.sh"
echo ""

View File

@@ -0,0 +1,9 @@
[Unit]
Description=Zapret auto-update service
After=network.target
[Service]
Type=oneshot
ExecStart=/opt/zapret/update.sh --auto
StandardOutput=journal
StandardError=journal

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Zapret auto-update timer
[Timer]
OnCalendar=daily
RandomizedDelaySec=3600
Persistent=true
[Install]
WantedBy=timers.target

14
systemd/zapret.service Normal file
View File

@@ -0,0 +1,14 @@
[Unit]
Description=Zapret DPI bypass
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/zapret-start.sh
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target

302
update.sh Normal file
View File

@@ -0,0 +1,302 @@
#!/bin/bash
# update.sh - Auto-update, auto-build, auto-test, auto-install pipeline
# Full automation: download updates → rebuild nfqws → test strategies → install working one
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
GITHUB_REPO="Flowseal/zapret-discord-youtube"
GITHUB_RAW="https://raw.githubusercontent.com/$GITHUB_REPO/main"
GITHUB_RELEASES="https://github.com/$GITHUB_REPO/releases"
LOCAL_VERSION_FILE="$SCRIPT_DIR/.service/version.txt"
UPDATE_LOG="$SCRIPT_DIR/.service/update.log"
mkdir -p "$SCRIPT_DIR/.service"
log_msg() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$UPDATE_LOG"
}
# Check remote version
check_remote_version() {
local remote_ver
remote_ver=$(curl -sfL "$GITHUB_RAW/.service/version.txt" 2>/dev/null | head -n1 | tr -d '[:space:]')
if [[ -z "$remote_ver" ]]; then
log_msg "ERROR: Failed to fetch remote version"
return 1
fi
echo "$remote_ver"
}
# Update lists and scripts (non-destructive)
update_files() {
log_msg "[*] Updating lists and scripts from GitHub..."
for file in list-general.txt list-google.txt list-exclude.txt ipset-exclude.txt; do
local url="$GITHUB_RAW/lists/$file"
local dest="$SCRIPT_DIR/lists/$file"
if curl -sfL "$url" -o "$dest.tmp" 2>/dev/null; then
mv "$dest.tmp" "$dest"
log_msg " [OK] Updated lists/$file"
else
log_msg " [SKIP] lists/$file (unavailable)"
fi
done
if [[ -f "$SCRIPT_DIR/.service/ipset_filter_loaded" ]] || [[ -f "$SCRIPT_DIR/.service/ipset_filter_any" ]]; then
local url="$GITHUB_RAW/.service/ipset-all.txt"
local dest="$SCRIPT_DIR/lists/ipset-all.txt"
if curl -sfL "$url" -o "$dest.tmp" 2>/dev/null; then
mv "$dest.tmp" "$dest"
log_msg " [OK] Updated lists/ipset-all.txt"
fi
fi
for file in lib/functions.sh utils/test_zapret.sh utils/targets.txt; do
local url="$GITHUB_RAW/$file"
local dest="$SCRIPT_DIR/$file"
if curl -sfL "$url" -o "$dest.tmp" 2>/dev/null; then
mv "$dest.tmp" "$dest"
log_msg " [OK] Updated $file"
fi
done
log_msg "[*] File update complete."
}
# Rebuild nfqws with verification
rebuild_nfqws() {
log_msg "[*] Rebuilding nfqws..."
if ! bash "$SCRIPT_DIR/install_nfqws.sh"; then
log_msg "[FAIL] nfqws build script failed."
return 1
fi
# Verify binary exists
if [[ ! -x "$BIN_DIR/nfqws" ]]; then
log_msg "[FAIL] nfqws binary not found after build."
return 1
fi
# Verify binary can start (quick help check)
if ! "$BIN_DIR/nfqws" --help >/dev/null 2>&1; then
log_msg "[FAIL] nfqws binary built but does not execute."
return 1
fi
log_msg "[OK] nfqws rebuilt and verified."
return 0
}
# Run autotest to find working strategy and install it
run_autotest_pipeline() {
log_msg "[*] Running auto-test pipeline to find working strategy..."
# Stop any existing service first
if command -v systemctl >/dev/null 2>&1; then
systemctl stop zapret.service 2>/dev/null || true
fi
cleanup_firewall >/dev/null 2>&1 || true
sleep 2
# Run autotest in auto mode
if bash "$SCRIPT_DIR/autotest.sh" --auto; then
log_msg "[OK] Auto-test found working strategy and installed it."
return 0
else
log_msg "[FAIL] Auto-test did not find any working strategy."
return 1
fi
}
# Restart service if installed
restart_service() {
if command -v systemctl >/dev/null 2>&1; then
if systemctl is-enabled zapret.service >/dev/null 2>&1; then
log_msg "[*] Restarting zapret.service..."
systemctl restart zapret.service
log_msg "[OK] Service restarted."
fi
fi
}
# Full pipeline: update → build → test → install
full_pipeline() {
local mode="${1:-interactive}"
local force="${2:-no}"
if [[ "$mode" == "interactive" ]]; then
echo ""
echo "=============================================="
echo " Zapret Full Auto Pipeline"
echo " Current: $LOCAL_VERSION"
echo "=============================================="
echo ""
fi
# Step 1: Check remote version
log_msg "[*] Step 1/4: Checking for updates..."
local remote_version
remote_version=$(check_remote_version) || {
log_msg "Could not check remote version."
if [[ "$mode" == "interactive" ]]; then
read -rp "Continue with local rebuild anyway? [y/N]: " ans
[[ "$ans" == [yY]* ]] || exit 1
else
exit 1
fi
remote_version="$LOCAL_VERSION"
}
if [[ "$mode" == "interactive" ]]; then
echo "Remote version: $remote_version"
echo "Local version: $LOCAL_VERSION"
echo ""
fi
# Decide whether to update
local do_update=0
if [[ "$remote_version" != "$LOCAL_VERSION" ]]; then
do_update=1
log_msg "New version available: $remote_version"
elif [[ "$force" == "yes" ]]; then
log_msg "Force rebuild requested."
do_update=1
fi
if [[ "$do_update" -eq 0 ]]; then
log_msg "No update needed."
if [[ "$mode" == "interactive" ]]; then
read -rp "Rebuild nfqws and re-test anyway? [y/N]: " ans
[[ "$ans" == [yY]* ]] || {
echo "[*] Nothing to do. Exiting."
exit 0
}
else
log_msg "Exiting (no update, no force)."
exit 0
fi
fi
# Step 2: Update files
if [[ "$remote_version" != "$LOCAL_VERSION" ]]; then
log_msg "[*] Step 2/4: Updating files from GitHub..."
update_files
echo "LOCAL_VERSION=\"$remote_version-linux\"" > "$LOCAL_VERSION_FILE"
else
log_msg "[*] Step 2/4: Skipping file update (same version, force mode)."
fi
# Step 3: Rebuild nfqws with verification
log_msg "[*] Step 3/4: Rebuilding nfqws..."
if ! rebuild_nfqws; then
log_msg "[CRITICAL] Build failed. Aborting."
if [[ "$mode" == "interactive" ]]; then
read -rp "Press Enter to exit..."
fi
exit 1
fi
# Step 4: Auto-test and install
log_msg "[*] Step 4/4: Auto-testing strategies..."
if run_autotest_pipeline; then
log_msg "[SUCCESS] Pipeline complete: updated, built, tested, installed."
else
log_msg "[WARNING] Build OK, but no working strategy found."
log_msg " You may need to adjust parameters manually."
fi
if [[ "$mode" == "interactive" ]]; then
echo ""
print_green "=============================================="
print_green " Full Pipeline Complete!"
print_green " Version: $(cat "$LOCAL_VERSION_FILE" 2>/dev/null || echo $LOCAL_VERSION)"
print_green "=============================================="
echo ""
systemctl status zapret --no-pager 2>/dev/null || true
fi
}
# Auto mode (for cron/systemd timers)
auto_mode() {
log_msg "Auto-update started..."
local remote_version
remote_version=$(check_remote_version) || {
log_msg "Update check failed. Exiting."
exit 1
}
if [[ "$remote_version" == "$LOCAL_VERSION" ]]; then
log_msg "No update needed."
exit 0
fi
log_msg "New version found: $remote_version"
full_pipeline auto no
log_msg "Auto-update finished."
}
# CLI
MODE="interactive"
FORCE="no"
while [[ $# -gt 0 ]]; do
case "$1" in
--auto|-a)
MODE="auto"
shift
;;
--force|-f)
FORCE="yes"
shift
;;
--full-auto)
# Fully non-interactive: even if same version, rebuild and re-test
MODE="auto"
FORCE="yes"
shift
;;
--help|-h)
cat <<EOF
Usage: $0 [OPTIONS]
Zapret Update Pipeline: checks version → updates files → rebuilds nfqws → auto-tests → installs.
Options:
--auto, -a Non-interactive mode (for cron/systemd timers)
--force, -f Force rebuild even if versions match
--full-auto Same as --auto --force (rebuild + re-test always)
--help, -h Show this help
Interactive mode (default):
sudo ./update.sh
Full automation (no questions, always rebuilds and re-tests):
sudo ./update.sh --full-auto
For systemd timer (daily auto-update):
sudo ./update.sh --auto
EOF
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage."
exit 1
;;
esac
done
if [[ "$MODE" == "auto" ]]; then
if [[ "$FORCE" == "yes" ]]; then
full_pipeline auto yes
else
auto_mode
fi
else
full_pipeline interactive "$FORCE"
fi

7
utils/targets.txt Normal file
View File

@@ -0,0 +1,7 @@
ytimg.com
discord.com
discordapp.com
youtube.com
googlevideo.com
play.google.com
cloudflare.com

108
utils/test_zapret.sh Normal file
View File

@@ -0,0 +1,108 @@
#!/bin/bash
# utils/test_zapret.sh - Test utility for checking DPI bypass
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_green() { echo -e "${GREEN}$1${NC}"; }
print_red() { echo -e "${RED}$1${NC}"; }
print_yellow(){ echo -e "${YELLOW}$1${NC}"; }
test_website() {
local url="$1"
local name="$2"
local timeout=10
local result
result=$(curl -o /dev/null -s -w "%{http_code}" --max-time "$timeout" -L "$url" 2>/dev/null)
if [[ "$result" == "200" ]] || [[ "$result" == "301" ]] || [[ "$result" == "302" ]]; then
print_green " [OK] $name ($url) - HTTP $result"
return 0
elif [[ -z "$result" ]]; then
print_red " [FAIL] $name ($url) - No response"
return 1
else
print_red " [FAIL] $name ($url) - HTTP $result"
return 1
fi
}
standard_tests() {
echo "[*] Standard tests - checking common sites..."
echo ""
local targets_file="$SCRIPT_DIR/utils/targets.txt"
if [[ ! -f "$targets_file" ]]; then
targets_file="/dev/stdin"
echo "ytimg.com"
echo "discord.com"
echo "discordapp.com"
echo "youtube.com"
echo "googlevideo.com"
fi
local total=0
local passed=0
while IFS= read -r line || [[ -n "$line" ]]; do
[[ -z "$line" ]] && continue
[[ "$line" =~ ^# ]] && continue
total=$((total + 1))
if test_website "https://$line" "$line"; then
passed=$((passed + 1))
fi
done < "$targets_file"
echo ""
echo "Results: $passed/$passed passed"
if [[ "$passed" -eq "$total" ]]; then
print_green "All tests passed!"
else
print_yellow "Some tests failed. Try a different strategy."
fi
}
dpi_checkers() {
echo "[*] DPI checkers - checking various endpoints..."
echo ""
local endpoints=(
"https://1.1.1.1|Cloudflare"
"https://8.8.8.8|Google DNS"
"https://check-host.net|Check-Host"
)
for entry in "${endpoints[@]}"; do
IFS='|' read -r url name <<< "$entry"
test_website "$url" "$name"
done
echo ""
echo "[*] Checking if TCP timestamps are enabled..."
if [[ -r /proc/sys/net/ipv4/tcp_timestamps ]]; then
local val
val=$(cat /proc/sys/net/ipv4/tcp_timestamps)
if [[ "$val" == "1" ]]; then
print_green " [OK] tcp_timestamps = 1"
else
print_red " [WARN] tcp_timestamps = $val (should be 1)"
fi
fi
}
case "${1:-standard}" in
standard)
standard_tests
;;
dpi)
dpi_checkers
;;
*)
echo "Usage: $0 [standard|dpi]"
exit 1
;;
esac