#!/bin/sh set -e CLIENT_NAME="{{CLIENT_NAME}}" PHOBOS_DIR="" ROUTER_PLATFORM="" . "$(dirname "$0")/lib-client.sh" . "$(dirname "$0")/install-obfuscator.sh" . "$(dirname "$0")/install-wireguard.sh" detect_3xui_mode() { local platform="$1" if [ "$platform" = "linux" ] && [ -f /etc/x-ui/x-ui.db ]; then echo "true" else echo "false" fi } check_dependencies() { local platform="$1" local missing="" local base_deps="grep cut date tee tar curl jq" local platform_deps="" if [ "$platform" = "openwrt" ]; then platform_deps="uci" fi for cmd in $base_deps $platform_deps; do if ! command -v "$cmd" >/dev/null 2>&1; then missing="$missing $cmd" fi done if [ -n "$missing" ]; then log "ВНИМАНИЕ: Отсутствуют необходимые утилиты:$missing" if [ "$platform" = "linux" ]; then log "Устанавливаю недостающие пакеты через apt-get..." if command -v apt-get >/dev/null 2>&1; then if ! apt-get update; then log "ОШИБКА: Не удалось обновить список пакетов apt-get" return 1 fi for cmd in $missing; do log "Установка $cmd..." if ! apt-get install -y "$cmd" 2>/dev/null; then log "ПРЕДУПРЕЖДЕНИЕ: Не удалось установить $cmd через apt-get" fi done else log "ОШИБКА: apt-get не найден. Невозможно установить зависимости." return 1 fi else log "Устанавливаю недостающие пакеты через opkg..." if command -v opkg >/dev/null 2>&1; then if ! opkg update; then log "ОШИБКА: Не удалось обновить список пакетов opkg" return 1 fi for cmd in $missing; do log "Установка $cmd..." if ! opkg install "$cmd" 2>/dev/null; then log "ПРЕДУПРЕЖДЕНИЕ: Не удалось установить $cmd через opkg" fi done else log "ОШИБКА: opkg не найден. Невозможно установить зависимости." return 1 fi fi fi return 0 } setup_configs() { log "Настройка конфигураций..." mkdir -p "$PHOBOS_DIR" cp wg-obfuscator.conf "$PHOBOS_DIR/${OBF_CONF_NAME}" chmod 600 "$PHOBOS_DIR/${OBF_CONF_NAME}" cp "${CLIENT_NAME}.conf" "$PHOBOS_DIR/${CLIENT_NAME}.conf" chmod 600 "$PHOBOS_DIR/${CLIENT_NAME}.conf" printf '%s' "${CLIENT_NAME}" > "$PHOBOS_DIR/${OBF_CONF_NAME%.conf}.link" if [ "$OBF_BINARY_NAME" != "wg-obfuscator" ]; then local used_ports="" for existing_conf in "$PHOBOS_DIR"/wg-obfuscator*.conf; do [ -f "$existing_conf" ] || continue [ "$(basename "$existing_conf")" = "${OBF_CONF_NAME}" ] && continue local port port=$(grep 'source-lport' "$existing_conf" 2>/dev/null | tr -d ' ' | cut -d'=' -f2) [ -n "$port" ] && used_ports="${used_ports} ${port}" done local new_port=13255 local port_taken=1 while [ "$port_taken" -eq 1 ]; do port_taken=0 for p in $used_ports; do if [ "$p" = "$new_port" ]; then port_taken=1 new_port=$((new_port + 1)) break fi done done sed -i "s/^source-lport = [0-9]*/source-lport = ${new_port}/" "$PHOBOS_DIR/${OBF_CONF_NAME}" sed -i "s/^Endpoint = 127\.0\.0\.1:[0-9]*/Endpoint = 127.0.0.1:${new_port}/" "$PHOBOS_DIR/${CLIENT_NAME}.conf" log " Назначен локальный порт obfuscator: $new_port" fi log "Конфигурации установлены:" log " - Obfuscator: $PHOBOS_DIR/${OBF_CONF_NAME}" log " - WireGuard: $PHOBOS_DIR/${CLIENT_NAME}.conf" } deploy_lib_client() { if [ -f "lib-client.sh" ]; then cp "lib-client.sh" "$PHOBOS_DIR/lib-client.sh" fi } deploy_uninstall_script() { log "Развертывание скрипта удаления Phobos..." if [ -f "phobos-uninstall.sh" ]; then cp "phobos-uninstall.sh" "$PHOBOS_DIR/phobos-uninstall.sh" chmod +x "$PHOBOS_DIR/phobos-uninstall.sh" log "Скрипт удаления установлен: $PHOBOS_DIR/phobos-uninstall.sh" else log "ПРЕДУПРЕЖДЕНИЕ: phobos-uninstall.sh не найден в архиве" fi } deploy_3xui_script() { log "Развертывание скрипта 3xui.sh..." if [ -f "3xui.sh" ]; then cp "3xui.sh" "$PHOBOS_DIR/3xui.sh" chmod +x "$PHOBOS_DIR/3xui.sh" log "Скрипт 3xui.sh установлен: $PHOBOS_DIR/3xui.sh" else log "ПРЕДУПРЕЖДЕНИЕ: 3xui.sh не найден в архиве" fi } run_3xui_integration() { log "" log "==> Интеграция WireGuard конфигурации в 3x-ui..." if [ ! -f "$PHOBOS_DIR/3xui.sh" ]; then log "ОШИБКА: Скрипт $PHOBOS_DIR/3xui.sh не найден" return 1 fi for cmd in jq sqlite3; do if ! command -v "$cmd" >/dev/null 2>&1; then log "Устанавливаю $cmd..." if command -v apt-get >/dev/null 2>&1; then apt-get update -qq && apt-get install -y -qq "$cmd" >/dev/null 2>&1 elif command -v yum >/dev/null 2>&1; then yum install -y -q "${cmd/sqlite3/sqlite}" >/dev/null 2>&1 elif command -v dnf >/dev/null 2>&1; then dnf install -y -q "${cmd/sqlite3/sqlite}" >/dev/null 2>&1 elif command -v apk >/dev/null 2>&1; then apk add --quiet "${cmd/sqlite3/sqlite}" >/dev/null 2>&1 fi if ! command -v "$cmd" >/dev/null 2>&1; then log "ОШИБКА: не удалось установить $cmd" return 1 fi fi done local wg_config="$PHOBOS_DIR/${CLIENT_NAME}.conf" if [ ! -f "$wg_config" ]; then log "ОШИБКА: Конфигурация WireGuard не найдена: $wg_config" return 1 fi log "Запуск интеграции: $PHOBOS_DIR/3xui.sh $wg_config" if "$PHOBOS_DIR/3xui.sh" "$wg_config"; then log "[OK] WireGuard конфигурация успешно интегрирована в 3x-ui" log "[OK] Outbound 'Phobos' добавлен в конфигурацию 3x-ui" return 0 else log "ОШИБКА: Не удалось интегрировать конфигурацию в 3x-ui" return 1 fi } cleanup_3xui_script() { local keep_script="$1" if [ "$keep_script" = "true" ]; then log "Скрипт 3xui.sh сохранен для использования в 3x-ui режиме" else if [ -f "$PHOBOS_DIR/3xui.sh" ]; then rm -f "$PHOBOS_DIR/3xui.sh" log "Скрипт 3xui.sh удален (не требуется в обычном режиме)" fi fi } install_wireguard_openwrt() { log "Установка пакетов WireGuard для OpenWRT..." if ! command -v wg >/dev/null 2>&1; then log "Установка kmod-wireguard и wireguard-tools..." opkg update opkg install kmod-wireguard wireguard-tools luci-proto-wireguard else log "WireGuard уже установлен" fi log "Установка luci-app-wireguard для веб-интерфейса..." opkg install luci-app-wireguard >/dev/null 2>&1 || log "ПРЕДУПРЕЖДЕНИЕ: luci-app-wireguard не удалось установить" log "✓ Пакеты WireGuard установлены" } configure_wireguard_openwrt() { log "" log "==> Автоматическая настройка WireGuard через UCI..." extract_wireguard_params if [ ! -f "./router-configure-wireguard-openwrt.sh" ]; then log "⚠ Скрипт router-configure-wireguard-openwrt.sh не найден" log " Используйте ручную настройку через LuCI или UCI" return 1 fi chmod +x ./router-configure-wireguard-openwrt.sh if ./router-configure-wireguard-openwrt.sh \ --client-name "$CLIENT_NAME" \ --client-private-key "$WG_PRIVATE_KEY" \ --client-ip "$CLIENT_IP" \ --client-ipv6 "$CLIENT_IPV6" \ --server-public-key "$WG_SERVER_PUBKEY" \ --endpoint-port "$WG_ENDPOINT_PORT" \ --keepalive 25 \ --mtu 1420 \ --fallback-config "$PHOBOS_DIR/${CLIENT_NAME}.conf"; then return 0 else return 1 fi } extract_wireguard_params() { log "Извлечение параметров WireGuard из конфигурации..." local config_file="$PHOBOS_DIR/${CLIENT_NAME}.conf" WG_PRIVATE_KEY=$(grep '^PrivateKey' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r') WG_ADDRESS=$(grep '^Address' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r') WG_SERVER_PUBKEY=$(grep '^PublicKey' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r') WG_ENDPOINT_PORT=$(grep '^Endpoint' "$config_file" | cut -d':' -f2 | tr -d ' \t\n\r') CLIENT_IP=$(echo "$WG_ADDRESS" | cut -d',' -f1 | tr -d ' ') CLIENT_IPV6=$(echo "$WG_ADDRESS" | cut -d',' -f2 | tr -d ' ') if [ -z "$CLIENT_IPV6" ] || [ "$CLIENT_IPV6" = "$CLIENT_IP" ]; then CLIENT_IPV6=$(grep -A 10 '\[Interface\]' "$config_file" | grep '^Address' | grep -o 'fd[0-9a-f:\/]*' | head -1) fi if [ -z "$CLIENT_IPV6" ]; then CLIENT_IPV6="none" fi if [ -z "$WG_ENDPOINT_PORT" ]; then WG_ENDPOINT_PORT=13255 fi log " Private Key: ${WG_PRIVATE_KEY:0:20}..." log " IPv4: $CLIENT_IP" log " IPv6: $CLIENT_IPV6" log " Server PubKey: ${WG_SERVER_PUBKEY:0:20}..." log " Endpoint port: $WG_ENDPOINT_PORT" } configure_wireguard_rci() { log "" log "==> Автоматическая настройка WireGuard через RCI API..." extract_wireguard_params if [ ! -f "./router-configure-wireguard.sh" ]; then log "⚠ Скрипт router-configure-wireguard.sh не найден" log " Используйте ручной импорт (см. инструкции ниже)" return 1 fi chmod +x ./router-configure-wireguard.sh if ./router-configure-wireguard.sh \ --client-name "$CLIENT_NAME" \ --client-private-key "$WG_PRIVATE_KEY" \ --client-ip "$CLIENT_IP" \ --client-ipv6 "$CLIENT_IPV6" \ --server-public-key "$WG_SERVER_PUBKEY" \ --endpoint-port "$WG_ENDPOINT_PORT" \ --keepalive 25 \ --mtu 1420 \ --fallback-config "$PHOBOS_DIR/${CLIENT_NAME}.conf"; then return 0 else return 1 fi } show_manual_instructions() { log "" log "╔════════════════════════════════════════════════════════════╗" log "║ Требуется ручной импорт WireGuard конфигурации ║" log "╚════════════════════════════════════════════════════════════╝" log "" log "Выполните следующие шаги:" log "" if [ "$ROUTER_PLATFORM" = "keenetic" ]; then log "1. Откройте веб-панель администрирования роутера Keenetic" log " (http://192.168.1.1 или http://my.keenetic.net)" log "" log "2. Перейдите в раздел: Интернет → Другие подключения" log "" log "3. Выберите 'Загрузить конфигурацию из файла' в разделе 'WireGuard'" log "" log "4. Укажите путь к файлу:" log " $PHOBOS_DIR/${CLIENT_NAME}.conf" log "" log "5. Активируйте подключение" elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then log "1. Откройте веб-интерфейс LuCI роутера OpenWRT" log " (обычно http://192.168.1.1)" log "" log "2. Перейдите в: Network → Interfaces" log "" log "3. Создайте новый интерфейс с протоколом WireGuard" log "" log "4. Используйте параметры из файла:" log " $PHOBOS_DIR/${CLIENT_NAME}.conf" log "" log "5. Настройте файрволл зону для интерфейса" fi log "" } show_final_info() { log "" log "╔════════════════════════════════════════════════════════════╗" log "║ Информация об установке ║" log "╚════════════════════════════════════════════════════════════╝" log "" log "Файлы установки:" if [ "$ROUTER_PLATFORM" = "keenetic" ]; then log " Бинарник: /opt/bin/${OBF_BINARY_NAME}" elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then log " Бинарник: /usr/bin/${OBF_BINARY_NAME}" elif [ "$ROUTER_PLATFORM" = "linux" ]; then log " Бинарник: /usr/local/bin/${OBF_BINARY_NAME}" fi log " Конфиг obfuscator: $PHOBOS_DIR/${OBF_CONF_NAME}" log " Конфиг WireGuard: $PHOBOS_DIR/${CLIENT_NAME}.conf" if [ "$ROUTER_PLATFORM" = "keenetic" ] || [ -f /opt/etc/init.d/${OBF_INIT_NAME} ]; then log " Init-скрипт: /opt/etc/init.d/${OBF_INIT_NAME}" elif [ "$ROUTER_PLATFORM" = "openwrt" ] && [ -f /etc/init.d/${OBF_SERVICE_NAME} ]; then log " Init-скрипт: /etc/init.d/${OBF_SERVICE_NAME}" elif [ "$ROUTER_PLATFORM" = "linux" ]; then log " Systemd service: /etc/systemd/system/${OBF_SERVICE_NAME}.service" log " WireGuard конфиг: /etc/wireguard/${OBF_WG_IFACE}.conf" fi log " Uninstall: $PHOBOS_DIR/phobos-uninstall.sh" log " Health monitor: $PHOBOS_DIR/phobos-health.sh" log " Failover config: $PHOBOS_DIR/failover.conf" log "" log "Управление:" if [ "$ROUTER_PLATFORM" = "keenetic" ] || [ -f /opt/etc/init.d/${OBF_INIT_NAME} ]; then log " /opt/etc/init.d/${OBF_INIT_NAME} status # Проверить что obfuscator запущен" elif [ "$ROUTER_PLATFORM" = "openwrt" ] && [ -f /etc/init.d/${OBF_SERVICE_NAME} ]; then log " /etc/init.d/${OBF_SERVICE_NAME} status # Проверить что obfuscator запущен" elif [ "$ROUTER_PLATFORM" = "linux" ]; then log " systemctl status ${OBF_SERVICE_NAME} # Проверить что obfuscator запущен" log " systemctl status wg-quick@${OBF_WG_IFACE} # Проверить что WireGuard запущен" fi log " $PHOBOS_DIR/phobos-uninstall.sh # Удалить Phobos" log "" } deploy_health_monitor() { log "Развертывание монитора здоровья Phobos..." if [ ! -f "phobos-health.sh" ]; then log "ПРЕДУПРЕЖДЕНИЕ: phobos-health.sh не найден в архиве" return 0 fi cp "phobos-health.sh" "$PHOBOS_DIR/phobos-health.sh" chmod +x "$PHOBOS_DIR/phobos-health.sh" if [ -f "failover.conf" ]; then cp "failover.conf" "$PHOBOS_DIR/failover.conf" chmod 600 "$PHOBOS_DIR/failover.conf" fi mkdir -p "$PHOBOS_DIR/state" # --- Phobos pull agent: panel -> router config sync (NAT-friendly) --- # Routers behind NAT cannot be reached by the panel over SSH, so they PULL # their failover.conf over HTTP. Ships client_id + pull_token from the package. if [ -f "phobos-pull.sh" ]; then cp "phobos-pull.sh" "$PHOBOS_DIR/phobos-pull.sh" chmod +x "$PHOBOS_DIR/phobos-pull.sh" echo "{{CLIENT_NAME}}" > "$PHOBOS_DIR/client_id" [ -f "pull_token" ] && cp "pull_token" "$PHOBOS_DIR/pull_token" log " Pull-агент установлен (client_id={{CLIENT_NAME}})" fi local cron_line="*/1 * * * * $PHOBOS_DIR/phobos-health.sh" local pull_line="*/1 * * * * $PHOBOS_DIR/phobos-pull.sh" [ -f "$PHOBOS_DIR/phobos-pull.sh" ] || pull_line="" if [ "$ROUTER_PLATFORM" = "keenetic" ]; then # Install cron if not present (Entware) if ! command -v crontab >/dev/null 2>&1 && command -v opkg >/dev/null 2>&1; then log " Установка cron через opkg..." opkg update >/dev/null 2>&1 opkg install cron >/dev/null 2>&1 /opt/etc/init.d/S10cron start >/dev/null 2>&1 || true fi local cron_file="/opt/etc/crontab" # Create crontab file if missing if [ ! -f "$cron_file" ]; then mkdir -p /opt/etc touch "$cron_file" fi if ! grep -q "phobos-health" "$cron_file" 2>/dev/null; then echo "$cron_line" >> "$cron_file" log " Cron (health) добавлен в $cron_file" fi if [ -n "$pull_line" ] && ! grep -q "phobos-pull" "$cron_file" 2>/dev/null; then echo "$pull_line" >> "$cron_file" log " Cron (pull) добавлен в $cron_file" fi /opt/etc/init.d/S10cron restart >/dev/null 2>&1 || true elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then (crontab -l 2>/dev/null | grep -v "phobos-health" | grep -v "phobos-pull"; echo "$cron_line"; [ -n "$pull_line" ] && echo "$pull_line") | crontab - log " Cron добавлен через crontab (health + pull)" elif [ "$ROUTER_PLATFORM" = "linux" ]; then { echo "$cron_line"; [ -n "$pull_line" ] && echo "$pull_line"; } > /etc/cron.d/phobos-health chmod 644 /etc/cron.d/phobos-health log " Cron добавлен в /etc/cron.d/phobos-health (health + pull)" fi log " Монитор здоровья: $PHOBOS_DIR/phobos-health.sh" log " Failover конфиг: $PHOBOS_DIR/failover.conf" log " Проверка каждую минуту через cron" } main() { ROUTER_PLATFORM=$(detect_router_platform) PHOBOS_DIR=$(detect_phobos_dir "$ROUTER_PLATFORM") IS_3XUI_MODE=$(detect_3xui_mode "$ROUTER_PLATFORM") log "==> Определена платформа: $ROUTER_PLATFORM" log "==> Директория Phobos: $PHOBOS_DIR" resolve_install_names log "==> Режим установки obfuscator: binary=${OBF_BINARY_NAME}, conf=${OBF_CONF_NAME}, init=${OBF_INIT_NAME}, service=${OBF_SERVICE_NAME}" if [ "$IS_3XUI_MODE" = "true" ]; then log "==> Обнаружен режим установки: 3x-ui" log "==> В этом режиме WireGuard не устанавливается" log "==> Будет развернут только wg-obfuscator и интеграция с 3x-ui" fi if [ "$ROUTER_PLATFORM" = "unknown" ]; then log "ОШИБКА: Неподдерживаемая платформа" log "Вывод uname -a: $(uname -a)" log "" log "Поддерживаемые платформы:" log " - Keenetic/Netcraze (определяется по 'Keenetic' или 'Netcraze' в uname)" log " - OpenWRT (определяется по 'OpenWrt', 'LEDE' или 'ImmortalWrt' в uname)" log " - Linux (Ubuntu/Debian)" exit 1 fi mkdir -p "$PHOBOS_DIR" log "==> Начало установки Phobos на роутер $ROUTER_PLATFORM" log "==> Клиент: $CLIENT_NAME" check_root if ! check_dependencies "$ROUTER_PLATFORM"; then log "ОШИБКА: Не удалось установить зависимости" exit 1 fi ARCH=$(detect_arch) log "Определена архитектура: $ARCH" if [ "$ARCH" = "unknown" ]; then log "Ошибка: неподдерживаемая архитектура" log "Вывод uname -m: $(uname -m)" exit 1 fi install_obfuscator "$ARCH" setup_configs deploy_lib_client deploy_uninstall_script deploy_health_monitor if [ "$IS_3XUI_MODE" = "true" ]; then deploy_3xui_script fi if [ "$ROUTER_PLATFORM" = "keenetic" ]; then create_init_script start_obfuscator if configure_wireguard_rci; then log "" log "╔════════════════════════════════════════════════════════════╗" log "║ ✓ Установка завершена успешно! ║" log "║ ✓ WireGuard настроен автоматически через RCI API ║" log "╚════════════════════════════════════════════════════════════╝" show_final_info else log "" log "╔════════════════════════════════════════════════════════════╗" log "║ ✓ Obfuscator установлен успешно ║" log "║ ⚠ WireGuard требует ручной настройки ║" log "╚════════════════════════════════════════════════════════════╝" show_manual_instructions show_final_info fi elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then install_wireguard_openwrt if [ -d "/opt/etc" ]; then create_init_script else create_procd_init_script fi start_obfuscator if configure_wireguard_openwrt; then log "" log "╔════════════════════════════════════════════════════════════╗" log "║ ✓ Установка завершена успешно! ║" log "║ ✓ WireGuard настроен автоматически через UCI ║" log "╚════════════════════════════════════════════════════════════╝" show_final_info else log "" log "╔════════════════════════════════════════════════════════════╗" log "║ ✓ Obfuscator установлен успешно ║" log "║ ⚠ WireGuard требует ручной настройки ║" log "╚════════════════════════════════════════════════════════════╝" show_manual_instructions show_final_info fi elif [ "$ROUTER_PLATFORM" = "linux" ]; then if [ "$IS_3XUI_MODE" = "true" ]; then log "" log "╔════════════════════════════════════════════════════════════╗" log "║ Режим установки: 3x-ui ║" log "╚════════════════════════════════════════════════════════════╝" log "" create_systemd_obfuscator_service if run_3xui_integration; then cleanup_3xui_script "true" log "" log "╔════════════════════════════════════════════════════════════╗" log "║ ✓ Установка в режиме 3x-ui завершена успешно! ║" log "║ ✓ Obfuscator настроен через systemd ║" log "║ ✓ Outbound 'Phobos' добавлен в конфигурацию 3x-ui ║" log "╚════════════════════════════════════════════════════════════╝" log "" log "Файлы установки:" log " Бинарник: /usr/local/bin/wg-obfuscator" log " Конфиг obfuscator: $PHOBOS_DIR/wg-obfuscator.conf" log " Конфиг WireGuard: $PHOBOS_DIR/${CLIENT_NAME}.conf" log " Скрипт 3xui.sh: $PHOBOS_DIR/3xui.sh" log " Systemd service: /etc/systemd/system/phobos-obfuscator.service" log "" log "Управление:" log " systemctl status phobos-obfuscator # Проверить что obfuscator запущен" log "" log "Примечание:" log " WireGuard управляется через 3x-ui панель" log " Скрипт 3xui.sh сохранен для повторной интеграции при необходимости" log "" else log "" log "╔════════════════════════════════════════════════════════════╗" log "║ ✗ Установка в режиме 3x-ui завершена с ошибками ║" log "╚════════════════════════════════════════════════════════════╝" exit 1 fi else install_wireguard_linux || { log "ОШИБКА: Не удалось установить WireGuard" exit 1 } create_systemd_obfuscator_service if configure_wireguard_linux; then configure_ufw_linux cleanup_3xui_script "false" log "" log "╔════════════════════════════════════════════════════════════╗" log "║ ✓ Установка завершена успешно! ║" log "║ ✓ WireGuard и Obfuscator настроены через systemd ║" log "╚════════════════════════════════════════════════════════════╝" show_final_info else cleanup_3xui_script "false" log "" log "╔════════════════════════════════════════════════════════════╗" log "║ ⚠ Установка завершена с предупреждениями ║" log "║ ⚠ Проверьте статус служб вручную ║" log "╚════════════════════════════════════════════════════════════╝" show_final_info fi fi fi log "==> Установка завершена." } main "$@"