Files
ai-setup/setup.sh
Виталий Никитенко e955c928d3 fix: сохранение конфига в /etc/ru-bypass.conf для systemd/NM dispatcher
ru-bypass.sh теперь сохраняет параметры (GATEWAY, DEV, LOCAL_DNS, AMNEZIA_SERVER,
KILL_SWITCH_EXCEPTIONS) в /etc/ru-bypass.conf при каждом запуске, и читает их
оттуда при старте из systemd/NM dispatcher (без env). ENV-переменные имеют приоритет.

setup.sh: read -e -i для KS_EXCEPTIONS - редактирование значения инлайн вместо
показа текущего значения в скобках.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 12:14:47 +03:00

232 lines
11 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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=""
saved_amn_srv=""
saved_ks_exc=""
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)
saved_amn_srv=$(grep '^AMNEZIA_SERVER=' "$net_conf" | cut -d= -f2)
saved_ks_exc=$(grep '^KILL_SWITCH_EXCEPTIONS=' "$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
read -rp "AMNEZIA_SERVER (IP/домен сервера Amnezia) [${saved_amn_srv:-пусто}]: " amn_srv
read -e -rp "KS_EXCEPTIONS (исключения kill switch: IP/домены через пробел): " -i "${saved_ks_exc}" ks_exc
gw="${gw:-$auto_gw}"
dev="${dev:-$auto_dev}"
[ "$local_dns" = "пусто" ] && local_dns=""
local_dns="${local_dns:-$saved_local_dns}"
[ "$amn_srv" = "пусто" ] && amn_srv=""
amn_srv="${amn_srv:-$saved_amn_srv}"
[ "$ks_exc" = "пусто" ] && ks_exc=""
printf 'GATEWAY=%s\nDEV=%s\nLOCAL_DNS=%s\nAMNEZIA_SERVER=%s\nKILL_SWITCH_EXCEPTIONS=%s\n' "$gw" "$dev" "$local_dns" "$amn_srv" "$ks_exc" > "$net_conf"
echo ""
sudo GATEWAY="$gw" DEV="$dev" LOCAL_DNS="$local_dns" AMNEZIA_SERVER="$amn_srv" KILL_SWITCH_EXCEPTIONS="$ks_exc" 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