#!/bin/bash # install_nfqws.sh - Build nfqws with fallback for РФ (GitHub blocked) set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BIN_DIR="$SCRIPT_DIR/bin" BUILD_DIR="/tmp/zapret-build-$$" # Require root if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then echo "[!] This script must be run as root (or with sudo)" echo " sudo $0" exit 1 fi source "$SCRIPT_DIR/lib/download_helper.sh" echo "==============================================" echo " Zapret Builder for Linux (v2 — РФ-ready)" echo "==============================================" echo "" # Load proxy load_proxy if [ -f /etc/os-release ]; then . /etc/os-release DISTRO="$ID" else DISTRO="unknown" fi echo "[*] Detected distro: $DISTRO" # Check if offline bundle exists (pre-downloaded) OFFLINE_SOURCES="" if [[ -d "$SCRIPT_DIR/.bundle/sources/zapret" ]]; then OFFLINE_SOURCES="$SCRIPT_DIR/.bundle/sources/zapret" echo "[OK] Using offline source: $OFFLINE_SOURCES" else echo "[*] No offline bundle found. Will try to download..." fi echo "[*] Installing build dependencies..." install_deps() { case "$DISTRO" in ubuntu|debian|linuxmint|pop|zorin|kubuntu|xubuntu|lubuntu) apt-get update apt-get install -y git make gcc curl iptables nftables libnetfilter-queue-dev libmnl-dev zlib1g-dev libcap-dev build-essential ;; arch|manjaro|endeavouros|garuda|artix|arcolinux|blackarch) if command -v pacman >/dev/null 2>&1; then pacman -Syu --noconfirm git make gcc curl iptables nftables libnetfilter_queue libmnl zlib libcap elif command -v yay >/dev/null 2>&1; then yay -Syu --noconfirm git make gcc curl iptables nftables libnetfilter_queue libmnl zlib libcap elif command -v paru >/dev/null 2>&1; then paru -Syu --noconfirm git make gcc curl iptables nftables libnetfilter_queue libmnl zlib libcap fi ;; fedora|rhel|centos|almalinux|rocky) dnf install -y git make gcc curl iptables nftables libnetfilter_queue-devel libmnl-devel zlib-devel libcap-devel ;; alpine) apk add --no-cache git make gcc curl iptables nftables libnetfilter_queue-dev libmnl-dev zlib-dev libcap-dev linux-headers ;; *) echo "[!] Unknown distro: $DISTRO" echo " Required: git, make, gcc, curl, iptables/nftables, libnetfilter_queue" read -rp "Continue anyway? [y/N]: " ans [[ "$ans" == [yY]* ]] || exit 1 ;; esac } install_deps echo "" echo "[*] Preparing zapret sources..." mkdir -p "$BUILD_DIR" if [[ -n "$OFFLINE_SOURCES" ]]; then echo " Copying offline sources..." cp -r "$OFFLINE_SOURCES" "$BUILD_DIR/zapret" else echo "[*] Downloading bol-van/zapret (with fallback)..." if ! clone_repo_fallback "bol-van/zapret" "master" "$BUILD_DIR/zapret"; then echo "" echo "[CRITICAL] Failed to download zapret sources." echo "" echo "Solutions:" echo " 1. Set proxy: export HTTPS_PROXY=socks5://127.0.0.1:1080" echo " 2. Use VPN and re-run" echo " 3. Pre-download with prepare_offline_bundle.sh (on machine WITH internet)" echo " tar -xzf bundle.tar.gz" echo " mv bundle/* /opt/zapret" echo " 4. Manual: git clone https://github.com/bol-van/zapret.git" echo "" exit 1 fi fi cd "$BUILD_DIR/zapret" echo "[*] Building nfqws..." # Fix: disable LTO and aggressive section-gc that can cause segfaults on some systems sed -i 's/-flto=auto//g; s/-Wl,--gc-sections//g; s/-ffunction-sections//g; s/-fdata-sections//g' nfq/Makefile 2>/dev/null || true if ! make -C nfq; then echo "[!] Build failed!" exit 1 fi if [ ! -f "$BUILD_DIR/zapret/nfq/nfqws" ]; then echo "[!] nfqws binary not found after build" exit 1 fi # Verify the binary actually runs (catch segfaults early). # Use --version because --help exits with code 1 in zapret. if ! "$BUILD_DIR/zapret/nfq/nfqws" --version > /dev/null 2>&1; then echo "[!] nfqws segfaults with current flags. Rebuilding with -O0 (no optimizations)..." sed -i 's/-Os/-O0/g' nfq/Makefile 2>/dev/null || true sed -E -i 's/(^| )-s($| )/\1\2/g' nfq/Makefile 2>/dev/null || true make -C nfq clean && make -C nfq if [ ! -f "$BUILD_DIR/zapret/nfq/nfqws" ]; then echo "[!] nfqws binary not found after rebuild" exit 1 fi if ! "$BUILD_DIR/zapret/nfq/nfqws" --version > /dev/null 2>&1; then echo "[!] nfqws still segfaults with -O0. Last attempt: disable LTO + gc-sections..." make -C nfq clean && CC=gcc CFLAGS="-std=gnu99 -O0 -g" LDFLAGS="" make -C nfq if [ ! -f "$BUILD_DIR/zapret/nfq/nfqws" ]; then echo "[!] nfqws binary not found after rebuild" exit 1 fi if ! "$BUILD_DIR/zapret/nfq/nfqws" --version > /dev/null 2>&1; then echo "[!] nfqws still segfaults. Aborting." exit 1 fi fi fi mkdir -p "$BIN_DIR" # Fix: if previous runs created bin/nfqws as a directory, remove it if [[ -d "$BIN_DIR/nfqws" ]]; then rm -rf "$BIN_DIR/nfqws" fi 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 local/offline)" fi done # Try offline bundle fallback for fake bins if [[ -d "$SCRIPT_DIR/.bundle" ]]; then 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 [[ -f "$SCRIPT_DIR/.bundle/$f" ]] && [[ ! -f "$BIN_DIR/$f" ]]; then cp "$SCRIPT_DIR/.bundle/$f" "$BIN_DIR/$f" echo " [OK] $f (from offline bundle)" fi done fi echo "" echo "[*] Setting capabilities..." if command -v setcap >/dev/null 2>&1; then setcap cap_net_admin,cap_net_raw+eip "$BIN_DIR/nfqws" 2>/dev/null || true echo " [OK] cap_net_admin,cap_net_raw set" fi echo "" echo "[*] Cleanup..." rm -rf "$BUILD_DIR" echo "" echo "==============================================" echo " Build complete! Binary: $BIN_DIR/nfqws" echo "=============================================="