#!/bin/bash # ============================================================ # PCA Phobos — TURNKEY installer (primary / panel node) # # One command, all dependencies, from a clean VPS: # bash <(curl -fsSL https://raw.githubusercontent.com/andrey271192/PCA_Phobos/main/install.sh) # # Installs, in order: # deps -> wg-obfuscator (Ground-Zerro) -> WireGuard wg0 -> # obfuscator services -> Phobos repo (onboarding scripts) + # PCA patches -> web panel -> nginx (/init,/packages) -> # server-side router watchdog. # # Env (all optional): # PANEL_PORT random 10000-59999 web panel port # PANEL_PASS OcAdmin2026! panel admin password # API_KEY random shared key (agents + router pull token) # OBF_PORTS 2083,5443,993 obfuscator listen ports # TG_TOKEN / TG_CHAT Telegram alerts # PCA_BRANCH main branch to pull PCA files from # ============================================================ set -e PANEL_PASS="${PANEL_PASS:-OcAdmin2026!}" TG_TOKEN="${TG_TOKEN:-}" TG_CHAT="${TG_CHAT:-}" OBF_PORTS="${OBF_PORTS:-2083,5443,993}" # Каналы: stable (открытый, публичный repo) · beta (тест) · dev (разработка). # beta и dev живут в ПРИВАТНОМ repo PCA_Phobos-dev — доступ по токену подписчика # (GH_TOKEN, read-only, выдаётся по подписке Boosty). stable — без токена. GH_TOKEN="${GH_TOKEN:-}" PUB_REPO="andrey271192/PCA_Phobos" DEV_REPO="andrey271192/PCA_Phobos-dev" CHANNEL="${CHANNEL:-stable}" case "$CHANNEL" in beta) REPO="$DEV_REPO"; PCA_BRANCH="${PCA_BRANCH:-beta}";; dev) REPO="$DEV_REPO"; PCA_BRANCH="${PCA_BRANCH:-dev}";; stable|main|"") REPO="$PUB_REPO"; PCA_BRANCH="${PCA_BRANCH:-main}";; *) REPO="$PUB_REPO"; PCA_BRANCH="${PCA_BRANCH:-$CHANNEL}";; esac if [ "$REPO" = "$DEV_REPO" ] && [ -z "$GH_TOKEN" ]; then echo "Канал '$CHANNEL' закрыт — это $([ "$CHANNEL" = dev ] && echo 'разработка (нестабильно)' || echo 'бета (тест)'), приватный репозиторий." echo "Нужен read-only токен подписчика:" echo " GH_TOKEN=ваш_токен CHANNEL=$CHANNEL bash <(curl -fsSL https://raw.githubusercontent.com/$PUB_REPO/main/install.sh)" echo "Токен выдаётся по подписке: https://boosty.to/andrey27" echo "Стабильная версия ставится без токена (CHANNEL=stable, по умолчанию)." exit 1 fi [ "$REPO" = "$DEV_REPO" ] && echo "Токен принят — закрытый канал '$CHANNEL' (приватный repo)." PHOBOS_DIR="/opt/Phobos" PANEL_DIR="/opt/phobos-panel" RAW="https://raw.githubusercontent.com/${REPO}/${PCA_BRANCH}" [ "$EUID" -eq 0 ] || { echo "Run as root"; exit 1; } if [ -z "$PANEL_PORT" ]; then PANEL_PORT=$(shuf -i 10000-59999 -n 1 2>/dev/null || awk 'BEGIN{srand(); print int(10000+rand()*50000)}') fi API_KEY="${API_KEY:-$(head -c 24 /dev/urandom | base64 | tr -d '/+=' | head -c 24)}" SERVER_IP=$(curl -s -m8 https://api.ipify.org || hostname -I | awk '{print $1}') IFACE=$(ip route get 8.8.8.8 2>/dev/null | awk '{for(i=1;i/dev/null systemctl enable cron -q 2>/dev/null || true; systemctl start cron 2>/dev/null || true # ── 2. wg-obfuscator binary (Ground-Zerro) ── echo "[2/9] wg-obfuscator..." mkdir -p "$PHOBOS_DIR"/{server,clients,bin,tokens,www/init,www/packages,packages} if [ ! -x /usr/local/bin/wg-obfuscator ]; then R=/tmp/phobos-obf; rm -rf "$R"; mkdir -p "$R"; cd "$R" git init -q; git remote add origin https://github.com/Ground-Zerro/Phobos.git git config core.sparseCheckout true; echo "wg-obfuscator" > .git/info/sparse-checkout git pull origin main -q cp -f "wg-obfuscator/bin/"wg-obfuscator-* "$PHOBOS_DIR/bin/" 2>/dev/null || true chmod +x "$PHOBOS_DIR/bin/"wg-obfuscator-* 2>/dev/null || true ln -sf "$PHOBOS_DIR/bin/wg-obfuscator-${ARCH}" /usr/local/bin/wg-obfuscator 2>/dev/null || true cd /; rm -rf "$R" fi _OBF_TAG=$(curl -fsSL -m10 https://api.github.com/repos/ClusterM/wg-obfuscator/releases/latest 2>/dev/null | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\(.*\)".*/\1/') _CB="https://github.com/ClusterM/wg-obfuscator/releases/download/${_OBF_TAG}" for _am in "aarch64:linux-arm64" "mipsel:linux-mipsel-mips32" "mips:linux-mips-mips32" "armv7:linux-armv7-hf"; do _da="${_am%%:*}"; _ss="${_am##*:}" if [ ! -f "$PHOBOS_DIR/bin/wg-obfuscator-${_da}" ] && [ -n "$_OBF_TAG" ]; then _t=$(mktemp -d) curl -fsSL -m30 "${_CB}/wg-obfuscator-${_OBF_TAG}-${_ss}.tar.gz" -o "$_t/o.tgz" 2>/dev/null && tar -xzf "$_t/o.tgz" -C "$_t" 2>/dev/null && _b=$(find "$_t" -name "wg-obfuscator" -type f | head -1) && [ -n "$_b" ] && cp "$_b" "$PHOBOS_DIR/bin/wg-obfuscator-${_da}" && chmod +x "$PHOBOS_DIR/bin/wg-obfuscator-${_da}" && echo " +wg-obfuscator-${_da} (ClusterM ${_OBF_TAG})" rm -rf "$_t" fi done [ -x /usr/local/bin/wg-obfuscator ] || ln -sf "$PHOBOS_DIR/bin/wg-obfuscator-${ARCH}" /usr/local/bin/wg-obfuscator 2>/dev/null || true [ -x /usr/local/bin/wg-obfuscator ] || { echo "ERROR: obfuscator binary for $ARCH missing"; exit 1; } echo " bins: $(ls $PHOBOS_DIR/bin/ | tr '\n' ' ')" # ── 3. Phobos repo (onboarding scripts) ── echo "[3/9] Phobos repo (onboarding scripts)..." R="$PHOBOS_DIR/repo"; rm -rf "$R"; mkdir -p "$R"; cd "$R" git init -q; git remote add origin https://github.com/Ground-Zerro/Phobos.git git config core.sparseCheckout true printf 'server\nclient\n' > .git/info/sparse-checkout git pull origin main -q; rm -rf .git find "$R" -name '*.sh' -exec chmod +x {} \; 2>/dev/null || true cd / # ── 4. WireGuard wg0 (primary) ── echo "[4/9] WireGuard wg0..." if [ ! -f /etc/wireguard/wg0.conf ]; then WG_PRIV=$(wg genkey); WG_PUB=$(echo "$WG_PRIV" | wg pubkey) cat > /etc/wireguard/wg0.conf <> /etc/sysctl.conf systemctl enable wg-quick@wg0 -q 2>/dev/null || true systemctl restart wg-quick@wg0 # ── 5. obfuscator services (multi-port) ── echo "[5/9] obfuscator services..." OBF_KEY=$(head -c 32 /dev/urandom | base64 | tr -d '/+=' | head -c 32) # Block direct WG (force obfuscation) unless ALLOW_PLAIN_WG=1 (e.g. for iOS WireGuard) if [ -z "${ALLOW_PLAIN_WG:-}" ]; then iptables -C INPUT -p udp --dport 51820 ! -s 127.0.0.1 -j DROP 2>/dev/null \ || iptables -A INPUT -p udp --dport 51820 ! -s 127.0.0.1 -j DROP else iptables -D INPUT -p udp --dport 51820 ! -s 127.0.0.1 -j DROP 2>/dev/null || true fi IFS=',' read -ra PORTS <<< "$OBF_PORTS" for PORT in "${PORTS[@]}"; do cat > "$PHOBOS_DIR/server/wg-obfuscator-${PORT}.conf" < /etc/systemd/system/wg-obfuscator-${PORT}.service < "$PHOBOS_DIR/server/server.env" </dev/null || true [ -f "$PHOBOS_DIR/tokens/tokens.json" ] || echo '[]' > "$PHOBOS_DIR/tokens/tokens.json" # ── 7. web panel ── echo "[7/9] web panel..." mkdir -p "$PANEL_DIR" fetch app.py "$PANEL_DIR/app.py" || { echo "ERROR: panel app.py fetch failed"; exit 1; } if [ ! -f "$PANEL_DIR/settings.json" ]; then cat > "$PANEL_DIR/settings.json" < "$PANEL_DIR/.port" cat > /etc/systemd/system/phobos-panel.service </dev/null || true cat > /etc/nginx/sites-available/phobos <<'NGINX' server { listen 80 default_server; listen [::]:80 default_server; location /init/ { alias /opt/Phobos/www/init/; default_type application/x-sh; } location /packages/ { alias /opt/Phobos/www/packages/; default_type application/octet-stream; } location /app/ { alias /opt/Phobos/www/app/; default_type application/octet-stream; } location / { return 404; } } NGINX ln -sf /etc/nginx/sites-available/phobos /etc/nginx/sites-enabled/phobos mkdir -p /opt/Phobos/www/app; chmod 755 /opt/Phobos/www /opt/Phobos/www/init /opt/Phobos/www/packages /opt/Phobos/www/app nginx -t >/dev/null 2>&1 && systemctl enable nginx -q 2>/dev/null && systemctl restart nginx || echo " WARN: nginx config test failed" # ── 9. router watchdog (auto reboot-recovery) ── echo "[9/9] router watchdog..." if [ -f "$PHOBOS_DIR/server/phobos-router-watchdog.py" ]; then # set -e safe: grep -v on an empty crontab returns 1, so guard with || true CRON_CUR=$(crontab -l 2>/dev/null | grep -v phobos-router-watchdog || true) printf '%s\n%s\n' "$CRON_CUR" \ "*/3 * * * * /usr/bin/python3 $PHOBOS_DIR/server/phobos-router-watchdog.py >/dev/null 2>&1" \ | grep -v '^[[:space:]]*$' | crontab - fi sleep 2 # persist channel + subscriber token so phobos-update can reach private channels mkdir -p "$PANEL_DIR" echo "$CHANNEL" > "$PANEL_DIR/.channel" 2>/dev/null || true if [ "$REPO" = "$DEV_REPO" ] && [ -n "$GH_TOKEN" ]; then ( umask 077; printf %s "$GH_TOKEN" > "$PANEL_DIR/.gh_token" ) fi echo "" echo "============================================" echo " Installation complete" echo " Panel : http://$SERVER_IP:$PANEL_PORT" echo " Login : admin" echo " Pass : $PANEL_PASS" echo " API key (agents+pull): $API_KEY" echo " WG pub: $WG_PUB" echo "============================================" echo "Status:" for s in wg-quick@wg0 phobos-panel nginx; do printf " %-18s %s\n" "$s" "$(systemctl is-active $s 2>/dev/null)"; done for PORT in "${PORTS[@]}"; do printf " %-18s %s\n" "wg-obfuscator-$PORT" "$(systemctl is-active wg-obfuscator-$PORT 2>/dev/null)"; done