fix(core): critical fixes for service menu, autotest, strategy runner, dependencies

- service.sh: split service_remove into internal (no prompts) and interactive
  versions to prevent 'eternal wait' when installing new strategy.
  Install now calls service_remove_internal > /dev/null instead of service_remove.
  Also filter strategy list to general*.sh only to avoid clutter.
  Systemd ExecStart now points to run_strategy.sh <name> consistently.

- run_strategy.sh: add SIGTERM/SIGINT trap cleanup_strategy() that kills nfqws
  and cleans up firewall. Prevents stale nfqws/firewall rules after autotest kill.
  Also handles nfqws exit gracefully with final cleanup.

- autotest.sh: rewritten to test strategies by config name (not wrapper filename).
  Stop now sends SIGTERM to wrapper (which triggers trap cleanup) instead of
  bare kill. Added extra sleep after stop to let trap fire.
  Auto-install ExecStart fixed to run_strategy.sh <strategy>.

- setup.sh: added libmnl-dev and zlib1g-dev to Ubuntu/Debian dependency install
  to prevent build failures (missing libmnl/libmnl.h and zlib.h).

- general*.sh: removed UTF-8 BOM (0xEF 0xBB 0xBF) that caused 'exec format error'
  when running scripts on Linux. All 19 wrappers cleaned.

- ensure_wrappers.sh: always rewrite wrappers to ensure no stale BOM or paths.

Fixes: eternal wait on menu option 1, nfqws build failure, stale processes after test.
This commit is contained in:
OpenCode Agent
2026-05-10 22:41:08 +04:00
parent 06484b84a2
commit 025d93da82
24 changed files with 862 additions and 829 deletions

View File

@@ -1,5 +1,5 @@
#!/bin/bash
# autotest.sh - Automatic strategy tester
# autotest.sh - Automatic strategy tester v2
# Iterates through all strategies, checks connectivity, suggests installation
set -e
@@ -16,25 +16,25 @@ TEST_URLS=(
# 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
general
ALT
ALT2
ALT3
ALT4
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
ALT5 # NOT RECOMMENDED, last
)
# Test a single URL
@@ -75,18 +75,18 @@ test_strategy() {
# Run a strategy with timeout
run_strategy_test() {
local strategy="$1"
local strategy_path="$SCRIPT_DIR/$strategy"
local strategy_name="${strategy%.sh}"
local strategy_path="$SCRIPT_DIR/run_strategy.sh"
local strategy_name="$strategy"
echo ""
echo "=============================================="
echo " Testing: $strategy_name"
echo " $(describe_strategy "$strategy_path")"
echo " $(describe_strategy "$SCRIPT_DIR/general_${strategy}.sh")"
echo "=============================================="
# Check if strategy file exists
if [[ ! -f "$strategy_path" ]]; then
print_yellow " [!] Strategy file not found, skipping..."
# Check if strategy config exists
if [[ ! -f "$SCRIPT_DIR/strategies/${strategy}.conf" ]]; then
print_yellow " [!] Strategy config not found, skipping..."
return 1
fi
@@ -94,9 +94,9 @@ run_strategy_test() {
cleanup_firewall >/dev/null 2>&1 || true
sleep 1
# Start strategy in background
# Start strategy in background (run_strategy.sh handles its own cleanup on signals)
echo " [*] Starting $strategy_name..."
"$strategy_path" >/dev/null 2>&1 &
"$strategy_path" "$strategy" >/dev/null 2>&1 &
local strategy_pid=$!
# Wait for nfqws to initialize
@@ -109,6 +109,7 @@ run_strategy_test() {
kill "$strategy_pid" 2>/dev/null || true
wait "$strategy_pid" 2>/dev/null || true
cleanup_firewall >/dev/null 2>&1 || true
sleep 1
return 1
fi
@@ -120,8 +121,12 @@ run_strategy_test() {
# Stop strategy
echo " [*] Stopping $strategy_name..."
# Kill wrapper first, then cleanup_firewall will kill nfqws
kill "$strategy_pid" 2>/dev/null || true
# Send SIGTERM to wrapper — it will cleanup firewall + nfqws via trap
kill -TERM "$strategy_pid" 2>/dev/null || true
# Give trap time to fire and cleanup
sleep 2
# Ensure nfqws is gone
pkill -f "nfqws.*qnum=$NFQUEUE_NUM" 2>/dev/null || true
wait "$strategy_pid" 2>/dev/null || true
cleanup_firewall >/dev/null 2>&1 || true
sleep 1
@@ -177,7 +182,7 @@ main() {
for strat in "${STRATEGIES[@]}"; do
if run_strategy_test "$strat"; then
working_strategy="$strat"
working_desc="$(describe_strategy "$SCRIPT_DIR/$strat")"
working_desc="$(describe_strategy "$SCRIPT_DIR/general_${strat}.sh")"
break
fi
done
@@ -186,7 +191,7 @@ main() {
echo "=============================================="
if [[ -n "$working_strategy" ]]; then
print_green " WORKING STRATEGY FOUND!"
print_green " Strategy: ${working_strategy%.sh}"
print_green " Strategy: $working_strategy"
print_green " Desc: $working_desc"
echo "=============================================="
echo ""
@@ -195,17 +200,17 @@ main() {
echo "[*] Auto-installing to systemd..."
# Write strategy marker directly
mkdir -p "$SCRIPT_DIR/.service"
echo "${working_strategy%.sh}" > "$SCRIPT_DIR/.service/installed_strategy"
echo "$working_strategy" > "$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})
Description=Zapret DPI bypass (strategy: $working_strategy)
After=network.target
[Service]
Type=simple
ExecStart=$SCRIPT_DIR/$working_strategy
ExecStart=$SCRIPT_DIR/run_strategy.sh $working_strategy
Restart=on-failure
RestartSec=5
StandardOutput=journal
@@ -228,12 +233,11 @@ EOF
echo ""
echo " sudo ./service.sh"
echo " → 1. Install Service"
echo " → Choose: ${working_strategy%.sh}"
echo " → Choose: $working_strategy"
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
bash "$SCRIPT_DIR/service.sh"
fi
fi
else
@@ -243,7 +247,7 @@ EOF
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 " - Try modifying strategy parameters manually in strategies/*.conf"
echo " - Check diagnostics: sudo ./service.sh → 10. Run Diagnostics"
fi

View File

@@ -10,22 +10,21 @@ for conf in "$SCRIPT_DIR/strategies"/*.conf; do
[[ -f "$conf" ]] || continue
name=$(basename "$conf" .conf)
wrapper="$SCRIPT_DIR/general_${name}.sh"
# Skip general.sh as special case (name = general)
if [[ "$name" == "general" ]]; then
wrapper="$SCRIPT_DIR/general.sh"
fi
if [[ ! -f "$wrapper" ]]; then
echo "[*] Creating wrapper: $(basename "$wrapper")$name"
cat > "$wrapper" <<EOF
# Always rewrite wrapper to ensure consistency (no BOM, correct shebang)
cat > "$wrapper" <<EOF
#!/bin/bash
# Auto-generated wrapper: $name
SCRIPT_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "\$SCRIPT_DIR/run_strategy.sh" "$name"
EOF
chmod +x "$wrapper"
fi
chmod +x "$wrapper"
echo "[*] Wrapper updated: $(basename "$wrapper")$name"
done
echo "[OK] All wrappers checked."

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,8 +2,6 @@
# run_strategy.sh - Generic strategy runner using .conf files
# Loads strategies/strategy_name.conf, substitutes variables, runs nfqws.
# set -e removed: nfqws may exit non-zero on SIGTERM; empty arrays are fine
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
@@ -102,4 +100,32 @@ done < "$TMP_ARGS"
rm -f "$TMP_ARGS"
trap - EXIT
run_nfqws "$0" "${CLEAN_ARGS[@]}"
# Setup firewall and start nfqws
check_nfqws || exit 1
tcp_enable_timestamps
setup_firewall
# Trap cleanup on SIGTERM/SIGINT (e.g. from systemd or autotest kill)
cleanup_strategy() {
print_yellow ""
print_yellow "[*] Caught stop signal, cleaning up..."
pkill -f "nfqws.*qnum=$NFQUEUE_NUM" 2>/dev/null || true
cleanup_firewall >/dev/null 2>&1 || true
exit 0
}
trap cleanup_strategy SIGTERM SIGINT
echo ""
print_cyan "[*] Starting strategy: $STRATEGY"
print_cyan "[*] $(describe_strategy "$SCRIPT_DIR/general_${STRATEGY}.sh")"
echo ""
# Start nfqws in background so this shell handles signals and cleanup
"$BIN_DIR/nfqws" --qnum=$NFQUEUE_NUM "${CLEAN_ARGS[@]}" &
NFQWS_PID=$!
wait "$NFQWS_PID"
EXIT_CODE=$?
# If nfqws exited on its own, cleanup firewall
cleanup_firewall >/dev/null 2>&1 || true
exit $EXIT_CODE

1153
service.sh

File diff suppressed because it is too large Load Diff

262
setup.sh
View File

@@ -1,131 +1,131 @@
#!/bin/bash
# setup.sh - Initial setup for zapret-discord-youtube Linux
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
print_red "[!] This script must be run as root (or with sudo)"
echo " sudo $0"
exit 1
fi
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)
apt-get update
apt-get install -y curl git make gcc build-essential
;;
arch|manjaro)
pacman -Syu --noconfirm curl git make gcc
;;
fedora)
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..."
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 ""
#!/bin/bash
# setup.sh - Initial setup for zapret-discord-youtube Linux
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/functions.sh"
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
print_red "[!] This script must be run as root (or with sudo)"
echo " sudo $0"
exit 1
fi
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)
apt-get update
apt-get install -y curl git make gcc build-essential libmnl-dev zlib1g-dev
;;
arch|manjaro)
pacman -Syu --noconfirm curl git make gcc
;;
fedora)
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..."
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 ""