#!/bin/bash # Мастер-скрипт. Запускай от обычного пользователя (sudo попросит сам где нужно). cd "$(dirname "$0")" BLD='\033[1m' GRN='\033[0;32m' YEL='\033[0;33m' GRY='\033[0;37m' CLR='\033[0m' mkdir -p "$HOME/.config/ai-setup" LOG="$HOME/.config/ai-setup/setup.log" _log() { printf '%s [%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1" "$2" >> "$LOG"; } if command -v whiptail >/dev/null 2>&1; then choice=$(whiptail --title "AI Setup" \ --menu "Выбери действие (стрелки + Enter):" 22 70 9 \ "1" "AI-инструменты (установить лаунчеры + ключи)" \ "2" "Сеть: ru-bypass + kill switch" \ "" "─── Дополнительно ───────────────────────────" \ "3" "Отключить kill switch (прямой доступ без VPN)" \ "4" "Включить kill switch (восстановить защиту)" \ "5" "Статус (Amnezia, UFW, AI инструменты, ключи)" \ "6" "Проверить сеть (маршрутизация, geo)" \ "7" "Обновить (git pull + перегенерация скриптов)" \ 3>&1 1>&2 2>&3) || exit 0 echo "" else echo "" echo -e "${BLD}=== AI Setup ===${CLR}" echo "" echo -e "${YEL}Шаги для новой машины (выполнить по порядку):${CLR}" echo "" echo -e " ${BLD}1) AI-инструменты${CLR}" echo -e " ${GRY}Устанавливает ai-claude, ai-gpt, ai-deepseek, ai-gemini и др.${CLR}" echo -e " ${GRY}Запрашивает API-ключи. Запускать один раз.${CLR}" echo "" echo -e " ${BLD}2) Сеть: ru-bypass + kill switch${CLR}" echo -e " ${GRY}.ru сайты (ozon, госуслуги) — напрямую с российским IP.${CLR}" echo -e " ${GRY}*.loc офисные адреса — тоже напрямую.${CLR}" echo -e " ${GRY}Всё остальное — только через Amnezia (kill switch).${CLR}" echo -e " ${GRY}Запускать один раз на каждой машине.${CLR}" echo "" echo -e "${YEL}Дополнительно (по необходимости):${CLR}" echo "" echo -e " ${BLD}3) Отключить kill switch${CLR}" echo -e " ${GRY}Временно — когда нужен прямой доступ без VPN (российский IP).${CLR}" echo "" echo -e " ${BLD}4) Включить kill switch${CLR}" echo -e " ${GRY}Вернуть защиту обратно после отключения.${CLR}" echo "" echo -e " ${BLD}5) Статус${CLR}" echo -e " ${GRY}Amnezia, UFW, сервисы, установленные AI инструменты и ключи.${CLR}" echo "" echo -e " ${BLD}6) Проверить сеть${CLR}" echo -e " ${GRY}Тесты маршрутизации: .ru напрямую, остальное через Amnezia.${CLR}" echo "" echo -e " ${BLD}7) Обновить${CLR}" echo -e " ${GRY}git pull + перегенерация всех скриптов в ~/.local/bin.${CLR}" echo "" echo -n "Выбери [1-7] или Enter для выхода: " read -r choice echo "" fi [ -n "$choice" ] && _log "setup" "Пункт $choice на $(hostname)" case "$choice" in 1) bash scripts/ai-setup.sh ;; 2) echo -e "${GRY}Нужно указать параметры твоей локальной сети:${CLR}" echo -e "${GRY} GATEWAY — IP домашнего/офисного роутера (через него пойдёт .ru трафик напрямую)${CLR}" echo -e "${GRY} DEV — сетевой интерфейс (wifi или провод), через который ты подключён к роутеру${CLR}" echo -e "${GRY} LOCAL_DNS — IP офисного DNS-сервера для разрешения *.loc доменов (необязательно)${CLR}" echo "" mkdir -p "$HOME/.config/ai-setup" cfg_dir="$HOME/.config/ai-setup" # Показываем существующие профили existing=$(ls "$cfg_dir"/network_*.conf 2>/dev/null | sed 's|.*/network_||;s|\.conf||' | tr '\n' ' ') if [ -n "$existing" ]; then echo -e "Существующие профили: ${BLD}${existing}${CLR}" echo -e "${GRY}Введи имя профиля (home/office/$(hostname) и т.д.) или Enter для текущего${CLR}" read -rp "Профиль [$(hostname)]: " chosen_profile chosen_profile="${chosen_profile:-$(hostname)}" else chosen_profile="$(hostname)" fi net_conf="$cfg_dir/network_${chosen_profile}.conf" auto_gw=$(ip route show default 2>/dev/null | awk '/default/ {print $3; exit}') auto_dev=$(ip route show default 2>/dev/null | awk '/default/ {print $5; exit}') auto_gw="${auto_gw:-192.168.1.1}" auto_dev="${auto_dev:-wlp1s0}" saved_local_dns="" if [ -f "$net_conf" ]; then saved_gw=$(grep '^GATEWAY=' "$net_conf" | cut -d= -f2) saved_dev=$(grep '^DEV=' "$net_conf" | cut -d= -f2) saved_local_dns=$(grep '^LOCAL_DNS=' "$net_conf" | cut -d= -f2) auto_gw="${saved_gw:-$auto_gw}" auto_dev="${saved_dev:-$auto_dev}" echo -e "Загружены параметры профиля ${BLD}${chosen_profile}${CLR}: GATEWAY=${BLD}${auto_gw}${CLR} DEV=${BLD}${auto_dev}${CLR}" else echo -e "Новый профиль ${BLD}${chosen_profile}${CLR}. Определено автоматически: GATEWAY=${BLD}${auto_gw}${CLR} DEV=${BLD}${auto_dev}${CLR}" fi echo -e "${GRY}(просто Enter чтобы принять, или введи другое значение)${CLR}" echo "" read -rp "GATEWAY (IP роутера) [${auto_gw}]: " gw read -rp "DEV (интерфейс) [${auto_dev}]: " dev read -rp "LOCAL_DNS (DNS для *.loc) [${saved_local_dns:-пусто}]: " local_dns gw="${gw:-$auto_gw}" dev="${dev:-$auto_dev}" [ "$local_dns" = "пусто" ] && local_dns="" local_dns="${local_dns:-$saved_local_dns}" printf 'GATEWAY=%s\nDEV=%s\nLOCAL_DNS=%s\n' "$gw" "$dev" "$local_dns" > "$net_conf" echo "" sudo GATEWAY="$gw" DEV="$dev" LOCAL_DNS="$local_dns" USER_HOME="$HOME" bash scripts/ru-bypass.sh ;; 3) echo -e "${YEL}Перед этим выйди из Claude Code — сессия сменит IP.${CLR}" echo -n "Продолжить? [y/N] " read -r confirm [ "$confirm" = "y" ] || [ "$confirm" = "Y" ] || exit 0 sudo USER_HOME="$HOME" bash scripts/ks-off.sh ;; 4) sudo USER_HOME="$HOME" bash scripts/ks-on.sh ;; 5) echo -e "${BLD}=== Статус ===${CLR}" echo "" echo -e "${BLD}Сеть:${CLR}" if ip link show amn0 &>/dev/null; then echo -e " ${GRN}✓${CLR} Amnezia (amn0) подключена" else echo -e " ${YEL}✗${CLR} Amnezia (amn0) не найдена" fi if sudo ufw status 2>/dev/null | grep -qE "активен|active"; then echo -e " ${GRN}✓${CLR} UFW kill switch активен" else echo -e " ${YEL}✗${CLR} UFW выключен" fi if systemctl is-active --quiet ru-bypass.service 2>/dev/null || systemctl is-enabled --quiet ru-bypass.service 2>/dev/null; then echo -e " ${GRN}✓${CLR} ru-bypass.service установлен" else echo -e " ${YEL}✗${CLR} ru-bypass.service не установлен (запусти пункт 2)" fi if systemctl is-enabled --quiet ru-ipset-restore.service 2>/dev/null; then echo -e " ${GRN}✓${CLR} ru-ipset-restore.service установлен" else echo -e " ${YEL}✗${CLR} ru-ipset-restore.service не установлен (запусти пункт 2)" fi ipv6_cnt=$(ip -6 addr show scope global 2>/dev/null | grep -c 'inet6' || true) if [ "$ipv6_cnt" -eq 0 ]; then echo -e " ${GRN}✓${CLR} IPv6 отключён (нет утечки)" else echo -e " ${YEL}!${CLR} IPv6 активен ($ipv6_cnt адресов) — возможна утечка, запусти пункт 4" fi echo "" echo -e "${BLD}AI инструменты:${CLR}" for cmd in ai-claude ai-gpt ai-deepseek ai-kimi ai-openrouter ai-gemini; do if command -v "$cmd" &>/dev/null; then echo -e " ${GRN}✓${CLR} $cmd" else echo -e " ${YEL}✗${CLR} $cmd" fi done echo "" echo -e "${BLD}API ключи:${CLR}" cfg="$HOME/.config/ai-setup" for f in deepseek_key kimi_key openrouter_key; do name="${f/_key/}" if [ -s "$cfg/$f" ]; then echo -e " ${GRN}✓${CLR} $name" else echo -e " ${YEL}✗${CLR} $name (не задан)" fi done echo "" echo -e "${BLD}API доступность:${CLR}" for entry in "Anthropic:api.anthropic.com" "DeepSeek:api.deepseek.com" "OpenAI:api.openai.com" "Kimi:api.kimi.com" "OpenRouter:openrouter.ai"; do _name="${entry%%:*}" _host="${entry##*:}" _ms=$(curl -s -o /dev/null -w "%{time_connect}" --max-time 5 "https://$_host" 2>/dev/null) if [ -n "$_ms" ] && [ "$_ms" != "0.000000" ]; then echo -e " ${GRN}✓${CLR} $_name: ${_ms}s" else echo -e " ${YEL}✗${CLR} $_name: недоступен" fi done echo "" echo -e "${BLD}Последние события:${CLR}" if [ -f "$LOG" ]; then tail -10 "$LOG" | sed 's/^/ /' else echo " (лог пуст)" fi ;; 6) bash tests/test_network.sh ;; 7) REPO_DIR="$(cd "$(dirname "$0")" && pwd)" echo -e "${BLD}Обновляем репозиторий...${CLR}" git -C "$REPO_DIR" pull --ff-only echo "" echo -e "${BLD}Перегенерация скриптов...${CLR}" bash "$REPO_DIR/scripts/ai-setup.sh" ;; "") exit 0 ;; *) echo "Неверный выбор." exit 1 ;; esac