Files
zapret-discord-youtube-linux/service.sh

557 lines
16 KiB
Bash
Executable File

#!/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 (find ALL working strategies)"
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" == general*.sh ]] || 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 'general*.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 | sed 's/^general_//')
[[ -z "$strategy_name" ]] && strategy_name="general"
echo ""
echo "[*] Installing strategy: $strategy_name"
service_remove_internal > /dev/null 2>&1 || true
mkdir -p "$SCRIPT_DIR/.service"
echo "$strategy_name" > "$SCRIPT_DIR/.service/installed_strategy"
cat > /etc/systemd/system/zapret.service <<EOF
[Unit]
Description=Zapret DPI bypass (strategy: $strategy_name)
After=network.target
[Service]
Type=simple
ExecStart=$SCRIPT_DIR/run_strategy.sh $strategy_name
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
if command -v systemctl >/dev/null 2>&1; then
systemctl daemon-reload
systemctl enable zapret.service
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: $SCRIPT_DIR/run_strategy.sh $strategy_name"
fi
read -rp "Press Enter to continue..."
}
# ============================================
# SERVICE REMOVE (internal — no prompts)
# ============================================
service_remove_internal() {
if command -v systemctl >/dev/null 2>&1; then
systemctl stop zapret.service 2>/dev/null || true
systemctl disable zapret.service 2>/dev/null || true
rm -f /etc/systemd/system/zapret.service
systemctl daemon-reload
fi
pkill -f "nfqws.*qnum=$NFQUEUE_NUM" 2>/dev/null || true
sleep 1
cleanup_firewall
rm -f "$SCRIPT_DIR/.service/installed_strategy"
}
# ============================================
# SERVICE REMOVE (interactive)
# ============================================
service_remove() {
echo ""
echo "[*] Removing services..."
service_remove_internal
echo ""
print_green "[OK] Services removed."
read -rp "Press Enter to continue..."
}
# ============================================
# SERVICE STATUS
# ============================================
service_status() {
echo ""
echo "[*] Service Status"
echo ""
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
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
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
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 "[*] Hosts File Manager"
echo ""
local hosts_file="$SCRIPT_DIR/.service/hosts"
if [[ ! -f "$hosts_file" ]]; then
print_red "[!] Local hosts file not found: $hosts_file"
read -rp "Press Enter to continue..."
return
fi
echo "[*] Local hosts entries (for GitHub, Telegram, Discord):"
echo ""
grep -v '^#' "$hosts_file" | grep -v '^$' | head -n 20
local total
total=$(grep -v '^#' "$hosts_file" | grep -v '^$' | wc -l)
echo ""
echo "Total entries: $total"
echo ""
read -rp "Append these entries to /etc/hosts? [y/N]: " ans
if [[ "$ans" == [yY]* ]]; then
sudo cp /etc/hosts "/etc/hosts.backup.$(date +%s)"
echo "" | sudo tee -a /etc/hosts > /dev/null
echo "# --- zapret-discord-youtube-linux hosts ---" | sudo tee -a /etc/hosts > /dev/null
grep -v '^#' "$hosts_file" | grep -v '^$' | sudo tee -a /etc/hosts > /dev/null
echo "# --- end zapret hosts ---" | sudo tee -a /etc/hosts > /dev/null
print_green "[OK] Entries added to /etc/hosts"
echo " Backup saved as /etc/hosts.backup.*"
else
echo "[*] Skipped. To add manually:"
echo " sudo nano /etc/hosts"
echo " Then copy from: $hosts_file"
fi
read -rp "Press Enter to continue..."
}
# ============================================
# CHECK FOR UPDATES
# ============================================
# ============================================
# 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
local local_ver_norm="${LOCAL_VERSION%-linux}"
if [[ "$local_ver_norm" == "$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 && [[ -n "${DISPLAY:-}" ]]; then
xdg-open "$github_release_url"
elif command -v gnome-open >/dev/null 2>&1 && [[ -n "${DISPLAY:-}" ]]; 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 ""
if [[ "$EUID" -ne 0 ]]; then
print_yellow "[!] Not running as root. Some checks may fail."
fi
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
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
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
if command -v resolvectl >/dev/null 2>&1; then
echo ""
echo "[*] DNS settings:"
resolvectl status 2>/dev/null | head -n 20 || true
fi
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
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 (menu 11 — finds ALL working strategies)
# ============================================
run_tests() {
echo ""
echo "[*] Running strategy tests..."
echo " This will test all strategies against YouTube + Discord."
echo " At the end you'll see a list of ALL working strategies."
echo ""
read -rp " Press Enter to start or Ctrl+C to cancel..."
bash "$SCRIPT_DIR/autotest.sh" --list-all
echo ""
read -rp "Press Enter to continue..."
}
# ============================================
# MAIN LOOP
# ============================================
main() {
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
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