diff --git a/ai-setup.sh b/ai-setup.sh index e918886..790174d 100755 --- a/ai-setup.sh +++ b/ai-setup.sh @@ -30,15 +30,104 @@ if ! command -v python3 &>/dev/null; then fi success "Python 3 найден" +# ── VLESS URL parser ─────────────────────────────────────────── +# Принимает vless:// URL, устанавливает переменные VL_* +parse_vless_url() { + local url="$1" + eval "$(python3 -c " +import urllib.parse, sys + +url = sys.argv[1] +rest = url[8:] # strip 'vless://' + +at_pos = rest.index('@') +uuid = rest[:at_pos] +rest = rest[at_pos+1:] + +colon_pos = rest.index(':') +q_pos = rest.index('?') +host = rest[:colon_pos] +port = rest[colon_pos+1:q_pos] + +rest = rest[q_pos+1:] +hash_pos = rest.index('#') if '#' in rest else len(rest) +qs = rest[:hash_pos] +name = rest[hash_pos+1:] if '#' in rest else '' + +params = urllib.parse.parse_qs(qs) +def get(p, default=''): + vals = params.get(p, [default]) + return vals[0] if vals else default + +print(f'VL_UUID={uuid}') +print(f'VL_ADDRESS={host}') +print(f'VL_PORT={port}') +print(f'VL_ENCRYPTION={get(\"encryption\")}') +print(f'VL_SECURITY={get(\"security\")}') +print(f'VL_SNI={get(\"sni\")}') +print(f'VL_FP={get(\"fp\", \"chrome\")}') +print(f'VL_PBK={get(\"pbk\")}') +print(f'VL_SID={get(\"sid\")}') +print(f'VL_TYPE={get(\"type\", \"xhttp\")}') +print(f'VL_PATH={urllib.parse.unquote(get(\"path\", \"/\"))}') +print(f'VL_MODE={get(\"mode\", \"auto\")}') +print(f'VL_NAME={name}') +" "$url")" +} + # ── 0. Выбор режима работы (vless / direct) ───────────────── read -r -p "Установить встроенный vless? [Y/n] " _vless_ans _vless_ans="${_vless_ans:-Y}" if [[ "$_vless_ans" =~ ^[Yy]$ ]]; then USE_VLESS=1 - info "Режим: vless + proxychains4" + + # Читаем список серверов + _VL_URLS=() + _VL_LABELS=() + _SERVERS_FILE="$SCRIPT_DIR/home-configs/vless/servers.conf" + + if [ ! -f "$_SERVERS_FILE" ]; then + err "Файл servers.conf не найден: $_SERVERS_FILE" + fi + + while IFS= read -r line; do + [[ "$line" =~ ^[[:space:]]*# ]] && continue + [[ -z "$line" ]] && continue + _vl_rest="${line#vless://}" + _vl_rest="${_vl_rest#*@}" + _vl_ip="${_vl_rest%%:*}" + _vl_name="${line##*#}" + [[ "$_vl_name" == "$line" ]] && _vl_name="" + _VL_URLS+=("$line") + _VL_LABELS+=("$_vl_ip ($_vl_name)") + done < "$_SERVERS_FILE" + + if [ "${#_VL_URLS[@]}" -eq 0 ]; then + err "Нет VLESS серверов в $_SERVERS_FILE" + fi + + echo "" + info "Доступные VLESS серверы:" + for i in "${!_VL_LABELS[@]}"; do + echo -e " ${GREEN}$((i+1))${NC}) ${_VL_LABELS[$i]}" + done + + read -r -p "Выбери сервер [1-${#_VL_URLS[@]}]: " _vl_choice + _vl_choice="${_vl_choice:-1}" + if ! [[ "$_vl_choice" =~ ^[0-9]+$ ]] || [ "$_vl_choice" -lt 1 ] || [ "$_vl_choice" -gt "${#_VL_URLS[@]}" ]; then + err "Неверный выбор: $_vl_choice" + fi + + _VL_SELECTED="${_VL_URLS[$((_vl_choice-1))]}" + parse_vless_url "$_VL_SELECTED" + info "Выбран: $VL_ADDRESS ($VL_NAME)" else USE_VLESS=0 info "Режим: direct (без проксирования)" + + # Останавливаем и отключаем xray (мог остаться от предыдущей установки) + sudo systemctl stop xray 2>/dev/null || true + sudo systemctl disable xray 2>/dev/null || true fi # ── 1. npm prefix в домашнюю папку ────────────────────────── @@ -88,6 +177,10 @@ if [ "$USE_VLESS" -eq 1 ]; then fi info "Устанавливаю xray..." + + # Останавливаем старый процесс (мог остаться от предыдущей установки) + sudo systemctl stop xray 2>/dev/null || true + XRAY_VERSION="26.3.27" XRAY_ARCH="64" XRAY_URL="https://github.com/XTLS/Xray-core/releases/download/v${XRAY_VERSION}/Xray-linux-${XRAY_ARCH}.zip" @@ -99,7 +192,58 @@ if [ "$USE_VLESS" -eq 1 ]; then rm -rf "$TMPDIR" sudo mkdir -p /etc/xray - sudo cp "$SCRIPT_DIR/home-configs/xray/config.json" /etc/xray/config.json + sudo tee /etc/xray/config.json > /dev/null << XRAYEOF +{ + "log": { "loglevel": "warning" }, + "inbounds": [ + { + "port": 1080, + "listen": "127.0.0.1", + "protocol": "socks", + "settings": { "udp": true } + }, + { + "port": 2080, + "listen": "127.0.0.1", + "protocol": "http" + } + ], + "outbounds": [ + { + "protocol": "vless", + "settings": { + "vnext": [ + { + "address": "$VL_ADDRESS", + "port": $VL_PORT, + "users": [ + { + "id": "$VL_UUID", + "encryption": "$VL_ENCRYPTION", + "flow": "" + } + ] + } + ] + }, + "streamSettings": { + "network": "$VL_TYPE", + "security": "$VL_SECURITY", + "realitySettings": { + "serverName": "$VL_SNI", + "fingerprint": "$VL_FP", + "publicKey": "$VL_PBK", + "shortId": "$VL_SID" + }, + "xhttpSettings": { + "path": "$VL_PATH", + "mode": "$VL_MODE" + } + } + } + ] +} +XRAYEOF sudo chmod 644 /etc/xray/config.json sudo tee /etc/systemd/system/xray.service > /dev/null << 'SVCEOF' @@ -115,12 +259,67 @@ Restart=on-failure WantedBy=multi-user.target SVCEOF + # Удаляем чужие drop-in оверрайды (могут переопределять ExecStart на старый конфиг) + sudo rm -rf /etc/systemd/system/xray.service.d/ + # Удаляем старый дефолтный конфиг xray из других путей + sudo rm -rf /usr/local/etc/xray/ + sudo systemctl daemon-reload sudo systemctl enable --now xray success "xray установлен и запущен" + # ── Отключение IPv6 (VLESS не тянет IPv6, браузеры зависают) ── + info "Отключаю IPv6 на уровне системы..." + sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1 + sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1 + sudo tee /etc/sysctl.d/99-disable-ipv6.conf > /dev/null << 'SYSCTEOF' +# Отключение IPv6 — требуется для стабильной работы VLESS/xray +net.ipv6.conf.all.disable_ipv6=1 +net.ipv6.conf.default.disable_ipv6=1 +SYSCTEOF + sudo systemctl restart systemd-resolved + success "IPv6 отключён, DNS-кэш очищен" + cp "$SCRIPT_DIR/home-configs/proxychains/proxychains-xray.conf" "$HOME/.proxychains-xray.conf" success "Proxychains конфиг обновлён" + + # ── Настройка Firefox на SOCKS5 + remote DNS ──────────────── + info "Настраиваю Firefox на SOCKS5 прокси..." + FIREFOX_PROFILE="" + if [ -d "$HOME/snap/firefox/common/.mozilla/firefox" ]; then + FIREFOX_PROFILE=$(find "$HOME/snap/firefox/common/.mozilla/firefox" -name "*.default*" -type d | head -1) + elif [ -d "$HOME/.mozilla/firefox" ]; then + FIREFOX_PROFILE=$(find "$HOME/.mozilla/firefox" -name "*.default*" -type d | head -1) + fi + + if [ -n "$FIREFOX_PROFILE" ]; then + cat > "$FIREFOX_PROFILE/user.js" << 'FJSEOF' +user_pref("network.proxy.type", 1); +user_pref("network.proxy.socks", "127.0.0.1"); +user_pref("network.proxy.socks_port", 1080); +user_pref("network.proxy.socks_remote_dns", true); +user_pref("network.proxy.http", ""); +user_pref("network.proxy.http_port", 0); +user_pref("network.proxy.ssl", ""); +user_pref("network.proxy.ssl_port", 0); +FJSEOF + success "Firefox настроен на SOCKS5 (профиль: $FIREFOX_PROFILE)" + else + warn "Firefox не найден, пропускаю настройку прокси" + fi + + # ── Настройка системного прокси (для Chrome/Chromium) ─────── + info "Настраиваю системный прокси..." + if command -v gsettings &>/dev/null; then + gsettings set org.gnome.system.proxy mode 'manual' 2>/dev/null || true + gsettings set org.gnome.system.proxy.http host '127.0.0.1' 2>/dev/null || true + gsettings set org.gnome.system.proxy.http port 2080 2>/dev/null || true + gsettings set org.gnome.system.proxy.socks host '127.0.0.1' 2>/dev/null || true + gsettings set org.gnome.system.proxy.socks port 1080 2>/dev/null || true + success "Системный прокси настроен (HTTP 2080 + SOCKS 1080)" + else + warn "gsettings не найден, пропускаю настройку системного прокси" + fi fi # ── 3. Claude Code ─────────────────────────────────────────── diff --git a/home-configs/vless/servers.conf b/home-configs/vless/servers.conf new file mode 100644 index 0000000..db646f4 --- /dev/null +++ b/home-configs/vless/servers.conf @@ -0,0 +1,4 @@ +# VLESS servers — один URL на строку +# Имя после # используется для отображения в меню выбора +vless://495ac855-d718-4581-8344-f1e62105a904@92.118.8.29:443?encryption=mlkem768x25519plus.native.0rtt.gNGR8kO_UDWjoeer_TenoRbA09ajfrSfahqkS4q0dTeCFutCHGJjIdhSl8Fv8HyYUyWB_2GqMrSIzLS9l1BiidClOnliyUmZylQwQoUFl6CsLsZxdrrDz3w2isuIhtXPfZw8lANOErk7p7mm4QN0H2ZKCOQQaxkL3XA8EcxqNuGhK4XLqlFBDommPJUQfPuP7LV3V7s8YTcwq1EUr-Nyv0CZRdcF9WCNCWq26TVYXFwHSkeknBBFKYEJiytB8DpIvlmTvREQfEVnTziwOdYKikQXeOYdbcuKSWGb2okDZjFzYckULaWhavOwRWnOquZqdXiatrNPmCWnG2mfcSxA0UdLu8ALiOtuPjBGDUqqaXhZLLuH1zhdsUE4PMqqkNnMvsRwmvAYgWwSKWioz3wTQ1sKVfW1jTh8LyouZaVkuqRTunwWBcVCRDYEFUh4TBB_-WOpu7eh4ROmj9w0mhWBrtRO-uin8ZwqhkeScQhwoFUEvlwCsAl8AevGmAm1qpdOzfXNUgBTtVoXG9OTMUk9ZORiTzO0tutVTlKjaiBb1vOqgiFqiPuG1csvaPt63LQ1e9ywvEek7NkLVnrJopmCnTiu9UhE7GwZbxI8FBFYrBmPpIUszLiWLQZqvySbqBrIFTC5lIw9WymdW5wKONs5DZmYtFZOHUVEFtVFJvcZqwnEJARKI_M-rvkS7FWPPCkKHpEVe_IJsgOgoUzI9yQI5kNlS5XAzUG7ZMGWtzYjOZNZ1FYP5NbBTTy9I8kpLRQv3yp7PYBGdBQapaYX82Qjc4orJdghG5UOTQwsokojPVaAzSWG4qk5hoNugvogx9KHdsitKXCDlhdksQS5Obc8uMg1TxO2c0AnR2nNNVqgb_prVUlaNHcP4wARfCqrMwdgYQSSoLZluah9a2eZxGcC6CMxPBsThCEwNzIJUZiuPIvEQVFyJpiCHeUErGZFLpmaE0MK2cEzD9N7pRVgEExvwIMnO3jIGmCz80FFuAmEjDG5iyMkzQpsEnBHwAaihjkSwgCsZzTL26OtIDUUYMZ1N8ciRRqTvSGzn_K6EUp7JaWygZGw3QCBRocO7SEWpuGvakJc0QV32vpty3c8UeIcJZlgGKgtcNcsVYvLpEkkYviNCbpq6jnECRYUuXGp_oQv1mwqx2WMqGic7LVZNtYCJ3fHAsGi4yh5nfU0dNSCC0cgeyakNXvL3eyqHIB_e8RrEiMywUg7_MGP2oE9ZOqayLRapVTGQ-YATgcnZ_Eg5bKHNcRVqBpo0heElCtMPoEdQYE_HZSOm1cf9nFIYqRJ6_RPJNKGDOBwy1wJWJel54y-CeY3S2vAWRibOFiwVGW01tHNSCEQBaiLEzQ2Xml6IkSAHNm9eifPrdxuBChibzco4dUFpumbxrRkJYAuqmQfWgi36ziojeEDLlUd55ZDeCOVn4MoHMcD4yzAkpdUelyBafeUoQEs6hCDf2p7CvCquWKoEzcwvuccR0GcN5un2sqQAMVKw3Gs3fsRwkgcdsK69oE4KfUKVjrBGkIk9ChYCJMYGZJ-pGkWFp1qLua2QnNmPVJlpPjurRJVoiAiOVE&security=reality&sni=www.amd.com&fp=chrome&pbk=AMoGtXyztJYD6GRP6m8K82Mi-5vthrNrppJkEmconTU&sid=9cd28fd258f8b99c&type=xhttp&path=%2F&mode=auto#RF-VPS1 +vless://91749001-1f60-4afb-b7b5-25d1480de980@194.87.213.143:443?encryption=mlkem768x25519plus.native.0rtt.D4eIFKFhlMVUsInLgmx5lWuTpBJ8B3lEWnA4gCKdZgw1rjlvHsWd38rC35BAQeKSeBmbZ_sIk6w1gzCCAcYKlJN8rMZyr4TEecnADumEI0e05fRcYCXH70BdHnJxkhklzUIwAKyZHmwlk7euozhYinwq-piRuEBvl0NS-tITgOaje8jLuMyrBTnBKBtzwDR43aMsDqZhzRi-qIaiy0GXjEgHmypFIFB3EOdmCukbvgyJuBAbttTHqdCedQCeJTNfs3tzmzqFKuJXVGRvAvipWGqC_4hzlTWaVXBiuysAmGMC0oqERTyUS9qKqytOr_oyu-jPzjCdIUTPAjdpw4kzXEiuetAuZNuwdbRAHAB_DadVIAsqyVapNIVP0UlN-PJE95pAS6Yfpru2uIBWcJZhV7LE2FKBtAcC31lHeVKy12pG_NlZopYltcmdacVeXBRd1wURrrDFNNTCKaG5wAFm3HFYrzY6qZfNanebgQeYIQm3rbbGGCLBYLyHxcmKeuWVIMTJlISicHdnNyok7KJ2gWKTWtREkfQMXrZKF8BeiSp-9FQX_UCwx0LMd0axB8hqCVtpGspbH8ugKamFr4olFyKrUdQuLhEM1_xzNgZT3dWhvCxDw1VOp3qMd6G4X4YhnABioLOPl2JEyjOLMdAFRlRrdXnNpJdTA0esrJFw5Mte2gNYDAgWEFoq5uupAZlYwniB69BCeEouQiU0GYdWkxwAqwy8xtCEs9Wi4RGPBmdZnhOb5LMUBACwvFm_haF5zgwDrTmUZWdKhXMDXOMOdrcQaDvMf3uk64Q6obe47hkn1LFQS5mKOYYAjblg1RV0y1ovWtFSVBuuCsckyNUPSjETKthQQ6OUgZmpN-pMlBgzGzi3rowqdjNzrMh894ufrptX2GBqEANIM3h5HkR2ObIlJdOv6rQRnmu09EVKp7BHAVLKJcJff9HJYWIqUueArllu5IivueGPG5gPMDIp5SoHVvk_eCMUY2lLtxEE1PCjbgt8ahKTQLcFCXmJf7h945F4jOsDLCxiBSSxaMZdK5AiGGcQm-mcQ4aXBLgiHLCfD3SU7UzIF9key8u35bBm2OVjyTWei-AOssdVV2qFMppuF7Myv4GaEMpQ1JGaLpxT9zSSdVqbO6aJNBkkFxJhcnWqm8CMWVkaGubHkSeDInS65_KFe6I8IrZVm9lBThN1mvdqWkCvZ_ooRiChX7hNKTAXH9cgW-OaOTY1eissDkmW2FEGcPU5iRcDY5kgubZYgTSaHKFAIqg-6NIQX1l3d6lx41EkwyKUCWU-zfjBGsdgszjHXykOrcNQ75o_M3k_-_IBdkOpaESrhSsj2bdNUVcx7fx1S2d6STiLIrW--WeoeBhb6BcytgkbnlRlmvfNDZbOTJYzXQLJtCRZv3xJyfcEB0UqvKFIaCtN4ubHTpyRZ5PHtYHDh9lmIASIItMqeXQlazktz-cajiOFX8RCIkcDFkZ-0KpmYiBToVpi-zSjdLCPPVMf14V5kqAP6EA1IiTJPwFuroWluOJ5j8mx4c0i8fbd1n_mTH_7Ff8Ognu-LFLBU9r9yWcVhBkm_JQ&security=reality&sni=vkvideo.ru&fp=chrome&pbk=BWwAjxuB6QbC2ta23L8_U4QjjkUs17NDi79Mm2RjQHQ&sid=17c863e8490260b6&type=xhttp&path=%2F&mode=packet-up#RF-Bridge-PQ