Ground-Zerro / Phobos Public
Code Issues Pull requests Actions Releases View on GitHub ↗
7.8 KB bash
#!/usr/bin/env bash

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

if [[ "$SCRIPT_DIR" != "/opt/Phobos/repo/server/scripts" ]]; then
  echo "[INFO] Копирование файлов репозитория в /opt/Phobos/repo..."
  mkdir -p /opt/Phobos/repo
  cp -r "$REPO_ROOT"/* /opt/Phobos/repo/
  rm -rf /opt/Phobos/repo/.git 2>/dev/null || true

  if [[ -x "/opt/Phobos/repo/server/scripts/phobos-installer.sh" ]]; then
    echo "[INFO] Перезапуск установщика из /opt/Phobos/repo..."
    exec /opt/Phobos/repo/server/scripts/phobos-installer.sh "$@"
  fi
fi

source "$(dirname "${BASH_SOURCE[0]}")/lib-core.sh"

check_root

OBF_LEVEL="${OBF_LEVEL:-2}"

get_obf_params() {
  local level="${1:-2}"
  case "$level" in
    1) echo "3 4" ;;
    2) echo "6 10" ;;
    3) echo "20 20" ;;
    4) echo "50 50" ;;
    5) echo "255 100" ;;
    *) echo "6 10" ;;
  esac
}

log_info "Остановка существующих служб Phobos..."
systemctl stop wg-obfuscator 2>/dev/null || true
systemctl stop phobos-http 2>/dev/null || true
systemctl stop wg-quick@wg0 2>/dev/null || true

spin() {
  local pid=$1
  local msg=$2
  local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
  while kill -0 "$pid" 2>/dev/null; do
    for (( i=0; i<${#chars}; i++ )); do
      printf "\r[%s] %s" "${chars:$i:1}" "$msg"
      sleep 0.1
    done
  done
  printf "\r"
}

step_deps() {
  log_info "Установка зависимостей..."
  (apt-get update -qq && apt-get install -y -qq wireguard jq curl build-essential ufw) >/dev/null 2>&1 &
  spin $! "Установка пакетов..."
  wait $!
  log_success "Зависимости установлены."
}

step_build() {
  log_info "Копирование бинарников wg-obfuscator..."

  if [[ -d "$REPO_DIR/wg-obfuscator/bin" ]]; then
    cp -f "$REPO_DIR/wg-obfuscator/bin"/wg-obfuscator-* "$PHOBOS_DIR/bin/" 2>/dev/null || true
  fi

  local arch=$(uname -m)
  if [[ ! -f "$PHOBOS_DIR/bin/wg-obfuscator-$arch" ]]; then
    log_error "Бинарник wg-obfuscator для $arch не найден!"
    exit 1
  fi

  chmod +x "$PHOBOS_DIR/bin/wg-obfuscator-$arch"
  ln -sf "$PHOBOS_DIR/bin/wg-obfuscator-$arch" /usr/local/bin/wg-obfuscator
  chmod +x /usr/local/bin/wg-obfuscator
  log_success "Бинарник wg-obfuscator установлен"

  log_info "Сборка darkhttpd..."
  local darkhttpd_version="1.16"
  local darkhttpd_url="https://github.com/emikulic/darkhttpd/archive/refs/tags/v${darkhttpd_version}.tar.gz"
  local build_dir="/tmp/darkhttpd-build"

  rm -rf "$build_dir"
  mkdir -p "$build_dir"

  if ! curl -sL "$darkhttpd_url" | tar -xz -C "$build_dir" --strip-components=1; then
    log_error "Не удалось скачать darkhttpd"
    exit 1
  fi

  if ! make -C "$build_dir" darkhttpd >/dev/null 2>&1; then
    log_error "Не удалось собрать darkhttpd"
    exit 1
  fi

  cp "$build_dir/darkhttpd" "$PHOBOS_DIR/bin/darkhttpd"
  chmod +x "$PHOBOS_DIR/bin/darkhttpd"
  ln -sf "$PHOBOS_DIR/bin/darkhttpd" /usr/local/bin/darkhttpd
  rm -rf "$build_dir"

  log_success "darkhttpd собран и установлен"
}

step_wg() {
  log_info "Настройка WireGuard..."
  mkdir -p /etc/wireguard

  local priv=$(wg genkey)
  local pub=$(echo "$priv" | wg pubkey)
  local wg_ipv4_net="10.25.0.0/16"
  local wg_ipv6_net="fd00:10:25::/48"
  local wg_ipv4_addr="10.25.0.1/16"
  local wg_ipv6_addr="fd00:10:25::1/48"

  cat > "$SERVER_ENV" <<EOF
SERVER_WG_PRIVATE_KEY=$priv
SERVER_WG_PUBLIC_KEY=$pub
SERVER_WG_IPV4_NETWORK=$wg_ipv4_net
SERVER_WG_IPV6_NETWORK=$wg_ipv6_net
EOF

  local iface=$(ip route | grep default | awk '{print $5}' | head -1)

  cat > "$WG_CONFIG" <<EOF
[Interface]
Address = $wg_ipv4_addr, $wg_ipv6_addr
ListenPort = 51820
PrivateKey = $priv
PostUp = iptables -A FORWARD -i wg0 -o wg0 -j DROP; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o $iface -j MASQUERADE; ip6tables -A FORWARD -i wg0 -o wg0 -j DROP; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o $iface -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o $iface -j MASQUERADE; ip6tables -D FORWARD -i wg0 -o wg0 -j DROP; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o $iface -j MASQUERADE
EOF
  chmod 600 "$WG_CONFIG"

  sysctl -w net.ipv4.ip_forward=1 >/dev/null
  echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/99-phobos.conf
  sysctl -p /etc/sysctl.d/99-phobos.conf >/dev/null

  systemctl enable wg-quick@wg0
  systemctl restart wg-quick@wg0
  log_success "WireGuard настроен"
}

get_public_ipv6() {
  local iface=$(ip route | grep default | awk '{print $5}' | head -1)
  [[ -z "$iface" ]] && return

  local ipv6=$(ip -6 addr show dev "$iface" scope global 2>/dev/null | grep -oP 'inet6 \K[0-9a-f:]+' | grep -v '^f[cd]' | head -1)
  [[ -n "$ipv6" ]] && echo "$ipv6"
}

step_obf() {
  log_info "Настройка Obfuscator..."

  local params=$(get_obf_params "$OBF_LEVEL")
  local key_len=$(echo "$params" | cut -d' ' -f1)
  local dummy=$(echo "$params" | cut -d' ' -f2)

  local port=$(find_free_port 1024 49151)
  local key=$(head -c $((key_len * 2)) /dev/urandom | base64 | tr -d '+/=\n' | head -c "$key_len")
  local pub_ip_v4
  pub_ip_v4=$(get_public_ipv4) || true
  if [[ -z "$pub_ip_v4" ]]; then
    log_warn "Не удалось определить публичный IP автоматически"
    while true; do
      read -rp "Введите публичный IPv4 сервера: " pub_ip_v4
      [[ "$pub_ip_v4" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] && break
      log_error "Неверный формат IP, повторите"
    done
  fi
  local pub_ip_v6=$(get_public_ipv6)

  cat >> "$SERVER_ENV" <<EOF
OBFUSCATOR_PORT=$port
OBFUSCATOR_KEY=$key
OBFUSCATOR_DUMMY=$dummy
OBFUSCATOR_IDLE=300
OBFUSCATOR_MASKING=STUN
SERVER_PUBLIC_IP_V4=$pub_ip_v4
SERVER_PUBLIC_IP_V6=$pub_ip_v6
WG_LOCAL_ENDPOINT=127.0.0.1:51820
CLIENT_WG_PORT=13255
EOF

  cat > /etc/systemd/system/wg-obfuscator.service <<EOF
[Unit]
Description=WireGuard Traffic Obfuscator
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/wg-obfuscator --config /opt/Phobos/server/wg-obfuscator.conf
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

  systemctl daemon-reload
  systemctl enable wg-obfuscator

  cat > "$OBF_CONFIG" <<EOF
[instance]
source-if = 0.0.0.0
source-lport = $port
target = 127.0.0.1:51820
key = $key
masking = STUN
verbose = INFO
idle-timeout = 300
max-dummy = $dummy
EOF

  systemctl restart wg-obfuscator
  log_success "Obfuscator настроен на порту $port"
}

step_http() {
  log_info "Настройка HTTP сервера..."

  local port=$(find_free_port 1024 49151)

  cat > /etc/systemd/system/phobos-http.service <<EOF
[Unit]
Description=Phobos HTTP Distribution Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=$WWW_DIR
ExecStart=/usr/local/bin/darkhttpd $WWW_DIR --port $port --no-listing
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

  systemctl daemon-reload
  systemctl enable phobos-http
  systemctl restart phobos-http

  echo "HTTP_PORT=$port" >> "$SERVER_ENV"

  log_success "HTTP сервер настроен на порту $port"
}

step_final() {
  log_info "Настройка Cron..."
  echo "*/10 * * * * root $REPO_DIR/server/scripts/phobos-system.sh cleanup" > /etc/cron.d/phobos-cleanup
  chmod 644 /etc/cron.d/phobos-cleanup

  log_info "Установка меню..."
  ln -sf "$REPO_DIR/server/scripts/phobos-menu.sh" /usr/local/bin/phobos

  log_success "Установка завершена! Запустите 'phobos' для управления системой."
}

ensure_dirs
step_deps
step_build
step_wg
step_obf
step_http
step_final