#!/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 check_root() { 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 } 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 # Verify the binary actually runs (catches segfaults/missing deps) if ! "$BIN_DIR/nfqws" --help >/dev/null 2>&1; then echo "" print_red "ERROR: nfqws binary exists but does not run (segfault? missing deps?)" echo "" echo "Try rebuilding:" 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 "$@" }