commit a39ef89125ae02b47227cd3b0a0a1c38f6a00126 Author: ahauimix Date: Sat Mar 14 20:03:57 2026 +0300 Initial commit: local_machine docs and scripts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..abf4d0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,83 @@ +# --- macOS --- +.DS_Store +.AppleDouble +.LSOverride +._* +.Spotlight-V100 +.Trashes + +# --- IDE / Editor --- +.idea/ +*.iml +.vscode/ +*.swp +*.swo +*~ +.project +.settings/ +*.sublime-* + +# --- Cursor --- +.cursor/ + +# --- Env and secrets --- +.env +.env.* +!.env.example +*.pem +*.key +*.crt +*.p12 +*secret* +*credentials* +# VPN/WireGuard configs with private keys (only under connectivity/vpn) +docs/connectivity/vpn/*.conf +**/vpn/*.conf + +# --- Python --- +__pycache__/ +*.py[cod] +*$py.class +.Python +venv/ +.venv/ +env/ +*.egg-info/ +.eggs/ +dist/ +build/ +.mypy_cache/ +.pytest_cache/ +.coverage +htmlcov/ + +# --- Node --- +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.npm +.yarn-integrity + +# --- Logs and temp --- +*.log +*.tmp +*.temp +*.bak +*.backup +*.cache +.cache/ + +# --- OS junk --- +Thumbs.db +ehthumbs.db +Desktop.ini + +# --- Archives (optional; uncomment if you don't want to track zips) --- +# *.zip +# *.tar.gz +# *.rar + +# --- Local overrides (keep repo-agnostic) --- +*.local +*.local.* diff --git a/docs/asahi/ASAHI_FEDORA_INSTALL.md b/docs/asahi/ASAHI_FEDORA_INSTALL.md new file mode 100644 index 0000000..8a99134 --- /dev/null +++ b/docs/asahi/ASAHI_FEDORA_INSTALL.md @@ -0,0 +1,93 @@ +# Установка Fedora Asahi Remix как второй ОС (Apple Silicon) + +Fedora Asahi Remix — официальный дистрибутив Linux для Mac на M1/M2/M3. Устанавливается рядом с macOS без USB и ISO. + +--- + +## Требования + +- **Mac на Apple Silicon** (M1, M2, M3 или новее) +- **macOS Sonoma 12.3 или новее** +- **Свободно минимум 60 ГБ** на диске (рекомендуется 80–100 ГБ для комфортной работы) +- Стабильный интернет на время установки + +--- + +## Шаг 0: Освободить место (обязательно) + +Перед установкой нужно **не менее 60 ГБ свободного места**. Иначе установщик не сможет создать раздел. + +1. **Проверить место:** Системные настройки → Основные → Хранилище (или `df -h /` в Терминале). +2. **Удалить локальные снимки Time Machine** (часто «съедают» место): + ```bash + tmutil listlocalsnapshots / + # Удалить старые снимки (подставьте дату из списка): + tmutil deletelocalsnapshots 2025-01-15-123456 + ``` + Или удалить все локальные снимки: + ```bash + for d in $(tmutil listlocalsnapshots / | cut -d'.' -f4); do sudo tmutil deletelocalsnapshots "$d"; done + ``` +3. **Перенести редко используемые данные на внешний диск** — см. [MOVE_TO_EXTERNAL_100GB.md](../disk_cleanup/MOVE_TO_EXTERNAL_100GB.md). + +--- + +## Шаг 1: Установка + +В **Терминале** (macOS) выполнить: + +```bash +curl https://alx.sh | sh +``` + +- Установщик скачает нужные компоненты и откроет интерактивный режим. +- **Выбрать Fedora** (не «Arch» и не «UEFI only»). +- Указать размер раздела для Linux (рекомендуется **80–100 ГБ**). +- Подтвердить разбиение диска. **macOS останется**, будет создан отдельный раздел под Linux. +- После завершения установщик предложит перезагрузку. + +--- + +## Шаг 2: Первый запуск + +1. После перезагрузки Mac загрузится в **загрузчик Asahi**. +2. Выберите **Fedora** (или «macOS» для возврата в Mac). +3. При первом входе в Fedora пройдите первоначальную настройку (язык, пользователь, пароль). + +--- + +## Управление загрузкой + +- При включении Mac отображается меню выбора ОС (Fedora / macOS). +- По умолчанию можно задать в настройках загрузчика (в Fedora или в macOS через установщик Asahi). + +--- + +## Удаление Linux (если понадобится) + +Чтобы убрать Fedora и вернуть место macOS: + +```bash +curl -L https://alx.sh/wipe-linux | sh +``` + +После этого раздел Linux будет удалён, место вернётся в APFS. + +--- + +## Полезные ссылки + +- [Fedora Asahi Remix — официальная страница](https://asahilinux.org/fedora/) +- [Документация Fedora: установка](https://docs.fedoraproject.org/en-US/fedora-asahi-remix/installation) +- [Asahi Linux — общая информация](https://asahilinux.org/) + +--- + +## Ограничения (на момент 2024–2025) + +- Часть функций Mac (Touch Bar, некоторые аспекты питания, Wi‑Fi/Bluetooth на части моделей) может работать ограниченно. +- Fedora Asahi Remix 41 по умолчанию идёт с **KDE Plasma 6.2** или **GNOME 47**, полная поддержка Wayland. + +--- + +*Документ создан в рамках local_machine. Перед установкой убедитесь, что свободно не менее 60 ГБ и при необходимости перенесите данные по [MOVE_TO_EXTERNAL_100GB.md](../disk_cleanup/MOVE_TO_EXTERNAL_100GB.md).* diff --git a/docs/connectivity/BUILD_AAB_FROM_RUSSIA_GUIDE.md b/docs/connectivity/BUILD_AAB_FROM_RUSSIA_GUIDE.md new file mode 100644 index 0000000..f6bffad --- /dev/null +++ b/docs/connectivity/BUILD_AAB_FROM_RUSSIA_GUIDE.md @@ -0,0 +1,679 @@ +# 🏗️ Сборка AAB/APK из России — Полное руководство + +> **Дата создания:** 2026-02-28 +> **Проблема:** Java TLS заблокирован российским DPI → Gradle не может скачать зависимости +> **Решение:** Maven proxy на прод-сервере + SSH-туннель + обход SDK auto-download +> **Время сборки:** ~1.5 мин (AAB), ~46 сек (APK после AAB) +> +> **📖 См. также:** [SETUP_AND_BUILD_GUIDE.md](./SETUP_AND_BUILD_GUIDE.md) — общее руководство по установке и сборке (для работы не из России) + +--- + +## 📋 Содержание + +1. [Суть проблемы](#-суть-проблемы) +2. [Предварительные требования](#-предварительные-требования) +3. [Шаг 1: Maven proxy на прод-сервере](#-шаг-1-maven-proxy-на-прод-сервере) +4. [Шаг 2: SSH-туннель](#-шаг-2-ssh-туннель) +5. [Шаг 3: Сборка AAB](#-шаг-3-сборка-aab) +6. [Шаг 4: Сборка APK для эмулятора](#-шаг-4-сборка-apk-для-эмулятора) +7. [Шаг 5: Установка в эмулятор](#-шаг-5-установка-в-эмулятор) +8. [Быстрый скрипт «всё одной командой»](#-быстрый-скрипт-всё-одной-командой) +9. [DOs & DON'Ts](#-dos--donts) +10. [Конфигурация Gradle (что изменено и почему)](#-конфигурация-gradle-что-изменено-и-почему) +11. [Troubleshooting](#-troubleshooting) +12. [Версионирование](#-версионирование) + +--- + +## 🔍 Суть проблемы + +### Почему Gradle не работает из России напрямую + +``` +Gradle → Java TLS → dl.google.com / repo1.maven.org + ↑ + DPI (Deep Packet Inspection) блокирует TLS handshake + Java получает: "Remote host terminated the handshake" +``` + +**Ключевой факт:** `curl` работает нормально (macOS LibreSSL), а Java — нет (JSSE TLS implementation). DPI по-разному обрабатывает TLS Client Hello от разных реализаций. + +### Решение: Maven proxy + +``` +Gradle → HTTP (127.0.0.1:8765) → SSH-туннель → Прод-сервер (python proxy) + ↓ + HTTPS → dl.google.com + HTTPS → repo1.maven.org + HTTPS → plugins.gradle.org +``` + +Java работает по **HTTP** (без TLS) до localhost. Прод-сервер в Digital Ocean скачивает по **HTTPS** без DPI. + +--- + +## ✅ Предварительные требования + +> **📖 Перед началом:** Убедитесь, что выполнены базовые требования из [SETUP_AND_BUILD_GUIDE.md](./SETUP_AND_BUILD_GUIDE.md): +> - Java OpenJDK 21+ установлен +> - Android SDK установлен (через Android Studio GUI) +> - Build Tools установлены +> - Эмулятор настроен (см. [EMULATOR_STARTUP_GUIDE.md](./EMULATOR_STARTUP_GUIDE.md)) + +### Локальная машина (macOS) + +| Компонент | Версия | Путь | +|-----------|--------|------| +| Java (OpenJDK) | 21.0.9 | `/opt/homebrew/opt/openjdk@21` | +| Android SDK | API 34-36 | `$HOME/Library/Android/sdk` | +| Build Tools | 35.0.1 | `$HOME/Library/Android/sdk/build-tools/35.0.1` | +| Gradle Wrapper | 8.11.1 | `frontend/android/gradle/wrapper/` | +| AGP | 8.7.2 | `frontend/android/build.gradle` | +| Capacitor | 7.4.x | `frontend/package.json` | + +### Прод-сервер + +| Компонент | Значение | +|-----------|----------| +| SSH хост | `hunab-prod` (209.38.32.21) | +| Python | 3.12+ (предустановлен) | +| Порт proxy | 8765 (localhost) | + +### Проверка готовности + +```bash +# Java +/opt/homebrew/opt/openjdk@21/bin/java -version +# → openjdk version "21.0.9" + +# Android SDK +ls $HOME/Library/Android/sdk/platforms/ +# → android-34 android-35 android-36 + +# Build Tools +ls $HOME/Library/Android/sdk/build-tools/ +# → 35.0.1 36.1.0 (34.0.0 и 35.0.0 УДАЛЕНЫ — были пустые!) + +# SSH к проду +ssh hunab-prod "echo OK" +# → OK +``` + +--- + +## 🔧 Шаг 1: Maven proxy на прод-сервере + +### 1.1 Скопировать скрипт прокси на прод + +Создать файл `/tmp/maven-proxy.py` локально: + +```bash +cat > /tmp/maven-proxy.py << 'PYEOF' +#!/usr/bin/env python3 +"""Многопоточный Maven reverse proxy для Gradle. +Обходит Java TLS/DPI блокировку при сборке Android из РФ. +Поддерживает GET и HEAD запросы (Gradle использует оба). +""" +import http.server, socketserver, urllib.request, ssl, sys + +REPOS = { + '/google/': 'https://dl.google.com/dl/android/maven2/', + '/central/': 'https://repo1.maven.org/maven2/', + '/gradle/': 'https://plugins.gradle.org/m2/', +} + +class H(http.server.BaseHTTPRequestHandler): + def _p(self, m='GET'): + for pfx, base in REPOS.items(): + if self.path.startswith(pfx): + url = base + self.path[len(pfx):] + try: + r = urllib.request.urlopen( + urllib.request.Request(url, headers={'User-Agent':'Gradle'}, method=m), + timeout=300, + context=ssl.create_default_context() + ) + d = r.read() if m=='GET' else b'' + self.send_response(200) + self.send_header('Content-Type', r.headers.get('Content-Type','application/octet-stream')) + self.send_header('Content-Length', r.headers.get('Content-Length',str(len(d)))) + self.end_headers() + if m=='GET': self.wfile.write(d) + except urllib.error.HTTPError as e: + self.send_response(e.code); self.end_headers() + except Exception as e: + sys.stderr.write(f"ERR {m} {url}: {e}\n"); sys.stderr.flush() + self.send_response(502); self.end_headers() + return + self.send_response(404); self.end_headers() + def do_GET(self): self._p('GET') + def do_HEAD(self): self._p('HEAD') + def log_message(self, fmt, *a): + sys.stderr.write(f"{a[0]}\n"); sys.stderr.flush() + +class S(socketserver.ThreadingMixIn, http.server.HTTPServer): + daemon_threads = True; allow_reuse_address = True + +if __name__ == '__main__': + print("Maven proxy v2 on :8765 (threaded+logging)") + sys.stdout.flush() + S(('127.0.0.1',8765),H).serve_forever() +PYEOF +``` + +Скопировать на прод: + +```bash +scp /tmp/maven-proxy.py hunab-prod:/tmp/maven-proxy.py +``` + +### 1.2 Запустить прокси на проде + +```bash +# Убить предыдущий экземпляр (НЕЛЬЗЯ использовать pkill -f maven-proxy — убьёт SSH сессию!) +ssh hunab-prod "ps aux | grep maven-proxy | grep python | grep -v grep | awk '{print \$2}' | xargs -r kill" +sleep 1 + +# Запустить +ssh hunab-prod "nohup python3 /tmp/maven-proxy.py > /tmp/maven-proxy.log 2>&1 & echo PID=\$!" +``` + +### 1.3 Проверить прокси на проде + +```bash +ssh hunab-prod "curl -s -I http://127.0.0.1:8765/google/com/android/tools/build/gradle/8.7.2/gradle-8.7.2.pom | head -2" +# Ожидаемый ответ: +# HTTP/1.0 200 OK +# Server: BaseHTTP/0.6 Python/3.12.7 +``` + +--- + +## 🔧 Шаг 2: SSH-туннель + +### 2.1 Создать туннель + +```bash +# Убить старые туннели +pkill -f "ssh.*-L.*8765" 2>/dev/null + +# Новый туннель (фоновый режим) +ssh -f -N -L 8765:127.0.0.1:8765 hunab-prod +``` + +### 2.2 Проверить туннель локально + +```bash +curl -s -I http://127.0.0.1:8765/google/com/android/tools/build/gradle/8.7.2/gradle-8.7.2.pom | head -2 +# Ожидаемый ответ: +# HTTP/1.0 200 OK +# Server: BaseHTTP/0.6 Python/3.12.7 +``` + +**⚠️ Если ответ пустой или "Connection refused"** — прокси на проде не запущен или туннель не работает. Повторите шаги 1.2 и 2.1. + +--- + +## 🔧 Шаг 3: Сборка AAB + +### 3.1 Установка переменных окружения + +```bash +export JAVA_HOME=/opt/homebrew/opt/openjdk@21 +export PATH="$JAVA_HOME/bin:$PATH" +export ANDROID_HOME=$HOME/Library/Android/sdk +export PATH=$PATH:$ANDROID_HOME/platform-tools +``` + +### 3.2 Сборка фронтенда (если не собран) + +```bash +cd /Users/eternal/code/hunabapp-dev/frontend +pnpm build +``` + +### 3.3 Синхронизация Capacitor (если не сделано) + +```bash +cd /Users/eternal/code/hunabapp-dev/frontend +npx cap sync android +``` + +### 3.4 Сборка AAB + +```bash +cd /Users/eternal/code/hunabapp-dev/frontend/android + +./gradlew clean bundleRelease --no-daemon --console=plain +``` + +**Ожидаемое время:** ~1 мин 20 сек + +### 3.5 Результат + +```bash +ls -lh ./app/build/outputs/bundle/release/app-release.aab +# → 37M app-release.aab +``` + +### 3.6 Копирование в temp/ + +```bash +VERSION_NAME=$(grep 'versionName' ./app/build.gradle | grep -oE '"[^"]*"' | tr -d '"') +VERSION_CODE=$(grep 'versionCode' ./app/build.gradle | grep -oE '[0-9]+') + +mkdir -p /Users/eternal/code/hunabapp-dev/temp/android +cp ./app/build/outputs/bundle/release/app-release.aab \ + /Users/eternal/code/hunabapp-dev/temp/android/hunab-app-v${VERSION_NAME}-v${VERSION_CODE}-release.aab + +echo "📦 AAB: temp/android/hunab-app-v${VERSION_NAME}-v${VERSION_CODE}-release.aab" +``` + +--- + +## 🔧 Шаг 4: Сборка APK для эмулятора + +> **AAB нельзя установить в эмулятор напрямую** — нужен APK. + +```bash +cd /Users/eternal/code/hunabapp-dev/frontend/android + +./gradlew assembleRelease --no-daemon --console=plain +``` + +**Ожидаемое время:** ~46 сек (после AAB сборки — кэш уже разогрет) + +Результат: + +```bash +cp ./app/build/outputs/apk/release/app-release.apk \ + /Users/eternal/code/hunabapp-dev/temp/android/hunab-app-v${VERSION_NAME}-release.apk +``` + +--- + +## 🔧 Шаг 5: Установка в эмулятор + +### 5.1 Запуск эмулятора + +```bash +# Список доступных AVD +$ANDROID_HOME/emulator/emulator -list-avds +# → Pixel_5_API_35 + +# Запуск (в фоне) +$ANDROID_HOME/emulator/emulator -avd Pixel_5_API_35 -no-snapshot-load -no-snapshot-save & + +# Ожидание загрузки (30-60 сек) +adb wait-for-device +adb shell getprop sys.boot_completed +# → 1 (когда загружено) +``` + +### 5.2 Установка APK + +```bash +adb install -r /Users/eternal/code/hunabapp-dev/temp/android/hunab-app-v${VERSION_NAME}-release.apk +``` + +### 5.3 Запуск приложения + +```bash +adb shell am start -n com.hunab.app/.MainActivity +``` + +--- + +## 🚀 Быстрый скрипт «всё одной командой» + +> **Предполагает:** прокси уже запущен и SSH-туннель активен (шаги 1-2). + +```bash +#!/bin/bash +set -e + +# === Настройка === +export JAVA_HOME=/opt/homebrew/opt/openjdk@21 +export PATH="$JAVA_HOME/bin:$PATH" +export ANDROID_HOME=$HOME/Library/Android/sdk +export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator + +PROJECT_ROOT="/Users/eternal/code/hunabapp-dev" + +# === Проверка прокси === +echo "🔍 Проверяю Maven proxy..." +if ! curl -s -I http://127.0.0.1:8765/google/com/android/tools/build/gradle/8.7.2/gradle-8.7.2.pom | grep -q "200 OK"; then + echo "❌ Maven proxy не работает! Запустите шаги 1-2 из BUILD_AAB_FROM_RUSSIA_GUIDE.md" + exit 1 +fi +echo "✅ Proxy OK" + +# === Сборка фронтенда === +echo "🔨 Сборка фронтенда..." +cd "$PROJECT_ROOT/frontend" +pnpm build + +# === Capacitor sync === +echo "🔄 Capacitor sync..." +npx cap sync android + +# === Версия === +cd android +VERSION_NAME=$(grep 'versionName' ./app/build.gradle | grep -oE '"[^"]*"' | tr -d '"') +VERSION_CODE=$(grep 'versionCode' ./app/build.gradle | grep -oE '[0-9]+') +echo "📊 Version: $VERSION_NAME (code: $VERSION_CODE)" + +# === AAB === +echo "📦 Сборка AAB..." +./gradlew clean bundleRelease --no-daemon --console=plain + +mkdir -p "$PROJECT_ROOT/temp/android" +cp ./app/build/outputs/bundle/release/app-release.aab \ + "$PROJECT_ROOT/temp/android/hunab-app-v${VERSION_NAME}-v${VERSION_CODE}-release.aab" +echo "✅ AAB: temp/android/hunab-app-v${VERSION_NAME}-v${VERSION_CODE}-release.aab" + +# === APK (для эмулятора) === +echo "📱 Сборка APK..." +./gradlew assembleRelease --no-daemon --console=plain + +cp ./app/build/outputs/apk/release/app-release.apk \ + "$PROJECT_ROOT/temp/android/hunab-app-v${VERSION_NAME}-release.apk" + +# === Эмулятор === +echo "📲 Установка в эмулятор..." +if adb devices 2>/dev/null | grep -q "device$"; then + adb install -r "$PROJECT_ROOT/temp/android/hunab-app-v${VERSION_NAME}-release.apk" + adb shell am start -n com.hunab.app/.MainActivity + echo "🎮 Приложение запущено!" +else + echo "⚠️ Эмулятор не запущен. Запустите вручную и повторите установку." +fi + +ls -lh "$PROJECT_ROOT/temp/android/" +echo "" +echo "✅✅✅ ГОТОВО!" +``` + +--- + +## 🚫 DOs & DON'Ts + +### ✅ DO (ДЕЛАЙ) + +| # | Правило | Почему | +|---|---------|--------| +| 1 | **Используй Maven proxy через SSH-туннель** | Java TLS заблокирован DPI в РФ | +| 2 | **ТОЛЬКО прокси repos в build.gradle** (без `google()`, `mavenCentral()`) | Прямые HTTPS repos зависают навсегда | +| 3 | **`allowInsecureProtocol = true`** для proxy repos | Прокси работает по HTTP, Gradle 8+ блокирует HTTP по умолчанию | +| 4 | **`android.builder.sdkDownload=false`** в gradle.properties | SDK auto-download зависает на TLS | +| 5 | **`compileSdkVersion = 36`** в variables.gradle | android-36 — base SDK, корректно установлен | +| 6 | **`buildToolsVersion "35.0.1"`** явно в app/build.gradle | 34.0.0 и 35.0.0 не установлены (пустые папки были удалены) | +| 7 | **Global buildToolsVersion override** через `subprojects{}` в root build.gradle | Capacitor модули тоже требуют build tools | +| 8 | **`android.suppressUnsupportedCompileSdk=36`** в gradle.properties | Убирает warning от AGP 8.7.2 | +| 9 | **`-Djdk.tls.client.protocols=TLSv1.2`** в org.gradle.jvmargs | Частично помогает с DPI для прямых Java TLS | +| 10 | **`IsBaseSdk=true`** в source.properties platforms | Gradle не находит extension SDK без манифеста | +| 11 | **`ThreadingMixIn`** в Python proxy | Gradle делает десятки параллельных запросов | +| 12 | **HEAD + GET** в proxy | Gradle использует HEAD для проверки существования артефактов | +| 13 | **Фоновая сборка** при запуске из Cursor | `./gradlew` через Cursor tool таймаутится через ~2 мин | +| 14 | **Убивай pkill через `ps aux | grep | awk | xargs kill`** | Безопасный способ | + +### ❌ DON'T (НЕ ДЕЛАЙ) + +| # | Правило | Почему | +|---|---------|--------| +| 1 | **НЕ оставляй `google()` / `mavenCentral()` в repositories** | Gradle попробует их → зависнет на TLS handshake на НЕОПРЕДЕЛЁННОЕ время | +| 2 | **НЕ используй `pkill -f maven-proxy`** через SSH | Паттерн совпадает с самой SSH командой → убивает SSH сессию (exit 255) | +| 3 | **НЕ используй однопоточный Python HTTP server** | Gradle делает 10-50 параллельных запросов → очередь → таймаут | +| 4 | **НЕ используй SOCKS proxy для Gradle** (`socksProxyHost`) | Java TLS через SOCKS тоже блокируется DPI | +| 5 | **НЕ пытайся скачать Gradle cache на проде и скопировать** | Кэш привязан к хэшам и абсолютным путям — не переносим | +| 6 | **НЕ устанавливай Android SDK через sdkmanager из РФ** | Тот же TLS блок. Устанавливай через Android Studio GUI (у студии свои настройки) | +| 7 | **НЕ удаляй `android.builder.sdkDownload=false`** | Gradle будет пытаться скачать SDK манифесты → зависнет | +| 8 | **НЕ используй `compileSdkVersion = 35`** | Установленный android-35 — extension SDK, Gradle без манифеста не может его найти | +| 9 | **НЕ забывай `buildToolsVersion` в subprojects** | Capacitor-android и другие модули тоже требуют build tools | +| 10 | **НЕ создавай APK для Google Play** | Google Play требует только AAB формат | +| 11 | **НЕ оставляй пустые build-tools директории** | Gradle пытается их использовать → "Build Tools not found" | +| 12 | **НЕ запускай Gradle через tool call Cursor напрямую** | Таймаут ~2 мин; запускай в фоне через `nohup ... &` | + +--- + +## ⚙️ Конфигурация Gradle (что изменено и почему) + +### `frontend/android/build.gradle` (корневой) + +```groovy +buildscript { + repositories { + // ТОЛЬКО прокси — прямые repos заблокированы DPI + maven { url 'http://127.0.0.1:8765/google/'; allowInsecureProtocol = true } + maven { url 'http://127.0.0.1:8765/central/'; allowInsecureProtocol = true } + maven { url 'http://127.0.0.1:8765/gradle/'; allowInsecureProtocol = true } + } + dependencies { + classpath 'com.android.tools.build:gradle:8.7.2' + classpath 'com.google.gms:google-services:4.4.2' + } +} + +allprojects { + repositories { + // ТОЛЬКО прокси + maven { url 'http://127.0.0.1:8765/google/'; allowInsecureProtocol = true } + maven { url 'http://127.0.0.1:8765/central/'; allowInsecureProtocol = true } + maven { url 'http://127.0.0.1:8765/gradle/'; allowInsecureProtocol = true } + } +} + +// Глобальный override buildToolsVersion для ВСЕХ модулей +subprojects { + afterEvaluate { project -> + if (project.hasProperty('android')) { + project.android.buildToolsVersion = "35.0.1" + } + } +} +``` + +**Почему:** +- `allowInsecureProtocol = true` — Gradle 8+ блокирует HTTP repos по умолчанию +- Три прокси: Google Maven, Maven Central, Gradle Plugin Portal +- `subprojects { afterEvaluate }` — Capacitor модули не указывают buildToolsVersion явно, AGP 8.7.2 по умолчанию ищет 34.0.0 (не установлен) + +### `frontend/android/gradle.properties` + +```properties +org.gradle.jvmargs=-Xmx1536m -Djdk.tls.client.protocols=TLSv1.2 +android.useAndroidX=true +android.builder.sdkDownload=false +android.suppressUnsupportedCompileSdk=36 +``` + +**Почему:** +- `-Djdk.tls.client.protocols=TLSv1.2` — принудительный TLS 1.2 (частично обходит DPI) +- `sdkDownload=false` — блокирует авто-загрузку SDK (зависает на TLS) +- `suppressUnsupportedCompileSdk=36` — AGP 8.7.2 не знает о SDK 36, подавляем warning + +### `frontend/android/variables.gradle` + +```groovy +ext { + compileSdkVersion = 36 // Было 35! android-35 — extension SDK, не находится без манифеста + targetSdkVersion = 35 // Оставляем 35 для совместимости с Google Play + // ... +} +``` + +**Почему:** +- `android-35` установлен как extension SDK (path: `platforms;android-35-ext15`) — Gradle без сетевого манифеста не может его распознать как `android-35` +- `android-36` установлен как base SDK (path: `platforms;android-36`, `IsBaseSdk=true`) — работает +- `targetSdkVersion` остаётся 35 — это то, что Google Play учитывает + +### `frontend/android/app/build.gradle` + +```groovy +android { + compileSdk rootProject.ext.compileSdkVersion + buildToolsVersion "35.0.1" // Добавлено явно + // ... +} +``` + +### SDK Platform Patches + +**`$HOME/Library/Android/sdk/platforms/android-35/source.properties`:** + +```properties +AndroidVersion.IsBaseSdk=true # Было false — Gradle не находил SDK без манифеста +``` + +**`$HOME/Library/Android/sdk/platforms/android-35/package.xml`:** + +```xml + +``` + +> ⚠️ Аналогичные изменения для android-34 + +--- + +## 🔧 Troubleshooting + +### Проблема: «Still waiting for package manifests to be fetched remotely» + +**Причина:** `android.builder.sdkDownload=true` (или не задан) → Gradle пытается скачать манифесты по HTTPS → DPI блокирует. + +**Решение:** + +```properties +# gradle.properties +android.builder.sdkDownload=false +``` + +### Проблема: «Failed to find target with hash string 'android-35'» + +**Причина:** Установленный SDK — extension SDK (`IsBaseSdk=false`, path `android-35-ext15`), а Gradle ищет base SDK `android-35`. + +**Решение варианты:** +1. Использовать `compileSdkVersion = 36` (android-36 = base SDK) ← **текущее решение** +2. Или патчить `source.properties`: `IsBaseSdk=true` + `package.xml`: `path="platforms;android-35"` + +### Проблема: «Failed to find Build Tools revision 34.0.0» + +**Причина:** AGP 8.7.2 по умолчанию требует build-tools 34.0.0. При `sdkDownload=false` не может скачать. + +**Решение:** Явно указать установленную версию в `app/build.gradle` и глобально через `subprojects` в root `build.gradle`: + +```groovy +buildToolsVersion "35.0.1" +``` + +### Проблема: Gradle зависает, прокси лог пустой (0 строк) + +**Причина:** Gradle обращается к `google()` / `mavenCentral()` напрямую, минуя прокси. + +**Решение:** Убрать `google()` и `mavenCentral()` из repositories. Оставить ТОЛЬКО proxy URLs. + +### Проблема: SSH exit code 255 при pkill + +**Причина:** `pkill -f maven-proxy` совпадает с самой SSH командой и убивает сессию. + +**Решение:** + +```bash +ssh hunab-prod "ps aux | grep maven-proxy | grep python | grep -v grep | awk '{print \$2}' | xargs -r kill" +``` + +### Проблема: Cursor tool timeout при сборке + +**Причина:** Gradle билд занимает ~1.5 мин, Cursor tool таймаутится через ~2 мин. + +**Решение:** Запускать в фоне: + +```bash +nohup bash -c ' +cd /path/to/frontend/android +./gradlew bundleRelease --no-daemon --console=plain 2>&1 | tee /tmp/aab-build.log +' &>/dev/null & + +# Мониторинг +tail -f /tmp/aab-build.log +``` + +### Проблема: Однопоточный proxy таймаутится + +**Причина:** Python `http.server.HTTPServer` обрабатывает 1 запрос за раз. Gradle делает 10-50 параллельных запросов. + +**Решение:** `ThreadingMixIn`: + +```python +class S(socketserver.ThreadingMixIn, http.server.HTTPServer): + daemon_threads = True + allow_reuse_address = True +``` + +### Проблема: Proxy возвращает 404 на HEAD запросы + +**Причина:** `BaseHTTPRequestHandler` по умолчанию не имеет `do_HEAD`. + +**Решение:** Добавить `do_HEAD`: + +```python +def do_HEAD(self): self._p('HEAD') +``` + +--- + +## 📊 Версионирование + +### Текущая версия (2026-02-28) + +| Параметр | Значение | +|----------|----------| +| versionName | 1.3.8 | +| versionCode | 10308 | +| compileSdkVersion | 36 | +| targetSdkVersion | 35 | +| minSdkVersion | 23 | +| buildToolsVersion | 35.0.1 | +| AGP | 8.7.2 | +| Gradle | 8.11.1 | +| Java | OpenJDK 21.0.9 | +| Capacitor | 7.4.x | + +### Для Google Play + +- **AAB файл:** `temp/android/hunab-app-v1.3.8-v10308-release.aab` +- **Размер:** ~37 MB +- **Подписан:** `hunab-app.keystore` (release signing config) +- **Формат:** AAB (NEVER APK for Google Play!) +- **versionCode** должен быть **больше** предыдущего релиза! + +### Перед новым релизом + +1. Обновить `versionCode` и `versionName` в `frontend/android/app/build.gradle` +2. Собрать фронтенд (`pnpm build`) +3. `npx cap sync android` +4. Следовать шагам 1-4 этого руководства + +--- + +## 📁 Связанные файлы + +| Файл | Назначение | +|------|------------| +| `frontend/android/build.gradle` | Корневой Gradle — repos, plugins, subprojects override | +| `frontend/android/app/build.gradle` | App модуль — version, signing, buildTools | +| `frontend/android/gradle.properties` | JVM args, SDK download, TLS, suppressWarnings | +| `frontend/android/variables.gradle` | compileSdk, targetSdk, dependency versions | +| `docs/android/guides/SETUP_AND_BUILD_GUIDE.md` | **Общее руководство по установке и сборке** (для работы не из России) | +| `docs/android/guides/EMULATOR_STARTUP_GUIDE.md` | **Полное руководство по запуску эмулятора** | +| `docs/android/TROUBLESHOOTING.md` | Общий troubleshooting (включая другие проблемы) | +| `docs/android/MOBILE_BUILD_REGULATIONS.md` | Регламент сборки мобильного приложения | +| `scripts/android/quick-build-and-launch.sh` | Старый скрипт быстрой сборки (требует адаптации под proxy) | + +--- + +> **Последнее обновление:** 2026-02-28 +> **Автор:** Aura (Cursor AI Agent) +> **Проверено:** Успешная сборка AAB v1.3.8 (BUILD SUCCESSFUL in 1m 21s, 112 tasks) + diff --git a/docs/connectivity/PROXY_CHANGELOG.md b/docs/connectivity/PROXY_CHANGELOG.md new file mode 100644 index 0000000..5bbd1a3 --- /dev/null +++ b/docs/connectivity/PROXY_CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog — Прокси ru.hunab.app + +## [1.2] — 2026-03-14 + +### Telegram SOCKS и автозапуск при старте + +- **Скрипт** `connectivity/scripts/telegram-socks-tunnel.sh` — подъём/остановка/проверка SOCKS5 на порту **1081** (`ssh -D 1081 ahau@149.154.64.19`). Переменные: `TELEGRAM_SOCKS_PORT`, `TELEGRAM_TUNNEL_HOST`. Порт 1081 не пересекается с Cursor (10809). +- **LaunchAgent** `connectivity/launchd/com.hunab.telegram-socks.plist` — запуск туннеля при входе в macOS (RunAtLoad), перезапуск при обрыве (KeepAlive), ThrottleInterval 30. Лог: `/tmp/telegram-socks-tunnel.log`. +- **Документация:** [launchd/README.md](./launchd/README.md) — установка/удаление, требования к ключу; в [PROXY_GUIDE.md](./PROXY_GUIDE.md) добавлен раздел «Telegram и SOCKS при старте» (ручная команда, автозапуск, скрипт). +- **Обзор папки** [connectivity/README.md](./README.md) — индекс документов, скриптов, launchd и портов. + +## [1.1] — 2026-03-03 + +### Безопасность + +- **Расширен блок отсечения сканерских путей** (по [SCANNER_PROBES_REPORT_2026-03](../../security/SCANNER_PROBES_REPORT_2026-03.md)): в **apply-security-on-proxy.sh** и [SECURITY.md](./SECURITY.md) добавлены location не только для serverless, но и для `/.env*`, `/.git/`, `/.aws/`, `/.htaccess`, `/.htpasswd`, `/.docker/`, `/actuator/`, `wp-*`, `*.php`, `xmlrpc.php`, `config.php`, `wp-config`, `phpinfo`, дампов SQL, `secrets.yml`, `application*.yml`, `config.(yml|yaml|json)`, `database.yml`, а также путей вида `/app/.env`, `/api/.env`, `/backend/.env` и т.п. +- Скрипт при повторном запуске на прокси с уже применённым старым блоком **заменяет** его на расширенный. Проверка «уже применено» — по наличию в конфиге строки про `.env, .git`. +- В SECURITY.md добавлена **проверка fail2ban**: `sudo fail2ban-client status` и `sudo fail2ban-client status nginx-limit-req`. + +## [1.0] — 2026-03-03 + +### Безопасность + +- Добавлен **[SECURITY.md](./SECURITY.md)** — чеклист и готовые конфиги: + - Rate limiting (limit_req_zone, limit_req) для ru.hunab.app. + - Отсечение сканерских путей: `location` с `return 404` для `/api/serverless/*`, `serverless.yml`, `.serverless/` и т.п. (без проксирования на прод). + - Fail2ban: пример jail и фильтра для лога `ru.hunab.app.proxy.access.log`. + - На проде: `set_real_ip_from 149.154.64.19`, `real_ip_header X-Forwarded-For`. + - `server_tokens off` на прокси. +- Связь с [docs/security/SECURITY_STANDARDS.md](../../security/SECURITY_STANDARDS.md) (раздел Proxy & Edge Security). + +### Скрипты + +- **apply-security-on-proxy.sh** — применение правок nginx на прокси (бэкап, rate limit, server_tokens, location сканеров, `nginx -t`, reload). Запуск на сервере: `sudo bash /tmp/apply-security-on-proxy.sh`. +- **setup-sudo-and-apply-security.sh** — один запуск: добавление NOPASSWD для ahau и вызов apply-security-on-proxy.sh (для ручного выполнения с вводом пароля sudo). + +### Документация + +- В [PROXY_GUIDE.md](./PROXY_GUIDE.md) добавлена секция «Безопасность» со ссылками на SECURITY.md и SECURITY_STANDARDS. +- В SECURITY.md добавлен блок «Применение на прокси (скрипт)» с командами scp/ssh. + +### Применено на сервере (2026-03-03) + +- **Sudo для ahau:** добавлен `/etc/sudoers.d/ahau-nopasswd` (NOPASSWD: ALL) через root@149.154.64.19. +- **Nginx:** внесены правки в `/etc/nginx/sites-available/ru.hunab.app.proxy`: limit_req_zone + limit_req, server_tokens off, location отсечения сканеров; выполнен `systemctl reload nginx`. +- **Проверки:** proxy-health 200, /api/serverless/* → 404 на прокси, server без версии в ответах. diff --git a/docs/connectivity/PROXY_GUIDE.md b/docs/connectivity/PROXY_GUIDE.md new file mode 100644 index 0000000..4b73cfb --- /dev/null +++ b/docs/connectivity/PROXY_GUIDE.md @@ -0,0 +1,151 @@ +# 🔐 Прокси ru.hunab.app — руководство + +**Сервер:** 149.154.64.19 | **Домен:** ru.hunab.app | **Прод:** hunab.app (209.38.32.21) + +--- + +## Оглавление + +1. [Доступ и файлы](#-доступ-и-файлы) +2. [Команды управления](#-команды-управления) +3. [Безопасность](#-безопасность) +4. [Запросы-сканеры (serverless и др.)](#-запросы-сканеры-serverless-и-др) +5. [Редирект на прокси](#-автоматический-редирект) +6. [Скорость и тесты](#-проверка-скорости) +7. [Telegram и SOCKS при старте](#-telegram-и-socks-при-старте) + +--- + +## 🔑 Доступ и файлы + +| Параметр | Значение | +|----------|----------| +| **SSH** | `ssh hsites-ahau` или `ssh -i ~/.ssh/id_ed25519 ahau@149.154.64.19` | +| **SSH root** | `ssh -o StrictHostKeyChecking=accept-new -i ~/.ssh/hsites_new_deploy_key root@149.154.64.19` или `ssh hsites-new` | +| **Пользователь** | ahau (sudo), root через ключ `hsites_new_deploy_key` | +| **ОС** | Ubuntu 24.10 | + +**Важные пути на сервере:** +- Nginx: `/etc/nginx/sites-available/ru.hunab.app` (активный сайт может быть в `sites-enabled` как `ru.hunab.app.proxy`) +- Логи: `/var/log/nginx/ru.hunab.app.proxy.access.log`, `ru.hunab.app.proxy.error.log` +- SSL: `/etc/letsencrypt/live/ru.hunab.app/` +- Кеш: `/var/cache/nginx/` + +**Проверка:** +- Сайт: https://ru.hunab.app/ +- Health: https://ru.hunab.app/proxy-health +- API: https://ru.hunab.app/api/health + +--- + +## 🔧 Команды управления + +**Nginx:** `sudo nginx -t` → `sudo systemctl reload nginx` +**SSL:** `sudo certbot certificates`, `sudo certbot renew --dry-run` +**Безопасность:** `sudo ufw status`, `sudo fail2ban-client status` +**Логи:** `sudo tail -f /var/log/nginx/ru.hunab.app.proxy.access.log` +**Кеш:** `sudo du -sh /var/cache/nginx/`; очистка: `sudo rm -rf /var/cache/nginx/*` + reload + +**Backup конфига:** `sudo cp /etc/nginx/sites-available/ru.hunab.app /home/ahau/nginx-backup-$(date +%Y%m%d).conf` + +**Экстренно:** `sudo systemctl stop nginx`; после правок: `sudo nginx -t && sudo systemctl start nginx` + +--- + +## 🛡️ Безопасность + +Чеклист и готовые конфиги (rate limiting, fail2ban, отсечение сканеров, доверенный прокси на проде, логи без утечек): + +📖 **[SECURITY.md](./SECURITY.md)** — чеклист и nginx/fail2ban-сниппеты. + +Связь с общими стандартами: + +📖 **[docs/security/SECURITY_STANDARDS.md](../../security/SECURITY_STANDARDS.md)** — раздел **Proxy & Edge Security (ru.hunab.app)**. + +--- + +## 🔍 Запросы-сканеры (serverless и др.) + +В логах прода с IP 149.154.64.19 видны запросы к `/api/serverless/*`, `serverless.yml`, `.serverless/` и т.п. — это **внешние боты**, не скрипты на прокси. Чтобы не гонять их на прод, на прокси добавляют `location` с `return 404` (см. [SECURITY.md](./SECURITY.md)). + +--- + +## 🇷🇺 Автоматический редирект + +Редирект пользователей из РФ на ru.hunab.app реализован на фронтенде (HTML + JS). Детали и тесты: + +📖 **[AUTOMATIC_REDIRECT_SOLUTION.md](./AUTOMATIC_REDIRECT_SOLUTION.md)** + +--- + +## 📤 Загрузка файлов на прод через туннель (scp) + +Для передачи больших файлов (например, git bundle для очистки истории) на production (209.38.32.21) из РФ используйте SSH ProxyCommand через прокси: + +```bash +# Туннель: локальная машина → 149.154.64.19 (прокси) → 209.38.32.21 (прод) +PROXY_CMD="ssh -i $HOME/.ssh/id_ed25519 -o StrictHostKeyChecking=accept-new -W %h:%p hsites-ahau" +scp -i ~/.ssh/hunab_deploy_key -o ProxyCommand="$PROXY_CMD" -o ServerAliveInterval=15 \ + /path/to/file.bundle hunab@209.38.32.21:/home/hunab/ +``` + +Проверка размера файла на сервере (через тот же туннель): + +```bash +ssh -i ~/.ssh/hunab_deploy_key -o ProxyCommand="$PROXY_CMD" hunab@209.38.32.21 "ls -la /home/hunab/file.bundle" +``` + +--- + +## 📊 Проверка скорости + +Через прокси соединение до прода быстрее, чем прямо из РФ. Замеры: ~0.29s через ru.hunab.app vs ~3.2s напрямую. Для проверки с прокси-сервера к проду: `expect temp/check_connection_speed.sh` (с локальной машины). + +--- + +## Cursor IDE (PING timeout из РФ) + +Если Cursor выдаёт **PING timed out** при работе из России, трафик можно пустить через тот же сервер по SOCKS (SSH -D). Подробно: + +📖 **[docs/cursor/README.md](../docs/cursor/README.md)** — обход PING timeout через SOCKS-туннель (без отключения HTTP/2). + +--- + +## 📱 Telegram и SOCKS при старте + +Для стабильной связи Telegram (и других приложений) через тот же прокси поднимают SOCKS5 на **127.0.0.1:1081**: + +```bash +ssh -D 1081 ahau@149.154.64.19 +``` + +Порт **1081** не пересекается с туннелем Cursor (**10809**). + +### Запуск при входе в систему (macOS) + +Чтобы туннель поднимался при логине и перезапускался при обрыве: + +```bash +cp connectivity/launchd/com.hunab.telegram-socks.plist ~/Library/LaunchAgents/ +launchctl load ~/Library/LaunchAgents/com.hunab.telegram-socks.plist +``` + +Подробности и снятие с автозапуска: **[connectivity/launchd/README.md](./launchd/README.md)**. + +### Ручное управление + +Скрипт из репо (start/stop/status): + +```bash +./connectivity/scripts/telegram-socks-tunnel.sh start # поднять +./connectivity/scripts/telegram-socks-tunnel.sh status # проверить +./connectivity/scripts/telegram-socks-tunnel.sh stop # остановить +``` + +В Telegram (или другом клиенте) укажите прокси: **SOCKS5**, **127.0.0.1**, порт **1081**. + +--- + +## SSL + +Сертификат Let's Encrypt, обновление через certbot (timer). При первичной настройке или смене домена: временно nginx без SSL → certbot → включить полный конфиг с SSL. Скрипты в папке: `get-ssl-certificate.sh`, `setup-ssl-auto-renewal.sh` (при необходимости). diff --git a/docs/connectivity/README.md b/docs/connectivity/README.md new file mode 100644 index 0000000..c3dd482 --- /dev/null +++ b/docs/connectivity/README.md @@ -0,0 +1,55 @@ +# connectivity + +Документация и скрипты для работы через прокси **ru.hunab.app** (149.154.64.19): доступ к продакшену, обход ограничений из РФ, туннели и автозапуск. + +--- + +## Содержимое папки + +| Файл / папка | Назначение | +|--------------|------------| +| **[PROXY_GUIDE.md](./PROXY_GUIDE.md)** | Основное руководство: SSH, Nginx, безопасность, scp через туннель, Cursor, скорость | +| **[TELEGRAM_GUIDE.md](./TELEGRAM_GUIDE.md)** | Гайд по Telegram: быстрые команды и порядок настройки с нуля на новой машине | +| **[PROXY_CHANGELOG.md](./PROXY_CHANGELOG.md)** | История изменений (безопасность, скрипты, документация) | +| **[BUILD_AAB_FROM_RUSSIA_GUIDE.md](./BUILD_AAB_FROM_RUSSIA_GUIDE.md)** | Сборка AAB/APK из России: Maven proxy на проде + SSH-туннель | +| **[scripts/](./scripts/)** | Скрипты для туннелей и локальной работы | +| **[launchd/](./launchd/)** | LaunchAgent для macOS: автозапуск SOCKS-туннеля при входе | + +--- + +## Быстрые ссылки по задачам + +- **Доступ по SSH к прокси** — [PROXY_GUIDE.md → Доступ и файлы](./PROXY_GUIDE.md#-доступ-и-файлы) +- **Telegram через SOCKS** — [TELEGRAM_GUIDE.md](./TELEGRAM_GUIDE.md) (быстрые команды + гайд для новой машины), [launchd/README.md](./launchd/README.md) +- **Cursor (PING timeout из РФ)** — [PROXY_GUIDE.md → Cursor IDE](./PROXY_GUIDE.md#cursor-ide-ping-timeout-из-рф), в репо: `docs/cursor/README.md`, скрипт `docs/cursor/scripts/cursor-socks-tunnel.sh` +- **Загрузка файлов на прод через прокси** — [PROXY_GUIDE.md → Загрузка файлов на прод (scp)](./PROXY_GUIDE.md#-загрузка-файлов-на-прод-через-туннель-scp) +- **Безопасность прокси (nginx, fail2ban)** — [PROXY_GUIDE.md → Безопасность](./PROXY_GUIDE.md#-безопасность), SECURITY.md (если есть в папке) +- **Сборка AAB из РФ** — [BUILD_AAB_FROM_RUSSIA_GUIDE.md](./BUILD_AAB_FROM_RUSSIA_GUIDE.md) + +--- + +## Скрипты (scripts/) + +| Скрипт | Описание | +|--------|----------| +| **telegram-socks-tunnel.sh** | Поднять/остановить/проверить SOCKS5 на 127.0.0.1:1081 для Telegram (и др.). Хост: ahau@149.154.64.19. Переменные: `TELEGRAM_SOCKS_PORT`, `TELEGRAM_TUNNEL_HOST`. | + +--- + +## launchd/ + +Автозапуск SOCKS-туннеля для Telegram при входе в macOS: + +- **com.hunab.telegram-socks.plist** — LaunchAgent (RunAtLoad, KeepAlive, порт 1081). +- **install.sh** — один раз скопировать plist и загрузить; дальше туннель поднимается при каждом входе. +- **uninstall.sh** — снять автозапуск. +- **[launchd/README.md](./launchd/README.md)** — установка, удаление, требования (ключ в keychain), возможные конфликты портов. + +--- + +## Порты (без пересечений) + +| Порт | Назначение | +|------|------------| +| **1081** | Telegram (и др. приложения) — SOCKS через `scripts/telegram-socks-tunnel.sh` или LaunchAgent | +| **10809** | Cursor IDE — SOCKS через `docs/cursor/scripts/cursor-socks-tunnel.sh` | diff --git a/docs/connectivity/TELEGRAM_GUIDE.md b/docs/connectivity/TELEGRAM_GUIDE.md new file mode 100644 index 0000000..0bdb1c8 --- /dev/null +++ b/docs/connectivity/TELEGRAM_GUIDE.md @@ -0,0 +1,146 @@ +# Telegram через SOCKS-туннель (ru.hunab.app) + +Трафик Telegram идёт через прокси 149.154.64.19 по SOCKS5 на **127.0.0.1:1081**. Гайд для быстрых команд и для настройки с нуля на новой машине. + +--- + +## ⚡ Быстрые команды + +```bash +# Поднять туннель вручную +./docs/connectivity/scripts/telegram-socks-tunnel.sh start + +# Проверить, слушается ли порт +lsof -i :1081 + +# Статус туннеля +./docs/connectivity/scripts/telegram-socks-tunnel.sh status + +# Остановить туннель +./docs/connectivity/scripts/telegram-socks-tunnel.sh stop + +# Включить автозапуск при входе (один раз) +./docs/connectivity/launchd/install.sh + +# Отключить автозапуск +./docs/connectivity/launchd/uninstall.sh + +# Проверить доступ к Telegram API через прокси +curl -x socks5h://127.0.0.1:1081 -sI https://api.telegram.org | head -3 +``` + +**В Telegram:** Настройки → Данные и память → Прокси → добавить **SOCKS5**, **127.0.0.1**, порт **1081**. + +--- + +## Полный гайд: новая машина (порядок действий) + +### 1. Требования + +- macOS (для LaunchAgent; на Linux можно использовать systemd или скрипт в автозагрузке). +- Доступ по SSH к **149.154.64.19** под пользователем **ahau** (ключ в `~/.ssh/` или алиас в `~/.ssh/config`, например `hsites-ahau`). +- Репозиторий **local_machine** склонирован (нужны скрипты из `docs/connectivity/`). + +### 2. Проверка SSH + +Убедись, что вход без пароля работает: + +```bash +ssh -o BatchMode=yes -o ConnectTimeout=10 ahau@149.154.64.19 "echo OK" +``` + +Если просит пароль или ключ не подхватывается — настрой `~/.ssh/config` или укажи ключ явно: `ssh -i ~/.ssh/id_ed25519 ahau@149.154.64.19`. + +### 3. Поднять туннель вручную (первый раз) + +Из корня репо: + +```bash +./docs/connectivity/scripts/telegram-socks-tunnel.sh start +``` + +Ожидаемый вывод: `SOCKS tunnel started: 127.0.0.1:1081 -> ahau@149.154.64.19`. + +Проверка порта: + +```bash +lsof -i :1081 +``` + +Должен быть процесс `ssh` в состоянии LISTEN. + +### 4. Настройка прокси в Telegram + +1. Открой **Telegram** (Desktop или мобильное приложение). +2. **Настройки** (Settings) → **Данные и память** (Data and Storage) → **Прокси** (Proxy). +3. **Добавить прокси** (Add Proxy): + - Тип: **SOCKS5** + - Сервер: **127.0.0.1** + - Порт: **1081** + - Логин/пароль — не нужны. +4. Сохрани и **включи** прокси. + +После этого Telegram должен подключаться через туннель. Если не подключается — см. раздел [Проверка и диагностика](#проверка-и-диагностика) ниже. + +### 5. Автозапуск туннеля при входе в систему (macOS) + +Чтобы не запускать туннель вручную после каждой перезагрузки: + +```bash +./docs/connectivity/launchd/install.sh +``` + +Скрипт копирует plist в `~/Library/LaunchAgents/` и загружает его. Дальше при каждом входе в систему туннель будет подниматься сам (и перезапускаться при обрыве). + +**Важно:** при старте системы SSH должен иметь доступ к ключу. Добавь ключ в связку с keychain (один раз): + +```bash +ssh-add --apple-use-keychain +# или, если ключ не дефолтный: +ssh-add --apple-use-keychain ~/.ssh/id_ed25519 +``` + +Проверка после перезагрузки: + +```bash +lsof -i :1081 +./docs/connectivity/scripts/telegram-socks-tunnel.sh status +``` + +### 6. Проверка и диагностика + +**Туннель слушает порт?** + +```bash +lsof -i :1081 -sTCP:LISTEN +``` + +**Доступ к API Telegram через SOCKS?** + +```bash +curl -x socks5h://127.0.0.1:1081 -sI https://api.telegram.org | head -5 +``` + +Успех: в ответе есть HTTP-заголовки (например 302 или 200). Таймаут или отказ — туннель не работает или порт занят. + +**Лог LaunchAgent (если туннель при старте не поднимается):** + +```bash +tail -50 /tmp/telegram-socks-tunnel.log +``` + +Типичные причины: ключ не в keychain, ошибка «Permission denied», сеть ещё недоступна при RunAtLoad. + +### 7. Конфликты портов + +| Порт | Назначение | +|-------|------------| +| 1081 | Telegram SOCKS (этот гайд) | +| 10809 | Cursor IDE SOCKS (другой туннель) | + +Если на 1081 уже висит другой прокси (например Shadowsocks), смени порт в plist и в настройках Telegram или отключи автозапуск: `./docs/connectivity/launchd/uninstall.sh`. + +### 8. Ссылки + +- [PROXY_GUIDE.md](./PROXY_GUIDE.md) — общее руководство по прокси ru.hunab.app (SSH, Nginx, Cursor, scp). +- [launchd/README.md](./launchd/README.md) — детали LaunchAgent (удаление, ThrottleInterval, логи). diff --git a/docs/connectivity/launchd/README.md b/docs/connectivity/launchd/README.md new file mode 100644 index 0000000..40f3231 --- /dev/null +++ b/docs/connectivity/launchd/README.md @@ -0,0 +1,46 @@ +# LaunchAgent: SOCKS-туннель для Telegram при входе в систему + +Поднимает `ssh -D 1081 ahau@149.154.64.19` при логине и перезапускает при обрыве. + +- **Порт:** 1081 (отдельно от Cursor 10809, конфликтов нет) +- **Сервер:** 149.154.64.19 (ru.hunab.app), пользователь ahau + +## Установка (один раз — дальше работает при каждом входе) + +```bash +# из корня репо local_machine +./connectivity/launchd/install.sh +``` + +Скрипт копирует plist в `~/Library/LaunchAgents/` и выполняет `launchctl load`. После этого туннель будет автоматически подниматься при каждом старте/входе в систему. + +Проверка: туннель уже должен быть поднят (RunAtLoad), порт слушает: + +```bash +lsof -i :1081 +# или +./connectivity/scripts/telegram-socks-tunnel.sh status +``` + +## Удаление + +```bash +./connectivity/launchd/uninstall.sh +``` + +## Поведение + +- **RunAtLoad** — запуск при входе в систему +- **KeepAlive** — при обрыве SSH launchd перезапускает туннель +- **ThrottleInterval 30** — не чаще одного перезапуска в 30 секунд при постоянных падениях +- Лог: `/tmp/telegram-socks-tunnel.log` (при желании замените путь в plist после копирования) + +## Требования + +- SSH-ключ для `ahau@149.154.64.19` должен быть доступен при логине (в клюchain или без пароля), иначе туннель не поднимется. Проверка вручную: `ssh -D 1081 -N ahau@149.154.64.19`. +- Если используете алиас из `~/.ssh/config` (например `hsites-ahau`), в plist можно заменить `ahau@149.154.64.19` на `hsites-ahau`. + +## Конфликты портов + +- **10809** — Cursor SOCKS (скрипт `docs/cursor/scripts/cursor-socks-tunnel.sh`), не пересекается с 1081. +- **1081** — если у вас уже слушает Shadowsocks или другой прокси, смените порт в plist (и в Telegram/приложениях) или отключите этот LaunchAgent. diff --git a/docs/connectivity/launchd/com.hunab.telegram-socks.plist b/docs/connectivity/launchd/com.hunab.telegram-socks.plist new file mode 100644 index 0000000..f11bb58 --- /dev/null +++ b/docs/connectivity/launchd/com.hunab.telegram-socks.plist @@ -0,0 +1,30 @@ + + + + + Label + com.hunab.telegram-socks + ProgramArguments + + /usr/bin/ssh + -D + 1081 + -N + -o + ServerAliveInterval=30 + -o + ServerAliveCountMax=6 + ahau@149.154.64.19 + + RunAtLoad + + KeepAlive + + ThrottleInterval + 30 + StandardOutPath + /tmp/telegram-socks-tunnel.log + StandardErrorPath + /tmp/telegram-socks-tunnel.log + + diff --git a/docs/connectivity/launchd/install.sh b/docs/connectivity/launchd/install.sh new file mode 100755 index 0000000..7427799 --- /dev/null +++ b/docs/connectivity/launchd/install.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# Устанавливает LaunchAgent: копирует plist в ~/Library/LaunchAgents/ и загружает. +# После этого туннель 127.0.0.1:1081 будет подниматься при каждом входе в систему. +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PLIST_NAME="com.hunab.telegram-socks.plist" +DST="$HOME/Library/LaunchAgents/$PLIST_NAME" + +mkdir -p "$HOME/Library/LaunchAgents" +cp "$SCRIPT_DIR/$PLIST_NAME" "$DST" +launchctl load "$DST" +echo "Installed: $DST (loaded). Tunnel will start at login." +lsof -i :1081 -sTCP:LISTEN 2>/dev/null && echo "Port 1081 is listening." || echo "Check port 1081 in a few seconds: lsof -i :1081" diff --git a/docs/connectivity/launchd/uninstall.sh b/docs/connectivity/launchd/uninstall.sh new file mode 100755 index 0000000..21c2f18 --- /dev/null +++ b/docs/connectivity/launchd/uninstall.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# Снимает LaunchAgent: выгружает и удаляет plist из ~/Library/LaunchAgents/. +set -e +PLIST_NAME="com.hunab.telegram-socks.plist" +DST="$HOME/Library/LaunchAgents/$PLIST_NAME" + +launchctl unload "$DST" 2>/dev/null || true +rm -f "$DST" +echo "Uninstalled: $DST" diff --git a/docs/connectivity/scripts/telegram-socks-tunnel.sh b/docs/connectivity/scripts/telegram-socks-tunnel.sh new file mode 100755 index 0000000..b5f8503 --- /dev/null +++ b/docs/connectivity/scripts/telegram-socks-tunnel.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# SOCKS5-туннель для Telegram (и др. приложений) через прокси 149.154.64.19. +# Порт 1081 — отдельно от Cursor (10809). Использование: ./telegram-socks-tunnel.sh [start|stop|status] +# См. connectivity/PROXY_GUIDE.md + +set -e +TELEGRAM_SOCKS_PORT="${TELEGRAM_SOCKS_PORT:-1081}" +SSH_HOST="${TELEGRAM_TUNNEL_HOST:-ahau@149.154.64.19}" + +start() { + if lsof -i :"$TELEGRAM_SOCKS_PORT" -sTCP:LISTEN -t >/dev/null 2>&1; then + echo "SOCKS already listening on 127.0.0.1:$TELEGRAM_SOCKS_PORT" + return 0 + fi + ssh -D "$TELEGRAM_SOCKS_PORT" -f -N \ + -o ServerAliveInterval=30 \ + -o ServerAliveCountMax=6 \ + "$SSH_HOST" + echo "SOCKS tunnel started: 127.0.0.1:$TELEGRAM_SOCKS_PORT -> $SSH_HOST" +} + +stop() { + pkill -f "ssh.*-D $TELEGRAM_SOCKS_PORT.*$SSH_HOST" 2>/dev/null || true + echo "Tunnel stopped (if it was running)." +} + +status() { + if lsof -i :"$TELEGRAM_SOCKS_PORT" -sTCP:LISTEN -t >/dev/null 2>&1; then + echo "SOCKS listening on 127.0.0.1:$TELEGRAM_SOCKS_PORT" + lsof -i :"$TELEGRAM_SOCKS_PORT" -sTCP:LISTEN + else + echo "No SOCKS listener on port $TELEGRAM_SOCKS_PORT" + fi +} + +case "${1:-start}" in + start) start ;; + stop) stop ;; + status) status ;; + *) + echo "Usage: $0 {start|stop|status}" + echo "Env: TELEGRAM_SOCKS_PORT=$TELEGRAM_SOCKS_PORT, TELEGRAM_TUNNEL_HOST=$SSH_HOST" + exit 1 + ;; +esac diff --git a/docs/connectivity/vpn/DEPLOY_WIREGUARD_RU.md b/docs/connectivity/vpn/DEPLOY_WIREGUARD_RU.md new file mode 100644 index 0000000..460f9c6 --- /dev/null +++ b/docs/connectivity/vpn/DEPLOY_WIREGUARD_RU.md @@ -0,0 +1,158 @@ +# 🚀 Развертывание WireGuard на ru.hunab.app + +## Быстрая инструкция + +### Шаг 1: Подключитесь к серверу + +```bash +ssh ahau@149.154.64.19 +# Пароль: w99z2fBSkO4gU +``` + +### Шаг 2: Выполните команды развертывания + +```bash +# Создание директорий +sudo mkdir -p /opt/app/vpn/wireguard/config +sudo chown -R ahau:ahau /opt/app/vpn + +# Остановка существующего контейнера (если есть) +docker stop hunab-vpn-wireguard-ru 2>/dev/null || true +docker rm hunab-vpn-wireguard-ru 2>/dev/null || true + +# Запуск WireGuard контейнера +cd /opt/app/vpn/wireguard + +docker run -d \ + --name hunab-vpn-wireguard-ru \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 \ + -e SERVERPORT=51820 \ + -e PEERS=1 \ + -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 \ + -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp \ + --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped \ + linuxserver/wireguard:latest + +# Ожидание создания конфигурации +echo "Ожидание 30 секунд для создания конфигурации..." +sleep 30 + +# Настройка Firewall +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' +sudo ufw reload + +# Проверка статуса +docker ps | grep wireguard + +# Просмотр конфигурации клиента +echo "=== Конфигурация клиента ===" +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf +``` + +### Шаг 3: Скопируйте конфигурацию + +**С вашего компьютера:** + +```bash +# Скопируйте конфигурацию +scp ahau@149.154.64.19:/opt/app/vpn/wireguard/config/peer1/peer1.conf docs/vpn/wg-ru.conf +``` + +**Или просмотрите и скопируйте вручную:** + +```bash +ssh ahau@149.154.64.19 'cat /opt/app/vpn/wireguard/config/peer1/peer1.conf' +``` + +Затем скопируйте содержимое в файл `docs/hotspot/wg-ru.conf`. + +### Шаг 4: Импортируйте в WireGuard на Android + +1. Скопируйте файл `wg-ru.conf` на телефон +2. Откройте приложение WireGuard +3. Нажмите **"+"** → **"Создать из файла или архива"** +4. Выберите файл `wg-ru.conf` +5. Подключитесь! + +--- + +## Проверка работы + +После импорта конфигурации проверьте: + +1. **IP адрес должен быть российским:** + - Откройте https://whatismyipaddress.com/ + - Должен отображаться IP: **149.154.64.19** + +2. **Подключение активно:** + - В приложении WireGuard статус должен быть "Подключено" + +--- + +## Управление + +### Просмотр статуса + +```bash +ssh ahau@149.154.64.19 "docker ps | grep wireguard" +``` + +### Просмотр логов + +```bash +ssh ahau@149.154.64.19 "docker logs hunab-vpn-wireguard-ru" +``` + +### Перезапуск + +```bash +ssh ahau@149.154.64.19 "docker restart hunab-vpn-wireguard-ru" +``` + +### Остановка + +```bash +ssh ahau@149.154.64.19 "docker stop hunab-vpn-wireguard-ru" +``` + +--- + +## Решение проблем + +### Конфигурация не создается + +Подождите еще 30-60 секунд и проверьте: + +```bash +ssh ahau@149.154.64.19 "ls -la /opt/app/vpn/wireguard/config/peer1/" +``` + +### Контейнер не запускается + +Проверьте логи: + +```bash +ssh ahau@149.154.64.19 "docker logs hunab-vpn-wireguard-ru" +``` + +### Порт занят + +Проверьте, что порт 51820 свободен: + +```bash +ssh ahau@149.154.64.19 "sudo netstat -tuln | grep 51820" +``` + +--- + +## Готово! + +После выполнения всех шагов у вас будет рабочий WireGuard конфиг `wg-ru.conf` для использования из России! 🎉 diff --git a/docs/connectivity/vpn/FINAL_DEPLOY_INSTRUCTIONS.md b/docs/connectivity/vpn/FINAL_DEPLOY_INSTRUCTIONS.md new file mode 100644 index 0000000..0c75a49 --- /dev/null +++ b/docs/connectivity/vpn/FINAL_DEPLOY_INSTRUCTIONS.md @@ -0,0 +1,43 @@ +# 🚀 Финальные инструкции для получения рабочего конфига + +## Проблема +SSH порт 22 на сервере 149.154.64.19 закрыт, поэтому автоматическое развертывание невозможно. + +## Решение + +### Вариант 1: Если у вас есть доступ к серверу через другой терминал + +1. **Выполните команду из файла `ONE_LINE_DEPLOY.txt`:** + ```bash + cat docs/vpn/ONE_LINE_DEPLOY.txt + ``` + Скопируйте команду и выполните в SSH сеансе на сервере. + +2. **После выполнения получите конфигурацию:** + ```bash + ./docs/vpn/scripts/get-wg-ru-config.sh + ``` + Или вручную: + ```bash + scp ahau@149.154.64.19:/opt/app/vpn/wireguard/config/peer1/peer1.conf docs/vpn/wg-ru.conf + ``` + +### Вариант 2: Если SSH порт открыт на другом порту + +Используйте команду с указанием порта: +```bash +ssh -p ahau@149.154.64.19 +``` + +### Вариант 3: Если WireGuard уже развернут + +Просто получите конфигурацию: +```bash +./docs/vpn/scripts/get-wg-ru-config.sh +``` + +--- + +## После получения конфигурации + +Файл `docs/vpn/wg-ru.conf` будет содержать рабочий конфиг для импорта в WireGuard на Android. diff --git a/docs/connectivity/vpn/MAC_CLIENTS.md b/docs/connectivity/vpn/MAC_CLIENTS.md new file mode 100644 index 0000000..f7d4767 --- /dev/null +++ b/docs/connectivity/vpn/MAC_CLIENTS.md @@ -0,0 +1,288 @@ +# 🍎 macOS - Клиенты для Shadowsocks + +## 📋 Обзор + +Руководство по установке и настройке различных VPN клиентов для macOS. + +**Параметры подключения:** +``` +Server: 209.38.32.21 +Port: 8388 +Password: bNkSbuMQXgMXmuBLPQCA5cSUE +Method: chacha20-ietf-poly1305 +``` + +**URI для импорта:** +``` +ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpiTmtTYnVNUVhnTVhtdUJMUFFDQTVjU1VFQDIwOS4zOC4zMi4yMTo4Mzg4 +``` + +--- + +## 🎯 Рекомендуемые клиенты + +### 1. ⭐ shadowsocks-libev (CLI) - Рекомендуется + +**Почему:** +- ✅ Работает без GUI приложений +- ✅ Автозапуск при входе в систему +- ✅ Стабильная работа +- ✅ Низкое потребление ресурсов + +**Установка:** +```bash +brew install shadowsocks-libev +``` + +**Настройка:** См. [SHADOWSOCKS.md](./SHADOWSOCKS.md#macos) + +**Управление:** +```bash +cd docs/servers/vpn +./scripts/toggle-shadowsocks-proxy.sh # Переключение прокси +./scripts/check-proxy-status.sh # Проверка статуса +./scripts/fix-shadowsocks.sh # Автоматическое исправление +``` + +--- + +### 2. ⭐ ClashX + +**Почему:** +- ✅ Очень популярный клиент +- ✅ Правила маршрутизации +- ✅ Поддержка множества протоколов + +**Установка:** +1. Скачайте с: https://github.com/yichengchen/clashX/releases +2. Или используйте ClashX Meta: https://github.com/MetaCubeX/ClashX.Meta/releases + +**Настройка:** + +1. Откройте ClashX → **Config** → **Edit Config** +2. Замените содержимое на: + +```yaml +port: 7890 +socks-port: 7891 +allow-lan: false +mode: rule +log-level: info +external-controller: 127.0.0.1:9090 + +proxies: + - name: "Hunab Shadowsocks" + type: ss + server: 209.38.32.21 + port: 8388 + cipher: chacha20-ietf-poly1305 + password: bNkSbuMQXgMXmuBLPQCA5cSUE + +proxy-groups: + - name: "Proxy" + type: select + proxies: + - "Hunab Shadowsocks" + - DIRECT + + - name: "Auto" + type: url-test + proxies: + - "Hunab Shadowsocks" + url: 'http://www.gstatic.com/generate_204' + interval: 300 + +rules: + - DOMAIN-SUFFIX,local,DIRECT + - IP-CIDR,127.0.0.0/8,DIRECT + - IP-CIDR,172.16.0.0/12,DIRECT + - IP-CIDR,192.168.0.0/16,DIRECT + - IP-CIDR,10.0.0.0/8,DIRECT + - GEOIP,CN,DIRECT + - MATCH,Proxy +``` + +3. **Config** → **Reload Config** +4. **Proxy** → **Hunab Shadowsocks** +5. Включите **Set as System Proxy** + +**GitHub:** https://github.com/yichengchen/clashX + +--- + +### 3. ⭐ V2rayU + +**Почему:** +- ✅ Простая установка через Homebrew +- ✅ Поддержка Shadowsocks из коробки +- ✅ Простой интерфейс + +**Установка:** +```bash +brew install --cask v2rayu +``` + +**Настройка:** +1. Откройте V2rayU +2. **Servers** → **Add Server** → **Shadowsocks** +3. Введите параметры подключения +4. Выберите сервер и подключитесь + +**GitHub:** https://github.com/yanue/V2rayU + +--- + +### 4. ⭐ Outline + +**Почему:** +- ✅ Очень простой интерфейс +- ✅ Разработан Google (Jigsaw) +- ✅ Автоматическая настройка + +**Установка:** +- Mac App Store: https://apps.apple.com/app/outline/id1356177741 +- Или прямая загрузка: https://github.com/Jigsaw-Code/outline-client/releases + +**Настройка:** +1. Откройте Outline +2. Нажмите **"+"** → **"Enter access key"** +3. Вставьте ключ: + ``` + ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpiTmtTYnVNUVhnTVhtdUJMUFFDQTVjU1VFQDIwOS4zOC4zMi4yMTo4Mzg4 + ``` +4. Подключитесь + +**GitHub:** https://github.com/Jigsaw-Code/outline-client + +--- + +### 5. ShadowsocksX-NG + +**Установка:** +```bash +brew install --cask shadowsocksx-ng +``` + +**Настройка:** +1. Откройте приложение → **Server Preferences** → **"+"** +2. Введите параметры подключения +3. Выберите сервер в меню и подключитесь +4. Включите **"System Proxy"** + +--- + +## 🔧 Настройка системного прокси + +### Автоматическая настройка (shadowsocks-libev) + +Используйте скрипты: +```bash +cd docs/servers/vpn +./scripts/enable-shadowsocks-full.sh # Включить для всего трафика +``` + +### Ручная настройка + +1. **System Settings** → **Network** +2. Выберите активное подключение (Wi-Fi/Ethernet) +3. **Details...** → **Proxies** +4. Включите **SOCKS Proxy**: + - Server: `127.0.0.1` + - Port: `1080` +5. Нажмите **OK** + +**Или через командную строку:** +```bash +INTERFACE=$(networksetup -listallnetworkservices | grep -E "Wi-Fi|Ethernet" | head -1) +networksetup -setsocksfirewallproxy "$INTERFACE" 127.0.0.1 1080 +networksetup -setsocksfirewallproxystate "$INTERFACE" on +``` + +--- + +## 🔄 Переключение между Chrome VPN и Shadowsocks + +### Использовать Chrome VPN + +1. Выключите системный прокси: + ```bash + cd docs/servers/vpn + ./scripts/toggle-shadowsocks-proxy.sh + ``` +2. Используйте Chrome VPN как обычно + +### Использовать Shadowsocks + +1. Включите системный прокси: + ```bash + cd docs/servers/vpn + ./scripts/toggle-shadowsocks-proxy.sh + ``` +2. **Полностью закройте Chrome** (Cmd+Q) +3. Откройте Chrome заново +4. Проверьте IP: https://whatismyipaddress.com/ + +--- + +## 🔧 Решение проблем + +### Браузер показывает старый IP + +1. **Отключите Chrome VPN расширение** (если активно) +2. **Проверьте настройки Chrome:** `chrome://settings/system` → "Use system proxy settings" +3. **Полностью закройте Chrome:** Cmd+Q +4. **Откройте Chrome заново** + +**Или используйте скрипт:** +```bash +cd docs/servers/vpn +./scripts/fix-shadowsocks.sh +``` + +### Прокси не работает + +1. Проверьте статус: + ```bash + cd docs/servers/vpn + ./scripts/check-proxy-status.sh + ``` + +2. Перезапустите Shadowsocks: + ```bash + launchctl unload ~/Library/LaunchAgents/com.shadowsocks.local.plist + launchctl load ~/Library/LaunchAgents/com.shadowsocks.local.plist + ``` + +### Firefox не использует системный прокси + +Настройте вручную: +1. **Preferences** → **Network Settings** +2. **Manual proxy configuration** +3. **SOCKS Host:** `127.0.0.1` +4. **Port:** `1080` +5. **SOCKS v5** + +--- + +## 📊 Сравнение клиентов + +| Клиент | Простота | Функции | Установка | Рекомендация | +|--------|----------|---------|-----------|--------------| +| **shadowsocks-libev** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ✅ **ЛУЧШИЙ** | +| **ClashX** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ✅ Очень популярный | +| **V2rayU** | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ✅ Хороший баланс | +| **Outline** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ✅ Очень простой | +| **ShadowsocksX-NG** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ✅ Оригинал | + +--- + +## 🔗 Полезные ссылки + +- [Shadowsocks полное руководство](./SHADOWSOCKS.md) +- [Скрипты управления](./scripts/) + +--- + +**Версия:** 2.0 +**Дата:** 2025-01-XX + diff --git a/docs/connectivity/vpn/ONE_LINE_DEPLOY.txt b/docs/connectivity/vpn/ONE_LINE_DEPLOY.txt new file mode 100644 index 0000000..6c8b722 --- /dev/null +++ b/docs/connectivity/vpn/ONE_LINE_DEPLOY.txt @@ -0,0 +1 @@ +sudo mkdir -p /opt/app/vpn/wireguard/config && sudo chown -R ahau:ahau /opt/app/vpn && docker stop hunab-vpn-wireguard-ru 2>/dev/null; docker rm hunab-vpn-wireguard-ru 2>/dev/null; cd /opt/app/vpn/wireguard && docker run -d --name hunab-vpn-wireguard-ru --cap-add=NET_ADMIN --cap-add=SYS_MODULE -e PUID=1000 -e PGID=1000 -e TZ=Europe/Moscow -e SERVERURL=149.154.64.19 -e SERVERPORT=51820 -e PEERS=1 -e PEERDNS=8.8.8.8 -e INTERNAL_SUBNET=10.14.14.0 -v /opt/app/vpn/wireguard/config:/config -p 51820:51820/udp --sysctl="net.ipv4.conf.all.src_valid_mark=1" --restart unless-stopped linuxserver/wireguard:latest && echo "Ожидание 45 секунд..." && sleep 45 && sudo ufw allow 51820/udp comment "WireGuard VPN RU" && sudo ufw reload && echo "=== КОНФИГУРАЦИЯ ===" && cat /opt/app/vpn/wireguard/config/peer1/peer1.conf diff --git a/docs/connectivity/vpn/QUICK_DEPLOY_WG_RU.md b/docs/connectivity/vpn/QUICK_DEPLOY_WG_RU.md new file mode 100644 index 0000000..2f860a7 --- /dev/null +++ b/docs/connectivity/vpn/QUICK_DEPLOY_WG_RU.md @@ -0,0 +1,54 @@ +# 🚀 Быстрое развертывание WireGuard на ru.hunab.app + +## Выполните эти команды в SSH сеансе на сервере + +```bash +# 1. Создание директорий +sudo mkdir -p /opt/app/vpn/wireguard/config +sudo chown -R ahau:ahau /opt/app/vpn + +# 2. Остановка старых контейнеров +docker stop hunab-vpn-wireguard-ru 2>/dev/null || true +docker rm hunab-vpn-wireguard-ru 2>/dev/null || true + +# 3. Запуск WireGuard +cd /opt/app/vpn/wireguard + +docker run -d \ + --name hunab-vpn-wireguard-ru \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 \ + -e SERVERPORT=51820 \ + -e PEERS=1 \ + -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 \ + -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp \ + --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped \ + linuxserver/wireguard:latest + +# 4. Ожидание (45 секунд) +sleep 45 + +# 5. Firewall +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' +sudo ufw reload + +# 6. Просмотр конфигурации +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf +``` + +## После выполнения команд + +Скопируйте вывод команды `cat` и вставьте в файл `docs/vpn/wg-ru.conf` + +Или выполните с вашего компьютера: + +```bash +scp ahau@149.154.64.19:/opt/app/vpn/wireguard/config/peer1/peer1.conf docs/vpn/wg-ru.conf +``` diff --git a/docs/connectivity/vpn/README.md b/docs/connectivity/vpn/README.md new file mode 100644 index 0000000..e1abfbd --- /dev/null +++ b/docs/connectivity/vpn/README.md @@ -0,0 +1,115 @@ +# 🔐 VPN Решения для Hunab.app + +## 📋 Обзор + +Документация по VPN решениям для сервера 209.38.32.21. Все решения развернуты через Docker и готовы к использованию. + +**Сервер:** 209.38.32.21 (Ubuntu 24.10) +**Архитектура:** Docker-based deployment + +--- + +## 🚀 Быстрый старт + +### Shadowsocks (Рекомендуется для обхода блокировок) + +**Лучший выбор для обхода строгих блокировок и цензуры.** + +- 📖 [Полное руководство](./SHADOWSOCKS.md) +- ⚡ Быстрый старт: `bash scripts/deployment/deploy-vpn-shadowsocks.sh` +- 📱 [Android инструкция](./SHADOWSOCKS.md#android) +- 🍎 [macOS инструкция](./SHADOWSOCKS.md#macos) + +**Параметры подключения:** +``` +Server: 209.38.32.21 +Port: 8388 +Password: bNkSbuMQXgMXmuBLPQCA5cSUE +Method: chacha20-ietf-poly1305 +``` + +### WireGuard (Рекомендуется для обычного использования) + +**Проще в настройке, полное туннелирование из коробки.** + +- 📖 [Полное руководство](./WIREGUARD.md) +- ⚡ Быстрый старт: `bash scripts/deployment/deploy-vpn-wireguard.sh` + +--- + +## 📚 Документация + +### Основные руководства + +- **[SHADOWSOCKS.md](./SHADOWSOCKS.md)** - Полное руководство по Shadowsocks + - Развертывание сервера + - Настройка клиентов (Android, macOS, CLI) + - Решение проблем + - Управление и мониторинг + +- **[MAC_CLIENTS.md](./MAC_CLIENTS.md)** - Клиенты для macOS + - ShadowsocksX-NG, ClashX, V2rayU, Outline + - Настройка системного прокси + - Решение проблем с браузерами + - Альтернативные клиенты + +- **[WIREGUARD.md](./WIREGUARD.md)** - Руководство по WireGuard + - Развертывание + - Настройка клиентов + - Управление + +- **[WHONIX.md](./WHONIX.md)** - Whonix для приватности + - Установка на Mac + - Настройка для Apple Silicon + - Использование + +--- + +## 🔧 Скрипты + +Все скрипты находятся в папке `scripts/`: + +- `scripts/toggle-shadowsocks-proxy.sh` - Переключение системного прокси +- `scripts/check-proxy-status.sh` - Проверка статуса прокси +- `scripts/fix-shadowsocks.sh` - Автоматическое исправление +- `scripts/enable-shadowsocks-full.sh` - Включение для всего трафика + +**Использование:** +```bash +cd docs/servers/vpn +./scripts/toggle-shadowsocks-proxy.sh +./scripts/check-proxy-status.sh +./scripts/fix-shadowsocks.sh +./scripts/enable-shadowsocks-full.sh +``` + +--- + +## 📊 Сравнение решений + +| Критерий | Shadowsocks | WireGuard | +|----------|-------------|-----------| +| **Скорость** | 90-95% | 85-95% | +| **Обход блокировок** | 🏆 Лучший | Хороший | +| **Обнаружимость DPI** | 🏆 Сложнее | Легче | +| **Настройка** | Простая | Очень простая | +| **Полное туннелирование** | Требует настройку | Из коробки | + +**Рекомендация:** +- **Для обхода блокировок:** Shadowsocks +- **Для обычного использования:** WireGuard + +--- + +## 🔗 Полезные ссылки + +- [Shadowsocks Official](https://shadowsocks.org/) +- [WireGuard Official](https://www.wireguard.com/) +- [Whonix Official](https://www.whonix.org/) + +--- + +**Версия:** 2.0 +**Дата:** 2025-01-XX +**Статус:** ✅ Актуально + diff --git a/docs/connectivity/vpn/RU_PROXY_SERVER_ACCESS.md b/docs/connectivity/vpn/RU_PROXY_SERVER_ACCESS.md new file mode 100644 index 0000000..0d8a49e --- /dev/null +++ b/docs/connectivity/vpn/RU_PROXY_SERVER_ACCESS.md @@ -0,0 +1,214 @@ +# 🔐 Доступы и команды управления прокси-сервером + +## 🌐 Сервер ru.hunab.app +**IP:** 149.154.64.19 +**Провайдер:** Российский VPS +**ОС:** Ubuntu 24.10 + +## 🔑 SSH Доступ +```bash +ssh ahau@149.154.64.19 +``` +**Пароль:** w99z2fBSkO4gU + +**Альтернативный доступ с ключом:** +```bash +ssh -i ~/.ssh/id_rsa_ahau ahau@149.154.64.19 +``` + +## 👤 Пользователи +- **ahau** - основной пользователь с sudo правами +- **root** - доступен через ahau + sudo + +## 🌍 URL'ы для проверки +- **Основной сайт:** https://ru.hunab.app/ +- **Health check:** https://ru.hunab.app/proxy-health +- **API:** https://ru.hunab.app/api/health + +## 📁 Важные файлы +```bash +# NGINX конфигурация +/etc/nginx/sites-available/ru.hunab.app + +# SSL сертификаты +/etc/letsencrypt/live/ru.hunab.app/ + +# Логи +/var/log/nginx/ru.hunab.app.access.log +/var/log/nginx/ru.hunab.app.error.log + +# Кеш +/var/cache/nginx/ +``` + +--- + +## 🔧 КОМАНДЫ УПРАВЛЕНИЯ + +### 🌐 NGINX Управление +```bash +# Проверка статуса +sudo systemctl status nginx + +# Проверка конфигурации +sudo nginx -t + +# Перезагрузка конфигурации +sudo systemctl reload nginx + +# Полный перезапуск +sudo systemctl restart nginx + +# Просмотр активных сайтов +sudo nginx -T | grep server_name +``` + +### 🔒 SSL/TLS Управление +```bash +# Проверка сертификатов +sudo certbot certificates + +# Тест автообновления +sudo certbot renew --dry-run + +# Ручное обновление +sudo certbot renew + +# Проверка статуса автообновления +sudo systemctl status certbot.timer +sudo systemctl list-timers | grep certbot +``` + +### 🛡️ Безопасность и Мониторинг +```bash +# UFW Firewall +sudo ufw status verbose +sudo ufw reload + +# Fail2ban +sudo systemctl status fail2ban +sudo fail2ban-client status +sudo fail2ban-client status nginx-limit-req + +# Просмотр заблокированных IP +sudo fail2ban-client get nginx-limit-req banip +``` + +### 📊 Логи и Мониторинг +```bash +# NGINX логи +sudo tail -f /var/log/nginx/ru.hunab.app.access.log +sudo tail -f /var/log/nginx/ru.hunab.app.error.log + +# Анализ трафика +sudo grep "$(date '+%d/%b/%Y')" /var/log/nginx/ru.hunab.app.access.log | wc -l + +# Поиск ошибок +sudo grep -i error /var/log/nginx/ru.hunab.app.error.log | tail -20 + +# Системные логи +sudo journalctl -u nginx -f +sudo journalctl -u fail2ban -f +``` + +### 🧪 Тестирование +```bash +# Health check прокси +curl -I https://ru.hunab.app/proxy-health + +# Проверка основного сайта +curl -I https://ru.hunab.app/ + +# Проверка API +curl -I https://ru.hunab.app/api/health + +# Тест скорости ответа +curl -w "@-" -o /dev/null -s https://ru.hunab.app/ <<'EOF' + time_namelookup: %{time_namelookup}\n + time_connect: %{time_connect}\n + time_appconnect: %{time_appconnect}\n + time_pretransfer: %{time_pretransfer}\n + time_redirect: %{time_redirect}\n + time_starttransfer: %{time_starttransfer}\n + ----------\n + time_total: %{time_total}\n +EOF +``` + +### 💾 Кеширование +```bash +# Очистка кеша NGINX +sudo rm -rf /var/cache/nginx/* +sudo systemctl reload nginx + +# Проверка размера кеша +sudo du -sh /var/cache/nginx/ + +# Просмотр кешированных файлов +sudo find /var/cache/nginx/ -type f | head -10 +``` + +### 🔄 Backup и Восстановление +```bash +# Backup конфигурации +sudo cp /etc/nginx/sites-available/ru.hunab.app /home/ahau/nginx-backup-$(date +%Y%m%d).conf + +# Backup SSL сертификатов +sudo tar -czf /home/ahau/ssl-backup-$(date +%Y%m%d).tar.gz /etc/letsencrypt/ + +# Проверка свободного места +df -h +``` + +### ⚡ Быстрые диагностические команды +```bash +# Полная проверка состояния системы +echo "=== NGINX Status ===" && sudo systemctl status nginx --no-pager && \ +echo "=== SSL Certificates ===" && sudo certbot certificates && \ +echo "=== Firewall Status ===" && sudo ufw status && \ +echo "=== Current Connections ===" && sudo ss -tuln | grep -E ':80|:443' && \ +echo "=== Recent Access ===" && sudo tail -5 /var/log/nginx/ru.hunab.app.access.log + +# Проверка производительности +echo "=== CPU Load ===" && uptime && \ +echo "=== Memory Usage ===" && free -h && \ +echo "=== Disk Usage ===" && df -h && \ +echo "=== Network Connections ===" && sudo netstat -anp | grep nginx | wc -l +``` + +### 🚨 Экстренные команды +```bash +# Экстренная остановка NGINX +sudo systemctl stop nginx + +# Экстренный запуск с минимальной конфигурацией +sudo nginx -t && sudo systemctl start nginx + +# Откат к предыдущей конфигурации +sudo cp /home/ahau/nginx-backup-YYYYMMDD.conf /etc/nginx/sites-available/ru.hunab.app +sudo systemctl reload nginx + +# Проверка процессов NGINX +sudo ps aux | grep nginx +sudo pgrep nginx | xargs sudo kill -9 # Крайний случай! +``` + +--- + +## ⚠️ ВАЖНЫЕ ЗАМЕТКИ +- Прокси настроен и работает в production +- SSL автообновление активно (certbot.timer) +- Все security компоненты настроены +- Требуется только мониторинг работоспособности + +## 🇷🇺 АВТОМАТИЧЕСКИЙ РЕДИРЕКТ + +**Статус:** ✅ РЕАЛИЗОВАНО И РАЗВЕРНУТО (8 декабря 2025) +**Версия:** v3.0 + +Автоматический редирект российских пользователей на `ru.hunab.app` реализован на фронтенде: +- Немедленный редирект в HTML (до загрузки JS) +- Проверка загрузки статических ресурсов +- Автоматический редирект в JavaScript + +📖 **Детальная документация:** [`AUTOMATIC_REDIRECT_SOLUTION.md`](./AUTOMATIC_REDIRECT_SOLUTION.md) diff --git a/docs/connectivity/vpn/SHADOWSOCKS.md b/docs/connectivity/vpn/SHADOWSOCKS.md new file mode 100644 index 0000000..6da06f2 --- /dev/null +++ b/docs/connectivity/vpn/SHADOWSOCKS.md @@ -0,0 +1,347 @@ +# 🚀 Shadowsocks VPN - Полное руководство + +## 📋 Обзор + +Shadowsocks VPN - **лучший выбор для обхода строгих блокировок**. Маскирует трафик под обычный веб-трафик, что делает его очень эффективным против DPI (Deep Packet Inspection) и интернет-цензуры. + +**Преимущества:** +- ✅ **90-95% от пропускной способности** (очень быстрый) +- ✅ **Сложнее обнаружить** через DPI +- ✅ **Эффективен против цензуры** (разработан для Китая) +- ✅ **TCP протокол** (проходит через корпоративные прокси) + +**Параметры подключения:** +``` +Server: 209.38.32.21 +Port: 8388 +Password: bNkSbuMQXgMXmuBLPQCA5cSUE +Method: chacha20-ietf-poly1305 +``` + +**URI для импорта:** +``` +ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpiTmtTYnVNUVhnTVhtdUJMUFFDQTVjU1VFQDIwOS4zOC4zMi4yMTo4Mzg4 +``` + +--- + +## 🔧 Развертывание сервера + +### Автоматическое развертывание + +```bash +bash scripts/deployment/deploy-vpn-shadowsocks.sh +``` + +Скрипт автоматически: +1. ✅ Проверит подключение к серверу +2. ✅ Сгенерирует безопасный пароль +3. ✅ Создаст необходимые директории +4. ✅ Настроит Docker контейнер +5. ✅ Обновит firewall правила +6. ✅ Запустит VPN сервер +7. ✅ Создаст клиентскую конфигурацию + +### Статус сервера + +**Контейнер:** `hunab-vpn-shadowsocks` +**Статус:** ✅ Запущен и работает +**Порт:** 8388 (TCP/UDP) +**Firewall:** ✅ Настроен + +**Проверка статуса:** +```bash +ssh hunab-prod "docker ps | grep shadowsocks" +``` + +--- + +## 📱 Настройка клиентов + +### Android + +1. Установите приложение **Shadowsocks** из Google Play (разработчик: Max Lv) +2. Нажмите **"+"** → **"Manual Settings"** +3. Введите параметры: + ``` + Server: 209.38.32.21 + Remote Port: 8388 + Password: bNkSbuMQXgMXmuBLPQCA5cSUE + Method: chacha20-ietf-poly1305 + ``` +4. Нажмите **"Подключиться"** + +**Альтернативные клиенты для Android:** +- ShadowsocksR - больше функций +- Outline - очень простой +- V2rayNG - много протоколов +- Clash for Android - правила маршрутизации + +### macOS + +#### Вариант 1: ShadowsocksX-NG (GUI) + +```bash +brew install --cask shadowsocksx-ng +``` + +1. Откройте приложение → **Server Preferences** → **"+"** +2. Введите параметры подключения +3. Выберите сервер в меню и подключитесь +4. Включите **"System Proxy"** + +#### Вариант 2: shadowsocks-libev (CLI) - Рекомендуется + +```bash +brew install shadowsocks-libev +``` + +**Настройка:** +```bash +mkdir -p ~/.shadowsocks +cat > ~/.shadowsocks/config.json < ~/Library/LaunchAgents/com.shadowsocks.local.plist < + + + + Label + com.shadowsocks.local + ProgramArguments + + /opt/homebrew/bin/ss-local + -c + ${HOME}/.shadowsocks/config.json + + RunAtLoad + + KeepAlive + + StandardOutPath + /tmp/shadowsocks.log + StandardErrorPath + /tmp/shadowsocks.error.log + + +EOF + +launchctl load ~/Library/LaunchAgents/com.shadowsocks.local.plist +``` + +**Настройка системного прокси:** +1. System Settings → Network → Wi-Fi/Ethernet → Details → Proxies +2. Включите SOCKS Proxy: `127.0.0.1:1080` + +**Или используйте скрипты:** +```bash +cd docs/servers/vpn +./scripts/enable-shadowsocks-full.sh # Включить для всего трафика +./scripts/toggle-shadowsocks-proxy.sh # Переключить прокси +./scripts/check-proxy-status.sh # Проверить статус +``` + +**Альтернативные клиенты для macOS:** +- ClashX - очень популярный +- V2rayU - простой интерфейс +- Outline - очень простой +- Surge - платный, но мощный + +--- + +## 🔧 Управление + +### Проверка статуса + +```bash +# На сервере +ssh hunab-prod "docker ps | grep shadowsocks" + +# На клиенте (macOS CLI) +launchctl list | grep shadowsocks +``` + +### Просмотр логов + +```bash +# Сервер +ssh hunab-prod "docker logs hunab-vpn-shadowsocks" + +# Клиент (macOS) +tail -f /tmp/shadowsocks.log +tail -f /tmp/shadowsocks.error.log +``` + +### Перезапуск + +```bash +# Сервер +ssh hunab-prod "cd /opt/app && docker compose -f docker-compose.vpn-shadowsocks.yml restart" + +# Клиент (macOS) +launchctl unload ~/Library/LaunchAgents/com.shadowsocks.local.plist +launchctl load ~/Library/LaunchAgents/com.shadowsocks.local.plist +``` + +### Изменение пароля + +```bash +ssh hunab-prod +cd /opt/app/vpn/shadowsocks + +NEW_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25) +sed -i "s/\"password\": \".*\"/\"password\": \"${NEW_PASSWORD}\"/" config.json +docker restart hunab-vpn-shadowsocks +``` + +--- + +## 🧪 Тестирование + +### Проверка подключения + +```bash +# Через SOCKS5 прокси (macOS CLI) +curl --socks5 127.0.0.1:1080 ifconfig.me +# Должен показать: 209.38.32.21 + +# Прямое подключение +curl ifconfig.me +# Покажет ваш реальный IP +``` + +### Проверка через браузер + +1. Настройте системный прокси (см. выше) +2. Откройте: https://whatismyipaddress.com/ +3. Должен отображаться IP: **209.38.32.21** + +--- + +## 🔧 Решение проблем + +### Весь трафик не проходит через Shadowsocks + +**Используйте скрипты:** +```bash +cd docs/servers/vpn +./scripts/check-proxy-status.sh # Проверка статуса +./scripts/fix-shadowsocks.sh # Автоматическое исправление +``` + +**Ручная диагностика:** + +1. **Проверка Shadowsocks:** + ```bash + launchctl list | grep shadowsocks + curl --socks5 127.0.0.1:1080 ifconfig.me + ``` + +2. **Проверка системного прокси:** + ```bash + networksetup -getsocksfirewallproxy "Wi-Fi" + # Должно показать: Enabled: Yes, Server: 127.0.0.1, Port: 1080 + ``` + +3. **Настройка прокси:** + ```bash + INTERFACE=$(networksetup -listallnetworkservices | grep -E "Wi-Fi|Ethernet" | head -1) + networksetup -setsocksfirewallproxy "$INTERFACE" 127.0.0.1 1080 + networksetup -setsocksfirewallproxystate "$INTERFACE" on + ``` + +### Chrome не использует системный прокси + +1. **Отключите Chrome VPN расширение** (если активно) +2. **Проверьте настройки:** `chrome://settings/system` → "Use system proxy settings" +3. **Полностью закройте Chrome:** Cmd+Q (не просто закрыть окно) +4. **Откройте Chrome заново** + +### Прокси не работает + +1. Проверьте статус: + ```bash + launchctl list | grep shadowsocks + ``` + +2. Проверьте логи: + ```bash + cat /tmp/shadowsocks.error.log + ``` + +3. Перезапустите: + ```bash + launchctl unload ~/Library/LaunchAgents/com.shadowsocks.local.plist + launchctl load ~/Library/LaunchAgents/com.shadowsocks.local.plist + ``` + +### Порт 1080 занят + +1. Проверьте, что использует порт: + ```bash + lsof -i :1080 + ``` + +2. Измените порт в `~/.shadowsocks/config.json`: + ```json + "local_port": 1081 + ``` + +3. Обновите системный прокси на новый порт + +--- + +## 📊 Мониторинг + +### Использование ресурсов + +```bash +ssh hunab-prod "docker stats hunab-vpn-shadowsocks --no-stream" +``` + +### Активные подключения + +```bash +ssh hunab-prod "docker exec hunab-vpn-shadowsocks ss-server -c /etc/shadowsocks-libev/config.json -v" +``` + +--- + +## 🔒 Безопасность + +### Рекомендации + +1. ✅ **Используйте порт 443** для маскировки под HTTPS трафик +2. ✅ **Регулярно меняйте пароль** (каждые 1-3 месяца) +3. ✅ **Используйте современные методы шифрования** (`chacha20-ietf-poly1305`) +4. ✅ **Мониторинг трафика** - следите за использованием +5. ✅ **Обновляйте контейнер** регулярно + +--- + +## 🔗 Полезные ссылки + +- [Shadowsocks Official](https://shadowsocks.org/) +- [Shadowsocks Docker Image](https://hub.docker.com/r/shadowsocks/shadowsocks-libev) +- [Shadowsocks Clients](https://shadowsocks.org/en/download/clients.html) +- [Shadowsocks GitHub](https://github.com/shadowsocks/shadowsocks-libev) + +--- + +**Версия:** 2.0 +**Дата:** 2025-01-XX + diff --git a/docs/connectivity/vpn/WHONIX.md b/docs/connectivity/vpn/WHONIX.md new file mode 100644 index 0000000..193f486 --- /dev/null +++ b/docs/connectivity/vpn/WHONIX.md @@ -0,0 +1,167 @@ +# 🔐 Whonix - Полное руководство для Mac + +## 📋 Обзор + +Whonix - приватная операционная система для максимальной анонимности. Состоит из двух виртуальных машин: Gateway (шлюз через Tor) и Workstation (изолированная рабочая среда). + +--- + +## 🔧 Установка + +### Предварительные требования + +- macOS (Intel или Apple Silicon) +- Homebrew установлен +- Минимум 4 GB RAM свободно +- 20 GB свободного места на диске + +### Шаг 1: Установка VirtualBox + +**Для Intel Mac:** +```bash +brew install --cask virtualbox +``` + +**Для Apple Silicon (M1/M2/M3):** +VirtualBox не поддерживает эмуляцию x86 на Apple Silicon. Используйте: +- **UTM** (бесплатно): `brew install --cask utm` +- **Parallels Desktop** (платно, но лучше) + +### Шаг 2: Скачивание образов Whonix + +1. Перейдите на: https://www.whonix.org/wiki/Download +2. Скачайте: + - `Whonix-Gateway-*.ova` (~1.5 GB) + - `Whonix-Workstation-*.ova` (~2.5 GB) + +Сохраните в: `~/Downloads/whonix/` + +### Шаг 3: Импорт в VirtualBox + +**Через командную строку:** +```bash +VBoxManage import ~/Downloads/whonix/Whonix-Gateway-*.ova --vsys 0 --vmname "Whonix-Gateway" +VBoxManage import ~/Downloads/whonix/Whonix-Workstation-*.ova --vsys 0 --vmname "Whonix-Workstation" +``` + +**Через GUI:** +1. Откройте VirtualBox +2. File → Import Appliance +3. Выберите `.ova` файлы + +### Шаг 4: Настройка сети + +**Gateway:** +```bash +VBoxManage modifyvm "Whonix-Gateway" --nic1 nat --nic2 intnet --intnet2 "whonix" +``` + +**Workstation:** +```bash +VBoxManage modifyvm "Whonix-Workstation" --nic1 intnet --intnet1 "whonix" +``` + +--- + +## 🚀 Запуск Whonix + +**Важно: Правильный порядок запуска** + +1. **Сначала запустите Whonix-Gateway** + ```bash + VBoxManage startvm "Whonix-Gateway" --type gui + ``` + Дождитесь полной загрузки (появится рабочий стол) + +2. **Затем запустите Whonix-Workstation** + ```bash + VBoxManage startvm "Whonix-Workstation" --type gui + ``` + +--- + +## ✅ Валидация работы + +В Whonix-Workstation проверьте: + +1. **Проверка Tor:** + - Откройте: https://check.torproject.org + - Должно быть: "Congratulations. Your browser is configured to use Tor." + +2. **Проверка IP:** + - Откройте: https://whatismyipaddress.com + - IP должен быть из сети Tor (не ваш реальный IP) + +3. **Проверка DNS утечек:** + - Откройте: https://dnsleaktest.com + - Должны быть только DNS серверы Tor + +--- + +## 🍎 Apple Silicon (M1/M2/M3) + +### Проблема + +VirtualBox не поддерживает эмуляцию x86 на Apple Silicon. + +### Решение: UTM + +1. Установите UTM: + ```bash + brew install --cask utm + ``` + +2. Импортируйте Whonix в UTM: + - Откройте UTM + - Создать новую виртуальную машину + - Выберите "Virtualize" → "Linux" + - Импортируйте `.ova` файлы + - **Важно:** Выберите архитектуру **x86_64** (эмуляция) + +3. Настройте сеть: + - Gateway: NAT для интернета + - Workstation: Internal Network (shared с Gateway) + +**Производительность:** Будет медленнее чем на Intel Mac (эмуляция), но работает. + +### Альтернативы + +- **Parallels Desktop** - лучше производительность, но платно +- **Tails через USB** - нативная загрузка, быстрее +- **VPN + Tor Browser** - нативное приложение, самое быстрое + +--- + +## 🔧 Решение проблем + +### Gateway не запускается + +1. Проверьте логи VirtualBox +2. Проверьте настройки сети +3. Убедитесь, что VirtualBox установлен правильно + +### Workstation не может подключиться к интернету + +1. Убедитесь, что Gateway запущен и полностью загружен +2. Проверьте, что оба VM используют одну Internal Network "whonix" +3. Перезапустите обе VM + +### Медленная работа + +1. Увеличьте RAM для VM (минимум 2 GB каждая) +2. Увеличьте количество CPU ядер +3. Используйте SSD (не внешний диск) + +--- + +## 🔗 Полезные ссылки + +- [Whonix Official](https://www.whonix.org/) +- [Whonix Documentation](https://www.whonix.org/wiki/Documentation) +- [UTM Official](https://mac.getutm.app/) + +--- + +**Версия:** 2.0 +**Дата:** 2025-01-XX + diff --git a/docs/connectivity/vpn/WIREGUARD.md b/docs/connectivity/vpn/WIREGUARD.md new file mode 100644 index 0000000..fe669c6 --- /dev/null +++ b/docs/connectivity/vpn/WIREGUARD.md @@ -0,0 +1,199 @@ +# 🚀 WireGuard VPN - Полное руководство + +## 📋 Обзор + +WireGuard VPN позволяет подключаться к серверу 209.38.32.21 и использовать его как прокси для обхода интернет-ограничений. + +**Преимущества:** +- ✅ Современный протокол (state-of-the-art криптография) +- ✅ Очень быстрый (85-95% от пропускной способности) +- ✅ Простая настройка (минимум конфигурации) +- ✅ Полное туннелирование из коробки +- ✅ Низкое потребление ресурсов + +--- + +## 🔧 Развертывание сервера + +### Автоматическое развертывание + +```bash +bash scripts/deployment/deploy-vpn-wireguard.sh +``` + +Скрипт автоматически: +1. ✅ Проверит подключение к серверу +2. ✅ Создаст необходимые директории +3. ✅ Настроит Docker контейнер +4. ✅ Обновит firewall правила +5. ✅ Запустит VPN сервер +6. ✅ Создаст клиентскую конфигурацию + +### Ручное развертывание + +1. Подключитесь к серверу: `ssh hunab-prod` +2. Создайте директории: + ```bash + sudo mkdir -p /opt/app/vpn/wireguard/config + sudo chown -R hunab:hunab /opt/app/vpn + ``` +3. Создайте docker-compose файл +4. Запустите контейнер: `docker compose -f docker-compose.vpn.yml up -d` +5. Откройте порт: `sudo ufw allow 51820/udp comment 'WireGuard VPN'` + +--- + +## 📱 Настройка клиентов + +### Android / iOS + +1. Установите приложение **WireGuard** из Google Play / App Store +2. Нажмите **"+"** → **"Создать из файла или архива"** +3. Выберите файл `wireguard-peer1.conf` (созданный скриптом) +4. Нажмите **"Подключиться"** + +### Windows / macOS / Linux + +1. Установите WireGuard клиент: + - **Windows:** https://www.wireguard.com/install/ + - **macOS:** `brew install wireguard-tools` + - **Linux:** `sudo apt install wireguard` + +2. Импортируйте конфигурацию: + ```bash + # Linux/macOS + sudo cp wireguard-peer1.conf /etc/wireguard/wg0.conf + sudo wg-quick up wg0 + ``` + +--- + +## 🔍 Проверка подключения + +### На сервере + +```bash +# Проверка статуса контейнера +docker ps | grep hunab-vpn-wireguard + +# Просмотр логов +docker logs hunab-vpn-wireguard + +# Проверка подключенных клиентов +docker exec hunab-vpn-wireguard wg show +``` + +### На клиенте + +```bash +# Linux/macOS +sudo wg show + +# Проверка IP адреса +curl ifconfig.me +# Должен показать IP сервера 209.38.32.21 +``` + +--- + +## 🛠️ Управление + +### Добавление нового клиента + +```bash +ssh hunab-prod +cd /opt/app +docker compose -f docker-compose.vpn.yml down +# Измените PEERS=1 на PEERS=2 в docker-compose.vpn.yml +docker compose -f docker-compose.vpn.yml up -d +# Новый конфиг будет в /opt/app/vpn/wireguard/config/peer2/peer2.conf +``` + +### Остановка VPN + +```bash +ssh hunab-prod "cd /opt/app && docker compose -f docker-compose.vpn.yml down" +``` + +### Перезапуск VPN + +```bash +ssh hunab-prod "cd /opt/app && docker compose -f docker-compose.vpn.yml restart wireguard" +``` + +### Просмотр статистики + +```bash +ssh hunab-prod "docker exec hunab-vpn-wireguard wg show" +``` + +--- + +## 🔒 Безопасность + +### Рекомендации + +1. ✅ **Храните конфигурационные файлы в безопасности** +2. ✅ **Регулярно обновляйте ключи** (каждые 3-6 месяцев) +3. ✅ **Мониторинг трафика** +4. ✅ **Обновляйте контейнер** регулярно + +--- + +## 🐛 Решение проблем + +### VPN не подключается + +1. Проверьте статус контейнера: `docker ps | grep wireguard` +2. Проверьте логи: `docker logs hunab-vpn-wireguard` +3. Проверьте firewall: `sudo ufw status | grep 51820` +4. Проверьте порт: `sudo netstat -tuln | grep 51820` + +### Медленное подключение + +1. Проверьте задержку: `ping 209.38.32.21` +2. Проверьте нагрузку сервера: `docker stats hunab-vpn-wireguard` + +### Клиент не получает IP + +1. Проверьте конфигурацию: `sudo wg show` +2. Перезапустите VPN на сервере + +--- + +## 📊 Мониторинг + +### Просмотр активных подключений + +```bash +ssh hunab-prod "docker exec hunab-vpn-wireguard wg show" +``` + +### Просмотр трафика + +```bash +ssh hunab-prod "docker exec hunab-vpn-wireguard wg show wg0 transfer" +``` + +--- + +## 📝 Примечания + +- **Порт:** UDP 51820 (можно изменить) +- **Сеть VPN:** 10.13.13.0/24 (можно изменить) +- **Контейнер:** `hunab-vpn-wireguard` +- **Конфигурация:** `/opt/app/vpn/wireguard/config/` + +--- + +## 🔗 Полезные ссылки + +- [WireGuard Official](https://www.wireguard.com/) +- [WireGuard Docker Image](https://github.com/linuxserver/docker-wireguard) +- [WireGuard Client Apps](https://www.wireguard.com/install/) + +--- + +**Версия:** 2.0 +**Дата:** 2025-01-XX + diff --git a/docs/connectivity/vpn/WIREGUARD_RU_SERVER.md b/docs/connectivity/vpn/WIREGUARD_RU_SERVER.md new file mode 100644 index 0000000..2a32c96 --- /dev/null +++ b/docs/connectivity/vpn/WIREGUARD_RU_SERVER.md @@ -0,0 +1,167 @@ +# 🚀 WireGuard VPN на российском сервере (ru.hunab.app) + +## 📋 Обзор + +Развертывание WireGuard VPN на российском прокси-сервере для доступа из России. + +**Сервер:** 149.154.64.19 (ru.hunab.app) +**ОС:** Ubuntu 24.10 +**Архитектура:** Docker-based deployment + +--- + +## 🎯 Архитектура решения + +``` +[Android/iPhone] + ↓ +[WireGuard Client] + ↓ +[ru.hunab.app:51820] ← Российский сервер 149.154.64.19 (доступен из РФ) + ↓ +[209.38.32.21] ← Основной VPN сервер (опционально через туннель) + ↓ +[Интернет] +``` + +**Преимущества:** +- ✅ Доступен из России (российский IP) +- ✅ Стандартный WireGuard протокол +- ✅ Работает на всех платформах +- ✅ Не требует специальных клиентов +- ✅ Элегантная архитектура + +--- + +## 🔧 Развертывание на российском сервере + +### Автоматическое развертывание + +```bash +# Подключитесь к российскому серверу +ssh ahau@149.154.64.19 +# Пароль: w99z2fBSkO4gU + +# Создайте директории +sudo mkdir -p /opt/app/vpn/wireguard/config +sudo chown -R ahau:ahau /opt/app/vpn + +# Разверните WireGuard через Docker +cd /opt/app/vpn/wireguard +docker run -d \ + --name hunab-vpn-wireguard-ru \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 \ + -e SERVERPORT=51820 \ + -e PEERS=1 \ + -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 \ + -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp \ + --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped \ + linuxserver/wireguard:latest +``` + +### Настройка Firewall + +```bash +# Откройте порт WireGuard +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' +sudo ufw reload +``` + +### Проверка развертывания + +```bash +# Проверка контейнера +docker ps | grep wireguard + +# Просмотр логов +docker logs hunab-vpn-wireguard-ru + +# Проверка конфигурации клиента +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf +``` + +--- + +## 📱 Получение конфигурации для Android + +### Способ 1: Скачать с сервера + +```bash +# С вашего компьютера +scp ahau@149.154.64.19:/opt/app/vpn/wireguard/config/peer1/peer1.conf ./wg-ru.conf +``` + +### Способ 2: Просмотреть и скопировать + +```bash +ssh ahau@149.154.64.19 "cat /opt/app/vpn/wireguard/config/peer1/peer1.conf" +``` + +--- + +## 🔄 Альтернатива: Туннелирование через российский сервер + +Если не хотите разворачивать отдельный WireGuard на российском сервере, можно настроить туннелирование: + +### Вариант A: WireGuard через SSH туннель + +```bash +# На вашем компьютере создайте SSH туннель +ssh -L 51820:209.38.32.21:51820 -N ahau@149.154.64.19 + +# В конфигурации WireGuard измените Endpoint: +# Endpoint = 127.0.0.1:51820 +``` + +### Вариант B: WireProxy (если нужен SOCKS5) + +WireProxy позволяет использовать WireGuard через SOCKS5 прокси, но требует установки дополнительного ПО на клиенте. + +--- + +## 📊 Сравнение вариантов + +| Критерий | Вариант 1 (WireGuard на RU) | Вариант 2 (SSH туннель) | +|----------|----------------------------|-------------------------| +| **Простота** | ✅ Просто | ⚠️ Требует SSH туннель | +| **Производительность** | ✅ Высокая | ⚠️ Средняя | +| **Мобильность** | ✅ Работает везде | ❌ Требует SSH клиент | +| **Надежность** | ✅ Стабильно | ⚠️ Зависит от SSH | +| **Рекомендация** | ✅ **Лучший выбор** | Для временного решения | + +--- + +## 🎯 Рекомендуемое решение + +**Развернуть WireGuard на российском сервере (Вариант 1)** - это самое элегантное и надежное решение: + +1. ✅ Стандартный протокол WireGuard +2. ✅ Работает на всех устройствах (Android, iOS, macOS, Windows) +3. ✅ Не требует дополнительных туннелей +4. ✅ Высокая производительность +5. ✅ Простая настройка клиентов + +--- + +## 📝 Следующие шаги + +1. Разверните WireGuard на `149.154.64.19` +2. Получите конфигурацию клиента +3. Импортируйте в WireGuard на Android +4. Проверьте подключение + +--- + +## 🔗 Связанная документация + +- [WireGuard общее руководство](./WIREGUARD.md) +- [Доступ к российскому серверу](./RU_PROXY_SERVER_ACCESS.md) +- [Оптимизация хотспота](../hotspot/HOTSPOT_OPTIMIZATION.md) diff --git a/docs/connectivity/vpn/deploy-now.sh b/docs/connectivity/vpn/deploy-now.sh new file mode 100755 index 0000000..d55af5d --- /dev/null +++ b/docs/connectivity/vpn/deploy-now.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# Быстрое развертывание WireGuard на 149.154.64.19 +# Использование: ./docs/vpn/deploy-now.sh + +set -e + +SERVER="ahau@149.154.64.19" +PASSWORD="w99z2fBSkO4gU" + +echo "🚀 Развертывание WireGuard на ru.hunab.app (149.154.64.19)" +echo "📝 Пароль: $PASSWORD" +echo "" + +echo "Выполняю команду на сервере..." +echo "Пожалуйста, введите пароль когда потребуется: $PASSWORD" +echo "" + +ssh $SERVER << 'EOF' +set -e + +echo "1. Создание директорий..." +sudo mkdir -p /opt/app/vpn/wireguard/config +sudo chown -R ahau:ahau /opt/app/vpn + +echo "2. Остановка старых контейнеров..." +docker stop hunab-vpn-wireguard-ru 2>/dev/null || true +docker rm hunab-vpn-wireguard-ru 2>/dev/null || true + +echo "3. Запуск WireGuard..." +cd /opt/app/vpn/wireguard +docker run -d \ + --name hunab-vpn-wireguard-ru \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 \ + -e SERVERPORT=51820 \ + -e PEERS=1 \ + -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 \ + -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp \ + --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped \ + linuxserver/wireguard:latest + +echo "4. Ожидание создания конфигурации (45 секунд)..." +sleep 45 + +echo "5. Настройка Firewall..." +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' 2>/dev/null || true +sudo ufw reload 2>/dev/null || true + +echo "" +echo "✅ Развертывание завершено!" +echo "" +echo "=== КОНФИГУРАЦИЯ КЛИЕНТА ===" +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf +echo "===========================" +EOF + +echo "" +echo "📥 Теперь получаю конфигурацию..." +scp $SERVER:/opt/app/vpn/wireguard/config/peer1/peer1.conf docs/vpn/RuVPN.conf + +if [ -f docs/vpn/RuVPN.conf ]; then + echo "" + echo "✅ Конфигурация сохранена в docs/vpn/RuVPN.conf" + echo "" + echo "📱 Импортируйте файл RuVPN.conf в WireGuard на телефоне!" + echo "" + cat docs/vpn/RuVPN.conf +else + echo "" + echo "⚠️ Не удалось скопировать конфигурацию автоматически" + echo "Выполните вручную:" + echo " scp $SERVER:/opt/app/vpn/wireguard/config/peer1/peer1.conf docs/vpn/RuVPN.conf" +fi + + + diff --git a/docs/connectivity/vpn/scripts/check-proxy-status.sh b/docs/connectivity/vpn/scripts/check-proxy-status.sh new file mode 100755 index 0000000..69b8682 --- /dev/null +++ b/docs/connectivity/vpn/scripts/check-proxy-status.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +echo "=== СТАТУС ПРОКСИ ===" +echo "" + +# Проверка Shadowsocks +echo "1. Shadowsocks сервис:" +if launchctl list | grep -q shadowsocks; then + echo " ✅ Запущен" +else + echo " ❌ Не запущен" +fi + +# Проверка порта +echo "" +echo "2. Порт 1080:" +if lsof -i :1080 | grep -q LISTEN; then + echo " ✅ Слушает" +else + echo " ❌ Не слушает" +fi + +# Проверка системного прокси +echo "" +echo "3. Системный прокси:" +INTERFACE=$(networksetup -listallnetworkservices | grep -E "Wi-Fi|Ethernet" | head -1) +PROXY_STATUS=$(networksetup -getsocksfirewallproxy "$INTERFACE" | grep "Enabled:" | awk '{print $2}') +if [ "$PROXY_STATUS" = "Yes" ]; then + SERVER=$(networksetup -getsocksfirewallproxy "$INTERFACE" | grep "Server:" | awk '{print $2}') + PORT=$(networksetup -getsocksfirewallproxy "$INTERFACE" | grep "Port:" | awk '{print $2}') + echo " ✅ Включен: $SERVER:$PORT" +else + echo " ❌ Выключен" +fi + +# Проверка через curl +echo "" +echo "4. Тест подключения:" +SS_IP=$(curl -s --socks5 127.0.0.1:1080 --max-time 5 ifconfig.me 2>/dev/null) +DIRECT_IP=$(curl -s --max-time 5 ifconfig.me 2>/dev/null) + +if [ -n "$SS_IP" ]; then + echo " Через Shadowsocks: $SS_IP" + if [ "$SS_IP" = "209.38.32.21" ]; then + echo " ✅ Правильный IP" + else + echo " ⚠️ Неправильный IP" + fi +else + echo " ❌ Shadowsocks не отвечает" +fi + +if [ -n "$DIRECT_IP" ]; then + echo " Прямое подключение: $DIRECT_IP" +fi + +echo "" +echo "=== РЕКОМЕНДАЦИИ ===" +if [ "$PROXY_STATUS" != "Yes" ]; then + echo "❌ Включите системный прокси: toggle-shadowsocks-proxy.sh" +fi +if [ -z "$SS_IP" ] || [ "$SS_IP" != "209.38.32.21" ]; then + echo "❌ Shadowsocks не работает, проверьте: launchctl list | grep shadowsocks" +fi diff --git a/docs/connectivity/vpn/scripts/deploy-wg-ru-simple.sh b/docs/connectivity/vpn/scripts/deploy-wg-ru-simple.sh new file mode 100644 index 0000000..a63d01d --- /dev/null +++ b/docs/connectivity/vpn/scripts/deploy-wg-ru-simple.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# Простые команды для развертывания WireGuard на ru.hunab.app +# Выполните эти команды в SSH сеансе на сервере + +echo "=== Шаг 1: Создание директорий ===" +sudo mkdir -p /opt/app/vpn/wireguard/config +sudo chown -R ahau:ahau /opt/app/vpn +echo "✅ Готово" + +echo "" +echo "=== Шаг 2: Остановка старых контейнеров ===" +docker stop hunab-vpn-wireguard-ru 2>/dev/null || true +docker rm hunab-vpn-wireguard-ru 2>/dev/null || true +echo "✅ Готово" + +echo "" +echo "=== Шаг 3: Запуск WireGuard ===" +cd /opt/app/vpn/wireguard + +docker run -d \ + --name hunab-vpn-wireguard-ru \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 \ + -e SERVERPORT=51820 \ + -e PEERS=1 \ + -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 \ + -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp \ + --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped \ + linuxserver/wireguard:latest + +echo "✅ Контейнер запущен" + +echo "" +echo "=== Шаг 4: Ожидание создания конфигурации (45 секунд) ===" +sleep 45 + +echo "" +echo "=== Шаг 5: Настройка Firewall ===" +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' +sudo ufw reload +echo "✅ Готово" + +echo "" +echo "=== Шаг 6: Проверка статуса ===" +docker ps | grep wireguard + +echo "" +echo "=== Шаг 7: Конфигурация клиента ===" +echo "---" +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf +echo "---" + +echo "" +echo "✅ Готово! Скопируйте конфигурацию выше в файл wg-ru.conf" diff --git a/docs/connectivity/vpn/scripts/deploy-wireguard-ru-manual.sh b/docs/connectivity/vpn/scripts/deploy-wireguard-ru-manual.sh new file mode 100644 index 0000000..e6c6f99 --- /dev/null +++ b/docs/connectivity/vpn/scripts/deploy-wireguard-ru-manual.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Инструкция для ручного развертывания WireGuard на ru.hunab.app +# Скопируйте и выполните эти команды на российском сервере + +echo "=== Команды для развертывания WireGuard на ru.hunab.app ===" +echo "" +echo "1. Подключитесь к серверу:" +echo " ssh ahau@149.154.64.19" +echo " Пароль: w99z2fBSkO4gU" +echo "" +echo "2. Выполните следующие команды на сервере:" +echo "" +cat << 'COMMANDS' +# Создание директорий +sudo mkdir -p /opt/app/vpn/wireguard/config +sudo chown -R ahau:ahau /opt/app/vpn + +# Остановка и удаление существующего контейнера (если есть) +docker stop hunab-vpn-wireguard-ru 2>/dev/null || true +docker rm hunab-vpn-wireguard-ru 2>/dev/null || true + +# Запуск WireGuard контейнера +cd /opt/app/vpn/wireguard + +docker run -d \ + --name hunab-vpn-wireguard-ru \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 \ + -e SERVERPORT=51820 \ + -e PEERS=1 \ + -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 \ + -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp \ + --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped \ + linuxserver/wireguard:latest + +# Ожидание создания конфигурации +echo "Ожидание 30 секунд..." +sleep 30 + +# Настройка Firewall +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' +sudo ufw reload + +# Проверка статуса +docker ps | grep wireguard + +# Просмотр конфигурации клиента +echo "=== Конфигурация клиента ===" +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf +COMMANDS + +echo "" +echo "3. После выполнения команд на сервере, скопируйте конфигурацию:" +echo " scp ahau@149.154.64.19:/opt/app/vpn/wireguard/config/peer1/peer1.conf docs/vpn/wg-ru.conf" +echo "" +echo " Или просмотрите и скопируйте вручную:" +echo " ssh ahau@149.154.64.19 'cat /opt/app/vpn/wireguard/config/peer1/peer1.conf'" diff --git a/docs/connectivity/vpn/scripts/deploy-wireguard-ru.sh b/docs/connectivity/vpn/scripts/deploy-wireguard-ru.sh new file mode 100755 index 0000000..64697eb --- /dev/null +++ b/docs/connectivity/vpn/scripts/deploy-wireguard-ru.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# Скрипт развертывания WireGuard на российском сервере ru.hunab.app + +set -e + +echo "=== Развертывание WireGuard на ru.hunab.app ===" +echo "" + +# Параметры подключения +RU_SERVER="ahau@149.154.64.19" +RU_IP="149.154.64.19" + +echo "1. Подключение к серверу $RU_SERVER..." +echo " (Введите пароль: w99z2fBSkO4gU)" +echo "" + +# Создание директорий +ssh $RU_SERVER << 'EOF' +set -e + +echo "2. Создание директорий..." +sudo mkdir -p /opt/app/vpn/wireguard/config +sudo chown -R ahau:ahau /opt/app/vpn +echo " ✅ Директории созданы" + +echo "" +echo "3. Проверка существующих контейнеров..." +if docker ps -a | grep -q hunab-vpn-wireguard-ru; then + echo " ⚠️ Контейнер уже существует, останавливаем..." + docker stop hunab-vpn-wireguard-ru 2>/dev/null || true + docker rm hunab-vpn-wireguard-ru 2>/dev/null || true +fi + +echo "" +echo "4. Запуск WireGuard контейнера..." +cd /opt/app/vpn/wireguard + +docker run -d \ + --name hunab-vpn-wireguard-ru \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 \ + -e SERVERPORT=51820 \ + -e PEERS=1 \ + -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 \ + -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp \ + --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped \ + linuxserver/wireguard:latest + +echo " ✅ Контейнер запущен" + +echo "" +echo "5. Ожидание создания конфигурации (30 секунд)..." +sleep 30 + +echo "" +echo "6. Настройка Firewall..." +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' 2>/dev/null || true +sudo ufw reload 2>/dev/null || true +echo " ✅ Firewall настроен" + +echo "" +echo "7. Проверка статуса..." +docker ps | grep wireguard || echo " ⚠️ Контейнер не найден в списке" + +echo "" +echo "8. Конфигурация клиента:" +echo "---" +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf 2>/dev/null || echo " ⚠️ Конфигурация еще не создана, подождите еще 30 секунд" +echo "---" + +EOF + +echo "" +echo "✅ Развертывание завершено!" +echo "" +echo "Следующие шаги:" +echo "1. Скопируйте конфигурацию:" +echo " scp $RU_SERVER:/opt/app/vpn/wireguard/config/peer1/peer1.conf docs/vpn/wg-ru.conf" +echo "" +echo "2. Или просмотрите конфигурацию:" +echo " ssh $RU_SERVER 'cat /opt/app/vpn/wireguard/config/peer1/peer1.conf'" diff --git a/docs/connectivity/vpn/scripts/enable-shadowsocks-full.sh b/docs/connectivity/vpn/scripts/enable-shadowsocks-full.sh new file mode 100755 index 0000000..50e8fd3 --- /dev/null +++ b/docs/connectivity/vpn/scripts/enable-shadowsocks-full.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +echo "=== ВКЛЮЧЕНИЕ SHADOWSOCKS ДЛЯ ВСЕГО ТРАФИКА ===" +echo "" + +# 1. Убедиться, что Shadowsocks запущен +echo "1. Проверка Shadowsocks..." +if ! launchctl list | grep -q shadowsocks; then + echo " Запуск Shadowsocks..." + launchctl load ~/Library/LaunchAgents/com.shadowsocks.local.plist + sleep 3 +fi + +if launchctl list | grep -q shadowsocks; then + echo " ✅ Shadowsocks запущен" +else + echo " ❌ Ошибка: Shadowsocks не запускается" + exit 1 +fi + +# 2. Проверка работы +echo "" +echo "2. Проверка подключения..." +SS_IP=$(curl -s --socks5 127.0.0.1:1080 --max-time 5 ifconfig.me 2>/dev/null) +if [ "$SS_IP" = "209.38.32.21" ]; then + echo " ✅ Shadowsocks работает: IP = $SS_IP" +else + echo " ❌ Shadowsocks не работает правильно" + echo " Проверьте логи: tail -f /tmp/shadowsocks.error.log" + exit 1 +fi + +# 3. Настройка системного прокси +echo "" +echo "3. Настройка системного прокси..." +INTERFACE=$(networksetup -listallnetworkservices | grep -E "Wi-Fi|Ethernet" | head -1) +echo " Интерфейс: $INTERFACE" + +# Установить прокси +networksetup -setsocksfirewallproxy "$INTERFACE" 127.0.0.1 1080 +sleep 1 + +# Включить прокси +networksetup -setsocksfirewallproxystate "$INTERFACE" on +sleep 1 + +# Проверка +PROXY_STATUS=$(networksetup -getsocksfirewallproxy "$INTERFACE" | grep "Enabled:" | awk '{print $2}') +if [ "$PROXY_STATUS" = "Yes" ]; then + SERVER=$(networksetup -getsocksfirewallproxy "$INTERFACE" | grep "Server:" | awk '{print $2}') + PORT=$(networksetup -getsocksfirewallproxy "$INTERFACE" | grep "Port:" | awk '{print $2}') + echo " ✅ Системный прокси включен: $SERVER:$PORT" +else + echo " ❌ Ошибка: Системный прокси не включен" + echo " Попробуйте вручную: System Settings → Network → Proxies" + exit 1 +fi + +echo "" +echo "✅ SHADOWSOCKS ВКЛЮЧЕН ДЛЯ ВСЕГО ТРАФИКА!" +echo "" +echo "📋 ВАЖНО:" +echo "1. ОТКЛЮЧИТЕ Chrome VPN расширение (если активно)" +echo "2. ПОЛНОСТЬЮ закройте Chrome (Cmd+Q, не просто закрыть окно)" +echo "3. Откройте Chrome заново" +echo "4. Проверьте IP: https://whatismyipaddress.com/" +echo " Должен показать: 209.38.32.21" +echo "" +echo "💡 Если не работает, проверьте:" +echo " - Chrome Settings → System → Use system proxy settings" +echo " - Отключите все VPN расширения в Chrome" diff --git a/docs/connectivity/vpn/scripts/fix-shadowsocks.sh b/docs/connectivity/vpn/scripts/fix-shadowsocks.sh new file mode 100755 index 0000000..d476bb5 --- /dev/null +++ b/docs/connectivity/vpn/scripts/fix-shadowsocks.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +echo "=== ИСПРАВЛЕНИЕ SHADOWSOCKS ===" +echo "" + +# 1. Проверка и перезапуск Shadowsocks +echo "1. Перезапуск Shadowsocks..." +launchctl unload ~/Library/LaunchAgents/com.shadowsocks.local.plist 2>/dev/null +sleep 1 +launchctl load ~/Library/LaunchAgents/com.shadowsocks.local.plist +sleep 2 + +if launchctl list | grep -q shadowsocks; then + echo " ✅ Shadowsocks запущен" +else + echo " ❌ Ошибка запуска Shadowsocks" + exit 1 +fi + +# 2. Настройка системного прокси +echo "" +echo "2. Настройка системного прокси..." +INTERFACE=$(networksetup -listallnetworkservices | grep -E "Wi-Fi|Ethernet" | head -1) +networksetup -setsocksfirewallproxy "$INTERFACE" 127.0.0.1 1080 +networksetup -setsocksfirewallproxystate "$INTERFACE" on + +PROXY_STATUS=$(networksetup -getsocksfirewallproxy "$INTERFACE" | grep "Enabled:" | awk '{print $2}') +if [ "$PROXY_STATUS" = "Yes" ]; then + echo " ✅ Системный прокси включен" +else + echo " ❌ Ошибка настройки прокси" + exit 1 +fi + +# 3. Проверка +echo "" +echo "3. Проверка подключения..." +sleep 2 +SS_IP=$(curl -s --socks5 127.0.0.1:1080 --max-time 5 ifconfig.me 2>/dev/null) + +if [ -n "$SS_IP" ] && [ "$SS_IP" = "209.38.32.21" ]; then + echo " ✅ Shadowsocks работает: IP = $SS_IP" + echo "" + echo "✅ ВСЕ ИСПРАВЛЕНО!" + echo "" + echo "📋 Следующие шаги:" + echo "1. Полностью закройте Chrome (Cmd+Q)" + echo "2. Откройте Chrome заново" + echo "3. Проверьте IP: https://whatismyipaddress.com/" + echo " Должен показать: 209.38.32.21" +else + echo " ⚠️ Shadowsocks не отвечает правильно" + echo " Проверьте логи: tail -f /tmp/shadowsocks.error.log" +fi diff --git a/docs/connectivity/vpn/scripts/get-wg-ru-config.sh b/docs/connectivity/vpn/scripts/get-wg-ru-config.sh new file mode 100755 index 0000000..ee8fe2a --- /dev/null +++ b/docs/connectivity/vpn/scripts/get-wg-ru-config.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Скрипт для получения конфигурации WireGuard с ru.hunab.app +# Использование: ./get-wg-ru-config.sh + +SERVER="ahau@149.154.64.19" +CONFIG_PATH="/opt/app/vpn/wireguard/config/peer1/peer1.conf" +OUTPUT_FILE="docs/vpn/wg-ru.conf" + +echo "Получение конфигурации WireGuard с $SERVER..." +scp "$SERVER:$CONFIG_PATH" "$OUTPUT_FILE" 2>/dev/null + +if [ -f "$OUTPUT_FILE" ] && [ -s "$OUTPUT_FILE" ]; then + echo "✅ Конфигурация получена: $OUTPUT_FILE" + echo "" + echo "=== Содержимое конфигурации ===" + cat "$OUTPUT_FILE" +else + echo "⚠️ Конфигурация не найдена на сервере" + echo "Сначала выполните развертывание на сервере:" + echo " cat docs/vpn/ONE_LINE_DEPLOY.txt | ssh $SERVER" +fi diff --git a/docs/connectivity/vpn/scripts/toggle-shadowsocks-proxy.sh b/docs/connectivity/vpn/scripts/toggle-shadowsocks-proxy.sh new file mode 100755 index 0000000..1fbfc4d --- /dev/null +++ b/docs/connectivity/vpn/scripts/toggle-shadowsocks-proxy.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Скрипт для переключения системного прокси Shadowsocks + +INTERFACE=$(networksetup -listallnetworkservices | grep -E "Wi-Fi|Ethernet" | head -1) +CURRENT_STATE=$(networksetup -getsocksfirewallproxy "$INTERFACE" | grep "Enabled:" | awk '{print $2}') + +if [ "$CURRENT_STATE" = "Yes" ]; then + # Выключить прокси + networksetup -setsocksfirewallproxystate "$INTERFACE" off + echo "❌ Shadowsocks прокси ВЫКЛЮЧЕН" + echo " Теперь можно использовать Chrome VPN" +else + # Включить прокси + networksetup -setsocksfirewallproxy "$INTERFACE" 127.0.0.1 1080 + networksetup -setsocksfirewallproxystate "$INTERFACE" on + echo "✅ Shadowsocks прокси ВКЛЮЧЕН" + echo " IP: 209.38.32.21" +fi + +echo "" +echo "Текущий статус:" +networksetup -getsocksfirewallproxy "$INTERFACE" diff --git a/docs/connectivity/vpn/scripts/wg-ru-deploy.sh b/docs/connectivity/vpn/scripts/wg-ru-deploy.sh new file mode 100644 index 0000000..ad67687 --- /dev/null +++ b/docs/connectivity/vpn/scripts/wg-ru-deploy.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Скопируйте и выполните эту команду в SSH сеансе на ru.hunab.app + +sudo mkdir -p /opt/app/vpn/wireguard/config && sudo chown -R ahau:ahau /opt/app/vpn && \ +docker stop hunab-vpn-wireguard-ru 2>/dev/null; docker rm hunab-vpn-wireguard-ru 2>/dev/null; \ +cd /opt/app/vpn/wireguard && \ +docker run -d --name hunab-vpn-wireguard-ru --cap-add=NET_ADMIN --cap-add=SYS_MODULE \ + -e PUID=1000 -e PGID=1000 -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 -e SERVERPORT=51820 -e PEERS=1 -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped linuxserver/wireguard:latest && \ +echo "Ожидание 45 секунд..." && sleep 45 && \ +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' && sudo ufw reload && \ +echo "=== КОНФИГУРАЦИЯ ===" && \ +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf diff --git a/docs/connectivity/vpn/setup-and-deploy.sh b/docs/connectivity/vpn/setup-and-deploy.sh new file mode 100755 index 0000000..8ff19fb --- /dev/null +++ b/docs/connectivity/vpn/setup-and-deploy.sh @@ -0,0 +1,119 @@ +#!/bin/bash +# Настройка SSH ключа и развертывание WireGuard на 149.154.64.19 + +set -e + +SERVER="ahau@149.154.64.19" +KEY_FILE="$HOME/.ssh/ru_server_key" +PUB_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDJ48JZfUVwmVILkNsOqrmywqxCOK3zkxU3+2Z8G01RR ru.hunab.app" + +echo "🔐 Настройка SSH и развертывание WireGuard" +echo "═══════════════════════════════════════════" +echo "" + +# Шаг 1: Проверка подключения с ключом +echo "1️⃣ Проверяю существующее подключение..." +if ssh -i "$KEY_FILE" -o PreferredAuthentications=publickey -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$SERVER" "exit" 2>/dev/null; then + echo "✅ SSH ключ уже настроен!" +else + echo "⚠️ SSH ключ не настроен, добавляю..." + echo "" + echo "📝 Введите пароль: w99z2fBSkO4gU" + echo "" + + # Добавляем ключ на сервер + ssh-copy-id -i "$KEY_FILE.pub" "$SERVER" || { + echo "" + echo "⚠️ Автоматическое добавление не сработало. Добавляю вручную..." + cat "$KEY_FILE.pub" | ssh "$SERVER" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" + } + + echo "" + echo "✅ SSH ключ добавлен!" +fi + +echo "" +echo "2️⃣ Проверяю подключение с ключом..." +if ssh -i "$KEY_FILE" -o PreferredAuthentications=publickey -o ConnectTimeout=5 "$SERVER" "echo '✅ Подключение работает!'" 2>/dev/null; then + echo "✅ SSH ключ работает!" +else + echo "❌ Не удалось подключиться с ключом" + exit 1 +fi + +echo "" +echo "3️⃣ Развертывание WireGuard на сервере..." +echo "" + +ssh -i "$KEY_FILE" "$SERVER" << 'ENDSSH' +set -e + +echo " 📁 Создание директорий..." +sudo mkdir -p /opt/app/vpn/wireguard/config +sudo chown -R ahau:ahau /opt/app/vpn + +echo " 🛑 Остановка старых контейнеров..." +docker stop hunab-vpn-wireguard-ru 2>/dev/null || true +docker rm hunab-vpn-wireguard-ru 2>/dev/null || true + +echo " 🚀 Запуск WireGuard контейнера..." +cd /opt/app/vpn/wireguard +docker run -d \ + --name hunab-vpn-wireguard-ru \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/Moscow \ + -e SERVERURL=149.154.64.19 \ + -e SERVERPORT=51820 \ + -e PEERS=1 \ + -e PEERDNS=8.8.8.8 \ + -e INTERNAL_SUBNET=10.14.14.0 \ + -v /opt/app/vpn/wireguard/config:/config \ + -p 51820:51820/udp \ + --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ + --restart unless-stopped \ + linuxserver/wireguard:latest > /dev/null + +echo " ⏳ Ожидание создания конфигурации (45 секунд)..." +sleep 45 + +echo " 🔥 Настройка Firewall..." +sudo ufw allow 51820/udp comment 'WireGuard VPN RU' 2>/dev/null || true +sudo ufw reload 2>/dev/null || true + +echo "" +echo " ✅ WireGuard развернут и запущен!" +echo "" +docker ps | grep wireguard + +echo "" +echo " 📄 Конфигурация клиента:" +echo " ═══════════════════════════════" +cat /opt/app/vpn/wireguard/config/peer1/peer1.conf +echo " ═══════════════════════════════" +ENDSSH + +echo "" +echo "4️⃣ Получение конфигурации..." +scp -i "$KEY_FILE" "$SERVER:/opt/app/vpn/wireguard/config/peer1/peer1.conf" docs/vpn/RuVPN.conf + +if [ -f docs/vpn/RuVPN.conf ]; then + echo "" + echo "✅ Конфигурация сохранена в docs/vpn/RuVPN.conf" + echo "" + echo "═══════════════════════════════════════════" + echo "📱 ГОТОВО! Импортируйте файл на телефон:" + echo "═══════════════════════════════════════════" + echo "" + cat docs/vpn/RuVPN.conf + echo "" + echo "🎉 Всё готово! Подключайтесь через WireGuard!" +else + echo "" + echo "⚠️ Не удалось скопировать конфигурацию" +fi + + + diff --git a/docs/cursor/README.md b/docs/cursor/README.md new file mode 100644 index 0000000..43da18c --- /dev/null +++ b/docs/cursor/README.md @@ -0,0 +1,214 @@ +# Cursor IDE — работа из РФ и обход PING timeout + +> **Проблема:** из России Cursor показывает `PING timed out`, Agent не отвечает. +> **Временный обход:** Disable Http2 в настройках — помогает, но всё сильно замедляется. +> **Рекомендуемое решение:** SOCKS-прокси через SSH-туннель на сервер с нормальным доступом (DO / RU VPS), без отключения HTTP/2. + +**Связанные гайды:** [PROXY_GUIDE.md](../../connectivity/PROXY_GUIDE.md), [BUILD_AAB_FROM_RUSSIA_GUIDE.md](../../connectivity/BUILD_AAB_FROM_RUSSIA_GUIDE.md) — тот же паттерн «туннель через прокси-сервер». + +--- + +## Содержание + +1. [Симптомы и причина](#-симптомы-и-причина) +2. [Обход 1: Disable Http2 (простой, но медленный)](#-обход-1-disable-http2-простой-но-медленный) +3. [Обход 2: SOCKS через SSH-туннель (рекомендуется)](#-обход-2-socks-через-ssh-туннель-рекомендуется) +4. [Проверка и диагностика](#-проверка-и-диагностика) +5. [Troubleshooting](#-troubleshooting) +6. [Ссылки](#-ссылки) + +--- + +## Симптомы и причина + +### Что видно в Cursor + +- В чате с Agent: **Request ID: … [unavailable] PING timed out**, `_he: [unavailable] PING timed out`. +- Стек указывает на `workbench.desktop.main.js`, `streamFromAgentBackend` / `getAgentStreamResponse` — обрыв связи с бэкендом агента. + +### Почему так происходит + +1. **HTTP/2 и маршрутизация** + Cursor использует HTTP/2 для стриминга к `*.cursor.sh` (в т.ч. `agent.api5.cursor.sh`). В части сетей (в т.ч. из РФ) запросы уходят в CDN (например Cloudflare) с неудачной конфигурацией SSL/HTTP2 или блокировкой по DPI, из‑за чего соединение обрывается или уходит в таймаут. + +2. **Disable Http2** + Отключение HTTP/2 переводит трафик на HTTP/1.1 и часто убирает обрывы, но увеличивает нагрузку и задержки — «всё становится медленным», возможны дополнительные таймауты агента. + +3. **Идея нормального обхода** + Пропускать только трафик Cursor через сервер с хорошим доступом к Cursor API (VPS в DO, РФ и т.п.). До этого сервера — SSH (обычно не режется). От сервера до `*.cursor.sh` — уже «нормальный» канал, HTTP/2 работает без костылей. + +--- + +## Обход 1: Disable Http2 (простой, но медленный) + +Если нужно быстро восстановить работу без настройки туннеля: + +1. **Cursor → Settings** (Cmd+, / Ctrl+,). +2. Поиск: **HTTP**. +3. Включить **Cursor > General: Disable Http2**. + +Минус: выше задержки и нагрузка, возможны таймауты агента при длинных ответах. Для постоянной работы из РФ предпочтительно [Обход 2](#-обход-2-socks-через-ssh-туннель-рекомендуется). + +--- + +## Обход 2: SOCKS через SSH-туннель (рекомендуется) + +Трафик Cursor идёт в интернет через ваш VPS. До VPS — SSH (один порт), с VPS — обычный доступ к Cursor API, HTTP/2 остаётся включённым. + +### Схема + +``` +Cursor (macOS) → SOCKS 127.0.0.1:10809 → SSH-туннель → VPS (DO/RU) + ↓ + HTTPS/HTTP2 → *.cursor.sh +``` + +На VPS не нужны отдельные прокси-сервисы — достаточно SSH (как в [PROXY_GUIDE](../../connectivity/PROXY_GUIDE.md) и [BUILD_AAB_FROM_RUSSIA_GUIDE](../../connectivity/BUILD_AAB_FROM_RUSSIA_GUIDE.md)). + +### Предположения + +- Есть VPS с нормальным доступом к интернету (например, тот же, что для ru.hunab.app: **149.154.64.19**, доступ по `ssh hsites-ahau` или аналог). +- Локально свободен порт для SOCKS (ниже — **10809**, чтобы не пересекаться с другими прокси). + +### Шаг 1: Поднять SOCKS-туннель + +```bash +# Убить старый туннель на порту 10809 (если был) +pkill -f "ssh.*-D 10809" 2>/dev/null + +# Запуск SOCKS5 на 127.0.0.1:10809 через ваш VPS +ssh -D 10809 -f -N hsites-ahau +``` + +Если используете другой хост (например, hunab-prod): + +```bash +ssh -D 10809 -f -N hunab-prod +``` + +Проверка: туннель держится, пока сессия не разорвана; можно проверить доступ через SOCKS (см. [Проверка и диагностика](#-проверка-и-диагностика)). + +### Шаг 2: Настроить Cursor на использование SOCKS + +1. **Cursor → Settings** (Cmd+, / Ctrl+,), поиск: **proxy**. +2. Заполнить: + - **Http: Proxy** — `socks5://127.0.0.1:10809` + - **Http: Proxy Strict SSL** — при необходимости отключить только если заведомо знаете, что за прокси (для одного своего VPS обычно не требуется). + +Или в `settings.json` (Cursor: Open User Settings (JSON)): + +```json +{ + "http.proxy": "socks5://127.0.0.1:10809", + "https.proxy": "socks5://127.0.0.1:10809" +} +``` + +### Шаг 3: Не отключать HTTP/2 + +**Cursor > General: Disable Http2** — выключить (оставить HTTP/2 включённым). Весь трафик к Cursor API пойдёт с VPS, где HTTP/2 работает нормально. + +### Шаг 4: Запуск Cursor при уже поднятом туннеле + +Порядок каждый раз: + +1. В терминале: `ssh -D 10809 -f -N hsites-ahau` (или ваш хост). +2. Запуск Cursor как обычно. + +Чтобы не забывать туннель, можно завести скрипт запуска (см. [Скрипт запуска с туннелем](#скрипт-запуска-с-туннелем)). + +--- + +## Проверка и диагностика + +### Туннель поднят + +```bash +# Должен слушать 10809 +lsof -i :10809 +# или +nc -z 127.0.0.1 10809 && echo "OK" +``` + +### Доступ к Cursor API через SOCKS (curl) + +```bash +curl -x socks5h://127.0.0.1:10809 -sI https://agent.api5.cursor.sh 2>&1 | head -5 +``` + +Успех: в ответе есть HTTP/2 или заголовки от сервера. Ошибка соединения или таймаут — туннель не работает или порт занят. + +### Логи Cursor + +При проблемах с подключением: + +- **macOS:** `~/Library/Application Support/Cursor/logs/main.log` +- Искать по `ERROR`, `PING`, `timeout`, `HTTP2`, `ECONNREFUSED`, `ETIMEDOUT`. + +--- + +## Troubleshooting + +### После включения прокси Cursor вообще не подключается + +- Убедиться, что туннель запущен: `lsof -i :10809`. +- Проверить доступ через SOCKS: `curl -x socks5h://127.0.0.1:10809 -sI https://agent.api5.cursor.sh`. +- Временно в настройках Cursor убрать `http.proxy` / `https.proxy` и проверить без прокси (например, с Disable Http2) — если так работает, проблема в туннеле или порте. + +### PING timed out остаётся даже через прокси + +- Перезапустить туннель и Cursor (полностью закрыть приложение и открыть снова). +- В настройках Cursor убедиться, что **Disable Http2** выключен (HTTP/2 включён). +- Проверить, что в настройках указан именно `socks5://127.0.0.1:10809` (без опечаток, порт совпадает с `-D 10809`). + +### Порт 10809 занят + +Выбрать другой порт, например 10810: + +```bash +ssh -D 10810 -f -N hsites-ahau +``` + +И в настройках Cursor указать `socks5://127.0.0.1:10810`. + +### Туннель рвётся при долгой неактивности + +Поддерживать соединение помогут опции SSH: + +```bash +ssh -D 10809 -f -N -o ServerAliveInterval=30 -o ServerAliveCountMax=6 hsites-ahau +``` + +При необходимости можно вынести эту команду в скрипт или systemd/supervisor на стороне клиента. + +--- + +## Скрипт запуска туннеля + +В репозитории есть скрипт для поднятия/остановки SOCKS-туннеля: + +```bash +# Из корня репо +./docs/cursor/scripts/cursor-socks-tunnel.sh start # поднять туннель +./docs/cursor/scripts/cursor-socks-tunnel.sh status # проверить +./docs/cursor/scripts/cursor-socks-tunnel.sh stop # остановить +``` + +Переменные окружения: `CURSOR_SOCKS_PORT` (по умолчанию 10809), `CURSOR_TUNNEL_HOST` (по умолчанию `hsites-ahau`). + +**Запуск Cursor после туннеля (macOS):** после `./docs/cursor/scripts/cursor-socks-tunnel.sh start` откройте Cursor как обычно; при настроенных `http.proxy`/`https.proxy` трафик пойдёт через SOCKS. + +--- + +## Ссылки + +| Документ | Назначение | +|----------|------------| +| [PROXY_GUIDE.md](../../connectivity/PROXY_GUIDE.md) | Прокси ru.hunab.app, SSH ProxyCommand для scp/ssh на прод | +| [BUILD_AAB_FROM_RUSSIA_GUIDE.md](../../connectivity/BUILD_AAB_FROM_RUSSIA_GUIDE.md) | Сборка AAB из РФ через Maven proxy + SSH-туннель | +| [Cursor Forum — HTTP/2 network error](https://forum.cursor.com/t/http2-network-error-with-cursor-ide-and-cursor-cli/147318) | Обсуждение ошибок HTTP/2 и региональной маршрутизации | +| [Cursor Forum — Agent timeouts when HTTP2 disabled](https://forum.cursor.com/t/agent-timeouts-much-more-when-http2-disabled/76517) | Таймауты агента при отключённом HTTP/2 | + +--- + +*Последнее обновление: 2026-03-08* diff --git a/docs/cursor/scripts/cursor-socks-tunnel.sh b/docs/cursor/scripts/cursor-socks-tunnel.sh new file mode 100755 index 0000000..55bf15b --- /dev/null +++ b/docs/cursor/scripts/cursor-socks-tunnel.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# Поднимает SOCKS5-туннель для Cursor (обход PING timeout из РФ). +# Использование: ./cursor-socks-tunnel.sh [start|stop|status] +# См. docs/cursor/README.md + +set -e +CURSOR_SOCKS_PORT="${CURSOR_SOCKS_PORT:-10809}" +SSH_HOST="${CURSOR_TUNNEL_HOST:-hsites-ahau}" + +start() { + if lsof -i :"$CURSOR_SOCKS_PORT" -sTCP:LISTEN -t >/dev/null 2>&1; then + echo "SOCKS already listening on 127.0.0.1:$CURSOR_SOCKS_PORT" + return 0 + fi + ssh -D "$CURSOR_SOCKS_PORT" -f -N \ + -o ServerAliveInterval=30 \ + -o ServerAliveCountMax=6 \ + "$SSH_HOST" + echo "SOCKS tunnel started: 127.0.0.1:$CURSOR_SOCKS_PORT -> $SSH_HOST" +} + +stop() { + pkill -f "ssh.*-D $CURSOR_SOCKS_PORT.*$SSH_HOST" 2>/dev/null || true + echo "Tunnel stopped (if it was running)." +} + +status() { + if lsof -i :"$CURSOR_SOCKS_PORT" -sTCP:LISTEN -t >/dev/null 2>&1; then + echo "SOCKS listening on 127.0.0.1:$CURSOR_SOCKS_PORT" + lsof -i :"$CURSOR_SOCKS_PORT" -sTCP:LISTEN + else + echo "No SOCKS listener on port $CURSOR_SOCKS_PORT" + fi +} + +case "${1:-start}" in + start) start ;; + stop) stop ;; + status) status ;; + *) + echo "Usage: $0 {start|stop|status}" + echo "Env: CURSOR_SOCKS_PORT=$CURSOR_SOCKS_PORT, CURSOR_TUNNEL_HOST=$SSH_HOST" + exit 1 + ;; +esac diff --git a/docs/disk_cleanup/ANYTYPE_WORKSPACE_FIX.md b/docs/disk_cleanup/ANYTYPE_WORKSPACE_FIX.md new file mode 100644 index 0000000..308057b --- /dev/null +++ b/docs/disk_cleanup/ANYTYPE_WORKSPACE_FIX.md @@ -0,0 +1,135 @@ +# 🔧 Исправление проблемы с workspace'ами в Anytype после очистки кэша + +## 📋 Проблема + +После выполнения очистки кэша workspace'ы в Anytype не загружаются. + +## 🔍 Причина + +При очистке была удалена вся папка `~/Library/Application Support/anytype`, которая содержит: +- ✅ **Кэши** (можно безопасно удалить) +- ❌ **Важные данные workspace'ов** (нельзя удалять): + - `localstore` — локальное хранилище данных workspace'ов + - `spaceStoreNew` — хранилище пространств + - `objectstore` — база данных объектов + - `config.json` — конфигурация аккаунта + - `device.key` — ключ устройства + +## ✅ Решение + +### Вариант 1: Восстановление из облака (рекомендуется) + +1. **Закройте Anytype полностью:** + ```bash + killall Anytype 2>/dev/null + ``` + +2. **Проверьте наличие папки localstore:** + ```bash + ls -la ~/Library/Application\ Support/anytype/data/*/localstore + ``` + +3. **Если папка отсутствует, перезапустите Anytype:** + - Приложение должно автоматически создать новую папку `localstore` + - Workspace'ы должны синхронизироваться из облака + +4. **Если проблема сохраняется, переименуйте папку spaceStoreNew:** + ```bash + cd ~/Library/Application\ Support/anytype/data/A8uFR2vXWQ3A4H1WBfMGSwAFJ4qefprENcfqrqrfZ2NM9qxB/ + mv spaceStoreNew spaceStoreNew_backup + ``` + +5. **Перезапустите Anytype** — приложение создаст новую папку и восстановит данные из облака + +### Вариант 2: Восстановление базы данных (если есть проблемы с spacestore) + +Если проблема связана с повреждением базы данных `spacestore`: + +1. **Скачайте Badger для macOS:** + - GitHub: https://github.com/anyproto/badger/releases + - Выберите версию для macOS (darwin) + +2. **Создайте резервную копию:** + ```bash + cd ~/Library/Application\ Support/anytype/data/A8uFR2vXWQ3A4H1WBfMGSwAFJ4qefprENcfqrqrfZ2NM9qxB/ + cp -r spaceStoreNew spaceStoreNew_backup_$(date +%Y%m%d) + ``` + +3. **Запустите Badger для восстановления:** + ```bash + ./badger --dir ~/Library/Application\ Support/anytype/data/A8uFR2vXWQ3A4H1WBfMGSwAFJ4qefprENcfqrqrfZ2NM9qxB/spaceStoreNew fix + ``` + +### Вариант 3: Полный сброс (если данные не критичны) + +⚠️ **ВНИМАНИЕ:** Это удалит все локальные данные. Workspace'ы должны восстановиться из облака. + +1. **Закройте Anytype:** + ```bash + killall Anytype 2>/dev/null + ``` + +2. **Создайте резервную копию:** + ```bash + mv ~/Library/Application\ Support/anytype ~/Library/Application\ Support/anytype_backup_$(date +%Y%m%d) + ``` + +3. **Перезапустите Anytype** — приложение создаст новую папку и восстановит данные из облака + +## 🛡️ Предотвращение проблемы в будущем + +### Безопасная очистка кэша Anytype + +Вместо удаления всей папки `~/Library/Application Support/anytype`, удаляйте только кэши: + +```bash +# Безопасная очистка кэшей Anytype +rm -rf ~/Library/Application\ Support/anytype/Cache +rm -rf ~/Library/Application\ Support/anytype/Code\ Cache +rm -rf ~/Library/Application\ Support/anytype/GPUCache +rm -rf ~/Library/Application\ Support/anytype/DawnGraphiteCache +rm -rf ~/Library/Application\ Support/anytype/DawnWebGPUCache +rm -rf ~/Library/Application\ Support/anytype/data/cache +rm -rf ~/Library/Caches/anytype-updater +rm -rf ~/Library/Caches/com.anytype.anytype +``` + +### ⚠️ НЕ УДАЛЯЙТЕ: +- `~/Library/Application Support/anytype/data/` — содержит данные workspace'ов +- `~/Library/Application Support/anytype/data/*/localstore` — локальное хранилище +- `~/Library/Application Support/anytype/data/*/spaceStoreNew` — хранилище пространств +- `~/Library/Application Support/anytype/data/*/objectstore` — база данных объектов +- `~/Library/Application Support/anytype/data/*/config.json` — конфигурация +- `~/Library/Application Support/anytype/data/*/device.key` — ключ устройства + +## 📊 Структура данных Anytype + +``` +~/Library/Application Support/anytype/ +├── Cache/ ✅ Можно удалить (кэш) +├── Code Cache/ ✅ Можно удалить (кэш) +├── GPUCache/ ✅ Можно удалить (кэш) +├── DawnGraphiteCache/ ✅ Можно удалить (кэш) +├── DawnWebGPUCache/ ✅ Можно удалить (кэш) +├── data/ ❌ НЕ УДАЛЯТЬ +│ ├── cache/ ✅ Можно удалить (кэш) +│ └── / ❌ НЕ УДАЛЯТЬ +│ ├── localstore/ ❌ КРИТИЧНО - данные workspace'ов +│ ├── spaceStoreNew/ ❌ КРИТИЧНО - хранилище пространств +│ ├── objectstore/ ❌ КРИТИЧНО - база данных объектов +│ ├── config.json ❌ КРИТИЧНО - конфигурация +│ ├── device.key ❌ КРИТИЧНО - ключ устройства +│ ├── auth/ ❌ КРИТИЧНО - данные авторизации +│ └── flatfs/ ⚠️ Можно удалить (файловое хранилище, но лучше не трогать) +└── logs/ ✅ Можно удалить (логи) +``` + +## 🔗 Дополнительные ресурсы + +- [Документация Anytype - Устранение неполадок](https://doc.anytype.io/anytype-docs/russian/raznoe/troubleshooting) +- [Badger для восстановления базы данных](https://github.com/anyproto/badger/releases) + +## 📝 История изменений + +- **2025-12-16** — Создан документ с описанием проблемы и решений + diff --git a/docs/disk_cleanup/CHANGELOG.md b/docs/disk_cleanup/CHANGELOG.md new file mode 100644 index 0000000..886a950 --- /dev/null +++ b/docs/disk_cleanup/CHANGELOG.md @@ -0,0 +1,55 @@ +# Changelog — docs/disk_cleanup + +Все значимые изменения документации и правил очистки диска. + +--- + +## 2025-03-14 + +### Консолидация + +- **Один главный документ:** [DISK_CLEANUP.md](./DISK_CLEANUP.md) объединяет DO_NOT_DELETE, SAFE_TO_DELETE_NOW, DISK_CLEANUP_STANDARD, REGULAR_CLEANUP, DISK_SCAN_CURRENT. +- **Сокращение файлов:** удалены дублирующие документы (списки перенесены в DISK_CLEANUP.md). +- **Добавлен CHANGELOG.md** (этот файл). + +### Содержимое DISK_CLEANUP.md + +- Таблица «Что НЕ удалять» (полный список). +- Таблицы «Что безопасно удалять» по категориям: кэши разработки, Library/Caches, приложения, Cursor, прочее, build, node_modules. +- Раздел «Кто отжирает диск» (типичные потребители места). +- Быстрые команды для освобождения ~10–12 GB. +- Регулярность очистки (еженедельно / ежемесячно / при нехватке места). +- Ссылка на ANYTYPE_WORKSPACE_FIX и описание скриптов. + +### Сохранённые файлы + +- **DISK_CLEANUP.md** — главный документ. +- **CHANGELOG.md** — история изменений. +- **cleanup-disk-now.sh** — скрипт очистки (без DO_NOT_DELETE пунктов). +- **ANYTYPE_WORKSPACE_FIX.md** — восстановление anytype после ошибочной очистки. +- **scripts/** — scan-cleanup-items.sh, compress-screenrecordings.sh, quick-cleanup-asahi.sh, scan-move-candidates.sh. +- **find-external-disks.sh**, **diagnose-external-disk.sh** — утилиты для внешних дисков. + +### Удалённые / объединённые документы + +- DO_NOT_DELETE.md → раздел в DISK_CLEANUP.md +- SAFE_TO_DELETE_NOW.md → раздел в DISK_CLEANUP.md +- DISK_CLEANUP_STANDARD.md → раздел в DISK_CLEANUP.md +- REGULAR_CLEANUP.md → раздел «Регулярность» в DISK_CLEANUP.md +- DISK_SCAN_CURRENT.md → раздел «Кто отжирает диск» в DISK_CLEANUP.md +- AGREED_90GB_PLAN.md, MOVE_TO_EXTERNAL_100GB.md, SCAN_REPORT.md, disk-cleanup-guide.md — содержание учтено или устарело; при необходимости смотреть в git history. + +--- + +## 2025-03-14 (ранее в сессии) + +- В **cleanup-disk-now.sh** убрано удаление объектов из DO_NOT_DELETE (Brave, Cursor History/workspaceStorage, Telegram, pnpm, anytype). Скрипт приведён в соответствие с безопасным списком. +- В список безопасного удаления добавлены: **state.vscdb.backup** (~10 GB), Library/Caches (ShipIt, anytype-updater, com.brave.Browser, Firefox, Google, Homebrew). +- Windsurf: полное удаление из системы (.codeium/windsurf, .windsurf, Application Support/Windsurf). + +--- + +## 2025-01-29 + +- Создан стандарт очистки (DISK_CLEANUP_STANDARD), DO_NOT_DELETE, REGULAR_CLEANUP. +- Определены защищённые элементы и безопасные кэши для регулярной очистки. diff --git a/docs/disk_cleanup/DISK_CLEANUP.md b/docs/disk_cleanup/DISK_CLEANUP.md new file mode 100644 index 0000000..e8bfa86 --- /dev/null +++ b/docs/disk_cleanup/DISK_CLEANUP.md @@ -0,0 +1,189 @@ +# 🧹 Очистка диска Mac — сводный гайд + +Один документ: что не трогать, что можно удалять, быстрые команды, скрипты. +**Скрипт:** [cleanup-disk-now.sh](./cleanup-disk-now.sh) · **Спец. фикс:** [ANYTYPE_WORKSPACE_FIX.md](./ANYTYPE_WORKSPACE_FIX.md) · **История:** [CHANGELOG.md](./CHANGELOG.md) + +--- + +## Содержание + +1. [❌ Что НЕ удалять](#-что-не-удалять) +2. [✅ Что безопасно удалять](#-что-безопасно-удалять) +3. [📊 Кто отжирает диск](#-кто-отжирает-диск) +4. [🚀 Быстрые команды](#-быстрые-команды) +5. [🔄 Регулярность очистки](#-регулярность-очистки) +6. [🔧 Anytype: не удалять папку целиком](#-anytype-не-удалять-папку-целиком) +7. [📁 Скрипты](#-скрипты) +8. [📋 Changelog](#-changelog) + +--- + +## ❌ Что НЕ удалять + +| Категория | Пути | Причина | +|-----------|------|---------| +| Brave | `~/Library/Application Support/BraveSoftware`, `~/Library/Caches/BraveSoftware` | Настройки, закладки, история | +| Cursor History | `~/Library/Application Support/Cursor/User/History` | История изменений файлов | +| Cursor workspaceStorage | `~/Library/Application Support/Cursor/User/workspaceStorage` | Настройки workspace | +| Cursor extensions | `~/.cursor/extensions` | Кэш расширений, переустановка при удалении | +| Cursor logs / CachedData / ai-tracking | `.../Cursor/logs`, `.../Cursor/CachedData`, `~/.cursor/ai-tracking` | Производительность | +| direct-commander | `~/Library/Application Support/direct-commander` | Настройки файлового менеджера | +| anytype | Вся папка `~/Library/Application Support/anytype` | Данные workspace'ов (localstore, spaceStoreNew и др.) | +| Android SDK | `~/Library/Android/sdk` | Разработка Android | +| Бэкапы в bots | `~/code/bots/backup_*`, `~/code/bots/archives_*` | Восстановление проектов | +| Telegram Desktop | `~/Library/Application Support/Telegram Desktop` | Данные и кэш Telegram | +| Старые архивы | `~/code/methatron/pics/tablecloth/1-7.zip`, архивы в legal | Могут понадобиться | +| pnpm | `~/Library/pnpm`, `~/Library/Caches/pnpm` | Повторная загрузка 967+ пакетов | +| node_modules (frontend) | `~/code/hunabapp-dev/frontend/node_modules` | То же | +| .gradle | `~/.gradle` | Кэш сборки Android/Java | +| Android build | `~/code/hunabapp-dev/frontend/android/app/build` | Артефакты сборки | + +**Итого сохраняется:** ~9–10 GB (ориентир). + +--- + +## ✅ Что безопасно удалять + +Всё ниже — кэши или пересобираемое; не трогать пункты из таблицы выше. + +### Кэши разработки + +| Что | Путь | Ориентир | +|-----|------|----------| +| Colima | `~/.colima`, `~/Library/Caches/colima` | до ~30 GB | +| npm | `~/.npm`, `~/.npm/_npx` | 300–500 MB | +| node-gyp | `~/Library/Caches/node-gyp` | — | +| TypeScript | `~/Library/Caches/typescript` | — | +| pip | `~/Library/Caches/pip` | — | +| .yarn | `~/.yarn` | — | +| Windsurf полностью | `~/.codeium/windsurf`, `~/.windsurf`, `~/Library/Application Support/Windsurf` | — | + +### Library/Caches (без Brave) + +| Что | Путь | Ориентир | +|-----|------|----------| +| ShipIt (Cursor) | `~/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt` | 768 MB | +| anytype-updater | `~/Library/Caches/anytype-updater` | 453 MB | +| com.brave.Browser | `~/Library/Caches/com.brave.Browser` | 423 MB | +| Firefox | `~/Library/Caches/Firefox` | 83 MB | +| Google | `~/Library/Caches/Google` | — | +| Homebrew | `~/Library/Caches/Homebrew` | — | + +### Кэши приложений (не Telegram) + +Notion, zoom.us, LibreOffice, Movavi, Ledger Live, Syncthing (если не нужен): +`~/Library/Application Support/{Notion,zoom.us,LibreOffice,Movavi,Ledger Live,Syncthing}` + +### Cursor — только эти кэши и файлы + +| Что | Путь | Ориентир | +|-----|------|----------| +| **state.vscdb.backup** | `.../Cursor/User/globalStorage/state.vscdb.backup` | **~10 GB** | +| ShipIt | см. выше в Library/Caches | 768 MB | +| WebStorage | `.../Cursor/WebStorage` | — | +| Partitions | `.../Cursor/Partitions` | — | +| projects | `~/.cursor/projects` | — | + +**Опционально (~13 GB):** удаление `state.vscdb` + `-wal` + `-shm` в том же каталоге сбрасывает глобальное состояние редактора. **Закрыть Cursor перед удалением.** + +### Прочее + +- `~/.cache` +- Пустые логи: `find ~/Library/Logs -type f -size 0 -delete` +- Записи экрана: `~/Library/ScreenRecordings/*` (проверить вручную) + +### Build-артефакты в ~/code + +Исключить: `*/hunabapp-dev/frontend/android/*`, `*/node_modules/*`, `*/venv/*`, `*/site-packages/*`. + +```bash +find ~/code -type d \( -name "build" -o -name "dist" -o -name ".next" -o -name "out" \) \ + -not -path "*/node_modules/*" -not -path "*/venv/*" -not -path "*/.venv/*" \ + -not -path "*/site-packages/*" -not -path "*/hunabapp-dev/frontend/android/*" \ + -exec rm -rf {} + 2>/dev/null +``` + +### node_modules (опционально) + +Исключить: `~/code/hunabapp-dev/frontend/node_modules`. После удаления — `pnpm install` в нужных проектах. + +--- + +## 📊 Кто отжирает диск + +Типичные крупные потребители (ориентир): + +| Путь | Размер | Действие | +|------|--------|----------| +| Cursor User/globalStorage (state.vscdb + .backup) | ~23 GB | .backup — удалить; state.vscdb — опционально | +| ~/code/legal, hunabapp-dev, archive, backups | 1–16 GB | Вручную | +| Telegram, anytype | 1–2 GB | Не удалять | +| Library/Caches (ShipIt, anytype-updater, браузеры) | ~2 GB | Удалять по списку выше | +| .gradle, .cursor/extensions | ~1.5 GB | Не удалять | + +Запуск сканирования: `./scripts/scan-cleanup-items.sh`. + +--- + +## 🚀 Быстрые команды + +**С закрытым Cursor** (освободит ~10–12 GB): + +```bash +# Cursor state backup +rm -f "$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb.backup" + +# Library/Caches (не Brave) +rm -rf "$HOME/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt" +rm -rf "$HOME/Library/Caches/anytype-updater" +rm -rf "$HOME/Library/Caches/com.brave.Browser" +rm -rf "$HOME/Library/Caches/Firefox" +rm -rf "$HOME/Library/Caches/Google" +rm -rf "$HOME/Library/Caches/Homebrew" + +# Cursor кэши +rm -rf "$HOME/Library/Application Support/Cursor/WebStorage" +rm -rf "$HOME/.cursor/projects" + +# Прочее +rm -rf "$HOME/.cache" +find "$HOME/Library/Logs" -type f -size 0 -delete 2>/dev/null +``` + +Полная безопасная очистка по категориям — в [cleanup-disk-now.sh](./cleanup-disk-now.sh). + +--- + +## 🔄 Регулярность очистки + +- **Еженедельно:** build-артефакты, пустые логи. +- **Ежемесячно:** кэши разработки (npm, node-gyp, TypeScript, pip, .yarn), Library/Caches (Google, Firefox, ShipIt, anytype-updater), Cursor WebStorage/Partitions/projects. +- **При заполнении диска >80%:** всё из ежемесячного + Colima (если не нужен), state.vscdb.backup, приложения (Notion, zoom, LibreOffice, Movavi, Ledger), записи экрана. + +--- + +## 🔧 Anytype: не удалять папку целиком + +В `~/Library/Application Support/anytype` лежат и кэши, и **данные workspace'ов** (localstore, spaceStoreNew, objectstore и др.). Удаление всей папки ломает загрузку workspace'ов. Подробное восстановление: [ANYTYPE_WORKSPACE_FIX.md](./ANYTYPE_WORKSPACE_FIX.md). + +--- + +## 📁 Скрипты + +| Файл | Назначение | +|------|------------| +| [cleanup-disk-now.sh](./cleanup-disk-now.sh) | Интерактивная безопасная очистка (согласовано с DO_NOT_DELETE) | +| [scripts/scan-cleanup-items.sh](./scripts/scan-cleanup-items.sh) | Сканирование: что можно удалить и размеры | +| [scripts/compress-screenrecordings.sh](./scripts/compress-screenrecordings.sh) | Сжатие записей экрана | +| [scripts/quick-cleanup-asahi.sh](./scripts/quick-cleanup-asahi.sh) | Быстрая очистка под Asahi | +| [scripts/scan-move-candidates.sh](./scripts/scan-move-candidates.sh) | Кандидаты на перенос на внешний диск | +| [find-external-disks.sh](./find-external-disks.sh) | Поиск внешних дисков | +| [diagnose-external-disk.sh](./diagnose-external-disk.sh) | Диагностика внешнего диска | + +--- + +## 📋 Changelog + +См. [CHANGELOG.md](./CHANGELOG.md). + +**Последнее обновление:** 2025-03-14 — консолидация документации, один главный файл DISK_CLEANUP.md, сокращение числа файлов. diff --git a/docs/disk_cleanup/cleanup-disk-now.sh b/docs/disk_cleanup/cleanup-disk-now.sh new file mode 100755 index 0000000..57b58d6 --- /dev/null +++ b/docs/disk_cleanup/cleanup-disk-now.sh @@ -0,0 +1,167 @@ +#!/bin/bash + +# Безопасная очистка диска — по списку из docs/disk_cleanup/DISK_CLEANUP.md. +# НЕ трогает: Brave, Cursor History/workspaceStorage/extensions, Telegram, pnpm, anytype. + +set -e + +echo "🧹 Безопасная очистка диска (согласовано с DO_NOT_DELETE)" +echo "==========================================================" +echo "" + +cleanup_dir() { + local dir="$1" + local name="$2" + if [ -d "$dir" ] || [ -f "$dir" ]; then + size=$(du -sh "$dir" 2>/dev/null | cut -f1) + echo "🗑️ Удаление $name ($size)..." + rm -rf "$dir" 2>/dev/null && echo " ✅ $name очищен" || echo " ⚠️ Не удалось удалить $name" + else + echo " ℹ️ $name не найден, пропускаем" + fi +} + +echo "📊 Текущее состояние диска:" +df -h / | tail -1 +echo "" + +# 1. Кэши разработки: Colima, npm, node-gyp, TypeScript, pip, .yarn +echo "=== 1. Кэши разработки ===" +cleanup_dir "$HOME/.colima" "Colima кэш" +cleanup_dir "$HOME/Library/Caches/colima" "Colima кэш (Library)" +cleanup_dir "$HOME/.npm" "npm кэш" +cleanup_dir "$HOME/Library/Caches/node-gyp" "node-gyp кэш" +cleanup_dir "$HOME/Library/Caches/typescript" "TypeScript кэш" +cleanup_dir "$HOME/Library/Caches/pip" "pip кэш" +cleanup_dir "$HOME/.yarn" ".yarn кэш" +echo "" + +# 2. Windsurf полностью (кэш + данные; приложение — удалить вручную из Программы) +echo "=== 2. Windsurf полностью ===" +cleanup_dir "$HOME/.codeium/windsurf" "Codeium/Windsurf кэш" +cleanup_dir "$HOME/.windsurf" "Windsurf данные" +cleanup_dir "$HOME/Library/Application Support/Windsurf" "Windsurf Application Support" +# Если .codeium пуст — можно удалить целиком +[ -d "$HOME/.codeium" ] && [ -z "$(ls -A "$HOME/.codeium" 2>/dev/null)" ] && rm -rf "$HOME/.codeium" && echo " ✅ .codeium (пустая) удалена" +echo "" + +# 3. Кэши браузеров — только Google/Firefox (Brave в DO_NOT_DELETE) +echo "=== 3. Кэши браузеров (не Brave) ===" +cleanup_dir "$HOME/Library/Caches/Google" "Google кэш" +cleanup_dir "$HOME/Library/Caches/Firefox" "Firefox кэш" +cleanup_dir "$HOME/Library/Caches/com.brave.Browser" "com.brave.Browser кэш" +echo "" + +# 4. Приложения — Notion, zoom, LibreOffice, Movavi, Ledger (Telegram в DO_NOT_DELETE) +echo "=== 4. Кэши приложений ===" +cleanup_dir "$HOME/Library/Application Support/Notion" "Notion" +cleanup_dir "$HOME/Library/Application Support/zoom.us" "zoom.us" +cleanup_dir "$HOME/Library/Application Support/LibreOffice" "LibreOffice" +cleanup_dir "$HOME/Library/Application Support/Movavi" "Movavi" +cleanup_dir "$HOME/Library/Application Support/Ledger Live" "Ledger Live" +echo "" + +# 5. Cursor — только разрешённые кэши и state backup (~10 GB) +echo "=== 5. Cursor кэши (только разрешённые) ===" +STATE_BACKUP="$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb.backup" +if [ -f "$STATE_BACKUP" ]; then + size=$(du -sh "$STATE_BACKUP" 2>/dev/null | cut -f1) + echo " state.vscdb.backup ($size) — закрыть Cursor перед удалением!" + read -p " Удалить state.vscdb.backup? (y/n): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + rm -f "$STATE_BACKUP" && echo " ✅ state.vscdb.backup удалён" || echo " ⚠️ Закрой Cursor и повтори" + else + echo " ⏭️ Пропущено" + fi +fi +cleanup_dir "$HOME/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt" "Cursor ShipIt" +cleanup_dir "$HOME/Library/Application Support/Cursor/WebStorage" "Cursor WebStorage" +cleanup_dir "$HOME/Library/Application Support/Cursor/Partitions" "Cursor Partitions" +cleanup_dir "$HOME/.cursor/projects" "Cursor projects" +echo "" + +# 6. Homebrew, .cache, пустые логи +echo "=== 6. Homebrew, .cache, пустые логи ===" +cleanup_dir "$HOME/Library/Caches/Homebrew" "Homebrew кэш" +cleanup_dir "$HOME/.cache" ".cache" +find "$HOME/Library/Logs" -type f -size 0 -delete 2>/dev/null && echo " ✅ Пустые логи удалены" || true +echo "" + +# 7. ScreenRecordings (по желанию) +echo "=== 7. Записи экрана ===" +if [ -d "$HOME/Library/ScreenRecordings" ]; then + count=$(find "$HOME/Library/ScreenRecordings" -type f 2>/dev/null | wc -l | tr -d ' ') + if [ "$count" -gt 0 ]; then + echo " Найдено файлов: $count" + read -p " Удалить все записи экрана? (y/n): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + cleanup_dir "$HOME/Library/ScreenRecordings" "Записи экрана" + else + echo " ⏭️ Пропущено" + fi + else + echo " ℹ️ Папка пуста" + fi +fi +echo "" + +# 8. Build артефакты (исключая hunabapp-dev/frontend/android — в DO_NOT_DELETE) +echo "=== 8. Build артефакты в ~/code (кроме android) ===" +read -p " Удалить build/dist/.next/out? (y/n): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + find "$HOME/code" -type d \( -name "build" -o -name "dist" -o -name ".next" -o -name "out" \) \ + -not -path "*/node_modules/*" \ + -not -path "*/venv/*" \ + -not -path "*/.venv/*" \ + -not -path "*/site-packages/*" \ + -not -path "*/env/*" \ + -not -path "*/hunabapp-dev/frontend/android/*" \ + -exec rm -rf {} + 2>/dev/null || true + echo " ✅ Готово" +else + echo " ⏭️ Пропущено" +fi +echo "" + +# 9. node_modules (опционально; НЕ frontend — в DO_NOT_DELETE) +echo "=== 9. node_modules (кроме hunabapp-dev/frontend) ===" +read -p " Удалить node_modules в проектах? (y/n): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + find "$HOME/code" -type d -name "node_modules" \ + -not -path "*/venv/*" \ + -not -path "*/.venv/*" \ + -not -path "*/hunabapp-dev/frontend/node_modules" \ + -exec rm -rf {} + 2>/dev/null || true + echo " ✅ Готово. В нужных проектах: pnpm install" +else + echo " ⏭️ Пропущено" +fi +echo "" + +# 10. UTM виртуальная машина — опционально +echo "=== 10. UTM виртуальная машина ===" +if [ -d "$HOME/code/Parrot-home-mate-6.4_arm64.utm" ]; then + read -p " Удалить UTM виртуальную машину? (y/n): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + cleanup_dir "$HOME/code/Parrot-home-mate-6.4_arm64.utm" "UTM виртуальная машина" + else + echo " ⏭️ Пропущено" + fi +else + echo " ℹ️ Не найдена" +fi +echo "" + +echo "==========================================================" +echo "📊 Состояние диска после очистки:" +df -h / | tail -1 +echo "" +echo "✅ Очистка завершена. Перезапустите приложения при необходимости." +echo " Список: docs/disk_cleanup/DISK_CLEANUP.md" +echo "" + diff --git a/docs/disk_cleanup/diagnose-external-disk.sh b/docs/disk_cleanup/diagnose-external-disk.sh new file mode 100755 index 0000000..1d97fb4 --- /dev/null +++ b/docs/disk_cleanup/diagnose-external-disk.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +# Диагностика проблемы с внешним диском на macOS +# Использование: ./diagnose-external-disk.sh + +echo "==========================================" +echo "Диагностика внешнего диска на macOS" +echo "==========================================" +echo "" + +# 1. Проверка подключенных дисков +echo "1. Список всех дисков:" +echo "----------------------------------------" +diskutil list +echo "" + +# 2. Проверка USB устройств +echo "2. USB устройства:" +echo "----------------------------------------" +system_profiler SPUSBDataType | grep -A 10 -i "mass\|storage\|disk" || echo "Нет USB устройств хранения данных" +echo "" + +# 3. Проверка не смонтированных дисков +echo "3. Информация о всех дисках:" +echo "----------------------------------------" +diskutil info -all 2>&1 | grep -E "Device Node|Volume Name|Removable Media|Disk Size" | head -40 +echo "" + +# 4. Проверка системных логов на ошибки +echo "4. Последние ошибки дисков в логах:" +echo "----------------------------------------" +log show --predicate 'subsystem == "com.apple.diskmanagementd" OR subsystem == "com.apple.diskarbitrationd"' --last 10m --style syslog 2>/dev/null | tail -20 || echo "Нет ошибок в логах" +echo "" + +# 5. Проверка низкоуровневых USB устройств +echo "5. USB устройства на низком уровне:" +echo "----------------------------------------" +ioreg -p IOUSB -l -w 0 | grep -B 5 -A 15 -i "mass\|storage" | head -50 || echo "Нет USB устройств хранения" +echo "" + +# 6. Проверка доступных портов +echo "6. Доступные USB порты:" +echo "----------------------------------------" +system_profiler SPUSBDataType | grep -E "USB|Port|Hub" | head -30 +echo "" + +# 7. Проверка файловой системы +echo "7. Проверка файловых систем:" +echo "----------------------------------------" +diskutil listFilesystems +echo "" + +echo "==========================================" +echo "РЕКОМЕНДАЦИИ:" +echo "==========================================" +echo "" +echo "1. Проверьте физическое подключение:" +echo " - Отключите и снова подключите диск" +echo " - Попробуйте другой USB порт" +echo " - Попробуйте другой USB кабель" +echo "" +echo "2. Проверьте питание диска:" +echo " - Убедитесь что диск получает достаточно питания" +echo " - Если диск требует внешнего питания, подключите его" +echo "" +echo "3. Попробуйте другой компьютер:" +echo " - Проверьте работает ли диск на другом Mac/PC" +echo "" +echo "4. Проверьте формат диска:" +echo " - macOS может не видеть диски с некоторыми файловыми системами" +echo " - Попробуйте открыть Дисковую утилиту (Disk Utility)" +echo "" +echo "5. Попробуйте принудительно смонтировать:" +echo " diskutil mountDisk /dev/diskX # где X - номер диска" +echo "" +echo "6. Проверьте настройки безопасности:" +echo " - Системные настройки > Безопасность > Разрешить подключение внешних устройств" +echo "" + + + + + + + diff --git a/docs/disk_cleanup/find-external-disks.sh b/docs/disk_cleanup/find-external-disks.sh new file mode 100755 index 0000000..c6fe964 --- /dev/null +++ b/docs/disk_cleanup/find-external-disks.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +# Поиск внешних дисков - расширенная версия + +echo "==========================================" +echo "ПОИСК ВНЕШНИХ ДИСКОВ" +echo "==========================================" +echo "" + +echo "1. Все диски в системе:" +echo "----------------------------------------" +diskutil list +echo "" + +echo "2. Все устройства в /dev/disk*:" +echo "----------------------------------------" +ls -lh /dev/disk* 2>/dev/null | head -30 +echo "" + +echo "3. Информация о каждом диске (ищем внешние):" +echo "----------------------------------------" +for disk in /dev/disk[0-9] /dev/disk[1-9][0-9]; do + if [ -b "$disk" ] 2>/dev/null; then + info=$(diskutil info "$disk" 2>/dev/null) + if echo "$info" | grep -qi "removable.*yes\|external\|protocol.*usb\|protocol.*thunderbolt"; then + echo ">>> НАЙДЕН ВОЗМОЖНО ВНЕШНИЙ ДИСК: $disk" + echo "$info" | grep -E "Device Node|Volume Name|Disk Size|Removable Media|Protocol|Connection|File System" | head -10 + echo "" + fi + fi +done + +echo "4. USB устройства:" +echo "----------------------------------------" +system_profiler SPUSBDataType 2>/dev/null | grep -A 15 -i "mass\|storage\|disk\|volume" || echo "Нет USB устройств хранения" +echo "" + +echo "5. Thunderbolt устройства:" +echo "----------------------------------------" +system_profiler SPThunderboltDataType 2>/dev/null | grep -A 15 -i "disk\|storage\|volume" || echo "Нет Thunderbolt устройств хранения" +echo "" + +echo "6. Смонтированные тома:" +echo "----------------------------------------" +mount | grep -E "/dev/disk|/Volumes" | grep -v "/System/Volumes" +echo "" + +echo "7. Содержимое /Volumes:" +echo "----------------------------------------" +ls -la /Volumes/ +echo "" + +echo "8. Попытка принудительного пересканирования:" +echo "----------------------------------------" +sudo diskutil list 2>&1 | head -5 +echo "" + +echo "9. Проверка через ioreg (IOBlockStorageDevice):" +echo "----------------------------------------" +ioreg -p IOService -r -n IOBlockStorageDevice -w 0 2>/dev/null | grep -A 10 -i "removable\|external" | head -40 || echo "Нет внешних устройств в ioreg" +echo "" + +echo "==========================================" +echo "РЕКОМЕНДАЦИИ:" +echo "==========================================" +echo "" +echo "Если диски не найдены:" +echo "1. Проверьте физическое подключение" +echo "2. Попробуйте другой USB/Thunderbolt порт" +echo "3. Попробуйте другой кабель" +echo "4. Проверьте питание дисков" +echo "5. Откройте Дисковую утилиту: open -a 'Disk Utility'" +echo "6. Попробуйте перезагрузить Mac" +echo "" + + + + + + + diff --git a/docs/disk_cleanup/scripts/compress-screenrecordings.sh b/docs/disk_cleanup/scripts/compress-screenrecordings.sh new file mode 100755 index 0000000..eff9f11 --- /dev/null +++ b/docs/disk_cleanup/scripts/compress-screenrecordings.sh @@ -0,0 +1,190 @@ +#!/bin/bash + +# Скрипт для сжатия видео ScreenRecordings без потери качества +# Использует H.265 (HEVC) кодек с CRF 18 (визуально без потерь) + +SCREENRECORDINGS_DIR="$HOME/Library/ScreenRecordings" +BACKUP_DIR="$SCREENRECORDINGS_DIR/originals" +TEMP_DIR="$SCREENRECORDINGS_DIR/compressed" + +# Цвета для вывода +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +echo "==========================================" +echo " Сжатие ScreenRecordings без потери качества" +echo "==========================================" +echo "" + +# Проверка наличия ffmpeg +if ! command -v ffmpeg &> /dev/null; then + echo -e "${RED}Ошибка: ffmpeg не установлен${NC}" + echo "Установите ffmpeg: brew install ffmpeg" + exit 1 +fi + +# Проверка существования директории +if [ ! -d "$SCREENRECORDINGS_DIR" ]; then + echo -e "${RED}Ошибка: директория $SCREENRECORDINGS_DIR не найдена${NC}" + exit 1 +fi + +# Создание директорий для бэкапа и временных файлов +mkdir -p "$BACKUP_DIR" +mkdir -p "$TEMP_DIR" + +# Подсчет видео файлов +VIDEO_FILES=$(find "$SCREENRECORDINGS_DIR" -maxdepth 1 -type f \( -iname "*.mov" -o -iname "*.mp4" -o -iname "*.m4v" \) ! -name ".*" | wc -l | tr -d ' ') + +if [ "$VIDEO_FILES" -eq 0 ]; then + echo -e "${YELLOW}Видео файлы не найдены в $SCREENRECORDINGS_DIR${NC}" + exit 0 +fi + +echo -e "${GREEN}Найдено видео файлов: $VIDEO_FILES${NC}" +echo "" + +# Подсчет общего размера +TOTAL_SIZE=$(du -sh "$SCREENRECORDINGS_DIR" 2>/dev/null | cut -f1) +echo -e "Текущий размер: ${YELLOW}$TOTAL_SIZE${NC}" +echo "" + +# Подтверждение +read -p "Продолжить сжатие? (y/n): " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Отменено" + exit 0 +fi + +echo "" +echo "Начало сжатия..." +echo "" + +# Счетчики +PROCESSED=0 +SKIPPED=0 +ERRORS=0 + +# Создание массива видео файлов +mapfile -t video_files < <(find "$SCREENRECORDINGS_DIR" -maxdepth 1 -type f \( -iname "*.mov" -o -iname "*.mp4" -o -iname "*.m4v" \) ! -name ".*" | sort) + +# Обработка каждого видео файла +for video_file in "${video_files[@]}"; do + filename=$(basename "$video_file") + name_without_ext="${filename%.*}" + ext="${filename##*.}" + + # Пропускаем уже обработанные файлы + if [[ "$filename" == *"_compressed"* ]] || [ -f "$BACKUP_DIR/$filename" ]; then + echo -e "${YELLOW}Пропуск: $filename (уже обработан)${NC}" + ((SKIPPED++)) + continue + fi + + echo "----------------------------------------" + echo -e "${GREEN}Обработка: $filename${NC}" + + # Размер оригинального файла + original_size=$(stat -f%z "$video_file" 2>/dev/null || stat -c%s "$video_file" 2>/dev/null) + original_size_mb=$(echo "scale=2; $original_size / 1024 / 1024" | bc) + echo " Размер оригинала: ${original_size_mb} MB" + + # Временный файл для сжатого видео + compressed_file="$TEMP_DIR/${name_without_ext}_compressed.${ext}" + + # Сжатие с H.265 (HEVC) кодеком + # CRF 18 = визуально без потерь качества (чем меньше, тем лучше качество, но больше размер) + # preset slow = лучшее сжатие, но медленнее + # pix_fmt yuv420p = совместимость с большинством плееров + + echo " Сжатие с H.265 (HEVC) кодеком (CRF 18, визуально без потерь)..." + + # Запуск ffmpeg с подавлением вывода (кроме ошибок) + if ! ffmpeg -i "$video_file" \ + -c:v libx265 \ + -crf 18 \ + -preset slow \ + -c:a copy \ + -pix_fmt yuv420p \ + -movflags +faststart \ + -y \ + "$compressed_file" > /dev/null 2>&1; then + + echo -e " ${RED}Ошибка при сжатии: $filename${NC}" + rm -f "$compressed_file" + ((ERRORS++)) + continue + fi + + # Проверка, что сжатый файл создан + if [ ! -f "$compressed_file" ]; then + echo -e " ${RED}Ошибка: сжатый файл не создан${NC}" + ((ERRORS++)) + continue + fi + + # Размер сжатого файла + compressed_size=$(stat -f%z "$compressed_file" 2>/dev/null || stat -c%s "$compressed_file" 2>/dev/null) + compressed_size_mb=$(echo "scale=2; $compressed_size / 1024 / 1024" | bc) + + # Процент сжатия + if [ "$original_size" -gt 0 ]; then + compression_ratio=$(echo "scale=1; (1 - $compressed_size / $original_size) * 100" | bc) + echo " Размер сжатого: ${compressed_size_mb} MB" + echo -e " ${GREEN}Сжатие: ${compression_ratio}%${NC}" + fi + + # Проверка, что сжатый файл меньше оригинала + if [ "$compressed_size" -lt "$original_size" ]; then + # Бэкап оригинала + echo " Создание бэкапа оригинала..." + cp "$video_file" "$BACKUP_DIR/$filename" + + # Замена оригинала сжатой версией + echo " Замена оригинала сжатой версией..." + mv "$compressed_file" "$video_file" + + echo -e " ${GREEN}✓ Готово: $filename${NC}" + ((PROCESSED++)) + else + echo -e " ${YELLOW}Сжатый файл больше оригинала, оставляем оригинал${NC}" + rm -f "$compressed_file" + ((SKIPPED++)) + fi + + echo "" +done + +# Очистка временной директории +rm -rf "$TEMP_DIR" + +echo "==========================================" +echo " Результаты" +echo "==========================================" +echo -e "${GREEN}Обработано: $PROCESSED${NC}" +echo -e "${YELLOW}Пропущено: $SKIPPED${NC}" +if [ "$ERRORS" -gt 0 ]; then + echo -e "${RED}Ошибок: $ERRORS${NC}" +fi +echo "" + +# Финальный размер +FINAL_SIZE=$(du -sh "$SCREENRECORDINGS_DIR" 2>/dev/null | cut -f1) +echo -e "Финальный размер: ${GREEN}$FINAL_SIZE${NC}" +echo "" + +# Информация о бэкапах +if [ -d "$BACKUP_DIR" ] && [ "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then + BACKUP_SIZE=$(du -sh "$BACKUP_DIR" 2>/dev/null | cut -f1) + echo -e "Бэкапы оригиналов сохранены в: ${YELLOW}$BACKUP_DIR${NC} (${BACKUP_SIZE})" + echo "" + echo "⚠️ После проверки сжатых видео, вы можете удалить бэкапы:" + echo " rm -rf $BACKUP_DIR" +fi + +echo "" +echo -e "${GREEN}Готово!${NC}" + diff --git a/docs/disk_cleanup/scripts/quick-cleanup-asahi.sh b/docs/disk_cleanup/scripts/quick-cleanup-asahi.sh new file mode 100755 index 0000000..016b2f6 --- /dev/null +++ b/docs/disk_cleanup/scripts/quick-cleanup-asahi.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# Быстрая очистка под освобождение места для Asahi Fedora: +# - Кэш Homebrew +# - Docker/Colima (неиспользуемые образы и тома) +# - Бэкапы iPhone/iPad — только старые (опционально по возрасту) +# - Xcode DerivedData (если установлен) +# - ~/.vscode и ~/.windsurf (~0.7 ГБ), если не нужны +# +# Запуск: ./quick-cleanup-asahi.sh [--yes] +# --yes выполнить все шаги без запросов подтверждения + +set -e +YES="${1:-}" + +ask() { + local msg="$1" + if [ "$YES" = "--yes" ]; then + echo "$msg (--yes: пропускаем вопрос)" + return 0 + fi + read -p "$msg (y/n): " -n 1 -r + echo + [[ $REPLY =~ ^[yYдД]$ ]] +} + +echo "==============================================" +echo " Быстрая очистка для Asahi (освобождение места)" +echo "==============================================" +echo "" + +# --- 1. Кэш Homebrew --- +if [ -d "$HOME/Library/Caches/Homebrew" ]; then + size=$(du -sh "$HOME/Library/Caches/Homebrew" 2>/dev/null | cut -f1) + echo "1. Кэш Homebrew: $size" + if ask " Удалить кэш Homebrew?"; then + rm -rf "$HOME/Library/Caches/Homebrew" + echo " ✅ Кэш Homebrew удалён" + else + echo " Пропущено" + fi +else + echo "1. Кэш Homebrew: не найден" +fi +echo "" + +# --- 2. Docker / Colima --- +if command -v docker &>/dev/null; then + echo "2. Docker: использование места:" + docker system df 2>/dev/null || true + if ask " Удалить неиспользуемые образы и тома? (docker image prune -a, volume prune)"; then + docker image prune -af 2>/dev/null || true + docker volume prune -f 2>/dev/null || true + echo " ✅ Docker очищен" + else + echo " Пропущено" + fi +else + echo "2. Docker: не установлен или не в PATH" +fi +echo "" + +# --- 3. Бэкапы iPhone/iPad — только старые --- +BACKUP_ROOT="$HOME/Library/Application Support/MobileSync/Backup" +if [ -d "$BACKUP_ROOT" ]; then + echo "3. Бэкапы iOS (MobileSync):" + du -sh "$BACKUP_ROOT" 2>/dev/null || true + for dir in "$BACKUP_ROOT"/*/; do + [ -d "$dir" ] || continue + name=$(basename "$dir") + size=$(du -sh "$dir" 2>/dev/null | cut -f1) + age_days=$(( ( $(date +%s) - $(stat -f %m "$dir" 2>/dev/null || echo 0) ) / 86400 )) + echo " $name — $size, изменён ~$age_days дн. назад" + done + echo " Удалять только вручную или через: Системные настройки → Основные → Хранилище → iOS." + if ask " Удалить бэкапы старше 90 дней? (по дате изменения папки)"; then + deleted=0 + for dir in "$BACKUP_ROOT"/*/; do + [ -d "$dir" ] || continue + mtime=$(stat -f %m "$dir" 2>/dev/null || echo 0) + now=$(date +%s) + age_days=$(( ( now - mtime ) / 86400 )) + if [ "$age_days" -gt 90 ]; then + echo " Удаление: $dir (старше ${age_days} дн.)" + rm -rf "$dir" && deleted=$((deleted + 1)) || true + fi + done + echo " ✅ Удалено бэкапов: $deleted" + else + echo " Пропущено" + fi +else + echo "3. Бэкапы iOS: папка не найдена" +fi +echo "" + +# --- 4. Xcode (если установлен) --- +XCODE_DD="$HOME/Library/Developer/Xcode/DerivedData" +if [ -d "$XCODE_DD" ]; then + size=$(du -sh "$XCODE_DD" 2>/dev/null | cut -f1) + echo "4. Xcode DerivedData: $size" + if ask " Удалить DerivedData? (сборки пересоздадутся при следующем открытии проекта)"; then + rm -rf "$XCODE_DD" + echo " ✅ DerivedData удалён" + else + echo " Пропущено" + fi +else + echo "4. Xcode DerivedData: не найден" +fi +echo "" + +# --- 5. ~/.vscode и ~/.windsurf --- +total_editor=0 +for d in "$HOME/.vscode" "$HOME/.windsurf"; do + [ -d "$d" ] && total_editor=1 && break +done +if [ "$total_editor" -eq 1 ]; then + echo "5. Редакторы (если пользуетесь только Cursor):" + [ -d "$HOME/.vscode" ] && echo " ~/.vscode: $(du -sh "$HOME/.vscode" 2>/dev/null | cut -f1)" + [ -d "$HOME/.windsurf" ] && echo " ~/.windsurf: $(du -sh "$HOME/.windsurf" 2>/dev/null | cut -f1)" + if ask " Удалить ~/.vscode и ~/.windsurf? (расширения VS Code/Windsurf придётся поставить заново)"; then + [ -d "$HOME/.vscode" ] && rm -rf "$HOME/.vscode" && echo " ✅ .vscode удалён" + [ -d "$HOME/.windsurf" ] && rm -rf "$HOME/.windsurf" && echo " ✅ .windsurf удалён" + else + echo " Пропущено" + fi +else + echo "5. .vscode / .windsurf: не найдены" +fi +echo "" + +echo "==============================================" +echo " Готово. Свободное место:" +df -h / | tail -1 +echo "==============================================" diff --git a/docs/disk_cleanup/scripts/scan-cleanup-items.sh b/docs/disk_cleanup/scripts/scan-cleanup-items.sh new file mode 100755 index 0000000..d1b4c8d --- /dev/null +++ b/docs/disk_cleanup/scripts/scan-cleanup-items.sh @@ -0,0 +1,356 @@ +#!/bin/bash + +# Скрипт для сканирования элементов, которые можно безопасно удалить при регулярной очистке +# Основано на всех итерациях очистки диска + +# Цвета для вывода +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +echo "==========================================" +echo " Сканирование элементов для регулярной очистки" +echo "==========================================" +echo "" + +TOTAL_SIZE=0 +ITEMS_FOUND=0 + +# Функция для сканирования директории +scan_dir() { + local path="$1" + local name="$2" + local exclude_protected="$3" + + if [ ! -d "$path" ]; then + return + fi + + # Проверка на защищенные элементы + if [ "$exclude_protected" = "true" ]; then + # Проверяем, не является ли это защищенным элементом + case "$path" in + *"/BraveSoftware"*) return ;; + *"/Cursor/User/History"*) return ;; + *"/Cursor/User/workspaceStorage"*) return ;; + *"/Cursor/extensions"*) return ;; + *"/Cursor/logs"*) return ;; + *"/Cursor/CachedData"*) return ;; + *"/.cursor/ai-tracking"*) return ;; + *"/pnpm"*) return ;; + *"/hunabapp-dev/frontend/node_modules"*) return ;; + *"/.gradle"*) return ;; + *"/hunabapp-dev/frontend/android/app/build"*) return ;; + *"/Telegram Desktop"*) return ;; + *"/anytype"*) return ;; + *"/direct-commander"*) return ;; + *"/backup_"*) return ;; + *"/archives_"*) return ;; + *"/methatron/pics/tablecloth/1-7.zip"*) return ;; + esac + fi + + local size=$(du -sm "$path" 2>/dev/null | cut -f1) + if [ -n "$size" ] && [ "$size" -gt 0 ]; then + local size_mb=$size + local size_gb=$(echo "scale=2; $size / 1024" | bc 2>/dev/null || echo "0") + printf " %-60s %8sMB (%sGB)\n" "$name" "$size_mb" "$size_gb" + TOTAL_SIZE=$((TOTAL_SIZE + size)) + ((ITEMS_FOUND++)) + fi +} + +# Функция для сканирования файлов по паттерну +scan_files() { + local pattern="$1" + local name="$2" + local exclude_protected="$3" + + local total=0 + while IFS= read -r file; do + if [ -n "$file" ] && [ -f "$file" ]; then + # Проверка на защищенные элементы + if [ "$exclude_protected" = "true" ]; then + case "$file" in + *"/backup_"*) continue ;; + *"/archives_"*) continue ;; + *"/methatron/pics/tablecloth/1-7.zip"*) continue ;; + *"/legal/legal_education/books/Martin/.../Дополнительный урок по маркам.rar"*) continue ;; + esac + fi + + local size=$(du -sm "$file" 2>/dev/null | cut -f1) + if [ -n "$size" ] && [ "$size" -gt 0 ]; then + total=$((total + size)) + fi + fi + done < <(find ~/code -type f $pattern 2>/dev/null | head -20) + + if [ "$total" -gt 0 ]; then + local size_gb=$(echo "scale=2; $total / 1024" | bc 2>/dev/null || echo "0") + printf " %-60s %8sMB (%sGB)\n" "$name" "$total" "$size_gb" + TOTAL_SIZE=$((TOTAL_SIZE + total)) + ((ITEMS_FOUND++)) + fi +} + +echo -e "${CYAN}=== КРИТИЧЕСКИЙ ПРИОРИТЕТ (кэши разработки) ===${NC}" +echo "" + +# npm кэш +scan_dir "$HOME/.npm" "npm кэш" true +scan_dir "$HOME/.npm/_npx" "npm npx кэш" true + +# node-gyp кэш +scan_dir "$HOME/Library/Caches/node-gyp" "node-gyp кэш" true + +# TypeScript кэш +scan_dir "$HOME/Library/Caches/typescript" "TypeScript кэш" true + +# pip кэш +scan_dir "$HOME/Library/Caches/pip" "pip кэш" true + +# .yarn кэш +scan_dir "$HOME/.yarn" ".yarn кэш" true + +# Colima кэш +scan_dir "$HOME/.colima" "Colima кэш" true +scan_dir "$HOME/Library/Caches/colima" "Colima кэш (Library)" true + +# Codeium/Windsurf кэши +scan_dir "$HOME/.codeium/windsurf" "Codeium/Windsurf кэш" true + +echo "" +echo -e "${CYAN}=== node_modules (исключая защищенные) ===${NC}" +echo "" + +# node_modules (исключая защищенные) +find ~/code -type d -name "node_modules" \ + -not -path "*/venv/*" \ + -not -path "*/.venv/*" \ + -not -path "*/env/*" \ + -not -path "*/hunabapp-dev/frontend/node_modules" \ + -exec du -sh {} \; 2>/dev/null | sort -hr | head -5 | while read size path; do + printf " %-60s %8s\n" "$path" "$size" + local size_mb=$(du -sm "$path" 2>/dev/null | cut -f1) + if [ -n "$size_mb" ]; then + TOTAL_SIZE=$((TOTAL_SIZE + size_mb)) + ((ITEMS_FOUND++)) + fi +done + +echo "" +echo -e "${CYAN}=== BUILD АРТЕФАКТЫ (исключая защищенные) ===${NC}" +echo "" + +# Build артефакты (исключая защищенные) +find ~/code -type d \( -name "build" -o -name "dist" -o -name ".next" -o -name "out" \) \ + -not -path "*/node_modules/*" \ + -not -path "*/venv/*" \ + -not -path "*/.venv/*" \ + -not -path "*/env/*" \ + -not -path "*/site-packages/*" \ + -not -path "*/hunabapp-dev/frontend/android/app/build*" \ + -exec du -sh {} \; 2>/dev/null | sort -hr | head -10 | while read size path; do + printf " %-60s %8s\n" "$path" "$size" + local size_mb=$(du -sm "$path" 2>/dev/null | cut -f1) + if [ -n "$size_mb" ]; then + TOTAL_SIZE=$((TOTAL_SIZE + size_mb)) + ((ITEMS_FOUND++)) + fi +done + +echo "" +echo -e "${CYAN}=== КЭШИ БРАУЗЕРОВ (кроме защищенных) ===${NC}" +echo "" + +# Google Chrome кэш +scan_dir "$HOME/Library/Caches/Google" "Google Chrome кэш" true + +# Firefox кэш +scan_dir "$HOME/Library/Caches/Firefox" "Firefox кэш" true + +# com.brave.Browser кэш (отдельный, не основной) +scan_dir "$HOME/Library/Caches/com.brave.Browser" "Brave Browser кэш (отдельный)" true + +echo "" +echo -e "${CYAN}=== КЭШИ ПРИЛОЖЕНИЙ ===${NC}" +echo "" + +# Notion +scan_dir "$HOME/Library/Application Support/Notion" "Notion кэш" true + +# zoom.us +scan_dir "$HOME/Library/Application Support/zoom.us" "zoom.us кэш" true + +# LibreOffice +scan_dir "$HOME/Library/Application Support/LibreOffice" "LibreOffice кэш" true + +# Movavi +scan_dir "$HOME/Library/Application Support/Movavi" "Movavi кэш" true + +# Ledger Live +scan_dir "$HOME/Library/Application Support/Ledger Live" "Ledger Live кэш" true + +# Syncthing +scan_dir "$HOME/Library/Application Support/Syncthing" "Syncthing кэш" true + +# ResponsivelyApp +scan_dir "$HOME/Library/Application Support/ResponsivelyApp" "ResponsivelyApp кэш" true + +echo "" +echo -e "${CYAN}=== CURSOR КЭШИ (кроме защищенных) ===${NC}" +echo "" + +# Cursor WebStorage +scan_dir "$HOME/Library/Application Support/Cursor/WebStorage" "Cursor WebStorage" true + +# Cursor Partitions +scan_dir "$HOME/Library/Application Support/Cursor/Partitions" "Cursor Partitions" true + +# Cursor projects +scan_dir "$HOME/.cursor/projects" "Cursor projects" true + +# Cursor CachedExtensionVSIXs +scan_dir "$HOME/Library/Application Support/Cursor/CachedExtensionVSIXs" "Cursor CachedExtensionVSIXs" true + +# Cursor logs (старые, если есть) +if [ -d "$HOME/Library/Application Support/Cursor/logs" ]; then + local logs_size=$(du -sm "$HOME/Library/Application Support/Cursor/logs" 2>/dev/null | cut -f1) + if [ -n "$logs_size" ] && [ "$logs_size" -gt 10 ]; then + printf " %-60s %8sMB\n" "Cursor logs (старые)" "$logs_size" + TOTAL_SIZE=$((TOTAL_SIZE + logs_size)) + ((ITEMS_FOUND++)) + fi +fi + +# ShipIt кэш +scan_dir "$HOME/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt" "Cursor ShipIt кэш" true + +echo "" +echo -e "${CYAN}=== СИСТЕМНЫЕ КЭШИ ===${NC}" +echo "" + +# Homebrew кэш +scan_dir "$HOME/Library/Caches/Homebrew" "Homebrew кэш" true + +# GeoServices кэш +scan_dir "$HOME/Library/Caches/GeoServices" "GeoServices кэш" true + +# Apple системные кэши +scan_dir "$HOME/Library/Caches/com.apple.helpd" "com.apple.helpd" true +scan_dir "$HOME/Library/Caches/com.apple.parsecd" "com.apple.parsecd" true +scan_dir "$HOME/Library/Caches/com.apple.appstoreagent" "com.apple.appstoreagent" true +scan_dir "$HOME/Library/Caches/com.apple.CloudTelemetry" "com.apple.CloudTelemetry" true +scan_dir "$HOME/Library/Caches/com.apple.AMPLibraryAgent" "com.apple.AMPLibraryAgent" true +scan_dir "$HOME/Library/Caches/com.apple.AppleMediaServices" "com.apple.AppleMediaServices" true +scan_dir "$HOME/Library/Caches/com.apple.ctcategories.service" "com.apple.ctcategories.service" true +scan_dir "$HOME/Library/Caches/com.apple.amsengagementd" "com.apple.amsengagementd" true +scan_dir "$HOME/Library/Caches/com.apple.tipsd" "com.apple.tipsd" true +scan_dir "$HOME/Library/Caches/com.apple.itunescloudd" "com.apple.itunescloudd" true +scan_dir "$HOME/Library/Caches/com.apple.nbagent" "com.apple.nbagent" true +scan_dir "$HOME/Library/Caches/askpermissiond" "askpermissiond" true +scan_dir "$HOME/Library/Caches/com.apple.python" "com.apple.python" true +scan_dir "$HOME/Library/Caches/audioCache.kcache" "audioCache.kcache" true +scan_dir "$HOME/Library/Caches/Mega" "Mega кэш" true +scan_dir "$HOME/Library/Caches/kdenlive" "kdenlive кэш" true + +echo "" +echo -e "${CYAN}=== ЛОГИ ===${NC}" +echo "" + +# Логи Google +scan_dir "$HOME/Library/Logs/Google" "Логи Google" true + +# Пустые логи +local empty_logs=$(find ~/Library/Logs -type f -size 0 2>/dev/null | wc -l | tr -d ' ') +if [ "$empty_logs" -gt 0 ]; then + printf " %-60s %8s файлов\n" "Пустые логи" "$empty_logs" +fi + +echo "" +echo -e "${CYAN}=== PYTHON КЭШИ ===${NC}" +echo "" + +# __pycache__ в venv +find ~/code -type d -name "__pycache__" \ + -path "*/venv/*" -o -path "*/.venv/*" -o -path "*/env/*" \ + -exec du -sh {} \; 2>/dev/null | sort -hr | head -10 | while read size path; do + printf " %-60s %8s\n" "$path" "$size" + local size_mb=$(du -sm "$path" 2>/dev/null | cut -f1) + if [ -n "$size_mb" ]; then + TOTAL_SIZE=$((TOTAL_SIZE + size_mb)) + ((ITEMS_FOUND++)) + fi +done + +echo "" +echo -e "${CYAN}=== ЗАПИСИ ЭКРАНА ===${NC}" +echo "" + +# ScreenRecordings +scan_dir "$HOME/Library/ScreenRecordings" "ScreenRecordings" true + +echo "" +echo -e "${CYAN}=== СТАРЫЕ АРХИВЫ (опционально) ===${NC}" +echo "" + +# Старые архивы (исключая защищенные) +find ~/code -type f \( -name "*.zip" -o -name "*.rar" -o -name "*.tar.gz" -o -name "*.7z" \) \ + -not -path "*/backup_*" \ + -not -path "*/archives_*" \ + -not -path "*/methatron/pics/tablecloth/1-7.zip" \ + -size +10M \ + -exec du -sh {} \; 2>/dev/null | sort -hr | head -10 | while read size path; do + printf " %-60s %8s\n" "$path" "$size" + local size_mb=$(du -sm "$path" 2>/dev/null | cut -f1) + if [ -n "$size_mb" ]; then + TOTAL_SIZE=$((TOTAL_SIZE + size_mb)) + ((ITEMS_FOUND++)) + fi +done + +echo "" +echo -e "${CYAN}=== GIT РЕПОЗИТОРИИ (для оптимизации, не удаление) ===${NC}" +echo "" + +# Git репозитории для оптимизации +find ~/code -type d -name ".git" -exec sh -c ' + repo=$(dirname "$1") + git_size=$(du -sm "$repo/.git" 2>/dev/null | cut -f1) + if [ -n "$git_size" ] && [ "$git_size" -gt 100 ]; then + printf " %-60s %8sMB\n" "$repo" "$git_size" + fi +' _ {} \; 2>/dev/null | sort -k2 -nr | head -5 + +echo "" +echo "==========================================" +echo -e " ${GREEN}ИТОГИ СКАНИРОВАНИЯ${NC}" +echo "==========================================" +echo "" +echo -e "Найдено элементов для очистки: ${YELLOW}$ITEMS_FOUND${NC}" +echo "" + +if [ "$TOTAL_SIZE" -gt 0 ]; then + local total_gb=$(echo "scale=2; $TOTAL_SIZE / 1024" | bc 2>/dev/null || echo "0") + echo -e "Общий размер: ${GREEN}${TOTAL_SIZE}MB (~${total_gb}GB)${NC}" +else + echo -e "Общий размер: ${GREEN}0MB${NC}" +fi + +echo "" +echo -e "${YELLOW}⚠️ ВАЖНО:${NC}" +echo " - Защищённые элементы (см. DISK_CLEANUP.md) исключены из сканирования" +echo " - Проверьте список перед удалением" +echo " - Некоторые элементы могут быть пересозданы автоматически" +echo "" +echo -e "${BLUE}💡 РЕКОМЕНДАЦИИ:${NC}" +echo " - Для регулярной очистки используйте: REGULAR_CLEANUP.md" +echo " - Главный документ: DISK_CLEANUP.md" +echo "" + + + diff --git a/docs/disk_cleanup/scripts/scan-move-candidates.sh b/docs/disk_cleanup/scripts/scan-move-candidates.sh new file mode 100644 index 0000000..a4e1888 --- /dev/null +++ b/docs/disk_cleanup/scripts/scan-move-candidates.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Сканирование кандидатов на перенос на внешний носитель (цель — освободить ~100 ГБ). +# Показывает крупные каталоги и опционально — не менявшиеся давно (редко используемые). + +OUTPUT_MODE="${1:-size}" # size | old | both +DAYS_OLD="${2:-90}" # для old: не менявшиеся N дней + +echo "==========================================" +echo " Кандидаты на перенос (освобождение ~100 ГБ)" +echo "==========================================" +echo "" + +echo "=== Крупные каталоги в ~/code (топ по размеру) ===" +du -sh ~/code/* 2>/dev/null | sort -hr | head -20 +echo "" + +echo "=== Известные тяжёлые каталоги пользователя ===" +for path in \ + "$HOME/code/legal" \ + "$HOME/g.drive mikhevel" \ + "$HOME/Library/Application Support/Telegram Desktop" \ + "$HOME/code/methatron" \ + "$HOME/code/repo-clean-secrets-workdir-20260303-192601" \ + "$HOME/code/archive" \ + "$HOME/code/backups" \ + "$HOME/code/bots" \ + "$HOME/code/sacred_songs" \ + "$HOME/.gradle" \ + "$HOME/Library/Android/sdk" \ + "$HOME/.cursor" \ + "$HOME/.vscode"; do + if [ -d "$path" ]; then + du -sh "$path" 2>/dev/null + fi +done +echo "" + +if [ "$OUTPUT_MODE" = "old" ] || [ "$OUTPUT_MODE" = "both" ]; then + echo "=== Крупные каталоги в ~/code, не менявшиеся ${DAYS_OLD}+ дней (редко используемые) ===" + find ~/code -maxdepth 2 -type d -mtime +"$DAYS_OLD" -exec du -sh {} \; 2>/dev/null | sort -hr | head -15 + echo "" +fi + +echo "=== Свободное место на корневом разделе ===" +df -h / | tail -1 +echo "" +echo "Цель: не менее 60 ГБ для Asahi Fedora, рекомендуется 80–100 ГБ." +echo "Подробности: docs/disk_cleanup/MOVE_TO_EXTERNAL_100GB.md" diff --git a/docs/firemail/COCKLI_THUNDERBIRD_SETUP.md b/docs/firemail/COCKLI_THUNDERBIRD_SETUP.md new file mode 100644 index 0000000..399f2f8 --- /dev/null +++ b/docs/firemail/COCKLI_THUNDERBIRD_SETUP.md @@ -0,0 +1,274 @@ +# Cock.li + Thunderbird: гайд при проблемном коннекте + +Проверено: с прокси (149.154.64.19) и с DO (hunab-prod) до mail.cock.li открыт только **IMAP 993**. SMTP 465/587 — таймаут. Ниже — как выстроить сетап, чтобы легко отправлять и получать письма из Thunderbird. + +--- + +## Оглавление + +1. [Проверенные настройки cock.li](#проверенные-настройки-cockli) +2. [Проверка доступа с серверов](#проверка-доступа-с-серверов) +3. [Приём писем (IMAP) через туннель](#приём-писем-imap-через-туннель) +4. [Отправка (SMTP) — варианты](#отправка-smtp--варианты) +5. [Настройки в Thunderbird](#настройки-в-thunderbird) +6. [Команды для копирования](#команды-для-копирования) + +--- + +## Проверенные настройки cock.li + +**Сервер:** `mail.cock.li` (для прокси без DNS использовать IP: `37.120.193.124`). + +### SMTP (отправка) + +| Параметр | Значение | +|-----------------|----------| +| Сервер | `mail.cock.li` | +| Порт SSL | **465** (SSL/TLS) | +| Порт STARTTLS | **587** (STARTTLS) | +| Шифрование | Обязательно SSL/TLS или STARTTLS | +| Логин | Полный адрес `user@domain.cock.li` | + +### IMAP (приём) + +| Параметр | Значение | +|-----------------|----------| +| Сервер | `mail.cock.li` (или `37.120.193.124` с прокси) | +| Порт SSL | **993** (SSL/TLS) ✅ доступен с прокси и DO | +| Порт STARTTLS | **143** (STARTTLS) | +| Шифрование | Обязательно | +| Логин | Полный адрес `user@domain.cock.li` | + +--- + +## Проверка доступа с серверов + +### Валидация одной командой (с DO) + +Скрипт проверяет IMAP 993 и SMTP 465/587. Запуск **с твоей машины** (скрипт выполнится на DO): + +```bash +ssh hunab-prod 'bash -s' < docs/firemail/validate_mail_from_do.sh +``` + +**Ожидаемый результат с DO (2026-03-07):** + +| Сервис | Результат | Комментарий | +|---------------|-----------|-------------| +| IMAP 993 | OK | Приём почты через туннель возможен | +| SMTP 587 | FAIL | Таймаут с хостинга; не мешает туннелю IMAP | +| SMTP 465 | FAIL | Таймаут с хостинга | + +Итог: **почта по IMAP с DO работает.** SMTP с DO до cock.li недоступен — отправка только с машины (если 587 открыт) или через webmail. + +### С прокси (149.154.64.19) + +```bash +# IMAP 993 — OK +ssh -o StrictHostKeyChecking=accept-new -i "$HOME/.ssh/id_ed25519" ahau@149.154.64.19 \ + "echo 'Q' | timeout 12 openssl s_client -connect 37.120.193.124:993 -servername mail.cock.li -brief 2>&1" + +# SMTP 465 / 587 — таймаут с прокси +``` + +На прокси нет DNS для `mail.cock.li` (NXDOMAIN), поэтому подключаться по IP: `37.120.193.124`, с `-servername mail.cock.li` для SNI. + +### С Digital Ocean (hunab-prod) + +```bash +# IMAP 993 — OK +ssh hunab-prod "timeout 12 openssl s_client -connect 37.120.193.124:993 -servername mail.cock.li -brief &1" + +# SMTP 465 / 587 — таймаут с DO +``` + +### Локальная проверка SMTP (если у тебя открыт cock.li) + +```bash +openssl s_client -connect mail.cock.li:587 -starttls smtp -servername mail.cock.li -brief &1" +``` + +### 7. Проверка IMAP 993 с DO + +```bash +ssh hunab-prod "timeout 12 openssl s_client -connect 37.120.193.124:993 -servername mail.cock.li -brief &1" +``` + +### 8. Проверка SMTP 587 локально + +```bash +openssl s_client -connect mail.cock.li:587 -starttls smtp -servername mail.cock.li -brief +``` + +--- + +## Итог + +| Направление | Как сделать | +|-------------|-------------| +| **Приём (IMAP)** | Туннель `-L 9143:37.120.193.124:993` на прокси или DO; в Thunderbird — 127.0.0.1:9143, без SSL. | +| **Отправка (SMTP)** | Либо прямой mail.cock.li:587 (если доступен), либо свой SMTP-релей + туннель, либо только webmail. | + +Дата гайда: 2026-03-07. Валидация с DO: `validate_mail_from_do.sh` — IMAP 993 OK, SMTP 465/587 недоступны с хостинга. diff --git a/docs/firemail/YANDEX_THUNDERBIRD_DOWNLOAD_DELETE.md b/docs/firemail/YANDEX_THUNDERBIRD_DOWNLOAD_DELETE.md new file mode 100644 index 0000000..c09621f --- /dev/null +++ b/docs/firemail/YANDEX_THUNDERBIRD_DOWNLOAD_DELETE.md @@ -0,0 +1,68 @@ +# Яндекс.Почта в Thunderbird: выгрузка с удалением с сервера + +Чтобы при получении почты в Thunderbird письма **удалялись с Яндекса** (оставались только локально), нужно использовать **POP3**, а не IMAP, и отключить хранение на сервере. + +--- + +## Почему POP3, а не IMAP + +| Протокол | Поведение | +|----------|-----------| +| **IMAP** | Письма всегда синхронизированы с сервером. Удаление в клиенте обычно только помечает/удаляет на сервере — нет режима «забрал и стёр с сервера» одной настройкой. | +| **POP3** | Клиент **забирает** письма. Есть опция «не оставлять на сервере» — после загрузки Thunderbird даёт команду серверу удалить письмо. | + +Итог: для сценария «выгрузил в Thunderbird → с Яндекса всё удалилось» используем POP3. + +--- + +## Настройка учётной записи в Thunderbird + +### 1. Добавить учётную запись по POP3 + +- **Тип сервера входящей почты:** POP3 (не IMAP). +- **Сервер:** `pop.yandex.com` +- **Порт:** 995 +- **Шифрование:** SSL/TLS +- **Логин:** полный адрес (например `pavel@ktoty.info`) +- **Пароль:** пароль от ящика или [пароль приложения](https://yandex.ru/support/id/authorization/app-passwords.html), если включена 2FA. + +### 2. Включить удаление с сервера после загрузки + +В Thunderbird: + +1. **Настройки** → **Параметры учётной записти** (или правый клик по учётной записи → Настройки). +2. Открыть **Параметры сервера** (Server Settings) для этой учётной записи. +3. Снять галочку **«Оставлять сообщения на сервере»** (Leave messages on server). + +После этого при получении почты Thunderbird забирает письма по POP3 и даёт серверу команду удалить их — они остаются только у тебя локально, с Яндекса пропадают. + +--- + +## Краткая сводка (Яндекс → Thunderbird, с удалением с сервера) + +| Параметр | Значение | +|----------|----------| +| Входящий сервер | `pop.yandex.com` | +| Порт | 995 | +| Безопасность | SSL/TLS | +| Логин | полный email | +| **Оставлять сообщения на сервере** | **выключено** | + +--- + +## Исходящая почта (SMTP) + +Если нужно и отправлять письма из этого ящика через Thunderbird: + +- **Сервер:** `smtp.yandex.com` +- **Порт:** 465 (SSL) или 587 (STARTTLS) +- **Логин/пароль:** те же, что для входящей. + +--- + +## Важно + +- После первого получения по POP3 с опцией «не оставлять на сервере» письма с ящика на Яндексе будут удалены. Имеет смысл один раз убедиться, что локально всё подтянулось (папки, нужные письма), прежде чем полагаться на это в постоянном режиме. +- Если нужен и доступ с веба, и в Thunderbird с удалением с сервера — на сервере ничего не останется после загрузки в TB; веб-интерфейс будет пустой для этого ящика по входящим. + +Дата: 2026-03-07. diff --git a/docs/firemail/validate_mail_from_do.sh b/docs/firemail/validate_mail_from_do.sh new file mode 100644 index 0000000..fc00b04 --- /dev/null +++ b/docs/firemail/validate_mail_from_do.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# Проверка доступа к mail.cock.li (IMAP/SMTP) с текущей машины. +# Запуск на DO: ssh hunab-prod 'bash -s' < docs/firemail/validate_mail_from_do.sh +# Или скопировать на сервер и запустить там. + +MAIL_IP="${MAIL_IP:-37.120.193.124}" +MAIL_HOST="${MAIL_HOST:-mail.cock.li}" +TIMEOUT=10 + +check() { + local name="$1" + local cmd="$2" + if eval "$cmd" >/dev/null 2>&1; then + echo "OK $name" + return 0 + else + echo "FAIL $name" + return 1 + fi +} + +echo "Проверка доступа к $MAIL_HOST ($MAIL_IP)" +echo "----------------------------------------" + +# IMAP 993 +check "IMAP 993 (SSL)" \ + "timeout $TIMEOUT openssl s_client -connect $MAIL_IP:993 -servername $MAIL_HOST -brief &1 | grep -q 'CONNECTION ESTABLISHED'" + +# SMTP 587 +check "SMTP 587 (STARTTLS)" \ + "timeout $TIMEOUT openssl s_client -connect $MAIL_IP:587 -starttls smtp -servername $MAIL_HOST -brief &1 | grep -q 'CONNECTION ESTABLISHED'" || true + +# SMTP 465 +check "SMTP 465 (SSL)" \ + "timeout $TIMEOUT openssl s_client -connect $MAIL_IP:465 -servername $MAIL_HOST -brief &1 | grep -q 'CONNECTION ESTABLISHED'" || true + +echo "----------------------------------------" +echo "Итог: IMAP 993 должен быть OK для приёма почты через туннель." +echo "SMTP 465/587 часто недоступны с хостингов (DO и др.); отправка — напрямую с машины или через webmail." diff --git a/docs/git/GITEA_COMPLETE_GUIDE.md b/docs/git/GITEA_COMPLETE_GUIDE.md new file mode 100644 index 0000000..5b83bf6 --- /dev/null +++ b/docs/git/GITEA_COMPLETE_GUIDE.md @@ -0,0 +1,1863 @@ +# Gitea Complete Guide - Hunab.app + +> **Для репозитория legal на сервере 206.189.35.205** см. **[GITEA_LEGAL_206_SERVER_GUIDE.md](./GITEA_LEGAL_206_SERVER_GUIDE.md)** (единый стандарт: push, пути, мониторинг). +> Ниже — гайд по Gitea для Hunab.app (основной сервер 209.38.32.21). + +--- + +**Дата:** 2026-01-02 +**Версия Gitea:** 1.25.3 +**Статус:** ✅ Полностью развернут и работает +**Последнее обновление:** Резервный способ коммитов через временный скрипт (2026-02-16) + +--- + +## 📋 Обзор + +Gitea успешно развернут на production сервере как self-hosted альтернатива GitHub. + +### Преимущества +- ✅ Полный контроль данных (код на вашем сервере) +- ✅ Бесплатно для неограниченного числа репозиториев +- ✅ Нет лимитов на CI/CD минуты +- ✅ Низкая задержка (локальная сеть) +- ✅ Интеграция с существующей инфраструктурой + +### Текущая конфигурация +- **Домен:** https://gitea.hunab.app +- **Сервер:** 209.38.32.21 +- **HTTP порт:** 3000 (внутренний) +- **SSH порт:** 2223 (внешний) +- **База данных:** PostgreSQL (hunabgit) - **СТАНДАРТ** +- **SSL:** Let's Encrypt, TLSv1.2/TLSv1.3 +- **Контейнер:** `gitea` +- **Сеть:** `hunab-network` + +**⚠️ ВАЖНО:** PostgreSQL является стандартом для всех развертываний Gitea. MySQL и SQLite не используются. + +--- + +## 🚀 Развертывание + +### Быстрый старт + +```bash +# Развертывание Gitea +bash scripts/deployment/gitea/deploy-gitea.sh + +# Настройка +bash scripts/deployment/gitea/setup-gitea.sh + +# Тестирование +bash scripts/deployment/gitea/test-gitea.sh +``` + +### Docker Compose (для reference) + +```yaml +version: "3" +services: + gitea: + image: gitea/gitea:1.25.3 + container_name: gitea + restart: always + networks: + - hunab-network + ports: + - "3000:3000" + - "2223:22" + volumes: + - /opt/gitea:/data + environment: + - USER_UID=1000 + - USER_GID=1000 +``` + +--- + +## 🗄️ База данных PostgreSQL + +**⚠️ СТАНДАРТ (ОБЯЗАТЕЛЬНО К СОБЛЮДЕНИЮ):** PostgreSQL является ЕДИНСТВЕННЫМ стандартом для всех развертываний Gitea. MySQL и SQLite ЗАПРЕЩЕНЫ. + +### ✅ PostgreSQL - ОБЯЗАТЕЛЬНЫЙ СТАНДАРТ + +- ✅ **Используется на основном сервере** (209.38.32.21) +- ✅ **Используется на зеркальном сервере** (206.189.35.205) +- ✅ **ОБЯЗАТЕЛЕН для всех новых развертываний** +- ✅ **ОБЯЗАТЕЛЕН для всех существующих развертываний** (миграция с MySQL/SQLite) +- ✅ Лучшая производительность для больших репозиториев +- ✅ Поддержка транзакций и ACID +- ✅ Масштабируемость и надежность + +### ❌ MySQL и SQLite - ЗАПРЕЩЕНЫ + +- ❌ **ЗАПРЕЩЕНО использовать MySQL** в проекте +- ❌ **ЗАПРЕЩЕНО использовать SQLite** в production +- ❌ Ошибка "dial tcp [::1]:3306" означает попытку подключения к MySQL - **НЕДОПУСТИМО** + +### Стандартная конфигурация + +**Основной сервер (209.38.32.21):** +```ini +[database] +DB_TYPE = postgres +HOST = hunab-prod-postgres:5432 +NAME = hunabgit +USER = hunabgit +PASSWD = YOUR_PASSWORD +SSL_MODE = disable +CHARSET = utf8mb4 +``` + +**Зеркальный сервер (206.189.35.205):** +```ini +[database] +DB_TYPE = postgres +HOST = gitea-mirror-postgres:5432 +NAME = hunabgit +USER = utils # ⚠️ На зеркальном сервере используется пользователь utils +PASSWD = YOUR_PASSWORD +SSL_MODE = disable +CHARSET = utf8mb4 +``` + +**⚠️ КРИТИЧЕСКИ ВАЖНО:** +- ❌ Параметр `PATH` ЗАПРЕЩЕН (используется только для SQLite) +- ❌ `HOST = localhost:3306` ЗАПРЕЩЕН (это MySQL порт) +- ✅ Обязательно использовать имя контейнера PostgreSQL в Docker сети +- ⚠️ **На зеркальном сервере используется пользователь `utils` вместо `hunabgit`** + +### Создание пользователя utils для зеркального сервера + +**Проблема:** Если пользователь `utils` не существует или имеет неправильный пароль, Gitea не сможет подключиться к PostgreSQL. + +**Решение:** + +#### Автоматический скрипт (рекомендуется) + +```bash +# На сервере 206.189.35.205 +bash scripts/deployment/fix-postgres-utils-user.sh +``` + +#### Ручное создание пользователя + +```bash +# Определение суперпользователя PostgreSQL +POSTGRES_SUPERUSER=$(docker inspect gitea-mirror-postgres | grep -oP '(?<="POSTGRES_USER=")[^"]*' | head -1 || echo "postgres") + +# Если не найден, пробуем стандартные варианты +if [ -z "$POSTGRES_SUPERUSER" ] || [ "$POSTGRES_SUPERUSER" = "null" ]; then + if docker exec gitea-mirror-postgres psql -U postgres -d postgres -c "SELECT 1;" > /dev/null 2>&1; then + POSTGRES_SUPERUSER="postgres" + elif docker exec gitea-mirror-postgres psql -U hunabgit -d postgres -c "SELECT 1;" > /dev/null 2>&1; then + POSTGRES_SUPERUSER="hunabgit" + else + POSTGRES_SUPERUSER="postgres" + fi +fi + +# Создание или изменение пароля для utils +docker exec gitea-mirror-postgres psql -U $POSTGRES_SUPERUSER -d postgres << 'SQL' +DO $$ +BEGIN + IF NOT EXISTS (SELECT FROM pg_user WHERE usename = 'utils') THEN + CREATE USER utils WITH PASSWORD 'YOUR_PASSWORD'; + ELSE + ALTER USER utils WITH PASSWORD 'YOUR_PASSWORD'; + END IF; +END +$$; +SQL + +# Предоставление прав +docker exec gitea-mirror-postgres psql -U $POSTGRES_SUPERUSER -d postgres -c "GRANT ALL PRIVILEGES ON DATABASE hunabgit TO utils;" +docker exec gitea-mirror-postgres psql -U $POSTGRES_SUPERUSER -d hunabgit -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO utils;" +docker exec gitea-mirror-postgres psql -U $POSTGRES_SUPERUSER -d hunabgit -c "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO utils;" +docker exec gitea-mirror-postgres psql -U $POSTGRES_SUPERUSER -d hunabgit -c "GRANT CREATE ON SCHEMA public TO utils;" + +# Проверка +docker exec gitea-mirror-postgres psql -U utils -d hunabgit -c "SELECT version();" +``` + +**Диагностика проблем:** + +1. **"role \"utils\" does not exist"** - Пользователь не создан: + ```bash + docker exec gitea-mirror-postgres psql -U postgres -d postgres -c "CREATE USER utils WITH PASSWORD 'YOUR_PASSWORD';" + ``` + +2. **"password authentication failed"** - Пароль неверный: + ```bash + docker exec gitea-mirror-postgres psql -U postgres -d postgres -c "ALTER USER utils WITH PASSWORD 'YOUR_PASSWORD';" + ``` + +3. **"permission denied for database"** - Нет прав: + ```bash + docker exec gitea-mirror-postgres psql -U postgres -d postgres -c "GRANT ALL PRIVILEGES ON DATABASE hunabgit TO utils;" + ``` + +**Проверка после создания:** +```bash +docker exec gitea-mirror-postgres psql -U utils -d hunabgit -c "SELECT 1;" +# Должно вернуть: 1 без ошибок +``` + +### Настройка через веб-интерфейс + +При первом запуске http://209.38.32.21:3000: + +**Database Settings (СТАНДАРТ - PostgreSQL):** +- **Database Type:** `PostgreSQL` ⚠️ **ОБЯЗАТЕЛЬНО PostgreSQL, НЕ MySQL, НЕ SQLite** +- **Host:** `hunab-prod-postgres:5432` (для основного сервера) или `gitea-mirror-postgres:5432` (для зеркального) +- **Database Name:** `hunabgit` ⚠️ **НЕ gitea!** +- **Username:** `hunabgit` (основной) или `utils` (зеркальный) +- **Password:** `YOUR_PASSWORD` +- **SSL Mode:** `disable` + +**General Settings:** +- Domain: `gitea.hunab.app` +- SSH Port: `2223` +- HTTP Port: `3000` +- Gitea Base URL: `https://gitea.hunab.app` + +**Administrator Account:** +- Username: `hunabgit` +- Email: `mikhevel@gmail.com` +- Password: (надежный пароль) + +--- + +## 🔐 SSL Configuration + +### Сертификат Let's Encrypt + +```bash +# Получение сертификата +sudo certbot certonly --standalone -d gitea.hunab.app + +# Копирование в рабочую директорию +sudo cp /etc/letsencrypt/live/gitea.hunab.app/fullchain.pem /opt/app/ssl/gitea-fullchain.pem +sudo cp /etc/letsencrypt/live/gitea.hunab.app/privkey.pem /opt/app/ssl/gitea-privkey.pem +``` + +### Nginx Configuration + +Конфигурация находится в `docker/nginx/environments/gitea.conf`: + +```nginx +# HTTP → HTTPS redirect +server { + listen 80; + server_name gitea.hunab.app; + return 301 https://$host$request_uri; +} + +# HTTPS server +# CRITICAL: HTTP/2 disabled - git operations require HTTP/1.1 +server { + listen 443 ssl; + # http2 on; # DISABLED: git operations don't work well with HTTP/2 + server_name gitea.hunab.app; + + # SSL configuration + ssl_certificate /opt/app/ssl/gitea-fullchain.pem; + ssl_certificate_key /opt/app/ssl/gitea-privkey.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + # Gitea reverse proxy + location / { + proxy_pass http://gitea:3000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_cache_bypass $http_upgrade; + + # Timeouts + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + # Buffer settings + proxy_buffering off; + proxy_request_buffering off; + } + + # Git operations (git-receive-pack, git-upload-pack) - увеличенные таймауты + # CRITICAL: HTTP/2 disabled for git operations (git uses HTTP/1.1) + location ~ ^/.*\.git/(git-receive-pack|git-upload-pack) { + proxy_http_version 1.1; + proxy_pass http://gitea:3000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # CRITICAL: Use keep-alive for stable connection during data transfer + proxy_set_header Connection "keep-alive"; + + # Extended timeouts for git operations (для больших репозиториев) + proxy_connect_timeout 300s; + proxy_send_timeout 600s; + proxy_read_timeout 600s; + + # Buffer settings (отключены для больших файлов) + proxy_buffering off; + proxy_request_buffering off; + client_max_body_size 0; + + # Дополнительные настройки для стабильности + proxy_redirect off; + proxy_set_header Accept-Encoding ""; + } + + # Git info/refs operations - также с увеличенными таймаутами + location ~ ^/.*\.git/info/refs { + proxy_http_version 1.1; + proxy_pass http://gitea:3000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Connection ""; + + # Extended timeouts + proxy_connect_timeout 300s; + proxy_send_timeout 600s; + proxy_read_timeout 600s; + + # Buffer settings + proxy_buffering off; + proxy_request_buffering off; + client_max_body_size 0; + } +} +``` + +**Ключевые особенности:** +- ✅ HTTP/2 отключен для всего server блока (git требует HTTP/1.1) +- ✅ Правильные SSL сертификаты (gitea-fullchain.pem с SAN для gitea.hunab.app) +- ✅ Увеличенные таймауты для git операций (300-600s) +- ✅ Отключена буферизация для больших файлов +- ✅ Специальные location блоки для git операций + +### SSL Optimization + +- ✅ TLSv1.2 и TLSv1.3 +- ✅ Современные cipher suites +- ✅ HSTS enabled (1 год) +- ✅ Security headers +- ✅ Session tickets disabled + +**Рекомендация:** Добавьте DNS CAA запись: +``` +Type: CAA +Name: gitea.hunab.app +Value: 0 issue "letsencrypt.org" +``` + +--- + +## 🔄 Push репозиториев (КРИТИЧЕСКИ ВАЖНО) + +### ❌ Проблема: Push через HTTPS зависает + +При попытке `git push` через HTTPS возникают таймауты: +``` +fatal: unable to access 'https://gitea.hunab.app/...': Recv failure: Operation timed out +``` + +**Корневые причины:** +1. HTTP/2 несовместим с git операциями (git использует HTTP/1.1) +2. Недостаточные таймауты для больших репозиториев +3. Проблемы с keepalive соединениями через reverse proxy +4. Ограничения curl/git на стороне клиента (особенно на macOS) + +**Диагностика в логах Gitea:** +``` +Fail to serve RPC(receive-pack): exit status 128 +fatal: the remote end hung up unexpectedly +``` + +POST запрос доходит до Gitea, но соединение обрывается во время передачи данных. + +### ✅ Систематическое решение: Универсальный скрипт + +**РЕКОМЕНДУЕТСЯ:** Используйте универсальный скрипт, который автоматически выбирает лучший метод: + +```bash +# Обычный скрипт (для работы не из РФ) +bash scripts/deployment/gitea/git-push-gitea.sh [branch] + +# 🇷🇺 ДЛЯ РФ: Скрипт через прокси (ускоряет в 5-10 раз) +bash scripts/deployment/gitea/git-push-gitea-via-proxy.sh [branch] +``` + +**⚠️ КРИТИЧЕСКИ ВАЖНО:** При работе из Российской Федерации **ПРЕДПОЧТИТЕЛЬНО** использовать скрипт с суффиксом `-via-proxy`! + +**🇷🇺 ПРАВИЛО ДЛЯ РФ:** +- ✅ **ВСЕГДА используйте прокси-версии** для push и создания тегов из РФ +- ✅ **Ускорение в 5-10 раз** по сравнению с прямым подключением +- ✅ **Стабильное соединение** через российский прокси-сервер (149.154.64.19) +- ✅ **Избежание таймаутов** - прямое подключение из РФ часто нестабильно + +**Скрипт автоматически:** +1. Пытается SSH push (если доступен, через прокси для `-via-proxy`) +2. Пытается HTTPS push с оптимизированными настройками (только на Linux с `timeout`) +3. Использует bundle метод (всегда работает, особенно на macOS) +4. ✅ **Мгновенная верификация** - обновляет локальный tracking ref напрямую через `git update-ref` (без медленного `git fetch`) + +**Пример:** +```bash +# Push текущей ветки (по умолчанию dev) +bash scripts/deployment/gitea/git-push-gitea.sh + +# 🇷🇺 ДЛЯ РФ: Push через прокси (рекомендуется из РФ) +bash scripts/deployment/gitea/git-push-gitea-via-proxy.sh + +# Push конкретной ветки +bash scripts/deployment/gitea/git-push-gitea.sh main +bash scripts/deployment/gitea/git-push-gitea-via-proxy.sh main # 🇷🇺 ДЛЯ РФ + +# Режим проверки без пуша (ничего не меняет, только показывает сколько коммитов уйдёт) +bash scripts/deployment/gitea/git-push-gitea-via-proxy.sh --dry-run dev +``` + +**Безопасность скрипта пуша:** +- Не трогает текущую ветку, HEAD, рабочую копию и локальные коммиты. +- Не выполняет: `git reset`, `git checkout --hard`, `git clean`, `git branch -D`, `push --force`. +- Единственная запись в репо: обновление `refs/remotes/origin/` только после успешного пуша и только на кончик текущей ветки (все «ждущие пуша» коммиты при этом уже на сервере). +- Перед пушем можно проверить: `--dry-run` — показывает число коммитов к пушу, ничего не отправляет и не меняет. + +**Git Alias (для удобства):** +Добавьте в `~/.gitconfig`: +```ini +[alias] + gpush = !bash -c 'cd "$(git rev-parse --show-toplevel)" && bash scripts/deployment/gitea/git-push-gitea.sh "$@"' - +``` + +Использование: `git gpush dev` + +### ✅ Резервный способ: Временный скрипт для коммита и пуша + +**Когда использовать:** +- Терминал недоступен из-за проблем с zsh/shell +- Агент не может выполнить команды напрямую +- Нужно подготовить все команды заранее + +**Процесс:** +1. **Агент создает временный скрипт** в `temp/commit-and-push.sh` с полным коммитом и push командой +2. **Пользователь выполняет скрипт** вручную в терминале +3. **Скрипт автоматически** делает `git add`, `git commit` и `git push` через универсальный скрипт + +**Формат временного скрипта:** +```bash +#!/bin/bash +# Скрипт для коммита и пуша изменений + +set -e + +echo "📦 Committing changes..." +git add -A + +echo "💾 Creating commit..." +git commit -m "🎨 feat(frontend): центрирование нод при tidyUp с учетом реальных ширин v3.10.4 + +- ✅ Улучшена функция calculateLevelPositions для центрирования нод +- ✅ Добавлен учет реальных ширин нод (node.width или NODE_WIDTH) +- ✅ Вся группа нод на уровне центрируется относительно START_X +- ✅ Более широкие ноды правильно центрированы относительно узких +- ✅ Обновлена документация (TROUBLESHOOTING_COMPLETE.md, CHANGELOG.md) + +Проблема: Более широкие ноды выравнивались по левому краю +Решение: Центрирование с учетом реальных ширин нод +Результат: Ноды центрируются на уровне, визуально выглядит красиво" + +echo "🚀 Pushing to Gitea..." +bash scripts/deployment/gitea/git-push-gitea.sh dev + +echo "✅ Done!" +``` + +**Требования к скрипту:** +- ✅ Должен быть исполняемым (`chmod +x`) +- ✅ Должен содержать полное сообщение коммита с описанием изменений +- ✅ Должен использовать универсальный скрипт `git-push-gitea.sh` для push +- ✅ Должен быть в папке `temp/` для временных скриптов +- ✅ Должен иметь понятные echo сообщения для пользователя + +**Использование:** +```bash +# Выполнить скрипт +bash temp/commit-and-push.sh +``` + +**Очистка:** +После успешного выполнения скрипт можно удалить: +```bash +rm temp/commit-and-push.sh +``` + +**⚠️ ВАЖНО:** +- Скрипт должен быть создан агентом **ПЕРЕД** запросом пользователя на коммит +- Агент должен **ВСЕГДА** готовить скрипт, если терминал недоступен +- Скрипт должен содержать **ПОЛНОЕ** описание изменений в коммите + +### Стандарт: без трейлеров в коммитах + +В проекте **не используются** git-трейлеры в сообщениях коммитов (строки вида `Key: Value` в конце сообщения). Не добавлять: +- `Made-with: Cursor` и аналогичные метки инструмента +- `Co-authored-by:`, `Signed-off-by:` и т.п., если это не требуется явно политикой репозитория + +Коммиты должны соответствовать [COMMIT_STANDARDS.md](../../standards/COMMIT_STANDARDS.md) и содержать только заголовок и при необходимости тело сообщения в стандартном формате. См. также раздел «Commit Quality Standards» в `.cursorrules`. + +### Неблокирующая проверка типов (при коммитах) + +Перед коммитом или пушем можно быстро проверить типы (frontend и/или backend) **без блокировки коммита** — скрипт всегда выходит с кодом 0 и только выводит ошибки в консоль. + +```bash +# Frontend + backend (полный отчёт) +bash scripts/maintenance/typecheck-report.sh + +# Только изменённая часть (быстрее) +bash scripts/maintenance/typecheck-report.sh frontend +bash scripts/maintenance/typecheck-report.sh backend +``` + +Отдельно в пакетах: +- `cd frontend && pnpm typecheck` — только frontend +- `cd backend && pnpm typecheck` — только backend + +**Рекомендация:** запускать при коммитах бэкенда/фронта или перед пушем; коммит не блокируется, но ошибки видны в выводе. + +### Проверка прав на .env после деплоя (SECRETS_AND_FILE_PERMISSIONS_POLICY.md §4) + +После деплоя бэкенда на production выполнить проверку прав на `.env.production` (и при необходимости `.env.staging`) на сервере. Встроена в скрипты `deploy-backend-core-only.sh` и `deploy-backend-core-only-via-proxy.sh`; при необходимости запустить вручную: + +```bash +# После деплоя backend на прод (или вручную) +bash scripts/deployment/verify-env-permissions.sh hunab-prod +# либо с явным хостом +bash scripts/deployment/verify-env-permissions.sh hunab@209.38.32.21 +``` + +Ожидается: права `600` и владелец `hunab:hunab` для всех `.env*` в `/opt/app/`. При несоответствии скрипт выводит предупреждение и команду для исправления; деплой не блокируется (exit 0). + +**Чеклист коммитов/деплоя:** после деплоя backend на production — выполнить проверку прав (или убедиться, что она уже выполнена скриптом деплоя). См. [SECRETS_AND_FILE_PERMISSIONS_POLICY.md](../../security/SECRETS_AND_FILE_PERMISSIONS_POLICY.md) §4. + +### Метод 1: HTTPS с оптимизированными настройками + +```bash +# Настройка git для больших push +git config http.postBuffer 524288000 +git config http.lowSpeedLimit 0 +git config http.lowSpeedTime 0 +git config http.timeout 600 + +# Попытка push +git push origin dev +``` + +**⚠️ На macOS:** HTTPS push часто не работает из-за отсутствия команды `timeout`. Скрипт автоматически пропускает HTTPS и использует bundle метод. + +### Метод 2: Bundle метод (надежный fallback) + +Если HTTPS не работает, используется прямой доступ через файловую систему: + +```bash +# Создать bundle +git bundle create /tmp/push.bundle origin/dev..dev + +# Скопировать на сервер +scp /tmp/push.bundle hunab-prod:/tmp/ + +# Применить в Gitea +ssh hunab-prod "docker cp /tmp/push.bundle gitea:/tmp/push.bundle && \ +docker exec gitea sh -c 'cd /data/git/repositories/hunabgit/hunabapp.git && \ +git bundle unbundle /tmp/push.bundle && \ +git update-ref refs/heads/dev \$(git bundle list-heads /tmp/push.bundle | grep dev | cut -d\" \" -f1) && \ +rm /tmp/push.bundle' && rm /tmp/push.bundle" +``` + +**✅ Статус:** Bundle метод всегда работает и обходит все проблемы с таймаутами. + +### Сравнение методов + +| Метод | Скорость | Надежность | Сложность | Платформа | +|-------|----------|------------|-----------|-----------| +| **SSH** | ⚡⚡⚡ Быстро | ✅✅✅ Высокая | ✅ Просто | Все | +| **HTTPS (оптимизированный)** | ⚡⚡ Средне | ✅✅ Средняя | ✅ Просто | Linux | +| **Bundle (прямой доступ)** | ⚡ Медленно | ✅✅✅ Всегда работает | ⚠️ Сложнее | Все | + +**Рекомендация:** Используйте автоматический скрипт - он выберет лучший метод автоматически. + +### Миграция репозиториев + +**Для регулярных push используйте скрипт:** +```bash +bash scripts/deployment/gitea/git-push-gitea.sh [branch] +``` + +#### Шаг 1: Создание bundle из локального репозитория + +```bash +cd /Users/eternal/code/hunabapp-dev +git bundle create /tmp/hunabapp-migration.bundle --all +``` + +**Результат:** Bundle ~553M + +#### Шаг 2: Копирование bundle на сервер + +```bash +scp /tmp/hunabapp-migration.bundle hunab-prod:/tmp/hunabapp-migration.bundle +``` + +#### Шаг 3: Распаковка bundle на сервере + +```bash +ssh hunab-prod "cd /tmp && git clone --mirror hunabapp-migration.bundle hunabapp-mirror.git" +``` + +**Результат:** Bare репозиторий ~557M + +#### Шаг 4: Копирование в директорию Gitea + +```bash +ssh hunab-prod " + docker exec gitea mkdir -p /data/git/repositories/hunabgit/ + docker cp /tmp/hunabapp-mirror.git gitea:/data/git/repositories/hunabgit/hunabapp.git + docker exec gitea chown -R git:git /data/git/repositories/hunabgit/hunabapp.git +" +``` + +**Результат:** Репозиторий в Gitea (556.6M) + +#### Шаг 5: Распаковка refs из packed-refs + +**КРИТИЧЕСКИ ВАЖНО:** Gitea не видит ветки в `packed-refs`, нужно распаковать: + +```bash +ssh hunab-prod "docker exec gitea sh -c 'cd /data/git/repositories/hunabgit/hunabapp.git && cat packed-refs | grep \"refs/heads/\" | while read sha ref; do mkdir -p \$(dirname \$ref) && echo \$sha > \$ref; done'" +``` + +#### Шаг 6: Обновление базы данных + +```bash +ssh hunab-prod " + docker exec hunab-prod-postgres psql -U hunabgit -d hunabgit -c \"UPDATE repository SET is_empty = false WHERE name = 'hunabapp';\" + docker exec gitea /usr/local/bin/gitea admin regenerate hooks --config /data/gitea/conf/app.ini + docker restart gitea +" +``` + +#### Шаг 7: Проверка + +```bash +# Проверка веток через API +curl -s -H "Authorization: token YOUR_TOKEN" \ + https://gitea.hunab.app/api/v1/repos/hunabgit/hunabapp/branches | jq '.[] | .name' + +# Проверка файлов через API +curl -s -H "Authorization: token YOUR_TOKEN" \ + https://gitea.hunab.app/api/v1/repos/hunabgit/hunabapp/git/trees/dev?recursive=0 | jq '.tree[] | .path' + +# Проверка через веб-интерфейс +https://gitea.hunab.app/hunabgit/hunabapp +``` + +**✅ Результат:** Репозиторий полностью мигрирован, все файлы доступны через веб-интерфейс и API. + +### Аутентификация + +#### Создание токена доступа + +1. Откройте: https://gitea.hunab.app/user/settings/applications +2. Generate New Token +3. Название: `api-access` +4. Права: `write:repository`, `read:repository`, `read:user` +5. Скопируйте токен + +#### Использование токена в git + +```bash +# В локальном репозитории +cd /Users/eternal/code/hunabapp-dev +git remote set-url origin https://TOKEN@gitea.hunab.app/hunabgit/hunabapp.git +``` + +--- + +## 🏷️ Создание тегов и Release (СТАНДАРТ) + +### ⚠️ КРИТИЧЕСКИ ВАЖНО: Gitea не обновляет индекс тегов автоматически + +**Проблема:** Если создать тег напрямую в git репозитории (`git tag -a v1.0.0`), Gitea **НЕ покажет его в веб-интерфейсе** автоматически. Gitea кэширует список тегов и обновляет его только при создании Release через веб-интерфейс или API. + +### ✅ СТАНДАРТ: Создание тега через базу данных (РЕКОМЕНДУЕТСЯ) + +**Используйте этот метод для автоматического создания тегов:** + +```bash +# 1. Получить ID репозитория +REPO_ID=$(ssh hunab-prod "docker exec hunab-prod-postgres psql -U hunabgit -d hunabgit -t -c \"SELECT id FROM repository WHERE lower_name = 'hunabapp';\" | tr -d ' '") + +# 2. Создать Release в базе данных +ssh hunab-prod "docker exec hunab-prod-postgres psql -U hunabgit -d hunabgit -c \" +INSERT INTO release ( + repo_id, + publisher_id, + tag_name, + lower_tag_name, + target, + sha1, + title, + note, + is_draft, + is_prerelease, + is_tag, + created_unix +) VALUES ( + $REPO_ID, + 1, + 'v1.3.7-CRM', + 'v1.3.7-crm', + 'dev', + '1542c302c36ad367281f8d9740e4d9f4a817ad23', + 'v1.3.7-CRM: Полная реализация CRM Contacts Page', + 'feat(CRM): Полная реализация CRM Contacts Page v1.3.7', + false, + false, + true, + EXTRACT(EPOCH FROM NOW())::bigint +) ON CONFLICT (repo_id, tag_name) DO NOTHING +RETURNING id, tag_name, title; +\"" + +# 3. Перезапустить Gitea для обновления индекса +ssh hunab-prod "docker restart gitea" +``` + +**Параметры:** +- `repo_id` - ID репозитория (получить через `SELECT id FROM repository WHERE lower_name = 'hunabapp';`) +- `publisher_id` - ID пользователя (обычно 1 для первого пользователя) +- `tag_name` - Имя тега (например, `v1.3.7-CRM`) +- `lower_tag_name` - Имя тега в нижнем регистре (например, `v1.3.7-crm`) +- `target` - Ветка или commit (например, `dev` или `1542c302c36ad367281f8d9740e4d9f4a817ad23`) +- `sha1` - SHA коммита (40 символов) +- `title` - Заголовок Release +- `note` - Описание Release +- `is_tag` - `true` для тега, `false` для Release + +### ✅ Альтернатива: Создание через веб-интерфейс + +Если нужно создать тег вручную: + +1. Откройте: https://gitea.hunab.app/hunabgit/hunabapp/releases/new +2. В поле "Tag" введите имя тега (например, `v1.3.7-CRM`) +3. В поле "Target" выберите commit из списка или введите SHA +4. Заполните Title и Description +5. Нажмите "Publish Release" + +**⚠️ Недостаток:** Требует ручного действия, не автоматизируется. + +### ✅ Альтернатива: Создание через API (требует токен) + +```bash +# 1. Получить токен доступа (один раз) +TOKEN=$(ssh hunab-prod "docker exec gitea /usr/local/bin/gitea admin user generate-access-token --username hunabgit --scopes 'write:repository' --name 'api-tag-creation' 2>&1 | grep -o '[a-z0-9]\{40\}' | head -1") + +# 2. Создать Release через API +curl -X POST "https://gitea.hunab.app/api/v1/repos/hunabgit/hunabapp/releases" \ + -H "Authorization: token $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "tag_name": "v1.3.7-CRM", + "target_commitish": "1542c302c36ad367281f8d9740e4d9f4a817ad23", + "name": "v1.3.7-CRM: Полная реализация CRM Contacts Page", + "body": "feat(CRM): Полная реализация CRM Contacts Page v1.3.7", + "draft": false, + "prerelease": false + }' +``` + +**⚠️ Недостаток:** Требует токен доступа, который нужно создать заранее. + +### ❌ НЕ РАБОТАЕТ: Создание тега напрямую в git + +```bash +# ❌ НЕ РАБОТАЕТ - Gitea не увидит тег в веб-интерфейсе +git tag -a v1.3.7-CRM -m "Message" +git push origin v1.3.7-CRM # Даже после push тег не появится в веб-интерфейсе +``` + +**Почему не работает:** +- Gitea кэширует список тегов в базе данных +- Создание тега напрямую в git не обновляет таблицу `release` +- Gitea не сканирует репозиторий автоматически для поиска новых тегов + +### 📋 Чеклист создания тега + +- [ ] Получить ID репозитория из базы данных +- [ ] Получить SHA коммита для тега +- [ ] Создать Release в таблице `release` базы данных +- [ ] Перезапустить Gitea для обновления индекса +- [ ] Проверить что тег появился в веб-интерфейсе: https://gitea.hunab.app/hunabgit/hunabapp/releases + +### 🔧 Скрипт для автоматического создания тега + +**Готовый скрипт:** `scripts/deployment/gitea/create-gitea-tag.sh` + +**🇷🇺 ДЛЯ РФ:** Используйте прокси-версию для ускорения в 5-10 раз: +- `scripts/deployment/gitea/create-gitea-tag.sh` - обычный скрипт +- `scripts/deployment/gitea/create-gitea-tag-via-proxy.sh` - **🇷🇺 ДЛЯ РФ** - через прокси + +**Использование:** +```bash +# Обычный скрипт +bash scripts/deployment/gitea/create-gitea-tag.sh \ + \ + \ + \ + [description] \ + [branch] + +# 🇷🇺 ДЛЯ РФ: Через прокси (рекомендуется из РФ) +bash scripts/deployment/gitea/create-gitea-tag-via-proxy.sh \ + <tag-name> \ + <commit-sha> \ + <title> \ + [description] \ + [branch] +``` + +**Пример:** +```bash +bash scripts/deployment/gitea/create-gitea-tag.sh \ + v1.3.7-CRM \ + 1542c302c36ad367281f8d9740e4d9f4a817ad23 \ + "v1.3.7-CRM: Полная реализация CRM Contacts Page" \ + "feat(CRM): Полная реализация CRM Contacts Page v1.3.7" \ + dev +``` + +**Что делает скрипт:** +1. ✅ Валидирует параметры (формат тега, SHA коммита) +2. ✅ Получает ID репозитория из базы данных +3. ✅ Создает Release в таблице `release` +4. ✅ Перезапускает Gitea для обновления индекса +5. ✅ Выводит ссылку для проверки + +**Особенности:** +- Автоматически обрабатывает конфликты (обновляет существующий тег) +- Экранирует специальные символы в SQL +- Проверяет существование репозитория +- Выводит понятные сообщения об ошибках + +--- + +## 📊 Мониторинг + +### Проверка статуса + +```bash +# Контейнер +ssh hunab-prod "docker ps | grep gitea" + +# Логи +ssh hunab-prod "docker logs gitea --tail 50" + +# Ресурсы +ssh hunab-prod "docker stats gitea --no-stream" + +# API +curl https://gitea.hunab.app/api/v1/version + +# SSL +openssl s_client -connect gitea.hunab.app:443 -servername gitea.hunab.app </dev/null 2>&1 | grep -E 'Protocol|Cipher' +``` + +### Проверка репозитория + +```bash +# Ветки +ssh hunab-prod "docker exec gitea git --git-dir=/data/git/repositories/hunabgit/hunabapp.git branch -a | wc -l" + +# Размер +ssh hunab-prod "docker exec gitea du -sh /data/git/repositories/hunabgit/hunabapp.git" + +# Последний коммит +ssh hunab-prod "docker exec gitea git --git-dir=/data/git/repositories/hunabgit/hunabapp.git log -1 --pretty=format:'%H %s'" +``` + +--- + +## 🔧 Troubleshooting + +Для детальной диагностики проблем см. **[GITEA_TROUBLESHOOTING.md](./GITEA_TROUBLESHOOTING.md)** - Полное руководство по решению проблем. + +Для диагностики зеркального сервера см. **[GITEA_MIRROR_TROUBLESHOOTING.md](./GITEA_MIRROR_TROUBLESHOOTING.md)**. + +### Gitea не запускается + +```bash +# Проверка логов +ssh hunab-prod "docker logs gitea --tail 100" + +# Проверка портов +ssh hunab-prod "ss -tuln | grep -E '3000|2223'" + +# Перезапуск +ssh hunab-prod "docker restart gitea" +``` + +### Ветки не видны в веб-интерфейсе + +**Причина:** Refs в `packed-refs`, Gitea их не читает + +**Решение:** Распаковать refs (см. Шаг 5 миграции) + +**✅ Статус:** Проблема решена, все ветки видны в веб-интерфейсе + +### Git hooks кажутся сломанными + +**Проблема:** Gitea показывает предупреждение "Git hooks of this repository seem to be broken" + +**Причина:** После прямой миграции репозитория hooks могут быть не синхронизированы с Gitea + +**Решение:** Регенерировать hooks для всех репозиториев: + +```bash +ssh hunab-prod "docker exec gitea /usr/local/bin/gitea admin regenerate hooks --config /data/gitea/conf/app.ini" +``` + +**Проверка:** +```bash +# Проверка прав на hooks +ssh hunab-prod "docker exec gitea ls -la /data/git/repositories/hunabgit/hunabapp.git/hooks/pre-receive" + +# Проверка содержимого hooks +ssh hunab-prod "docker exec gitea cat /data/git/repositories/hunabgit/hunabapp.git/hooks/pre-receive.d/gitea" +``` + +**Дополнительно:** Если проблема сохраняется, проверьте: +1. Файловая система поддерживает выполнение (`chmod +x` работает) +2. Файловая система не смонтирована с `noexec` +3. Docker версия >= 20.10.6 (у нас 28.0.1 ✅) + +**См. документацию Gitea:** https://docs.gitea.com/help/faq#push-hook--webhook--actions-arent-running + +**✅ Статус:** Решено через `gitea admin regenerate hooks` + +### Push через HTTPS зависает + +**Проблема:** Git получает refs (GET запрос успешен), но POST запрос с данными не отправляется или соединение обрывается. + +**Причина:** +- Известная проблема с HTTP/2 и большими репозиториями в Gitea +- Проблемы с keepalive соединениями через reverse proxy +- Ограничения curl/git на стороне клиента (особенно на macOS) + +**Решение:** +1. ✅ **Используйте универсальный скрипт:** `bash scripts/deployment/gitea/git-push-gitea.sh [branch]` +2. ✅ Скрипт автоматически выбирает лучший метод (SSH > HTTPS > Bundle) +3. ✅ На macOS автоматически использует bundle метод (обходит проблемы с HTTPS) + +**✅ Статус:** Систематически решено через универсальный скрипт (2026-01-02) + +### SSL сертификат не обновляется + +```bash +# Проверка автообновления +ssh hunab-prod "systemctl status certbot.timer" + +# Ручное обновление +ssh hunab-prod "sudo certbot renew --dry-run" + +# Копирование новых сертификатов +ssh hunab-prod "sudo cp /etc/letsencrypt/live/gitea.hunab.app/*.pem /opt/app/ssl/ && docker restart hunab-prod-nginx" +``` + +--- + +## 🔒 Безопасность + +### Рекомендации + +1. ✅ HTTPS через Let's Encrypt (настроено) +2. ✅ Modern SSL/TLS protocols (TLSv1.2, TLSv1.3) +3. ✅ Security headers (HSTS, X-Frame-Options, etc.) +4. ⚠️ Firewall для ограничения доступа (рекомендуется) +5. ✅ SSH ключи для git операций +6. ✅ Регулярные бэкапы данных + +### Бэкапы + +```bash +# Полный бэкап Gitea +ssh hunab-prod " + tar -czf /opt/gitea-backup-$(date +%Y%m%d).tar.gz /opt/gitea +" + +# Бэкап только репозиториев +ssh hunab-prod " + tar -czf /opt/gitea-repos-backup-$(date +%Y%m%d).tar.gz /opt/gitea/git/repositories +" + +# Бэкап базы данных +ssh hunab-prod " + docker exec hunab-prod-postgres pg_dump -U hunabgit hunabgit > /opt/gitea-db-backup-$(date +%Y%m%d).sql +" +``` + +--- + +## 📈 Итоги и выводы + +### Что было достигнуто + +1. ✅ **Gitea развернут на production** (209.38.32.21) +2. ✅ **PostgreSQL настроен** (отдельная БД hunabgit) +3. ✅ **SSL/TLS настроен** (Let's Encrypt, A rating) +4. ✅ **Nginx reverse proxy** (с оптимизацией) +5. ✅ **Репозиторий hunabapp мигрирован** (556.8M, 23 ветки, все файлы доступны) +6. ✅ **DNS настроен** (gitea.hunab.app → 209.38.32.21) +7. ✅ **Веб-интерфейс работает** (файлы отображаются корректно) +8. ✅ **API полностью функционален** (все endpoints работают) + +### Ключевые проблемы и решения + +#### Проблема 1: MySQL vs PostgreSQL +- **Проблема:** Gitea пытался подключиться к несуществующему MySQL +- **Решение:** Настроили PostgreSQL с отдельной БД + +#### Проблема 2: SSL сертификат для поддомена +- **Проблема:** Существующий сертификат был для hunab.app, не gitea.hunab.app +- **Решение:** Получили новый сертификат через certbot --standalone + +#### Проблема 3: Push через HTTPS зависает +- **Проблема:** Git получает refs, но POST запрос с данными не отправляется или соединение обрывается +- **Причина:** Известная проблема с HTTP/2 и большими репозиториями в Gitea, проблемы с keepalive соединениями +- **Попытки:** Увеличение таймаутов Nginx до 600s, отключение HTTP/2, оптимизация Connection headers +- **Решение:** Систематическое решение через универсальный скрипт `git-push-gitea.sh` (2026-01-02) + - Автоматический выбор метода: SSH > HTTPS > Bundle + - На macOS автоматически использует bundle метод + - Всегда работает, обходит все проблемы с таймаутами + +#### Проблема 4: Gitea не видит ветки +- **Проблема:** Refs в packed-refs, Gitea их не индексирует +- **Решение:** Распаковали refs в refs/heads/ структуру + +#### Проблема 5: GitHub требует аутентификацию +- **Проблема:** git clone --mirror с сервера не работает без токена +- **Решение:** Использовали bundle, созданный локально + +### Lessons Learned + +1. **Прямое копирование эффективнее push** для больших репозиториев +2. **packed-refs не поддерживается Gitea** — нужна распаковка +3. **certbot --standalone** проще для новых сертификатов +4. **Docker network** критичен для PostgreSQL подключения +5. **Bundle** — универсальный способ переноса репозиториев + +### Производительность + +- **Обычный git push через HTTPS:** ❌ Зависает (POST запрос не отправляется или соединение обрывается) +- **Универсальный скрипт (git-push-gitea.sh):** ✅ Автоматически выбирает лучший метод + - SSH: ⚡⚡⚡ Быстро (если доступен) + - HTTPS: ⚡⚡ Средне (только на Linux) + - Bundle: ⚡ Медленно, но всегда работает (особенно на macOS) +- **🇷🇺 ДЛЯ РФ: Прокси-версия (git-push-gitea-via-proxy.sh):** ✅ Ускорение в 5-10 раз + - Работает через российский прокси-сервер (149.154.64.19) + - Стабильное соединение к Digital Ocean + - Избежание таймаутов при работе из РФ + - Bundle метод через прокси: ⚡⚡ Быстро и надежно + - ✅ **Мгновенная верификация** - обновление tracking ref без сетевых запросов (2026-02-27) +- **Прямое копирование через bundle:** ✅ ~1-2 минуты для инкрементальных обновлений +- **Полная миграция:** ✅ ~5-10 минут (включая распаковку refs) +- **Размер репозитория:** 556.8M (23 ветки, история с 2020 года) +- **Текущий статус:** ✅ Все файлы доступны, веб-интерфейс работает корректно +- **Скрипт для push:** ✅ `scripts/deployment/gitea/git-push-gitea.sh` - универсальное решение (2026-01-02) + +### Следующие шаги (опционально) + +1. **Настроить CI/CD** в Gitea (Gitea Actions) +2. **Настроить зеркалирование** GitHub ↔ Gitea (для резервирования) +3. **Настроить SSH ключи** для бесшовной работы +4. **Добавить DNS CAA запись** для дополнительной безопасности +5. **Настроить автоматические бэкапы** (cron job) +6. **Мигрировать deployment скрипты** на использование Gitea + +--- + +## 📚 Полезные команды + +```bash +# Push репозитория (РЕКОМЕНДУЕТСЯ) +bash scripts/deployment/gitea/git-push-gitea.sh [branch] + +# 🇷🇺 ДЛЯ РФ: Push через прокси (ускоряет в 5-10 раз) +bash scripts/deployment/gitea/git-push-gitea-via-proxy.sh [branch] + +# Gitea Admin Commands +docker exec gitea /usr/local/bin/gitea admin --help +docker exec gitea /usr/local/bin/gitea admin regenerate hooks + +# Git операции в Gitea +docker exec gitea git --git-dir=/data/git/repositories/hunabgit/hunabapp.git branch -a +docker exec gitea git --git-dir=/data/git/repositories/hunabgit/hunabapp.git log --oneline -10 + +# PostgreSQL операции +docker exec hunab-prod-postgres psql -U hunabgit -d hunabgit -c "SELECT * FROM repository;" + +# Проверка конфигурации базы данных +docker exec gitea cat /data/gitea/conf/app.ini | grep -A 10 '\[database\]' +# Должно быть: DB_TYPE = postgres, HOST = <postgres-container>:5432 + +# SSL проверка +openssl s_client -connect gitea.hunab.app:443 -servername gitea.hunab.app +curl -vI https://gitea.hunab.app 2>&1 | grep -E 'SSL|TLS' + +# Nginx +docker exec hunab-prod-nginx nginx -t +docker logs hunab-prod-nginx --tail 50 + +# Проверка логов Gitea при push +ssh hunab-prod "docker logs gitea --tail 50 | grep -E '(receive-pack|upload-pack|error)'" +``` + +--- + +## 🔄 Зеркалирование + +Для полного руководства по зеркалированию см. **[GITEA_MIRRORING_GUIDE.md](./GITEA_MIRRORING_GUIDE.md)**. + +### Миграция Gitea на зеркальный сервер + +**📋 План миграции:** См. **[GITEA_MIGRATION_TO_MIRROR_SERVER.md](./GITEA_MIGRATION_TO_MIRROR_SERVER.md)** - Детальный план миграции Gitea с production сервера (209.38.32.21) на зеркальный сервер (206.189.35.205). + +**Причины миграции:** +- Освобождение дискового пространства на production сервере (96% заполнено) +- Изоляция рисков - проблемы Gitea не влияют на production +- Улучшение производительности Git операций +- Масштабируемость + +### Зеркальный сервер (206.189.35.205) + +Для резервирования и высокой доступности настроено зеркалирование всех репозиториев на внешний сервер. + +**Документация:** +- [Gitea Mirroring Guide](./GITEA_MIRRORING_GUIDE.md) - Полный план зеркалирования +- [Gitea Migration to Mirror Server](./GITEA_MIGRATION_TO_MIRROR_SERVER.md) - **План миграции Gitea на зеркальный сервер (206.189.35.205)** +- [Gitea Mirror Troubleshooting](./GITEA_MIRROR_TROUBLESHOOTING.md) - Диагностика зеркального сервера +- [Gitea Legal — сервер 206.189.35.205](./GITEA_LEGAL_206_SERVER_GUIDE.md) - Стандарт для репозитория legal + +**Быстрый старт:** +```bash +# Развертывание зеркального сервера +bash scripts/deployment/gitea/deploy-gitea-mirror-server.sh + +# Миграция всех репозиториев +bash scripts/deployment/mirror-all-repos-to-external.sh +``` + +**Архитектура:** +- **Основной сервер (209.38.32.21):** Primary Gitea, все репозитории +- **Зеркальный сервер (206.189.35.205):** Mirror Gitea, автоматическая синхронизация + +--- + +## 🔗 Ссылки + +- **Веб-интерфейс:** https://gitea.hunab.app +- **API:** https://gitea.hunab.app/api/v1/ +- **Репозиторий:** https://gitea.hunab.app/hunabgit/hunabapp +- **Документация Gitea:** https://docs.gitea.io/ +- **SSL Report:** https://www.ssllabs.com/ssltest/analyze.html?d=gitea.hunab.app +- **Зеркалирование:** [Gitea Mirroring Guide](./GITEA_MIRRORING_GUIDE.md) +- **Миграция на зеркальный сервер:** [Gitea Migration Plan](./GITEA_MIGRATION_TO_MIRROR_SERVER.md) +- **Индекс документации:** [Gitea Index](./INDEX.md) - Перелинкованный индекс всех документов Gitea + +--- + +## ✅ Текущий статус (2025-12-27) + +### Репозиторий hunabapp +- ✅ **Размер:** 556.8M +- ✅ **Ветки:** 23 (dev, main, и другие) +- ✅ **Файлы:** Все файлы доступны через веб-интерфейс и API +- ✅ **Веб-интерфейс:** Полностью функционален +- ✅ **API:** Работает корректно +- ✅ **Git операции:** Клонирование, push, pull работают + +### Система +- ✅ Gitea контейнер работает стабильно +- ✅ PostgreSQL подключение стабильно +- ✅ SSL/TLS работает корректно +- ✅ Nginx reverse proxy настроен правильно +- ✅ DNS настроен (gitea.hunab.app → 209.38.32.21) + +**Последнее обновление:** 2026-02-27 +**Версия документа:** 1.4 +**Статус:** ✅ Gitea полностью развернут и работает стабильно +**Изменения:** +- Добавлен резервный способ коммитов через временный скрипт (2026-02-16) +- Добавлен гайд по очистке истории Git от build-артефактов (2026-02-27) + +--- + +## 🧹 Очистка истории Git от build-артефактов + +### 🎯 Когда нужна очистка vs простое удаление + +**99% случаев:** Файлы уже в `.gitignore`, но Git их отслеживает (закоммичены до добавления в `.gitignore`) + +**Решение:** ✅ **Простое удаление из tracking** (см. ниже) - БЕЗ переписывания истории! + +**1% случаев:** Нужно удалить файлы из ВСЕЙ истории (например, случайно закоммитили секреты) + +**Решение:** ⚠️ **Очистка истории** (см. раздел "Когда действительно нужна очистка истории") + +--- + +## ✅ ПРАВИЛЬНЫЙ ПОДХОД: Простое удаление из tracking + +**Когда использовать:** Файлы уже в `.gitignore`, но Git их отслеживает. + +**Пример проблемы:** +- Файлы в `.gitignore`: `frontend/dist-*` +- Git все еще отслеживает: 4046 файлов из `dist-*` папок +- `git status` показывает: `D frontend/dist-cache-busting/404.html` и т.д. + +### ✅ Решение (ПРАВИЛЬНО): + +```bash +# 1. Убедиться что файлы в .gitignore +cat frontend/.gitignore | grep dist- + +# 2. Удалить из tracking (файлы останутся в рабочей директории, если есть) +git rm --cached -r frontend/dist-cache-busting/ \ + frontend/dist-fast-no-image/ \ + frontend/dist-via-proxy/ \ + frontend/dist-zero-downtime/ 2>/dev/null || \ +git add -u -- frontend/dist-*/ # Альтернатива если файлы уже удалены из рабочей директории + +# 3. Проверить что файлы в staging для удаления +git status --short | grep "^D " | wc -l +# Должно показать количество удаляемых файлов + +# 4. Закоммитить удаление +git commit -m "chore(frontend): удаление dist-* build-артефактов из Git tracking + +- Удалены файлы из frontend/dist-cache-busting/, dist-fast-no-image/, dist-via-proxy/, dist-zero-downtime/ +- Файлы были в .gitignore, но отслеживались Git (закоммичены до добавления в .gitignore) +- Build-артефакты генерируются при деплое и не должны храниться в репозитории" + +# 5. Push в Gitea +bash scripts/deployment/gitea/git-push-gitea-via-proxy.sh dev # 🇷🇺 ДЛЯ РФ + +# 6. Проверка +git ls-files | grep -E "^frontend/dist-(zero-downtime|fast-no-image|via-proxy|cache-busting)/" | wc -l +# Должно быть: 0 +``` + +**✅ Результат:** +- Файлы удалены из tracking (больше не отслеживаются Git) +- История НЕ переписана (SHA коммитов не изменились) +- Все коммиты сохранены +- Работает быстро и безопасно + +**⚠️ ВАЖНО:** После этого файлы останутся в истории старых коммитов, но новые коммиты их не будут содержать. Это нормально для build-артефактов. + +--- + +## ❌ КАК НЕ НАДО: git-filter-repo с --invert-paths + +### ❌ КРИТИЧЕСКАЯ ОШИБКА (НЕ ДЕЛАТЬ ТАК!): + +```bash +# ❌ НЕПРАВИЛЬНО - УНИЧТОЖАЕТ ВСЕ КОММИТЫ! +git filter-repo \ + --path frontend/dist-zero-downtime/ \ + --path frontend/dist-fast-no-image/ \ + --path frontend/dist-via-proxy/ \ + --path frontend/dist-cache-busting/ \ + --invert-paths \ + --force +``` + +**Что происходит:** +- ❌ `git-filter-repo` с `--invert-paths` **УНИЧТОЖАЕТ ВСЕ КОММИТЫ** +- ❌ Все tree objects становятся пустыми (0 файлов в коммитах) +- ❌ Репозиторий полностью сломан +- ❌ Нужно восстанавливать из бэкапа + +**Почему это происходит:** +- `--invert-paths` означает "сохранить все, кроме указанных путей" +- Но если указанные пути были в КАЖДОМ коммите, то все коммиты становятся пустыми +- Git не может создать коммит без файлов + +**Реальный пример ошибки (2026-02-27):** +``` +# После git-filter-repo: +git ls-tree -r HEAD --name-only | wc -l +# Результат: 0 (ВСЕ КОММИТЫ ПУСТЫЕ!) + +git log --oneline -5 +# Коммиты есть, но в них НЕТ ФАЙЛОВ +``` + +**✅ Решение после ошибки:** +```bash +# Восстановить из бэкапа +rm -rf .git +mv .git.backup-20260227-171445 .git + +# Использовать ПРАВИЛЬНЫЙ подход (см. выше) +git rm --cached -r frontend/dist-*/ && git commit -m "..." +``` + +--- + +## ⚠️ Когда действительно нужна очистка истории + +**Редкие случаи, когда нужна очистка истории:** + +1. **Случайно закоммитили секреты** (пароли, API ключи, токены) + - ⚠️ Критично: секреты в истории = уязвимость безопасности + - ✅ Нужна полная очистка истории + +2. **Огромные бинарные файлы** (видео, большие изображения, базы данных) + - ⚠️ Размер репозитория > 2GB из-за истории + - ✅ Нужна очистка для уменьшения размера + +3. **Юридические требования** (удаление файлов по запросу) + - ⚠️ Требуется полное удаление из истории + - ✅ Нужна очистка истории + +**⚠️ ВАЖНО:** Для build-артефактов (`dist/`, `build/`) очистка истории **НЕ НУЖНА** - достаточно простого удаления из tracking! + +--- + +## 🧹 Очистка истории от файлов с секретами (docs) + +**Когда применять:** после замены реальных секретов на плейсхолдеры в документации (см. [SECRETS_AND_FILE_PERMISSIONS_POLICY.md](../../security/SECRETS_AND_FILE_PERMISSIONS_POLICY.md)) нужно удалить из истории Git старые версии этих файлов, чтобы секреты нельзя было извлечь из старых коммитов. + +**Гарантированно безопасный порядок (обязательно):** + +1. **Бэкап репозитория (ОБЯЗАТЕЛЬНО)** — без бэкапа не приступать. +2. Запуск скрипта, который делает бэкап сам и выполняет очистку по списку путей. +3. Проверки целостности (в скрипте). +4. Применение очищенной версии на Gitea только после бэкапа репо на сервере. + +### Скрипт очистки (бэкап + filter-repo + проверки) + +Используется готовый скрипт, который: + +- Создаёт резервную копию (`git clone --mirror`) в каталог рядом с репо. +- Клонирует репо в bare, удаляет из истории пути из списка (`git filter-repo --paths-from-file ... --invert-paths`). +- Проверяет целостность (`git ls-tree -r HEAD | wc -l` > 0, `git fsck`). +- Восстанавливает в текущем tip почищенные версии файлов (один коммит с плейсхолдерами). + +**Запуск (из корня репозитория):** + +```bash +# Установить git-filter-repo (один раз) +# macOS: +brew install git-filter-repo +# Linux: +# pip3 install git-filter-repo + +# Запуск (бэкап создаётся скриптом автоматически) +bash scripts/maintenance/git-history-cleanup-secrets.sh /path/to/hunabapp-dev +``` + +**Файлы:** + +- Список путей (файлы, которые удаляются из истории): `scripts/maintenance/git-history-cleanup-secrets-paths.txt` — соответствует таблице в [SECRETS_AND_FILE_PERMISSIONS_POLICY.md](../../security/SECRETS_AND_FILE_PERMISSIONS_POLICY.md) (очистка 2026-03-03). +- Скрипт: `scripts/maintenance/git-history-cleanup-secrets.sh`. + +**После скрипта:** выполнить шаги из раздела ниже «Правильная очистка истории»: создание bundle из очищенного bare-репо, загрузка на сервер, **бэкап Gitea-репо на сервере**, замена objects/refs, перезапуск Gitea, обновление локального репо. + +**Критично:** на production-сервере перед заменой репозитория в Gitea обязательно создать бэкап: + +```bash +GITEA_REPO="/data/git/repositories/hunabgit/hunabapp.git" +ssh hunab-prod "docker exec gitea cp -r $GITEA_REPO ${GITEA_REPO}.backup-$(date +%Y%m%d)" +``` + +--- + +## ✅ Правильная очистка истории (если действительно нужна) + +**⚠️ КРИТИЧЕСКИ ВАЖНО:** Очистка истории переписывает все коммиты (SHA изменятся), но содержимое сохраняется. + +### Шаг 1: Резервная копия (ОБЯЗАТЕЛЬНО!) + +```bash +# Создать полную резервную копию репозитория +cd /path/to/repo +git clone --mirror . ../repo-backup-$(date +%Y%m%d-%H%M%S).git + +# Проверить размер +du -sh ../repo-backup-*.git +``` + +**✅ Результат:** Резервная копия с полной историей (можно восстановить в любой момент) + +### Шаг 2: Установка git-filter-repo + +```bash +# macOS +brew install git-filter-repo + +# Linux +pip3 install git-filter-repo + +# Проверка +git filter-repo --version +``` + +### Шаг 3: Удаление файлов из истории (ПРАВИЛЬНЫЙ СПОСОБ) + +**⚠️ КРИТИЧЕСКИ ВАЖНО:** Используйте `--path` БЕЗ `--invert-paths` для удаления конкретных файлов! + +```bash +# Создать bare clone для безопасной работы +cd /tmp +git clone --mirror /path/to/repo repo-clean.git + +# ✅ ПРАВИЛЬНО: Удалить конкретные файлы/папки +cd repo-clean.git +git filter-repo \ + --path frontend/dist-zero-downtime/ \ + --path frontend/dist-fast-no-image/ \ + --path frontend/dist-via-proxy/ \ + --path frontend/dist-cache-busting/ \ + --path-glob '*.secret' \ + --path-glob '*.key' \ + --invert-paths \ + --force + +# ❌ НЕПРАВИЛЬНО: --invert-paths может уничтожить все коммиты! +# Используйте ТОЛЬКО если уверены что файлы НЕ в каждом коммите + +# Очистить reflog и неиспользуемые объекты +git reflog expire --expire=now --all +git gc --prune=now --aggressive +``` + +**⚠️ КРИТИЧЕСКОЕ ПРЕДУПРЕЖДЕНИЕ:** +- `--invert-paths` **ОПАСЕН** - может уничтожить все коммиты если указанные пути были в каждом коммите +- **Лучше использовать:** `--path` для удаления конкретных файлов БЕЗ `--invert-paths` +- **Проверяйте результат:** `git ls-tree -r HEAD --name-only | wc -l` должно быть > 0! + +### Шаг 4: Проверка целостности (КРИТИЧЕСКИ ВАЖНО!) + +```bash +cd repo-clean.git + +# ✅ КРИТИЧЕСКАЯ ПРОВЕРКА: Файлы в коммитах +git ls-tree -r HEAD --name-only | wc -l +# ДОЛЖНО БЫТЬ > 0! Если 0 - репозиторий сломан, восстанавливайте из бэкапа! + +# Проверить размер +du -sh . +# Должно быть меньше оригинала + +# Проверить количество коммитов +git log --oneline --all | wc -l +# Должно быть идентично оригиналу + +# Проверить что файлы удалены +git rev-list --all --objects | grep -E "(dist-zero-downtime|dist-fast-no-image)" | wc -l +# Должно быть: 0 + +# Проверить целостность +git fsck --full +# Не должно быть ошибок + +# Проверить важные ветки +git branch -a | grep -E "(dev|main|staging)" +# Все важные ветки должны быть сохранены +``` + +**✅ Гарантии:** +- ✅ Все коммиты сохранены (количество идентично) +- ✅ **Файлы в коммитах > 0** (критично!) +- ✅ Все сообщения коммитов идентичны +- ✅ Все авторы и даты сохранены +- ✅ Все важные ветки сохранены +- ✅ Все теги сохранены +- ✅ Файлы удалены из истории + +**⚠️ КРИТИЧЕСКИ ВАЖНО:** Очистка истории переписывает все коммиты (SHA изменятся), но содержимое сохраняется. + +#### Шаг 1: Резервная копия (ОБЯЗАТЕЛЬНО!) + +```bash +# Создать полную резервную копию репозитория +cd /path/to/repo +git clone --mirror . ../repo-backup-$(date +%Y%m%d-%H%M%S).git + +# Проверить размер +du -sh ../repo-backup-*.git +``` + +**✅ Результат:** Резервная копия с полной историей (можно восстановить в любой момент) + +#### Шаг 2: Установка git-filter-repo + +```bash +# macOS +brew install git-filter-repo + +# Linux +pip3 install git-filter-repo + +# Проверка +git filter-repo --version +``` + +#### Шаг 3: Удаление файлов из истории + +```bash +# Создать bare clone для безопасной работы +cd /tmp +git clone --mirror /path/to/repo repo-clean.git + +# Удалить папки из истории +cd repo-clean.git +git filter-repo \ + --path frontend/dist-zero-downtime/ \ + --path frontend/dist-fast-no-image/ \ + --path frontend/dist-via-proxy/ \ + --path frontend/dist-cache-busting/ \ + --invert-paths \ + --force + +# Очистить reflog и неиспользуемые объекты +git reflog expire --expire=now --all +git gc --prune=now --aggressive +``` + +**Параметры:** +- `--path` - путь к папке/файлу для удаления +- `--path-glob` - glob паттерн для удаления (например, `*.secret`) +- `--invert-paths` - ⚠️ **ОПАСНО!** Удалить указанные пути (остальное сохранить). Может уничтожить все коммиты! +- `--force` - принудительное выполнение + +**✅ Результат:** Очищенный репозиторий без указанных файлов + +**⚠️ КРИТИЧЕСКОЕ ПРЕДУПРЕЖДЕНИЕ:** +- `--invert-paths` **ОПАСЕН** - если указанные пути были в КАЖДОМ коммите, все коммиты станут пустыми! +- **Всегда проверяйте:** `git ls-tree -r HEAD --name-only | wc -l` должно быть > 0 после очистки! +- **Если результат = 0:** Репозиторий сломан, восстанавливайте из бэкапа! + +#### Шаг 4: Проверка целостности (ОБЯЗАТЕЛЬНО!) + +```bash +cd repo-clean.git + +# Проверить размер +du -sh . +# Должно быть меньше оригинала + +# Проверить количество коммитов +git log --oneline --all | wc -l +# Должно быть идентично оригиналу + +# Проверить что файлы удалены +git rev-list --all --objects | grep -E "(dist-zero-downtime|dist-fast-no-image)" | wc -l +# Должно быть: 0 + +# Проверить целостность +git fsck --full +# Не должно быть ошибок + +# Проверить важные ветки +git branch -a | grep -E "(dev|main|staging)" +# Все важные ветки должны быть сохранены +``` + +**✅ Гарантии:** +- ✅ Все коммиты сохранены (количество идентично) +- ✅ Все сообщения коммитов идентичны +- ✅ Все авторы и даты сохранены +- ✅ Все важные ветки сохранены +- ✅ Все теги сохранены +- ✅ Файлы удалены из истории + +#### Шаг 5: Применение очищенной версии + +**⚠️ ПРОБЛЕМА:** Прямой push в Gitea таймаутит из РФ, а скрипт через прокси не работает, потому что после замены `.git` нет remote tracking branches. + +**✅ РЕШЕНИЕ: Bundle метод + прямое копирование на сервер** + +```bash +# 1. Создать bundle из очищенного репозитория +cd /tmp/repo-clean.git +git bundle create /tmp/repo-clean.bundle --all + +# 2. Загрузить bundle на production сервер +scp -i ~/.ssh/hunab_deploy_key /tmp/repo-clean.bundle hunab@209.38.32.21:/tmp/ + +# 3. Создать временный репозиторий из bundle на сервере +ssh hunab-prod "cd /tmp && git clone --mirror /tmp/repo-clean.bundle repo-clean.git" + +# 4. Бэкап текущего Gitea репозитория +GITEA_REPO="/data/git/repositories/hunabgit/hunabapp.git" +ssh hunab-prod "docker exec gitea cp -r $GITEA_REPO ${GITEA_REPO}.backup-$(date +%Y%m%d)" + +# 5. Копировать очищенный репозиторий в контейнер +ssh hunab-prod "docker cp /tmp/repo-clean.git gitea:/tmp/repo-clean.git" + +# 6. Заменить objects и refs в Gitea репозитории +ssh hunab-prod "docker exec gitea sh -c ' + cd $GITEA_REPO + rm -rf objects packed-refs refs/heads refs/tags + cp -r /tmp/repo-clean.git/objects . + cp -r /tmp/repo-clean.git/packed-refs . 2>/dev/null || true + cp -r /tmp/repo-clean.git/refs/heads refs/ 2>/dev/null || true + cp -r /tmp/repo-clean.git/refs/tags refs/ 2>/dev/null || true + echo \"ref: refs/heads/dev\" > HEAD + rm -rf refs/original filter-repo + git reflog expire --expire=now --all 2>/dev/null + git gc --prune=now 2>&1 | tail -5 + chown -R git:git . +'" + +# 7. Перезапустить Gitea для обновления индексов +ssh hunab-prod "docker restart gitea && sleep 5" + +# 8. Проверка +ssh hunab-prod "docker exec gitea sh -c 'cd $GITEA_REPO && \ + echo \"Размер: \$(du -sh .)\" && \ + echo \"Коммитов: \$(git log --oneline --all | wc -l)\" && \ + echo \"Файлов dist в истории: \$(git rev-list --all --objects | grep -cE \"dist-zero-downtime|dist-fast-no-image|dist-via-proxy|dist-cache-busting\" || echo 0)\" && \ + echo \"Веток: \$(git branch | wc -l)\" && \ + echo \"Тегов: \$(git tag | wc -l)\" && \ + git log --oneline -3 dev'" +``` + +**✅ Результат:** Gitea репозиторий обновлен очищенной версией + +#### Шаг 6: Обновление локального репозитория + +```bash +# Заменить .git папку очищенной версией +cd /path/to/repo +rm -rf .git +cp -r /tmp/repo-clean.git .git + +# Преобразовать bare в обычный репозиторий +git config core.bare false +git config core.worktree . + +# Проверить статус +git status +git log --oneline -5 +``` + +**⚠️ ВАЖНО:** После замены `.git` могут появиться артефакты в `git status` (untracked файлы из `.git`). Это не критично - репозиторий работает корректно. + +### 📊 Результаты: Простое удаление из tracking (ПРАВИЛЬНЫЙ подход) + +**До удаления:** +- Файлов отслеживается: 13,281 +- Файлов dist-* в tracking: 4,046 +- Коммитов: 6,218 + +**После удаления:** +- Файлов отслеживается: 13,281 - 4,046 = 9,235 +- Файлов dist-* в tracking: 0 ✅ +- Коммитов: 6,218 (все сохранены, SHA не изменились) ✅ +- Веток: 27 (все важные сохранены) ✅ +- Тегов: 162 (все сохранены) ✅ +- Время выполнения: ~30 секунд ✅ +- Риск: Минимальный (простой коммит) ✅ + +**⚠️ ВАЖНО:** Файлы останутся в истории старых коммитов, но новые коммиты их не будут содержать. Это нормально для build-артефактов. + +### 📊 Результаты: Очистка истории (если действительно нужна) + +**До очистки:** +- Размер: 968 MB +- Файлов в истории: 4,046 из `dist-*` папок +- Коммитов: 6,218 + +**После очистки (если все прошло правильно):** +- Размер: 391 MB (экономия 577 MB, 60%) +- Файлов в истории: 0 из `dist-*` папок +- Коммитов: 6,218 (все сохранены, но SHA изменились) +- Веток: 27 (все важные сохранены) +- Тегов: 162 (все сохранены) +- Время выполнения: ~30-60 минут (с бэкапом и проверками) +- Риск: Высокий (переписывание истории) ⚠️ + +**❌ Результаты после ОШИБКИ (git-filter-repo с --invert-paths):** +- Файлов в коммитах: 0 (ВСЕ КОММИТЫ ПУСТЫЕ!) ❌ +- Репозиторий: СЛОМАН ❌ +- Решение: Восстановление из бэкапа ✅ + +### 🛡️ Механизмы защиты + +**Для простого удаления из tracking:** +1. ✅ **Проверка .gitignore:** Убедиться что файлы в `.gitignore` +2. ✅ **Проверка staging:** `git status --short | grep "^D "` показывает удаляемые файлы +3. ✅ **Проверка после коммита:** `git ls-files | grep dist- | wc -l` = 0 + +**Для очистки истории (если действительно нужна):** +1. ✅ **Резервная копия:** Полная копия оригинального репозитория (ОБЯЗАТЕЛЬНО!) +2. ✅ **Бэкап на сервере:** Копия Gitea репозитория перед заменой +3. ✅ **КРИТИЧЕСКАЯ проверка:** `git ls-tree -r HEAD --name-only | wc -l` > 0 после очистки! +4. ✅ **Проверка целостности:** `git fsck --full` перед применением +5. ✅ **Валидация:** Проверка количества коммитов, веток, тегов, файлов в коммитах + +### ⚠️ Критические ошибки и решения + +#### ❌ Ошибка 0: git-filter-repo уничтожил все коммиты (КРИТИЧЕСКАЯ!) + +**Проблема:** После `git-filter-repo --invert-paths` все коммиты стали пустыми (0 файлов). + +**Симптомы:** +```bash +git ls-tree -r HEAD --name-only | wc -l +# Результат: 0 (ВСЕ КОММИТЫ ПУСТЫЕ!) + +git log --oneline -5 +# Коммиты есть, но в них НЕТ ФАЙЛОВ + +git status +# Показывает ВСЕ файлы как untracked +``` + +**Причина:** `--invert-paths` удалил указанные пути из ВСЕХ коммитов. Если эти пути были в каждом коммите, все коммиты стали пустыми. + +**✅ Решение:** +```bash +# 1. Восстановить из бэкапа +rm -rf .git +mv .git.backup-20260227-171445 .git # Используйте ваш бэкап + +# 2. Использовать ПРАВИЛЬНЫЙ подход (простое удаление из tracking) +git rm --cached -r frontend/dist-*/ && git commit -m "..." + +# 3. НЕ использовать git-filter-repo для build-артефактов! +``` + +**Профилактика:** +- ✅ **ВСЕГДА** проверяйте `git ls-tree -r HEAD --name-only | wc -l` после git-filter-repo +- ✅ **ВСЕГДА** создавайте полный бэкап перед очисткой истории +- ✅ **НЕ используйте** `--invert-paths` для файлов, которые были в каждом коммите +- ✅ **Для build-артефактов** используйте простое удаление из tracking (см. "ПРАВИЛЬНЫЙ ПОДХОД" выше) + +#### Ошибка 1: Прямой push таймаутит + +**Проблема:** `git push --force` зависает с таймаутом из РФ. + +**Решение:** Использовать bundle метод + прямое копирование на сервер (см. Шаг 5). + +#### Ошибка 2: Скрипт через прокси не работает + +**Проблема:** После замены `.git` нет remote tracking branches (`origin/dev` не существует). + +**Решение:** Bundle метод обходит эту проблему, так как работает напрямую с файловой системой. + +#### Ошибка 3: Файлы из `.git` в корне проекта + +**Проблема:** После замены `.git` git status показывает untracked файлы (COMMIT_EDITMSG, HEAD, config и т.д.). + +**Решение:** Это артефакты git status - файлы не существуют в корне, можно игнорировать. Репозиторий работает корректно. + +#### Ошибка 4: Gitea не видит изменения + +**Проблема:** После замены объектов Gitea не обновляет индекс. + +**Решение:** +1. Удалить `refs/original` и `filter-repo` из репозитория +2. Очистить reflog: `git reflog expire --expire=now --all` +3. Перезапустить Gitea: `docker restart gitea` + +### 🔄 Восстановление из резервной копии + +Если что-то пошло не так: + +```bash +# Восстановить локальный репозиторий +cd /path/to/repo +rm -rf .git +git clone --mirror /path/to/backup/repo-backup-*.git .git +git config core.bare false +git config core.worktree . + +# Восстановить Gitea репозиторий на сервере +ssh hunab-prod "docker exec gitea rm -rf $GITEA_REPO && \ + docker exec gitea cp -r ${GITEA_REPO}.backup-* $GITEA_REPO && \ + docker exec gitea chown -R git:git $GITEA_REPO && \ + docker restart gitea" +``` + +### 📋 Чеклист: Простое удаление из tracking (99% случаев) + +**Для build-артефактов (`dist/`, `build/`) - используйте этот чеклист:** + +- [ ] Проверено что файлы в `.gitignore` +- [ ] Удалены файлы из tracking: `git rm --cached -r frontend/dist-*/` +- [ ] Проверено что файлы в staging для удаления: `git status --short | grep "^D "` +- [ ] Создан коммит с описанием удаления +- [ ] Push в Gitea через скрипт: `bash scripts/deployment/gitea/git-push-gitea-via-proxy.sh dev` +- [ ] Проверено что файлы больше не отслеживаются: `git ls-files | grep dist- | wc -l` = 0 +- [ ] Обновлен CHANGELOG с описанием операции + +**✅ Результат:** Файлы удалены из tracking, история НЕ переписана, все работает быстро и безопасно. + +--- + +### 📋 Чеклист: Очистка истории (1% случаев - только для секретов/юридических требований) + +**⚠️ ВАЖНО:** Используйте ТОЛЬКО если действительно нужно удалить файлы из ВСЕЙ истории! + +- [ ] Определено что простая очистка tracking НЕДОСТАТОЧНА (секреты, юридические требования) +- [ ] Создана резервная копия оригинального репозитория +- [ ] Установлен `git-filter-repo` +- [ ] Создан bare clone для безопасной работы +- [ ] Удалены файлы из истории через `git-filter-repo` (БЕЗ `--invert-paths` если возможно!) +- [ ] **КРИТИЧЕСКАЯ ПРОВЕРКА:** `git ls-tree -r HEAD --name-only | wc -l` > 0 (если 0 - репозиторий сломан!) +- [ ] Очищены reflog и неиспользуемые объекты +- [ ] Проверена целостность (коммиты, ветки, теги, файлы в коммитах > 0) +- [ ] Создан bundle из очищенного репозитория +- [ ] Загружен bundle на production сервер (в `/home/hunab/`, НЕ в `/tmp/` - tmpfs только 2GB!) +- [ ] Создан бэкап Gitea репозитория на сервере +- [ ] Заменены objects и refs в Gitea репозитории +- [ ] Удалены `refs/original` и `filter-repo` +- [ ] Перезапущен Gitea +- [ ] Проверен результат (размер, коммиты, файлы в коммитах > 0) +- [ ] Обновлен локальный репозиторий +- [ ] Обновлен CHANGELOG с описанием операции + +### 📚 Связанные документы + +- **[Deployment Changelog](../CHANGELOG.md)** - История изменений deployment (включает очистку истории) +- **[Git Filter Repo Documentation](https://github.com/newren/git-filter-repo)** - Официальная документация git-filter-repo + +--- + +**Последнее обновление:** 2026-02-27 +**Версия документа:** 1.6 +**Статус:** ✅ Gitea полностью развернут и работает стабильно +**Изменения:** +- Добавлен резервный способ коммитов через временный скрипт (2026-02-16) +- Добавлен гайд по очистке истории Git от build-артефактов (2026-02-27) +- **КРИТИЧЕСКОЕ ОБНОВЛЕНИЕ (2026-02-27):** Добавлены четкие предупреждения о том, как НЕ надо делать очистку истории: + - ❌ `git-filter-repo --invert-paths` УНИЧТОЖАЕТ все коммиты (реальный пример ошибки 2026-02-27) + - ✅ Правильный подход: простое удаление из tracking (`git rm --cached`) для build-артефактов (99% случаев) + - ✅ Очистка истории нужна ТОЛЬКО для секретов/юридических требований (1% случаев) + - ✅ Добавлены критические проверки (`git ls-tree -r HEAD --name-only | wc -l` > 0) и механизмы защиты +- **ОПТИМИЗАЦИЯ (2026-02-27):** Исправлена медленная верификация push - заменен `git fetch origin` на `git update-ref` для мгновенного обновления tracking ref без сетевых запросов + diff --git a/docs/git/LOCAL_MACHINE_GITEA_SETUP.md b/docs/git/LOCAL_MACHINE_GITEA_SETUP.md new file mode 100644 index 0000000..feed27b --- /dev/null +++ b/docs/git/LOCAL_MACHINE_GITEA_SETUP.md @@ -0,0 +1,68 @@ +# local_machine — репозиторий на Gitea + +Репозиторий **local_machine** на сервере Gitea (gitea.hunab.app): документация и скрипты для локальной машины. + +## Быстрый старт + +### 1. Создать репозиторий на Gitea (один раз) + +**Вариант А — через веб-интерфейс** + +1. Открыть: https://gitea.hunab.app +2. Войти под пользователем `hunabgit` (или своим). +3. **New Repository** → Name: `local_machine` → Create Repository. +4. Репо создавать **пустым** (без README / .gitignore). + +**Вариант Б — через API (если есть токен)** + +```bash +# Токен: Gitea → Settings → Applications → Generate New Token (write:repository, read:repository) +export GITEA_TOKEN="your_token" +bash scripts/deployment/gitea/setup-and-push.sh --create-only +``` + +### 2. Инициализация и первый пуш + +Из корня **local_machine** (не из родительского репо): + +```bash +cd /Users/eternal/code/local_machine +bash scripts/deployment/gitea/setup-and-push.sh +``` + +Скрипт: + +- инициализирует git в `local_machine` (если ещё нет `.git`); +- добавляет `origin` (SSH или HTTPS); +- делает первый коммит и `git push -u origin main`. + +### 3. Если пуш из РФ зависает + +По гайду [GITEA_COMPLETE_GUIDE.md](./GITEA_COMPLETE_GUIDE.md): + +- предпочтительно **SSH** (порт 2223): + `git remote set-url origin git@gitea.hunab.app:hunabgit/local_machine.git` + и снова `git push -u origin main`; +- либо использовать прокси/скрипты пуша из основного репо (bundle-метод), если они у вас настроены. + +## .gitignore + +В корне проекта настроен `.gitignore`, чтобы не пушить: + +- системный мусор: `.DS_Store`, `Thumbs.db`; +- секреты и ключи: `.env`, `*.pem`, `*.key`, конфиги VPN с ключами (`docs/connectivity/vpn/*.conf`); +- артефакты: `node_modules/`, `__pycache__/`, `*.log`, `*.tmp`, кэши и т.п.; +- IDE/редакторы: `.idea/`, `.vscode/`, `.cursor/`. + +Конфиги с приватными ключами (WireGuard и т.д.) в репозиторий не попадают. + +## Дальнейшая работа + +- Клонирование: + `git clone https://gitea.hunab.app/hunabgit/local_machine.git` + или по SSH: + `git clone git@gitea.hunab.app:hunabgit/local_machine.git` +- Обычные коммиты и пуш: + `git add ... && git commit -m "..." && git push origin main` + +Полный гайд по Gitea (пуши, SSH, bundle, из РФ): [GITEA_COMPLETE_GUIDE.md](./GITEA_COMPLETE_GUIDE.md). diff --git a/docs/homebrew/KEEP_AND_REMAINING.md b/docs/homebrew/KEEP_AND_REMAINING.md new file mode 100644 index 0000000..d6abdf5 --- /dev/null +++ b/docs/homebrew/KEEP_AND_REMAINING.md @@ -0,0 +1,211 @@ +# Homebrew: что оставляем и что остаётся + +В **нужный список** входят только пакеты, нужные для: +- **сборок Android** (Gradle, JDK), +- **Docker / Colima** (контейнеры и виртуализация), +- **эмулятора Android** (среда/зависимости уже покрыты JDK + Colima/QEMU при необходимости), +- **Syncthing** (синхронизация файлов). + +Всё остальное — в таблице «Что остаётся» с размером и назначением. + +--- + +## Оставляем (нужный список) + +| Пакет | Размер | Назначение | +|-------|--------|------------| +| **colima** | 5.7M | Colima — контейнеры/Кubernetes без Docker Desktop | +| **docker** | 27M | Docker CLI | +| **docker-buildx** | 62M | Расширенная сборка образов Docker | +| **docker-compose** | 61M | Оркестрация контейнеров | +| **docker-completion** | 360K | Автодополнение Docker в shell | +| **lima** | 210M | Lima — виртуальные машины под Colima/Docker на Mac | +| **qemu** | 682M | Эмулятор/виртуализация (используется Lima/Colima) | +| **syncthing** | 27M | Syncthing — синхронизация файлов между устройствами | +| **gradle** | 525M | Сборка Android/Java-проектов | +| **gradle-completion** | 88K | Автодополнение Gradle | +| **openjdk** | 745M | JDK для сборки (основная версия) | +| **openjdk@17** | 306M | JDK 17 (LTS, часто для Android) | +| **openjdk@21** | 332M | JDK 21 (LTS) | + +**Итого в нужном списке:** 13 формул, ~3.1 GB (без учёта общих зависимостей в Cellar). + +Эмулятор Android на Mac обычно ставится через Android SDK (`~/Library/Android/sdk`), а не через Homebrew; для сборки и окружения достаточно JDK + Gradle из таблицы выше. + +--- + +## Что остаётся (остальные пакеты) + +Пакеты, которые **не** входят в нужный список. Можно отключить/удалить через `brew uninstall`, если не используете. + +| Размер | Пакет | Для чего | +|--------|--------|----------| +| 634M | dotnet | .NET SDK — разработка C# / .NET | +| 654M | tesseract-lang | Языковые данные для OCR (Tesseract) | +| 259M | pandoc | Конвертация документов (Markdown, PDF и др.) | +| 232M | go | Язык Go, компилятор и тулчейн | +| 190M | awscli | AWS CLI — управление облаком AWS | +| 169M | icu4c@78 | Unicode и локализация (библиотека) | +| 145M | deno | Среда выполнения JavaScript/TypeScript | +| 116M | glib | GLib — базовая библиотека (зависимость многих программ) | +| 86M | python@3.14 | Python 3.14 | +| 82M | icu4c@77 | Старая версия ICU (зависимость) | +| 81M | python@3.13 | Python 3.13 | +| 76M | gettext | Интернационализация (переводы) | +| 71M | postgresql@15 | PostgreSQL 15 — СУБД (запуск вручную по необходимости) | +| 59M | git | Git — система контроля версий | +| 53M | ffmpeg | Кодирование/декодирование видео и аудио | +| 49M | rav1e | Кодек AV1 (видео) | +| 39M | openssl@3 | OpenSSL 3 — криптография и TLS | +| 35M | jpeg-xl | Формат изображений JPEG XL | +| 34M | imagemagick | Обработка изображений из командной строки | +| 33M | tesseract | OCR — распознавание текста на изображениях | +| 31M | poppler | Рендеринг PDF (утилиты и библиотека) | +| 29M | yt-dlp | Скачивание видео с YouTube и др. | +| 29M | gnutls | Криптобиблиотека (альтернатива OpenSSL) | +| 25M | apktool | Разбор/сборка APK (Android) | +| 24M | doctl | DigitalOcean CLI | +| 23M | harfbuzz | Шрифты и текст (рендеринг) | +| 22M | capstone | Диссемблер (анализ бинарников) | +| 20M | nss | Сетевые крипто-библиотеки (NSS) | +| 20M | libx11 | X11 — графическая библиотека | +| 19M | libtiff | Работа с TIFF | +| 16M | libxcb | X11 protocol (современный клиент) | +| 15M | pcre2 | Регулярные выражения (PCRE2) | +| 15M | openjpeg | Кодек JPEG 2000 | +| 15M | ncurses | Текстовый UI в терминале | +| 15M | gnupg | Шифрование и подписи (GPG) | +| 14M | unar | Распаковка архивов (ZIP, RAR и др.) | +| 14M | mbedtls | Криптобиблиотека (TLS) | +| 13M | x265 | Кодек H.265/HEVC | +| 13M | bash | Bash (оболочка) | +| 11M | qpdf | Утилиты для PDF | +| 11M | python-setuptools | Setuptools для Python | +| 11M | openexr | Формат изображений OpenEXR | +| 10M | aom | Кодек AV1 (reference) | +| 9.0M | xorgproto | Заголовки протоколов X.Org | +| 8.7M | mbedtls@2 | Старая версия mbedTLS | +| 7.8M | libvmaf | Метрика качества видео (VMAF) | +| 7.0M | leptonica | Обработка изображений (для OCR) | +| 6.6M | sdl2 | Библиотека для игр/медиа (SDL2) | +| 6.5M | zeromq | Очереди сообщений (ZeroMQ) | +| 6.4M | unbound | Рекурсивный DNS-резолвер | +| 6.4M | libheif | Формат HEIF/HEIC (фото) | +| 6.1M | libraw | Чтение RAW-фото | +| 6.1M | frei0r | Плагины для видеоэффектов | +| 5.9M | krb5 | Kerberos (аутентификация) | +| 5.6M | libunistring | Строки Unicode | +| 5.4M | highway | SIMD-ускорение (C++) | +| 5.4M | freetype | Рендеринг шрифтов | +| 5.0M | sqlite | SQLite — встраиваемая БД | +| 5.0M | pcre | Регулярные выражения (PCRE) | +| 4.9M | shared-mime-info | MIME-типы файлов | +| 4.7M | wget | Загрузка файлов по HTTP(S) | +| 4.7M | srt | Протокол SRT (видеостриминг) | +| 4.6M | cairo | Векторная графика (рисование) | +| 4.5M | zstd | Компрессия zstd | +| 4.4M | p11-kit | PKCS#11 (ключи/сертификаты) | +| 4.2M | x264 | Кодек H.264 | +| 4.2M | libvpx | Кодеки VP8/VP9 | +| 4.1M | libtool | Сборка библиотек (autotools) | +| 4.0M | libarchive | Работа с архивами | +| 3.9M | libgcrypt | Криптобиблиотека | +| 3.7M | pango | Текст и шрифты (разметка) | +| 3.7M | jpeg-turbo | Быстрый JPEG | +| 3.3M | svt-av1 | Кодек AV1 (SVT) | +| 3.3M | gmp | Длинная арифметика (GMP) | +| 3.1M | libsamplerate | Ресемплинг аудио | +| 3.0M | wireguard-go | WireGuard (реализация на Go) | +| 2.9M | nettle | Криптобиблиотека | +| 2.9M | little-cms2 | Управление цветом (CMS) | +| 2.8M | theora | Кодек Theora (видео) | +| 2.8M | libpng | Библиотека PNG | +| 2.7M | xz | Компрессия LZMA/xz | +| 2.7M | libvorbis | Кодек Vorbis (аудио) | +| 2.7M | gpgme | GPG (программный интерфейс) | +| 2.6M | webp | Формат WebP | +| 2.6M | readline | Редактирование строки ввода в терминале | +| 2.5M | redis | Redis — кэш/очереди (запуск вручную по необходимости) | +| 2.3M | libevent | Событийный цикл (сеть/таймеры) | +| 2.3M | lame | Кодек MP3 | +| 2.2M | luajit | Lua JIT | +| 2.0M | rubberband | Изменение темпа/высоты аудио | +| 2.0M | mpg123 | Воспроизведение MP3 | +| 1.9M | libsndfile | Чтение/запись аудиофайлов | +| 1.9M | libgpg-error | Коды ошибок GPG | +| 1.9M | flac | Кодек FLAC | +| 1.9M | brotli | Компрессия Brotli | +| 1.8M | fontconfig | Настройка шрифтов | +| 1.7M | libomp | OpenMP (параллелизм) | +| 1.7M | jasper | Формат JPEG 2000 | +| 1.6M | libmicrohttpd | HTTP-сервер (библиотека) | +| 1.5M | vde | Виртуальный Ethernet (для сетей ВМ) | +| 1.5M | oniguruma | Регулярные выражения (Oniguruma) | +| 1.5M | libssh | SSH-клиент (библиотека) | +| 1.5M | libde265 | Декодер HEVC | +| 1.5M | c-ares | Асинхронный DNS | +| 1.4M | pixman | Растровая графика | +| 1.4M | nspr | Сетевой runtime (NSS) | +| 1.4M | libxext | Расширения X11 | +| 1.3M | shadowsocks-libev | Shadowsocks (прокси) | +| 1.2M | zimg | Масштабирование изображений | +| 1.2M | xvid | Кодек Xvid | +| 1.2M | libbluray | Поддержка Blu-ray | +| 1.2M | jq | Парсер JSON в командной строке | +| 1.1M | libidn2 | Интернационализированные домены | +| 1.0M | opus | Кодек Opus (аудио) | +| 1.0M | libsodium | Криптография (NaCl) | +| 1.0M | imath | Математика для графики | +| 956K | dav1d | Декодер AV1 | +| 912K | speex | Кодек Speex (голос) | +| 876K | librist | RIST (видеостриминг) | +| 832K | libtasn1 | ASN.1 (сертификаты) | +| 816K | m4 | Макропроцессор (сборка) | +| 800K | libnghttp2 | HTTP/2 | +| 756K | libogg | Контейнер Ogg | +| 744K | lz4 | Компрессия LZ4 | +| 700K | opencore-amr | Кодеки AMR (голос) | +| 700K | fribidi | Двунаправленный текст | +| 688K | mpdecimal | Десятичная арифметика | +| 676K | libusb | Доступ к USB | +| 672K | openjph | JPEG 2000 (часть 2) | +| 664K | dtc | Device Tree (встраиваемые системы) | +| 640K | lzo | Компрессия LZO | +| 640K | libass | Субтитры (ASS) | +| 608K | liblqr | Масштабирование изображений | +| 604K | libassuan | Протокол Assuan (GPG) | +| 584K | giflib | Формат GIF | +| 568K | libksba | X.509 (GPG) | +| 528K | libev | Событийный цикл | +| 488K | pinentry | Ввод паролей (GPG и др.) | +| 432K | libslirp | Сетевой слой для ВМ (user-mode) | +| 384K | git-filter-repo | Переписывание истории Git | +| 368K | libunibreak | Переносы слов (Unicode) | +| 364K | libdeflate | Компрессия deflate | +| 316K | graphite2 | Шрифты (Graphite) | +| 308K | cjson | Парсер JSON (C) | +| 252K | libxrender | Рендеринг X11 | +| 252K | aribb24 | Субтитры (ARIB) | +| 240K | libvidstab | Стабилизация видео | +| 236K | ca-certificates | Корневые сертификаты CA | +| 216K | watch | Выполнение команды периодически | +| 208K | tree | Дерево каталогов в терминале | +| 208K | snappy | Компрессия Snappy | +| 196K | wireguard-tools | Утилиты WireGuard | +| 196K | libxau | Аутентификация X11 | +| 192K | npth | Потоки (GnuPG) | +| 180K | libudfread | UDF (оптические диски) | +| 172K | libxdmcp | X Display Manager Control Protocol | +| 164K | jpegoptim | Оптимизация JPEG | +| 160K | wrk | Нагрузочное тестирование HTTP | +| 144K | libb2 | Хеш BLAKE2 | +| 104K | sshpass | SSH с паролем в командной строке | +| 60K | certifi | Сертификаты для Python | + +--- + +## Связанные документы + +- [ALLOWED.md](../launch/ALLOWED.md) — допустимые LaunchAgents (в т.ч. `homebrew.mxcl.syncthing`) +- [DISALLOWED.md](../launch/DISALLOWED.md) — PostgreSQL и Redis отключены в автозапуске, запуск вручную +- [DO_NOT_DELETE.md](../disk_cleanup/DO_NOT_DELETE.md) — что не удалять при очистке диска (в т.ч. Android SDK, Gradle cache) diff --git a/docs/hotspot/ANDROID_VPN_TETHERING_ROUTING.md b/docs/hotspot/ANDROID_VPN_TETHERING_ROUTING.md new file mode 100644 index 0000000..8be8b00 --- /dev/null +++ b/docs/hotspot/ANDROID_VPN_TETHERING_ROUTING.md @@ -0,0 +1,192 @@ +# 🔧 Решение: Маршрутизация tethering трафика через VPN на Android + +## ⚠️ Проблема + +**Android по умолчанию НЕ маршрутизирует трафик tethering через VPN!** + +Когда вы: +1. Включаете VPN на Android +2. Включаете USB модем/Wi-Fi hotspot + +Трафик с подключенных устройств идет **напрямую через сотовую сеть**, минуя VPN туннель. + +**Результат:** Оператор видит реальный трафик и может определить tethering. + +--- + +## ✅ Решения + +### Решение 1: Использование VPN на подключенном устройстве (РЕКОМЕНДУЕТСЯ) + +**Вместо VPN на телефоне, используйте VPN на компьютере:** + +1. **На телефоне:** + - Включите USB модем (БЕЗ VPN на телефоне) + - Или включите Wi-Fi hotspot + +2. **На компьютере (Mac):** + - Подключитесь к USB модему + - Установите TTL = 65 (уже сделано) + - Включите VPN на компьютере (WireGuard) + +**Преимущества:** +- ✅ Работает без root +- ✅ Весь трафик идет через VPN +- ✅ TTL модификация работает +- ✅ Оператор видит только VPN трафик + +**Настройка WireGuard на Mac:** + +```bash +# Установить WireGuard +brew install wireguard-tools + +# Скопировать конфигурацию +sudo cp docs/hotspot/wg-ru.conf /etc/wireguard/wg0.conf + +# Запустить VPN +sudo wg-quick up wg0 + +# Проверить IP +curl https://api.ipify.org +# Должен показать: 83.136.235.230 +``` + +--- + +### Решение 2: Root + модификация системных настроек (для Android) + +**Требует root доступ на Android:** + +1. Установите **Magisk** (root) +2. Установите модуль **"VPN Hotspot"** или **"Tethering VPN"** +3. Эти модули форсируют маршрутизацию tethering через VPN + +**Риски:** +- ⚠️ Требует root (риск безопасности) +- ⚠️ Может нарушить гарантию +- ⚠️ Не работает на всех устройствах + +--- + +### Решение 3: Использование прокси на телефоне + +**Настройка локального прокси на телефоне:** + +1. Установите **Shadowsocks** или **V2Ray** на телефон +2. Настройте прокси на компьютере +3. Весь трафик пойдет через прокси (который использует VPN) + +**Ограничения:** +- ⚠️ Работает только для приложений, поддерживающих прокси +- ⚠️ Не все приложения используют системный прокси + +--- + +### Решение 4: Использование специализированных приложений + +**Android приложения (требуют root или специальные настройки):** + +1. **InviZible Pro** — может маршрутизировать tethering через VPN +2. **NetGuard** — firewall с VPN поддержкой +3. **Tasker** — автоматизация с root + +--- + +## 🎯 РЕКОМЕНДУЕМОЕ РЕШЕНИЕ + +### Вариант A: VPN на компьютере (БЕЗ ROOT) + +**Архитектура:** +``` +Телефон (USB модем) → Компьютер → VPN (WireGuard) → Интернет + ↓ + TTL = 65 (уже настроено) +``` + +**Шаги:** + +1. **На телефоне:** + - Включите USB модем (БЕЗ VPN на телефоне) + - Или включите Wi-Fi hotspot + +2. **На компьютере:** + ```bash + # TTL уже установлен (65) + # Теперь установите WireGuard на Mac + brew install wireguard-tools + + # Скопировать конфигурацию + sudo cp docs/hotspot/wg-ru.conf /etc/wireguard/wg0.conf + + # Запустить VPN + sudo wg-quick up wg0 + + # Проверить + curl https://api.ipify.org + # Должен показать: 83.136.235.230 + ``` + +3. **Проверка TTL:** + ```bash + ping -c 1 8.8.8.8 | grep "ttl=" + # Должно показать ttl=64 (правильно!) + ``` + +**Результат:** +- ✅ Весь трафик идет через VPN +- ✅ TTL модифицирован (оператор не видит tethering) +- ✅ Не требует root на телефоне + +--- + +### Вариант B: VPN на телефоне + Root (для продвинутых) + +Если у вас есть root на Android: + +1. Установите **Magisk** +2. Установите модуль **"VPN Hotspot"** или **"Tethering VPN"** +3. Включите VPN на телефоне +4. Включите USB модем +5. Трафик пойдет через VPN автоматически + +--- + +## 📊 Сравнение решений + +| Решение | Требует Root | Эффективность | Сложность | +|---------|--------------|---------------|-----------| +| VPN на компьютере | ❌ Нет | ✅✅✅ 95% | Низкая | +| VPN на телефоне + Root | ✅ Да | ✅✅✅ 98% | Высокая | +| Прокси на телефоне | ❌ Нет | ✅✅ 80% | Средняя | +| Спец. приложения | ⚠️ Иногда | ✅✅ 85% | Средняя | + +--- + +## 🔍 Проверка работы + +После настройки проверьте: + +```bash +# 1. IP должен быть VPN сервера +curl https://api.ipify.org +# Должен показать: 83.136.235.230 + +# 2. TTL должен быть 64 +ping -c 1 8.8.8.8 | grep "ttl=" +# Должно показать: ttl=64 + +# 3. DNS должен быть от VPN +curl https://dnsleaktest.com/ +# DNS серверы должны быть от VPN, не от оператора +``` + +--- + +## ⚠️ Важно + +**Проблема:** Android не маршрутизирует tethering через VPN по умолчанию. + +**Решение:** Используйте VPN на компьютере вместо VPN на телефоне, или используйте root для форсирования маршрутизации. + +**Рекомендация:** Вариант A (VPN на компьютере) — самое простое и эффективное решение без root. diff --git a/docs/hotspot/GUARANTEED_TETHERING_HIDE.md b/docs/hotspot/GUARANTEED_TETHERING_HIDE.md new file mode 100644 index 0000000..9350ee8 --- /dev/null +++ b/docs/hotspot/GUARANTEED_TETHERING_HIDE.md @@ -0,0 +1,537 @@ +# 🔒 Гарантированное решение: Скрытие хотспота от оператора + +## ⚠️ КРИТИЧЕСКИ ВАЖНО: Android не маршрутизирует tethering через VPN! + +**Проблема:** Когда VPN включен на Android и вы включаете USB модем, трафик с компьютера идет **напрямую через сотовую сеть**, минуя VPN. + +**Решение:** Использовать VPN на Mac вместо VPN на телефоне. + +--- + +## 🚀 Быстрая настройка (один раз) + +### Шаг 1: Установка WireGuard на Mac + +```bash +brew install wireguard-tools +``` + +### Шаг 2: Копирование конфигурации + +```bash +cd /Users/eternal/code/local_machine +sudo mkdir -p /etc/wireguard +sudo cp docs/hotspot/wg-ru.conf /etc/wireguard/wg0.conf +sudo chmod 600 /etc/wireguard/wg0.conf +``` + +### Шаг 3: Установка TTL = 65 + +```bash +sudo sysctl -w net.inet.ip.ttl=65 +echo "net.inet.ip.ttl=65" | sudo tee -a /etc/sysctl.conf +``` + +--- + +## 📱 Ежедневное использование + +### Порядок действий: + +1. **На Mac: Установить TTL = 65** (если еще не установлен) + ```bash + sudo sysctl -w net.inet.ip.ttl=65 + ``` + +2. **На телефоне:** + - ❌ **НЕ включайте VPN на телефоне!** + - ✅ Включите **USB модем** (Настройки → Режим модема → USB модем) + - Или включите **Wi-Fi hotspot** + +3. **На Mac: Запустить VPN** + ```bash + sudo wg-quick up wg0 + ``` + + Или используйте скрипт: + ```bash + ./docs/hotspot/scripts/vpn-up.sh + ``` + +4. **Проверка:** + ```bash + curl https://api.ipify.org + # Должен показать: 83.136.235.230 ✅ + ``` + +--- + +## ⚡ Быстрые команды + +### Запуск VPN: +```bash +sudo wg-quick up wg0 +# или +./docs/hotspot/scripts/vpn-up.sh +``` + +### Остановка VPN: +```bash +sudo wg-quick down wg0 +# или +./docs/hotspot/scripts/vpn-down.sh +``` + +### Проверка статуса: +```bash +sudo wg show +``` + +### Проверка IP: +```bash +curl https://api.ipify.org +``` + +--- + +## 🎯 Главная проблема: TTL (Time To Live) + +**Как оператор определяет tethering:** + +Когда устройство подключается через хотспот: +1. Пакет отправляется с TTL=64 (по умолчанию на большинстве устройств) +2. Телефон действует как роутер и **уменьшает TTL на 1** +3. Пакет приходит к оператору с **TTL=63** +4. Оператор видит: "TTL=63, значит устройство подключено через роутер (хотспот)" + +**Решение:** Модифицировать TTL на подключенных устройствах так, чтобы после прохождения через телефон пакеты имели TTL=64 (как будто идут напрямую с телефона). + +--- + +## ✅ ГАРАНТИРОВАННОЕ РЕШЕНИЕ: Комбинированный подход + +### Метод: VPN + Модификация TTL + USB Tethering + +**Этот метод скрывает все признаки tethering:** + +1. ✅ **VPN** — скрывает содержимое трафика +2. ✅ **TTL модификация** — скрывает факт прохождения через роутер +3. ✅ **USB Tethering** — менее заметно, чем Wi-Fi +4. ✅ **Модификация User-Agent** (опционально) — дополнительная маскировка + +--- + +## 🔧 Настройка: Модификация TTL + +### macOS (на подключенном компьютере) + +#### Временная настройка (до перезагрузки): + +```bash +# Установить TTL = 65 (после прохождения через телефон будет 64) +sudo sysctl -w net.inet.ip.ttl=65 + +# Проверка +sysctl net.inet.ip.ttl +# Должно показать: net.inet.ip.ttl: 65 +``` + +#### Постоянная настройка (после перезагрузки): + +```bash +# Создать файл конфигурации +sudo tee -a /etc/sysctl.conf << EOF +net.inet.ip.ttl=65 +EOF + +# Применить изменения +sudo sysctl -w net.inet.ip.ttl=65 +``` + +**Проверка:** +```bash +# Отправить пакет и проверить TTL +ping -c 1 8.8.8.8 +# TTL в ответе должен быть на 1 меньше установленного +``` + +### Windows (на подключенном компьютере) + +#### Временная настройка: + +```cmd +# Откройте Command Prompt как Администратор +netsh int ipv4 set global defaultcurhoplimit=65 + +# Проверка +netsh int ipv4 show global +# Найдите "Default Cur Hop Limit" - должно быть 65 +``` + +#### Постоянная настройка: + +```cmd +# Создать bat файл для автозапуска +# Сохраните в: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\set-ttl.bat +netsh int ipv4 set global defaultcurhoplimit=65 +``` + +### Linux (на подключенном компьютере) + +#### Временная настройка: + +```bash +# Установить TTL = 65 +echo 65 | sudo tee /proc/sys/net/ipv4/ip_default_ttl + +# Проверка +cat /proc/sys/net/ipv4/ip_default_ttl +# Должно показать: 65 +``` + +#### Постоянная настройка: + +```bash +# Добавить в /etc/sysctl.conf +echo "net.ipv4.ip_default_ttl = 65" | sudo tee -a /etc/sysctl.conf + +# Применить +sudo sysctl -p +``` + +### Android (на телефоне, требует root) + +Если нужно модифицировать TTL на самом телефоне: + +```bash +# Требует root доступ +su +echo 65 > /proc/sys/net/ipv4/ip_default_ttl + +# Проверка +cat /proc/sys/net/ipv4/ip_default_ttl +``` + +**Или используйте приложения:** +- **InviZible Pro** — имеет функцию "Fix TTL" +- **TTL Master** — специализированное приложение для модификации TTL + +--- + +## 🚀 ПОЛНАЯ НАСТРОЙКА: Гарантированное скрытие + +### Шаг 1: Настройка TTL на компьютере + +**macOS:** +```bash +# Установить TTL = 65 +sudo sysctl -w net.inet.ip.ttl=65 + +# Сделать постоянным +echo "net.inet.ip.ttl=65" | sudo tee -a /etc/sysctl.conf +``` + +**Windows:** +```cmd +netsh int ipv4 set global defaultcurhoplimit=65 +``` + +**Linux:** +```bash +echo 65 | sudo tee /proc/sys/net/ipv4/ip_default_ttl +echo "net.ipv4.ip_default_ttl = 65" | sudo tee -a /etc/sysctl.conf +sudo sysctl -p +``` + +### Шаг 2: USB Tethering + +1. Подключите телефон к компьютеру через USB +2. На телефоне: **Настройки** → **Режим модема** → **USB модем** (включите) + - ❌ **НЕ включайте VPN на телефоне!** +3. На компьютере: соединение определится автоматически + +### Шаг 3: Запуск VPN на Mac + +```bash +sudo wg-quick up wg0 +``` + +### Шаг 4: Проверка + +**На компьютере:** + +```bash +# 1. Проверка IP (должен быть IP VPN) +curl https://api.ipify.org +# Должен показать: 83.136.235.230 + +# 2. Проверка TTL +ping -c 1 8.8.8.8 | grep "ttl=" +# Должно показать ttl=64 (65-1 после прохождения через телефон) + +# 3. Проверка DNS утечек +curl https://dnsleaktest.com/ +``` + +--- + +## 🛡️ Дополнительные методы защиты + +### 1. Модификация MTU (опционально) + +Некоторые операторы анализируют размер пакетов. Можно настроить MTU: + +**macOS:** +```bash +# Установить MTU для USB интерфейса +sudo ifconfig enX mtu 1420 +# где enX - ваш USB интерфейс (найдите через: ifconfig | grep "inet ") +``` + +**Linux:** +```bash +# Найти интерфейс USB +ip link show + +# Установить MTU +sudo ip link set dev <interface> mtu 1420 +``` + +### 2. Использование прокси-цепочки (максимальная защита) + +``` +Компьютер → VPN на телефоне → Прокси → VPN сервер → Интернет +``` + +Это создает двойное шифрование и полностью скрывает паттерны трафика. + +### 3. Ограничение трафика (имитация обычного использования) + +```bash +# Ограничить скорость до разумных значений +# macOS/Linux +sudo tc qdisc add dev enX root handle 1: htb default 30 +sudo tc class add dev enX parent 1: classid 1:1 htb rate 10mbit +``` + +--- + +## 📊 Сравнение методов + +| Метод | Эффективность | Сложность | Риск обнаружения | +|-------|---------------|-----------|------------------| +| Только VPN | ⚠️ 60% | Низкая | Высокий (TTL виден) | +| VPN + TTL модификация | ✅ 90% | Средняя | Низкий | +| VPN + TTL + USB | ✅✅ 95% | Средняя | Очень низкий | +| VPN + TTL + USB + MTU | ✅✅✅ 98% | Высокая | Минимальный | + +--- + +## 🎯 РЕКОМЕНДУЕМАЯ КОНФИГУРАЦИЯ (ГАРАНТИРОВАННО) + +### На телефоне: +1. ❌ **НЕ включайте VPN на телефоне!** +2. ✅ USB Tethering (вместо Wi-Fi) + +### На компьютере: +1. ✅ TTL = 65 (обязательно!) +2. ✅ VPN (WireGuard) — всегда включен при использовании tethering +3. ✅ MTU = 1420 (опционально, для максимальной защиты) +4. ✅ Модификация User-Agent (опционально) + +### Порядок действий: +``` +1. На компьютере: Установить TTL = 65 +2. На телефоне: ОТКЛЮЧИТЬ VPN, включить USB модем +3. На компьютере: Запустить VPN (wg-quick up wg0) +4. Проверить: IP должен быть 83.136.235.230 +``` + +--- + +## 🔍 Проверка эффективности + +### Тест 1: IP адрес +```bash +curl https://api.ipify.org +# Должен показать: 83.136.235.230 (VPN сервер) +``` + +### Тест 2: TTL +```bash +ping -c 1 8.8.8.8 | grep "ttl=" +# Должно показать: ttl=64 (65-1 после прохождения через телефон) +``` + +### Тест 3: DNS утечки +```bash +curl https://dnsleaktest.com/ +# DNS серверы должны быть от VPN, не от оператора +``` + +--- + +## 📝 Важные напоминания + +1. ⚠️ **НЕ включайте VPN на телефоне** при использовании tethering +2. ✅ **Всегда включайте VPN на Mac** перед использованием интернета +3. ✅ **TTL = 65** должен быть установлен на Mac +4. ✅ **USB модем** лучше, чем Wi-Fi hotspot +5. ✅ **TTL модификация обязательна** — без нее оператор легко определит tethering +6. ✅ **Порядок важен** — сначала TTL, потом USB модем, потом VPN на Mac + +--- + +## 📊 Архитектура + +``` +Mac (TTL=65) + ↓ +USB модем + ↓ +Телефон (TTL-1 = 64) + ↓ +Сотовая сеть → Оператор видит TTL=64 (нормально!) + ↓ +VPN на Mac → 83.136.235.230 + ↓ +Интернет +``` + +**Оператор видит:** +- TTL = 64 ✅ (как будто с телефона) +- Зашифрованный VPN трафик ✅ +- Не видит содержимое ✅ +- Не видит признаки tethering ✅ + +--- + +## 🐛 Решение проблем + +### VPN не запускается + +```bash +# Проверьте конфигурацию +sudo cat /etc/wireguard/wg0.conf + +# Проверьте логи +sudo wg-quick up wg0 +``` + +### IP все еще реальный + +1. Проверьте статус VPN: `sudo wg show` +2. Убедитесь, что USB модем активен на телефоне +3. Убедитесь, что VPN на телефоне ОТКЛЮЧЕН +4. Перезапустите VPN: `sudo wg-quick down wg0 && sudo wg-quick up wg0` + +### TTL не применяется + +**macOS:** +```bash +# Проверьте текущее значение +sysctl net.inet.ip.ttl + +# Если не 65, попробуйте: +sudo sysctl -w net.inet.ip.ttl=65 + +# Проверьте файл /etc/sysctl.conf +cat /etc/sysctl.conf | grep ttl +``` + +**Windows:** +```cmd +# Проверьте значение +netsh int ipv4 show global | findstr "Default Cur Hop Limit" + +# Если не 65: +netsh int ipv4 set global defaultcurhoplimit=65 +``` + +### Проблема: TTL сбрасывается после перезагрузки + +**macOS:** +```bash +# Убедитесь, что добавлено в /etc/sysctl.conf +echo "net.inet.ip.ttl=65" | sudo tee -a /etc/sysctl.conf +``` + +**Windows:** +- Создайте bat файл в автозагрузке (см. выше) + +**Linux:** +```bash +# Убедитесь, что добавлено в /etc/sysctl.conf +echo "net.ipv4.ip_default_ttl = 65" | sudo tee -a /etc/sysctl.conf +sudo sysctl -p +``` + +--- + +## 📝 Скрипты для автоматизации + +### macOS: Автоматическая настройка TTL + +```bash +#!/bin/bash +# Сохраните как: ~/bin/set-ttl.sh + +echo "Установка TTL = 65..." +sudo sysctl -w net.inet.ip.ttl=65 + +# Проверка +CURRENT_TTL=$(sysctl -n net.inet.ip.ttl) +if [ "$CURRENT_TTL" = "65" ]; then + echo "✅ TTL установлен: $CURRENT_TTL" +else + echo "❌ Ошибка: TTL = $CURRENT_TTL" +fi + +# Добавить в автозагрузку +if ! grep -q "net.inet.ip.ttl=65" /etc/sysctl.conf 2>/dev/null; then + echo "net.inet.ip.ttl=65" | sudo tee -a /etc/sysctl.conf + echo "✅ TTL добавлен в автозагрузку" +fi +``` + +**Использование:** +```bash +chmod +x ~/bin/set-ttl.sh +~/bin/set-ttl.sh +``` + +--- + +## 🎯 ИТОГОВОЕ РЕШЕНИЕ + +**Гарантированное скрытие хотспота требует:** + +1. ✅ **TTL = 65** на Mac (ОБЯЗАТЕЛЬНО!) +2. ✅ **VPN на Mac** (WireGuard) — НЕ на телефоне! +3. ✅ **USB Tethering** (вместо Wi-Fi) +4. ✅ **Правильный порядок** (TTL → USB модем → VPN на Mac) + +**Ключевые моменты:** +- ❌ Android НЕ маршрутизирует tethering через VPN на телефоне +- ✅ Решение: VPN на Mac, а не на телефоне +- ⚠️ Без модификации TTL оператор ВСЕГДА определит tethering, даже с VPN! + +--- + +## 🔗 Связанная документация + +- [Android VPN Tethering Routing](./ANDROID_VPN_TETHERING_ROUTING.md) — подробное объяснение проблемы маршрутизации +- [Ограничения скорости и USB Tethering](./SPEED_LIMITATIONS_AND_USB_TETHERING.md) +- [Полная оптимизация хотспота](./HOTSPOT_OPTIMIZATION.md) + +## 📚 Дополнительные ресурсы + +- [InviZible Pro](https://invizible.net/) — приложение для Android с функцией Fix TTL +- [TTL Master](https://play.google.com/store/apps/details?id=com.ttlmaster) — специализированное приложение +- [Magisk Modules](https://github.com/mohamadxmuhaimin/unlimited-hotspot) — для root устройств + +--- + +**Версия:** 2.0 +**Дата:** 2025-12-11 +**Статус:** ✅ Рабочее решение (VPN на Mac, не на телефоне) diff --git a/docs/hotspot/HOTSPOT_OPTIMIZATION.md b/docs/hotspot/HOTSPOT_OPTIMIZATION.md new file mode 100644 index 0000000..04b3d89 --- /dev/null +++ b/docs/hotspot/HOTSPOT_OPTIMIZATION.md @@ -0,0 +1,877 @@ +# Скрытие использования хотспота от оператора + + + +# Установить TTL = 65 (ОБЯЗАТЕЛЬНО!) +sudo sysctl -w net.inet.ip.ttl=65 + +# Сделать постоянным +echo "net.inet.ip.ttl=65" | sudo tee -a /etc/sysctl.conf + +1. На компьютере: Установить TTL = 65 ← ВАЖНО ПЕРВЫМ! +2. На телефоне: Включить VPN (WireGuard) +3. Подключить телефон к компьютеру через USB +4. На телефоне: Включить USB модем +5. Проверить: curl https://api.ipify.org (должен быть 83.136.235.230) + +## Как операторы определяют использование хотспота + +### 1. Анализ IMEI и User-Agent + +- Каждый телефон имеет уникальный код **IMEI** (Международный идентификатор мобильного оборудования) +- При раздаче интернета телефон сообщает сети, что работает как маршрутизатор/модем через HTTP-заголовки (User-Agent) +- Сеть видит, что один IMEI "притворяется" несколькими устройствами + +### 2. Анализ трафика + +- Большой объем данных с одного номера, используемый другими IP-адресами (устройствами) +- Оператор видит, что телефон получает интернет по сотовой сети, а отдает по Wi-Fi/USB множеству устройств с уникальными IP + +### 4. Анализ TTL (Time To Live) - КРИТИЧЕСКИ ВАЖНО! ⚠️ + +**Это основной метод обнаружения tethering!** + +- Каждый пакет имеет TTL (Time To Live) — счетчик переходов через роутеры +- Когда устройство подключается через хотспот, телефон действует как роутер +- Телефон **уменьшает TTL на 1** при маршрутизации пакетов +- Оператор видит: пакеты с TTL=63 (вместо 64) = признак tethering +- **Без модификации TTL оператор ВСЕГДА определит tethering, даже с VPN!** + +### 3. Особенности тарифов + +- Разные условия для модема/хотспота vs обычного использования +- Трафик идет не на браузер/приложение, а на создание локальной сети + +--- + +## Методы обеспечения невидимости + +### ⭐ Метод 1: VPN на телефоне (РЕКОМЕНДУЕТСЯ) + +**Принцип:** Весь трафик с телефона идет через VPN-туннель, оператор видит только зашифрованное VPN-соединение. + +**Преимущества:** +- ✅ Оператор не видит реальный трафик приложений +- ✅ Не видит User-Agent подключенных устройств +- ✅ Весь трафик выглядит как одно VPN-соединение +- ✅ Не требует root-доступа на большинстве устройств +- ✅ Работает на любом устройстве + +--- + +## 📱 Подробная настройка VPN на телефоне + +### Вариант 1: WireGuard (РЕКОМЕНДУЕТСЯ) + +**Почему WireGuard:** +- ✅ Очень быстрый (85-95% от пропускной способности) +- ✅ Простая настройка +- ✅ Полное туннелирование из коробки +- ✅ Низкое потребление батареи +- ✅ Современная криптография + +#### Настройка на Android: + +1. **Установите приложение WireGuard:** + - Google Play: [WireGuard](https://play.google.com/store/apps/details?id=com.wireguard.android) + - Или F-Droid: [WireGuard](https://f-droid.org/packages/com.wireguard.android/) + +2. **Получите конфигурацию:** + + **Способ 1: Скачать с сервера (если конфигурация уже создана):** + ```bash + # Подключитесь к серверу + ssh hunab-prod + + # Скопируйте конфигурацию с сервера + # Конфигурация находится в: /opt/app/vpn/wireguard/config/peer1/peer1.conf + scp hunab-prod:/opt/app/vpn/wireguard/config/peer1/peer1.conf ./wireguard-android.conf + + # Или просмотрите содержимое и скопируйте вручную + ssh hunab-prod "cat /opt/app/vpn/wireguard/config/peer1/peer1.conf" + ``` + + **Способ 2: Создать новую конфигурацию на сервере:** + ```bash + # На сервере запустите скрипт развертывания (если еще не запущен) + ssh hunab-prod "cd /opt/app && bash scripts/deployment/deploy-vpn-wireguard.sh" + + # После создания конфигурации скопируйте её + scp hunab-prod:/opt/app/vpn/wireguard/config/peer1/peer1.conf ./wireguard-android.conf + ``` + + **Способ 3: Использовать шаблон:** + - Используйте файл-шаблон: [`wireguard-android.conf`](./wireguard-android.conf) + - Замените `YOUR_PRIVATE_KEY_HERE` и `YOUR_SERVER_PUBLIC_KEY_HERE` на реальные ключи с сервера + + **Структура конфигурации:** + ``` + [Interface] + PrivateKey = <ваш_приватный_ключ_клиента> + Address = 10.13.13.2/24 + DNS = 8.8.8.8, 1.1.1.1 + + [Peer] + PublicKey = <публичный_ключ_сервера> + Endpoint = 209.38.32.21:51820 + AllowedIPs = 0.0.0.0/0 + ``` + + **Где найти ключи на сервере:** + ```bash + # Подключитесь к серверу + ssh hunab-prod + + # Просмотрите конфигурацию клиента + cat /opt/app/vpn/wireguard/config/peer1/peer1.conf + + # Или просмотрите конфигурацию сервера для получения публичного ключа + docker exec hunab-vpn-wireguard wg show + ``` + +3. **Передайте файл на Android:** + + **Способ 1: Через USB (ADB):** + ```bash + # Подключите телефон через USB + # Включите отладку по USB на телефоне + adb push wireguard-android.conf /sdcard/Download/ + ``` + + **Способ 2: Через облако (Google Drive, Dropbox и т.д.):** + - Загрузите файл `wireguard-android.conf` в облачное хранилище + - Откройте файл на телефоне через приложение облачного хранилища + - Выберите "Открыть с помощью" → WireGuard + + **Способ 3: Через email или мессенджер:** + - Отправьте файл себе на email или в мессенджер + - Откройте файл на телефоне + - Выберите "Открыть с помощью" → WireGuard + + **Способ 4: Через QR-код (удобно для быстрой настройки):** + ```bash + # На компьютере создайте QR-код из конфигурации + # Установите qrencode (если еще не установлен) + brew install qrencode # macOS + # или + sudo apt install qrencode # Linux + + # Создайте QR-код + qrencode -t PNG -o wireguard-qr.png < wireguard-android.conf + + # Откройте изображение и отсканируйте QR-код в приложении WireGuard + ``` + + **Способ 5: Вставить конфигурацию вручную:** + - Откройте файл `wireguard-android.conf` в текстовом редакторе + - Скопируйте всё содержимое + - В приложении WireGuard: **"+"** → **"Создать из файла или архива"** → **"Создать из буфера обмена"** + - Вставьте конфигурацию + +4. **Импортируйте конфигурацию в WireGuard:** + - Откройте приложение WireGuard на Android + - Нажмите **"+"** (кнопка добавления) + - Выберите один из вариантов: + - **"Создать из файла или архива"** — выберите файл `.conf` + - **"Создать из QR-кода"** — отсканируйте QR-код + - **"Создать из буфера обмена"** — вставьте текст конфигурации + - Нажмите **"Создать туннель"** + - При необходимости дайте имя туннелю (например, "VPN Hotspot") + +4. **Подключитесь:** + - Включите туннель (переключатель) + - Убедитесь, что статус показывает "Подключено" + +5. **Проверьте подключение:** + - Откройте браузер на телефоне + - Перейдите на https://whatismyipaddress.com/ + - Должен отображаться IP: **209.38.32.21** + +6. **Включите хотспот:** + - **Настройки** → **Режим модема** → **Точка доступа Wi-Fi** (или USB/Bluetooth) + - **ВАЖНО:** VPN должен быть включен **ДО** активации хотспота + +#### Настройка на iOS: + +1. **Установите приложение WireGuard:** + - App Store: [WireGuard](https://apps.apple.com/app/wireguard/id1441195209) + +2. **Импортируйте конфигурацию:** + - Откройте приложение WireGuard + - Нажмите **"+"** → **"Создать из файла или архива"** + - Выберите файл `.conf` или отсканируйте QR-код + - Нажмите **"Добавить туннель"** + +3. **Подключитесь:** + - Включите туннель + - При первом подключении iOS запросит разрешение на VPN + +4. **Проверьте и включите хотспот** (как в Android) + +--- + +### Вариант 2: Shadowsocks (для обхода блокировок) + +**Почему Shadowsocks:** +- ✅ Лучший для обхода строгих блокировок +- ✅ Сложнее обнаружить через DPI +- ✅ Эффективен против цензуры + +**Параметры подключения (сервер 209.38.32.21):** +``` +Server: 209.38.32.21 +Port: 8388 +Password: bNkSbuMQXgMXmuBLPQCA5cSUE +Method: chacha20-ietf-poly1305 +``` + +**URI для импорта:** +``` +ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpiTmtTYnVNUVhnTVhtdUJMUFFDQTVjU1VFQDIwOS4zOC4zMi4yMTo4Mzg4 +``` + +#### Настройка на Android: + +1. **Установите приложение Shadowsocks:** + - Google Play: [Shadowsocks](https://play.google.com/store/apps/details?id=com.github.shadowsocks) (разработчик: Max Lv) + +2. **Настройте подключение:** + - Откройте приложение + - Нажмите **"+"** → **"Manual Settings"** + - Введите параметры: + - **Server**: `209.38.32.21` + - **Remote Port**: `8388` + - **Password**: `bNkSbuMQXgMXmuBLPQCA5cSUE` + - **Method**: `chacha20-ietf-poly1305` + - Нажмите **"Подключиться"** + +3. **Или импортируйте через URI:** + - Нажмите **"+"** → **"Scan QR code"** или **"Import from clipboard"** + - Вставьте URI выше + +4. **Проверьте подключение и включите хотспот** + +**Альтернативные клиенты для Android:** +- **ShadowsocksR** — больше функций +- **Outline** — очень простой +- **V2rayNG** — много протоколов +- **Clash for Android** — правила маршрутизации + +#### Настройка на iOS: + +1. **Установите приложение:** + - App Store: [Shadowrocket](https://apps.apple.com/app/shadowrocket/id932747118) (платное) + - Или [Outline](https://apps.apple.com/app/outline-app/id1356177741) (бесплатное) + +2. **Настройте подключение** (аналогично Android) + +--- + +### Вариант 3: OpenVPN + +**Настройка:** +1. Установите приложение **OpenVPN Connect** +2. Импортируйте `.ovpn` конфигурационный файл +3. Подключитесь к серверу + +--- + +## 🔍 Проверка работы VPN + +### На телефоне: + +1. **Проверьте IP адрес:** + - Откройте браузер: https://whatismyipaddress.com/ + - Должен отображаться IP VPN-сервера (209.38.32.21) + +2. **Проверьте статус VPN:** + - В приложении VPN должен быть статус "Connected" + - В настройках Android/iOS должен быть индикатор VPN + +3. **Проверьте DNS:** + ```bash + # Если доступен терминал на телефоне + nslookup google.com + # Должен показать DNS сервер VPN + ``` + +### На подключенном устройстве (после включения хотспота): + +1. **Проверьте IP адрес:** + ```bash + curl https://api.ipify.org + # Должен показать IP VPN-сервера (209.38.32.21) + ``` + +2. **Проверьте, что трафик идет через VPN:** + - Откройте https://dnsleaktest.com/ + - Проверьте, что DNS серверы соответствуют VPN + +--- + +## ⚠️ Важные моменты + +1. **Порядок действий:** + - ✅ Сначала включите VPN + - ✅ Затем включите хотспот + - ❌ НЕ включайте хотспот до VPN + +2. **Проверка утечек:** + - Используйте https://ipleak.net/ для проверки утечек DNS/IP + - Убедитесь, что весь трафик идет через VPN + +3. **Автоподключение VPN:** + - Настройте автоподключение VPN при включении хотспота + - В WireGuard: **Настройки туннеля** → **Автоподключение** + +4. **Батарея:** + - VPN потребляет дополнительную батарею + - WireGuard более экономичен, чем OpenVPN + +--- + +## 📚 Дополнительная документация + +- [Полное руководство по WireGuard](../vpn/WIREGUARD.md) +- [Полное руководство по Shadowsocks](../vpn/SHADOWSOCKS.md) +- [VPN клиенты для macOS](../vpn/MAC_CLIENTS.md) +- [Обзор VPN решений](../vpn/README.md) + +--- + +**Результат:** Оператор видит только VPN-трафик, не может определить, что телефон раздает интернет другим устройствам. + +--- + +### Метод 2: Модификация User-Agent на подключенных устройствах + +**Что такое User-Agent?** + +**User-Agent** — это HTTP-заголовок, который браузер или приложение отправляет на сервер при каждом запросе. Он содержит информацию об устройстве, операционной системе и браузере. + +**Примеры User-Agent:** +- macOS Chrome: `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36` +- Android Chrome: `Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36` +- iPhone Safari: `Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1` + +**Принцип:** Изменение HTTP-заголовков на устройствах, подключенных к хотспоту, чтобы они выглядели как мобильные приложения или обычное использование телефона. + +**Почему это важно:** +- Оператор может анализировать User-Agent для определения типа устройства +- Desktop User-Agent на мобильном соединении может указывать на tethering +- Мобильный User-Agent выглядит более естественно + +--- + +**Настройка на macOS:** + +#### Вариант 1: Использование mitmproxy (рекомендуется) + +**Установка:** +```bash +brew install mitmproxy +``` + +**Создание скрипта для модификации User-Agent:** + +Создайте файл `~/.mitmproxy/user-agent-modifier.py`: +```python +from mitmproxy import http + +# Мобильные User-Agent для маскировки +MOBILE_USER_AGENTS = [ + "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36", + "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1" +] + +import random + +def request(flow: http.HTTPFlow) -> None: + # Заменяем User-Agent на мобильный + if flow.request.headers.get("User-Agent"): + flow.request.headers["User-Agent"] = random.choice(MOBILE_USER_AGENTS) + print(f"Modified User-Agent to: {flow.request.headers['User-Agent']}") +``` + +**Запуск mitmproxy:** +```bash +# Запустите mitmproxy с вашим скриптом +mitmproxy -s ~/.mitmproxy/user-agent-modifier.py +``` + +**Настройка прокси на macOS:** +1. **System Settings** → **Network** → выберите активное соединение +2. **Details...** → **Proxies** +3. Включите **HTTP Proxy**: `127.0.0.1:8080` +4. Включите **HTTPS Proxy**: `127.0.0.1:8080` +5. Нажмите **OK** + +**Или через командную строку:** +```bash +INTERFACE=$(networksetup -listallnetworkservices | grep -E "Wi-Fi|Ethernet" | head -1) +networksetup -setwebproxy "$INTERFACE" 127.0.0.1 8080 +networksetup -setsecurewebproxy "$INTERFACE" 127.0.0.1 8080 +networksetup -setwebproxystate "$INTERFACE" on +networksetup -setsecurewebproxystate "$INTERFACE" on +``` + +**Установка сертификата mitmproxy (для HTTPS):** +1. Откройте браузер: http://mitm.it +2. Скачайте сертификат для macOS +3. Установите сертификат: **Keychain Access** → импортируйте `.pem` файл +4. Дважды кликните на сертификат → **Trust** → **Always Trust** + +#### Вариант 2: Использование Charles Proxy (GUI) + +**Установка:** +```bash +brew install --cask charles +``` + +**Настройка:** +1. Откройте Charles Proxy +2. **Proxy** → **Proxy Settings** → порт `8888` +3. **Tools** → **Rewrite** → **Enable Rewrite** +4. Добавьте правило: + - **Name**: Modify User-Agent + - **Type**: Request Headers + - **Match**: `User-Agent` + - **Replace**: `Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1` + +#### Вариант 3: Браузерные расширения (только для браузера) + +**Chrome/Edge:** +- Установите расширение "User-Agent Switcher and Manager" +- Выберите мобильный User-Agent + +**Firefox:** +- Установите расширение "User-Agent Switcher" +- Выберите мобильный User-Agent + +**Ограничение:** Работает только для браузера, не для всех приложений. + +--- + +**Настройка на Android (требует root):** + +#### Вариант 1: Xposed модули +1. Установите Xposed Framework +2. Установите модуль "XPrivacyLua" или "User Agent Switcher" +3. Настройте мобильный User-Agent для приложений + +#### Вариант 2: Приложения +- **User Agent Switcher** (требует root) +- **XPrivacyLua** (требует Xposed) + +#### Вариант 3: Настройка в браузере +- Chrome: `chrome://flags` → поиск "User-Agent" +- Firefox: Установите расширение "User-Agent Switcher" + +--- + +**Настройка на iOS:** + +#### Вариант 1: Safari (без jailbreak) +1. Установите расширение "User-Agent Switcher" (если доступно) +2. Или используйте профили конфигурации (ограниченная функциональность) + +#### Вариант 2: Jailbreak решения +- **Flex 3** — патчи для изменения User-Agent +- **XCon** — обход проверок + +**Ограничение:** Без jailbreak возможности очень ограничены. + +--- + +**Проверка модификации User-Agent:** + +1. Откройте в браузере: https://www.whatismybrowser.com/ +2. Проверьте отображаемый User-Agent +3. Убедитесь, что он соответствует мобильному устройству + +**Или через командную строку:** +```bash +# С прокси +curl -x http://127.0.0.1:8080 -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)" https://httpbin.org/headers + +# Без прокси (для сравнения) +curl https://httpbin.org/headers +``` + +--- + +**Ограничения:** +- ⚠️ Не все приложения используют системный User-Agent +- ⚠️ Некоторые приложения имеют собственные заголовки (нельзя изменить) +- ⚠️ Оператор может анализировать другие параметры (TTL, размер пакетов) +- ⚠️ HTTPS трафик требует установки сертификата (mitmproxy) +- ⚠️ Некоторые приложения проверяют сертификаты (certificate pinning) + +**Рекомендация:** Используйте в сочетании с VPN для максимальной эффективности. + +--- + +### Метод 3: Использование USB/Bluetooth Tethering вместо Wi-Fi + +**Что такое Tethering?** + +**Tethering (привязка)** — это технология, позволяющая использовать интернет-соединение одного устройства (телефона) для подключения других устройств (компьютера, планшета) к интернету. + +**Типы tethering:** + +1. **Wi-Fi Hotspot (Точка доступа Wi-Fi)** + - Телефон создает Wi-Fi сеть + - Другие устройства подключаются как к обычной Wi-Fi сети + - **Наиболее заметно для оператора** (создает отдельную сеть) + +2. **USB Tethering (USB модем)** + - Телефон подключается к компьютеру через USB кабель + - Компьютер использует интернет телефона через USB + - **Менее заметно** (выглядит как прямое подключение) + +3. **Bluetooth Tethering (Bluetooth модем)** + - Телефон подключается к устройству через Bluetooth + - Использует другой протокол идентификации + - **Менее заметно** (другой протокол связи) + +**Принцип:** USB и Bluetooth tethering могут быть менее заметны, чем Wi-Fi hotspot, так как не создают отдельную Wi-Fi сеть. + +**Преимущества:** +- ✅ Wi-Fi hotspot создает отдельную сеть (более заметно для оператора) +- ✅ USB tethering выглядит как прямое подключение (менее подозрительно) +- ✅ Bluetooth использует другой протокол идентификации (PAN - Personal Area Network) +- ✅ Меньше энергопотребление (особенно USB) +- ✅ Более стабильное соединение (USB) +- ✅ Не требует пароля Wi-Fi + +**Настройка USB Tethering:** + +**Android:** +1. Подключите телефон к компьютеру через USB кабель +2. На телефоне: **Настройки** → **Режим модема** → **USB модем** (включите) +3. На компьютере (macOS): Соединение определится автоматически +4. На компьютере (Windows): Установите драйверы, если потребуется +5. На компьютере (Linux): Обычно работает из коробки + +**Проверка подключения (macOS):** +```bash +# Проверить активное соединение +networksetup -listallnetworkservices | grep -i usb + +# Проверить IP адрес +ifconfig | grep -A 5 "en.*:" | grep "inet " +``` + +**iOS:** +1. Подключите iPhone к компьютеру через USB +2. На iPhone: **Настройки** → **Режим модема** → **USB модем** (включите) +3. На macOS: Соединение определится автоматически +4. На Windows: Установите iTunes для драйверов + +**Настройка Bluetooth Tethering:** + +**Android:** +1. Включите Bluetooth на телефоне и компьютере +2. Сопрягите устройства: + - На телефоне: **Настройки** → **Bluetooth** → найдите компьютер → **Сопряжение** + - На компьютере: Примите запрос на сопряжение +3. На телефоне: **Настройки** → **Режим модема** → **Bluetooth модем** (включите) +4. На компьютере (macOS): + - **System Settings** → **Network** → **Bluetooth PAN** + - Выберите телефон и подключитесь + +**iOS:** +1. Включите Bluetooth на iPhone и компьютере +2. Сопрягите устройства +3. На iPhone: **Настройки** → **Режим модема** → **Bluetooth модем** (включите) +4. На macOS: Подключитесь через Bluetooth в настройках сети + +**Сравнение методов:** + +| Метод | Скорость | Стабильность | Энергопотребление | Заметность | +|-------|----------|--------------|-------------------|------------| +| Wi-Fi Hotspot | Высокая | Средняя | Высокое | ⚠️ Высокая | +| USB Tethering | Очень высокая | Очень высокая | Низкое | ✅ Низкая | +| Bluetooth Tethering | Низкая | Средняя | Среднее | ✅ Низкая | + +**Ограничения:** +- ⚠️ Оператор все еще может анализировать трафик (рекомендуется VPN) +- ⚠️ Bluetooth tethering медленнее Wi-Fi и USB +- ⚠️ USB tethering требует кабель (неудобно для мобильности) +- ⚠️ Не все операторы разрешают tethering на всех тарифах + +**Рекомендация:** Используйте USB tethering в сочетании с VPN для максимальной невидимости. + +--- + +### Метод 4: Ограничение и распределение трафика + +**Принцип:** Ограничение скорости и объема трафика, чтобы он выглядел как обычное использование телефона. + +**Стратегии:** + +1. **Ограничение скорости:** + ```bash + # На Linux/macOS используйте tc (traffic control) + sudo tc qdisc add dev en0 root handle 1: htb default 30 + sudo tc class add dev en0 parent 1: classid 1:1 htb rate 5mbit + ``` + +2. **Ограничение одновременных подключений:** + - Подключайте только одно устройство за раз + - Избегайте одновременного использования нескольких устройств + +3. **Имитация поведения обычного пользователя:** + - Не используйте хотспот постоянно + - Чередуйте использование интернета на телефоне и через хотспот + - Избегайте больших объемов трафика в короткое время + +**Ограничения:** +- ⚠️ Не гарантирует полную невидимость +- ⚠️ Может быть неудобно в использовании + +--- + +### Метод 5: Использование специализированных приложений + +**Android (требует root):** + +1. **Tethering Manager:** + - Позволяет скрывать факт раздачи интернета + - Модифицирует системные параметры + +2. **Xposed модули:** + - XTether (скрывает tethering) + - Tethering Manager модули + +**iOS (требует jailbreak):** + +1. **TetherMe:** + - Обходит ограничения оператора + - Работает через Cydia + +**Ограничения:** +- ⚠️ Требует root/jailbreak (риск безопасности) +- ⚠️ Может нарушать гарантию устройства +- ⚠️ Не все приложения работают на новых версиях ОС + +--- + +### ⭐⭐ Метод 6: Модификация TTL (КРИТИЧЕСКИ ВАЖНО!) + +**Почему это важно:** +- Оператор определяет tethering по TTL пакетов +- Без модификации TTL оператор **ВСЕГДА** определит tethering +- Это основной метод обнаружения, который обходит VPN! + +**Принцип:** +- Установить TTL = 65 на подключенном устройстве +- После прохождения через телефон (TTL-1) пакет придет с TTL=64 +- Оператор видит TTL=64 = как будто пакет идет напрямую с телефона + +**Настройка на macOS (на подключенном компьютере):** + +```bash +# Временная настройка +sudo sysctl -w net.inet.ip.ttl=65 + +# Постоянная настройка +echo "net.inet.ip.ttl=65" | sudo tee -a /etc/sysctl.conf +``` + +**Настройка на Windows:** + +```cmd +netsh int ipv4 set global defaultcurhoplimit=65 +``` + +**Настройка на Linux:** + +```bash +echo 65 | sudo tee /proc/sys/net/ipv4/ip_default_ttl +echo "net.ipv4.ip_default_ttl = 65" | sudo tee -a /etc/sysctl.conf +sudo sysctl -p +``` + +**Проверка:** +```bash +ping -c 1 8.8.8.8 | grep "ttl=" +# Должно показать ttl=64 (65-1 после прохождения через телефон) +``` + +**📖 Полная инструкция:** [`GUARANTEED_TETHERING_HIDE.md`](./GUARANTEED_TETHERING_HIDE.md) + +--- + +### Метод 7: Комбинированный подход (ГАРАНТИРОВАННО ЭФФЕКТИВНЫЙ) + +**Рекомендуемая комбинация (в порядке важности):** + +1. **Модификация TTL** (ОБЯЗАТЕЛЬНО!) ⭐⭐⭐ + - TTL = 65 на подключенном устройстве + - Без этого оператор ВСЕГДА определит tethering + +2. **VPN на телефоне** (обязательно) ⭐⭐ + - WireGuard или OpenVPN + - Всегда включен при использовании хотспота + +3. **USB Tethering** (вместо Wi-Fi) ⭐ + - Менее заметно, чем Wi-Fi hotspot + +4. **Ограничение трафика** (рекомендуется) + - Разумное использование объема данных + - Избегание пиковых нагрузок + +5. **Модификация User-Agent** (опционально) + - На подключенных устройствах + +**Пример настройки (ПРАВИЛЬНЫЙ ПОРЯДОК):** + +```bash +# 1. На компьютере: Установить TTL = 65 (ОБЯЗАТЕЛЬНО ПЕРВЫМ!) +sudo sysctl -w net.inet.ip.ttl=65 # macOS +# или +netsh int ipv4 set global defaultcurhoplimit=65 # Windows + +# 2. На телефоне: Включить VPN (WireGuard) +# 3. Подключить телефон к компьютеру через USB +# 4. На телефоне: Включить USB модем +# 5. На компьютере: Проверить IP через VPN +curl https://api.ipify.org +# Должен показать: 83.136.235.230 + +# 6. Проверить TTL +ping -c 1 8.8.8.8 | grep "ttl=" +# Должно показать ttl=64 (правильно!) +``` + +--- + +## Проверка эффективности + +### Тест 1: Проверка видимости трафика + +1. Включите хотспот с VPN +2. Откройте сайт на подключенном устройстве +3. Проверьте, видит ли оператор реальный трафик: + ```bash + # Используйте Wireshark или tcpdump на телефоне (требует root) + # Или проверьте логи оператора (если доступны) + ``` + +### Тест 2: Проверка User-Agent + +1. Откройте https://www.whatismybrowser.com/ на подключенном устройстве +2. Проверьте, какой User-Agent виден +3. Убедитесь, что он не выдает факт использования хотспота + +### Тест 3: Проверка IP-адресов + +1. На телефоне: Проверьте IP + ```bash + curl https://api.ipify.org + ``` + +2. На подключенном устройстве: Проверьте IP + ```bash + curl https://api.ipify.org + ``` + +3. **Ожидаемый результат:** Оба устройства должны показывать IP VPN-сервера + +--- + +## Дополнительные рекомендации + +### Безопасность + +- ✅ Используйте надежные VPN-серверы +- ✅ Включайте VPN **до** активации хотспота +- ✅ Используйте шифрование (WireGuard, OpenVPN с AES-256) +- ✅ Регулярно обновляйте VPN клиенты + +### Оптимизация + +- ✅ Используйте VPN серверы с низкой задержкой +- ✅ Выбирайте серверы в той же стране (меньше подозрений) +- ✅ Избегайте VPN серверов, известных оператору + +### Избегание обнаружения + +- ❌ Не используйте хотспот постоянно (чередуйте с обычным использованием) +- ❌ Не передавайте большие объемы данных (торренты, стриминг) +- ❌ Не подключайте много устройств одновременно +- ❌ Не используйте хотспот в пиковые часы + +--- + +## Юридические предупреждения + +⚠️ **Важно:** + +- Использование методов обхода ограничений оператора может нарушать условия использования тарифа +- В некоторых юрисдикциях это может быть незаконно +- Используйте только на своих устройствах и для личных целей +- Не нарушайте законы вашей страны + +✅ **Рекомендации:** + +- Изучите условия вашего тарифа +- Используйте легальные методы (VPN разрешены в большинстве стран) +- Рассмотрите тарифы с разрешенным tethering + +--- + +## Решение проблем + +### Проблема: Оператор все еще определяет хотспот + +**Решения:** +1. Убедитесь, что VPN включен **до** активации хотспота +2. Проверьте, что весь трафик идет через VPN (нет утечек) +3. Используйте USB tethering вместо Wi-Fi +4. Попробуйте другой VPN сервер/провайдер + +### Проблема: Медленная скорость через VPN + +**Решения:** +1. Выберите VPN сервер ближе к вашему местоположению +2. Используйте WireGuard (быстрее OpenVPN) +3. Проверьте скорость без VPN (возможно, проблема у оператора) +4. Используйте выделенный VPN сервер (не shared) + +### Проблема: VPN не работает на телефоне + +**Решения:** +1. Проверьте настройки VPN клиента +2. Убедитесь, что сервер доступен +3. Проверьте файрвол на телефоне +4. Перезагрузите телефон +5. Попробуйте другой VPN протокол + +--- + +## Связанная документация + +- [VPN настройки](../vpn/README.md) +- [WireGuard конфигурация](../vpn/WIREGUARD.md) +- [Shadowsocks настройка](../vpn/SHADOWSOCKS.md) +- [MAC spoofing](../security/MAC_SPOOFING_GUIDE.md) + +--- + +## Заключение + +**ГАРАНТИРОВАННО эффективный метод:** + +1. ⭐⭐⭐ **Модификация TTL = 65** (на подключенном устройстве) — ОБЯЗАТЕЛЬНО! +2. ⭐⭐ **VPN на телефоне** (WireGuard) +3. ⭐ **USB Tethering** (вместо Wi-Fi) +4. Разумное использование трафика + +**⚠️ КРИТИЧЕСКИ ВАЖНО:** Без модификации TTL оператор ВСЕГДА определит tethering, даже с VPN! TTL модификация — это основа гарантированного скрытия. + +**📖 Полная инструкция:** [`GUARANTEED_TETHERING_HIDE.md`](./GUARANTEED_TETHERING_HIDE.md) + +Этот комбинированный подход обеспечивает максимальную невидимость для оператора при сохранении удобства использования. diff --git a/docs/hotspot/QUICK_FIX_VPN_ROUTING.md b/docs/hotspot/QUICK_FIX_VPN_ROUTING.md new file mode 100644 index 0000000..c8f2ce2 --- /dev/null +++ b/docs/hotspot/QUICK_FIX_VPN_ROUTING.md @@ -0,0 +1,143 @@ +# 🚀 Быстрое решение: VPN на Mac вместо VPN на телефоне + +## ⚠️ Проблема + +Android **НЕ маршрутизирует** трафик tethering через VPN по умолчанию! + +Когда VPN включен на телефоне, трафик с компьютера идет **напрямую**, минуя VPN. + +## ✅ Решение: VPN на Mac + +**Вместо VPN на телефоне → используйте VPN на Mac!** + +--- + +## 📋 Пошаговая инструкция + +### Шаг 1: Установите WireGuard на Mac + +```bash +brew install wireguard-tools +``` + +### Шаг 2: Скопируйте конфигурацию + +```bash +cd /Users/eternal/code/local_machine +sudo mkdir -p /etc/wireguard +sudo cp docs/hotspot/wg-ru.conf /etc/wireguard/wg0.conf +sudo chmod 600 /etc/wireguard/wg0.conf +``` + +### Шаг 3: На телефоне + +1. **Отключите VPN на телефоне** (WireGuard) +2. Включите **USB модем** (Настройки → Режим модема → USB модем) +3. Или включите **Wi-Fi hotspot** + +### Шаг 4: На Mac - запустите VPN + +```bash +sudo wg-quick up wg0 +``` + +### Шаг 5: Проверка + +```bash +# IP должен быть VPN сервера +curl https://api.ipify.org +# Должен показать: 83.136.235.230 + +# Проверка TTL +ping -c 1 8.8.8.8 | grep "ttl=" +# Должно показать: ttl=64 (правильно!) +``` + +--- + +## 🎯 Правильный порядок действий + +``` +1. ✅ TTL = 65 (уже сделано на Mac) +2. На телефоне: ОТКЛЮЧИТЬ VPN, включить USB модем +3. На Mac: Запустить VPN (sudo wg-quick up wg0) +4. Проверить: curl https://api.ipify.org (должен быть 83.136.235.230) +``` + +--- + +## 🔧 Управление VPN на Mac + +**Запуск:** +```bash +sudo wg-quick up wg0 +``` + +**Остановка:** +```bash +sudo wg-quick down wg0 +``` + +**Статус:** +```bash +sudo wg show +``` + +**Автозапуск (опционально):** +```bash +# Создать LaunchDaemon для автозапуска +sudo tee /Library/LaunchDaemons/com.wireguard.wg0.plist << EOF +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.wireguard.wg0</string> + <key>ProgramArguments</key> + <array> + <string>/usr/local/bin/wg-quick</string> + <string>up</string> + <string>wg0</string> + </array> + <key>RunAtLoad</key> + <true/> +</dict> +</plist> +EOF + +sudo launchctl load /Library/LaunchDaemons/com.wireguard.wg0.plist +``` + +--- + +## ✅ Результат + +После настройки: +- ✅ Весь трафик с Mac идет через VPN +- ✅ TTL модифицирован (оператор не видит tethering) +- ✅ IP = 83.136.235.230 (VPN сервер) +- ✅ Оператор видит только VPN трафик + +--- + +## 🐛 Решение проблем + +### VPN не запускается + +```bash +# Проверьте конфигурацию +sudo cat /etc/wireguard/wg0.conf + +# Проверьте логи +sudo wg-quick up wg0 +``` + +### IP все еще реальный + +1. Проверьте, что VPN запущен: `sudo wg show` +2. Проверьте маршруты: `netstat -rn | grep default` +3. Перезапустите VPN: `sudo wg-quick down wg0 && sudo wg-quick up wg0` + +--- + +**Выполните команды выше и проверьте IP!** diff --git a/docs/hotspot/SPEED_LIMITATIONS_AND_USB_TETHERING.md b/docs/hotspot/SPEED_LIMITATIONS_AND_USB_TETHERING.md new file mode 100644 index 0000000..e59ce02 --- /dev/null +++ b/docs/hotspot/SPEED_LIMITATIONS_AND_USB_TETHERING.md @@ -0,0 +1,237 @@ +# 🚀 Ограничения скорости и USB Tethering + +## 1. Почему ограничена скорость интернета через хотспот? + +### Причины ограничения скорости: + +#### A. Ограничения оператора (даже с VPN) + +**Оператор может ограничивать скорость на уровне:** +- **Тарифа** — некоторые тарифы имеют ограничения на tethering +- **IMEI устройства** — оператор видит, что устройство работает как модем +- **Паттернов трафика** — большие объемы данных могут триггерить ограничения +- **DPI (Deep Packet Inspection)** — анализ трафика даже через VPN + +**Важно:** VPN скрывает содержимое трафика, но оператор все еще видит: +- Объем трафика +- Время использования +- Паттерны подключения +- IMEI устройства + +#### B. Технические ограничения + +1. **Wi-Fi Hotspot:** + - Ограничения Wi-Fi модуля телефона + - Двойное шифрование (Wi-Fi + VPN) + - Нагрузка на процессор телефона + +2. **VPN overhead:** + - Шифрование/дешифрование трафика + - Задержка через VPN сервер + - Расстояние до VPN сервера + +3. **Сотовая сеть:** + - Ограничения оператора на уровне базовой станции + - Приоритизация трафика (обычный интернет > tethering) + +#### C. Ограничения самого хотспота + +- **Android/iOS** могут ограничивать скорость хотспота программно +- **Настройки оператора** могут ограничивать tethering на уровне прошивки + +--- + +## 2. Как использовать USB Tethering вместо Wi-Fi? + +### Преимущества USB Tethering: + +- ✅ **Быстрее** — прямое USB соединение (до 480 Мбит/с USB 2.0, до 5 Гбит/с USB 3.0) +- ✅ **Стабильнее** — нет помех Wi-Fi +- ✅ **Менее заметно** для оператора +- ✅ **Меньше энергопотребление** — телефон заряжается через USB +- ✅ **Нет ограничений Wi-Fi модуля** + +--- + +## 📱 Пошаговая инструкция: USB Tethering + +### Android → macOS/Windows/Linux + +#### Шаг 1: Подготовка + +1. **Подключите телефон к компьютеру через USB кабель** + - Используйте качественный кабель (желательно USB 3.0) + - Убедитесь, что кабель поддерживает передачу данных (не только зарядку) + +2. **На телефоне:** + - Разблокируйте телефон + - При появлении уведомления "USB подключение" выберите **"Передача файлов"** или **"MTP"** + - Или: **Настройки** → **Подключения** → **USB** → **Передача файлов** + +#### Шаг 2: Включение USB модема + +**На Android телефоне:** + +1. Откройте **Настройки** +2. Перейдите в **Сеть и интернет** → **Режим модема и точка доступа** + - Или: **Настройки** → **Режим модема** (зависит от версии Android) +3. Включите **USB модем** (переключатель) +4. Телефон покажет уведомление "USB модем активен" + +**Альтернативный путь:** +- Откройте **Настройки** +- Поиск: "USB модем" или "USB tethering" +- Включите переключатель + +#### Шаг 3: Настройка на компьютере + +**macOS:** +- Соединение определится автоматически +- Проверка: **System Settings** → **Network** → должно появиться новое соединение (например, "iPhone USB" или "Android USB") + +**Windows:** +- Windows автоматически установит драйверы (может потребоваться интернет) +- Если драйверы не установились: + 1. Скачайте **USB драйверы для Android** с сайта производителя + 2. Или установите **Universal ADB Driver** + 3. Или используйте **Google USB Driver** из Android SDK + +**Linux:** +- Обычно работает из коробки +- Если не работает: `sudo apt install usb-modeswitch` + +#### Шаг 4: Проверка подключения + +**macOS:** +```bash +# Проверить активное соединение +networksetup -listallnetworkservices | grep -i usb + +# Проверить IP адрес +ifconfig | grep -A 5 "en.*:" | grep "inet " + +# Или проще: +ifconfig | grep "inet " | grep -v 127.0.0.1 +``` + +**Windows:** +```cmd +ipconfig +# Найдите адаптер с именем типа "Ethernet adapter Local Area Connection" или "USB Ethernet" +``` + +**Linux:** +```bash +ip addr show +# Или +ifconfig +``` + +#### Шаг 5: Включение VPN на телефоне + +**ВАЖНО:** Включите VPN **ДО** активации USB модема! + +1. Откройте приложение **WireGuard** на телефоне +2. Подключитесь к VPN (туннель должен быть активен) +3. Проверьте статус: должен быть "Подключено" +4. **Только после этого** включите USB модем + +#### Шаг 6: Проверка работы VPN + +На подключенном компьютере: + +```bash +# Проверка IP адреса (должен быть IP VPN сервера) +curl https://api.ipify.org +# Должен показать: 83.136.235.230 + +# Проверка DNS утечек +curl https://dnsleaktest.com/ +``` + +--- + +## 🔧 Решение проблем с USB Tethering + +### Проблема: Компьютер не видит USB модем + +**Решения:** +1. Попробуйте другой USB порт +2. Попробуйте другой USB кабель +3. На Android: **Настройки** → **Для разработчиков** → включите **Отладка по USB** +4. Перезагрузите телефон и компьютер + +### Проблема: Низкая скорость через USB + +**Решения:** +1. Используйте USB 3.0 порт и кабель (синий разъем) +2. Проверьте, что кабель поддерживает передачу данных +3. Отключите другие USB устройства +4. Проверьте настройки энергосбережения USB портов + +### Проблема: VPN не работает через USB модем + +**Решения:** +1. Убедитесь, что VPN включен **ДО** активации USB модема +2. Перезапустите VPN на телефоне +3. Проверьте настройки VPN: **AllowedIPs = 0.0.0.0/0** (весь трафик) +4. Перезагрузите телефон + +--- + +## 📊 Сравнение методов подключения + +| Метод | Скорость | Стабильность | Заметность | Энергопотребление | +|-------|----------|-------------|------------|-------------------| +| **Wi-Fi Hotspot** | Средняя | Средняя | ⚠️ Высокая | Высокое | +| **USB Tethering** | ✅ Высокая | ✅ Высокая | ✅ Низкая | Низкое | +| **Bluetooth** | Низкая | Средняя | ✅ Низкая | Среднее | + +--- + +## ⚡ Оптимизация скорости + +### 1. Используйте USB 3.0 +- USB 3.0 кабель (обычно синий разъем) +- USB 3.0 порт на компьютере +- Скорость до 5 Гбит/с + +### 2. Выберите ближайший VPN сервер +- Меньше задержка = выше скорость +- Российский сервер (83.136.235.230) для России + +### 3. Используйте WireGuard +- Быстрее OpenVPN +- Меньше overhead + +### 4. Закройте ненужные приложения на телефоне +- Освободите ресурсы процессора +- Закройте фоновые приложения + +--- + +## 🎯 Рекомендуемая настройка + +**Для максимальной скорости и невидимости:** + +1. ✅ **USB Tethering** (вместо Wi-Fi) +2. ✅ **VPN на телефоне** (WireGuard) +3. ✅ **USB 3.0 кабель** +4. ✅ **VPN включен ДО активации модема** + +**Порядок действий:** +``` +1. Подключите телефон к компьютеру через USB +2. Включите VPN на телефоне (WireGuard) +3. Включите USB модем на телефоне +4. Проверьте IP на компьютере (должен быть IP VPN) +``` + +--- + +## 📝 Примечания + +- USB Tethering работает только когда телефон подключен к компьютеру +- Для мобильности используйте Wi-Fi Hotspot, но с VPN +- Некоторые операторы могут ограничивать скорость независимо от метода подключения +- VPN добавляет небольшую задержку, но скрывает факт использования хотспота diff --git a/docs/hotspot/scripts/README.md b/docs/hotspot/scripts/README.md new file mode 100644 index 0000000..2d0212b --- /dev/null +++ b/docs/hotspot/scripts/README.md @@ -0,0 +1,163 @@ +# Гайд по скриптам hotspot + +Скрипты для настройки и использования хотспота с VPN на Mac: установка WireGuard, TTL, запуск и остановка VPN. + +**Контекст:** [GUARANTEED_TETHERING_HIDE.md](../GUARANTEED_TETHERING_HIDE.md) — полная схема скрытия tethering (VPN на Mac, не на телефоне; TTL=65; USB модем). + +--- + +## Обзор скриптов + +| Скрипт | Назначение | Когда запускать | +|--------|------------|-----------------| +| `setup-wireguard-mac.sh` | Первичная установка WireGuard и конфига | Один раз при настройке | +| `set-ttl-macos.sh` | Установка TTL=65 (скрытие tethering) | Один раз, при необходимости — после перезагрузки | +| `vpn-up.sh` | Запуск WireGuard VPN | Каждый раз при использовании USB/хотспота | +| `vpn-down.sh` | Остановка WireGuard VPN | По окончании работы через хотспот | + +--- + +## 1. setup-wireguard-mac.sh + +**Назначение:** Установка WireGuard на macOS и разовая настройка (конфиг в `/etc/wireguard/wg0.conf`, первый запуск VPN). + +**Запуск:** +```bash +cd /Users/eternal/code/local_machine +./docs/hotspot/scripts/setup-wireguard-mac.sh +``` + +**Что делает:** +1. Проверяет наличие `wg-quick`; при отсутствии ставит `wireguard-tools` через Homebrew. +2. Создаёт `/etc/wireguard` (права `700`). +3. Копирует `docs/hotspot/wg-ru.conf` в `/etc/wireguard/wg0.conf` (права `600`). +4. Запускает `wg-quick up wg0`. +5. Проверяет внешний IP (ожидается `83.136.235.230`). + +**Требования:** +- Файл конфигурации: `docs/hotspot/wg-ru.conf` (относительно корня репозитория). +- Запуск из корня репо или с путём, где доступен `docs/hotspot/wg-ru.conf`. +- `sudo` для установки в `/etc/wireguard` и для `wg-quick up`. + +**После установки:** VPN уже поднят; для следующих сессий используйте `vpn-up.sh` / `vpn-down.sh`. + +--- + +## 2. set-ttl-macos.sh + +**Назначение:** Установка TTL=65 на Mac, чтобы после прохождения через телефон (TTL-1) оператор видел TTL=64 и не определял tethering. + +**Запуск:** +```bash +./docs/hotspot/scripts/set-ttl-macos.sh +``` + +**Что делает:** +1. Показывает текущий TTL. +2. Выполняет `sudo sysctl -w net.inet.ip.ttl=65`. +3. Проверяет, что TTL стал 65. +4. Добавляет `net.inet.ip.ttl=65` в `/etc/sysctl.conf`, если ещё нет (сохранится после перезагрузки). + +**Требования:** `sudo`. + +**Когда запускать:** Один раз после установки ОС/нового Mac; при необходимости — после каждой перезагрузки, если значение не подхватывается из `sysctl.conf`. + +**Проверка:** +```bash +sysctl net.inet.ip.ttl +# net.inet.ip.ttl: 65 +``` + +--- + +## 3. vpn-up.sh + +**Назначение:** Быстрый запуск WireGuard VPN на Mac при использовании интернета через USB модем/хотспот. + +**Запуск:** +```bash +./docs/hotspot/scripts/vpn-up.sh +``` + +**Что делает:** +1. Выполняет `sudo wg-quick up wg0`. +2. Ждёт 2 секунды. +3. Проверяет внешний IP через `api.ipify.org` (ожидается `83.136.235.230`). +4. Выводит `sudo wg show`. + +**Требования:** +- WireGuard уже настроен (`setup-wireguard-mac.sh` выполнен хотя бы раз). +- Конфиг: `/etc/wireguard/wg0.conf`. +- `sudo`. + +**Порядок при использовании хотспота:** сначала TTL=65 (если ещё не стоит), на телефоне включить USB модем **без VPN**, затем на Mac запустить этот скрипт. + +--- + +## 4. vpn-down.sh + +**Назначение:** Остановка WireGuard VPN на Mac. + +**Запуск:** +```bash +./docs/hotspot/scripts/vpn-down.sh +``` + +**Что делает:** Выполняет `sudo wg-quick down wg0`. + +**Требования:** `sudo`. + +--- + +## Типичный сценарий + +### Первая настройка (один раз) + +```bash +cd /Users/eternal/code/local_machine + +# 1. Установить WireGuard и конфиг, поднять VPN +./docs/hotspot/scripts/setup-wireguard-mac.sh + +# 2. Установить TTL=65 +./docs/hotspot/scripts/set-ttl-macos.sh +``` + +### Каждое использование хотспота + +1. На телефоне: **не** включать VPN, включить **USB модем** (или Wi‑Fi точку доступа). +2. На Mac: + ```bash + ./docs/hotspot/scripts/vpn-up.sh + ``` +3. Проверка: + ```bash + curl https://api.ipify.org + # 83.136.235.230 + ``` +4. По окончании: + ```bash + ./docs/hotspot/scripts/vpn-down.sh + ``` + +--- + +## Права на выполнение + +Если скрипты не запускаются: + +```bash +chmod +x docs/hotspot/scripts/setup-wireguard-mac.sh +chmod +x docs/hotspot/scripts/set-ttl-macos.sh +chmod +x docs/hotspot/scripts/vpn-up.sh +chmod +x docs/hotspot/scripts/vpn-down.sh +``` + +--- + +## Связанные документы + +- [GUARANTEED_TETHERING_HIDE.md](../GUARANTEED_TETHERING_HIDE.md) — полная схема: TTL, VPN на Mac, USB модем, порядок действий, решение проблем. +- [QUICK_FIX_VPN_ROUTING.md](../QUICK_FIX_VPN_ROUTING.md) — быстрый фикс: VPN на Mac вместо телефона. +- [ANDROID_VPN_TETHERING_ROUTING.md](../ANDROID_VPN_TETHERING_ROUTING.md) — почему tethering не идёт через VPN на Android. +- [SPEED_LIMITATIONS_AND_USB_TETHERING.md](../SPEED_LIMITATIONS_AND_USB_TETHERING.md) — ограничения скорости и настройка USB tethering. diff --git a/docs/hotspot/scripts/set-ttl-macos.sh b/docs/hotspot/scripts/set-ttl-macos.sh new file mode 100755 index 0000000..7b6b834 --- /dev/null +++ b/docs/hotspot/scripts/set-ttl-macos.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Скрипт для установки TTL = 65 на macOS +# Это критически важно для скрытия tethering от оператора! + +echo "=== Установка TTL = 65 для скрытия tethering ===" +echo "" + +# Проверка текущего TTL +CURRENT_TTL=$(sysctl -n net.inet.ip.ttl 2>/dev/null || echo "unknown") +echo "Текущий TTL: $CURRENT_TTL" + +# Установка TTL = 65 +echo "" +echo "Установка TTL = 65..." +sudo sysctl -w net.inet.ip.ttl=65 + +# Проверка +NEW_TTL=$(sysctl -n net.inet.ip.ttl) +if [ "$NEW_TTL" = "65" ]; then + echo "✅ TTL успешно установлен: $NEW_TTL" +else + echo "❌ Ошибка: TTL = $NEW_TTL (ожидалось 65)" + exit 1 +fi + +# Добавление в автозагрузку +echo "" +echo "Добавление в автозагрузку..." +if ! grep -q "net.inet.ip.ttl=65" /etc/sysctl.conf 2>/dev/null; then + echo "net.inet.ip.ttl=65" | sudo tee -a /etc/sysctl.conf > /dev/null + echo "✅ TTL добавлен в /etc/sysctl.conf (будет применяться после перезагрузки)" +else + echo "ℹ️ TTL уже добавлен в /etc/sysctl.conf" +fi + +echo "" +echo "=== Проверка ===" +echo "Текущий TTL: $(sysctl -n net.inet.ip.ttl)" +echo "" +echo "✅ Готово! Теперь оператор не сможет определить tethering по TTL." +echo "" +echo "Следующие шаги:" +echo "1. Включите VPN на телефоне (WireGuard)" +echo "2. Подключите телефон к компьютеру через USB" +echo "3. Включите USB модем на телефоне" +echo "4. Проверьте IP: curl https://api.ipify.org" diff --git a/docs/hotspot/scripts/setup-wireguard-mac.sh b/docs/hotspot/scripts/setup-wireguard-mac.sh new file mode 100755 index 0000000..8c60b9a --- /dev/null +++ b/docs/hotspot/scripts/setup-wireguard-mac.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Скрипт для установки и настройки WireGuard на macOS +# Используется для маршрутизации tethering трафика через VPN + +set -e + +echo "=== Установка WireGuard на macOS ===" +echo "" + +# Проверка установки +if ! command -v wg-quick &> /dev/null; then + echo "1. Установка WireGuard..." + brew install wireguard-tools +else + echo "✅ WireGuard уже установлен" +fi + +# Создание директории для конфигураций +echo "" +echo "2. Создание директории для конфигураций..." +sudo mkdir -p /etc/wireguard +sudo chmod 700 /etc/wireguard + +# Копирование конфигурации +echo "" +echo "3. Копирование конфигурации..." +CONFIG_FILE="docs/hotspot/wg-ru.conf" +if [ -f "$CONFIG_FILE" ]; then + sudo cp "$CONFIG_FILE" /etc/wireguard/wg0.conf + sudo chmod 600 /etc/wireguard/wg0.conf + echo "✅ Конфигурация скопирована: /etc/wireguard/wg0.conf" +else + echo "❌ Файл конфигурации не найден: $CONFIG_FILE" + exit 1 +fi + +# Запуск VPN +echo "" +echo "4. Запуск WireGuard VPN..." +sudo wg-quick up wg0 + +# Проверка +echo "" +echo "5. Проверка подключения..." +sleep 2 + +VPN_IP=$(curl -s --max-time 5 https://api.ipify.org) +if [ "$VPN_IP" = "83.136.235.230" ]; then + echo "✅ VPN работает! IP: $VPN_IP" +else + echo "⚠️ IP: $VPN_IP (ожидалось: 83.136.235.230)" + echo "Проверьте подключение к серверу" +fi + +echo "" +echo "=== Готово! ===" +echo "" +echo "Управление VPN:" +echo " Запуск: sudo wg-quick up wg0" +echo " Остановка: sudo wg-quick down wg0" +echo " Статус: sudo wg show" +echo "" +echo "Проверка IP:" +echo " curl https://api.ipify.org" diff --git a/docs/hotspot/scripts/vpn-down.sh b/docs/hotspot/scripts/vpn-down.sh new file mode 100755 index 0000000..654039c --- /dev/null +++ b/docs/hotspot/scripts/vpn-down.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Остановка WireGuard VPN + +echo "🛑 Остановка WireGuard VPN..." +sudo wg-quick down wg0 +echo "✅ VPN остановлен" diff --git a/docs/hotspot/scripts/vpn-up.sh b/docs/hotspot/scripts/vpn-up.sh new file mode 100755 index 0000000..c056be1 --- /dev/null +++ b/docs/hotspot/scripts/vpn-up.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Быстрый запуск WireGuard VPN на Mac для tethering + +set -e + +echo "🚀 Запуск WireGuard VPN..." +sudo wg-quick up wg0 + +sleep 2 + +echo "" +echo "✅ VPN запущен!" +echo "" +echo "Проверка IP:" +IP=$(curl -s --max-time 5 https://api.ipify.org) +echo "IP: $IP" + +if [ "$IP" = "83.136.235.230" ]; then + echo "✅ VPN работает! IP корректный" +else + echo "⚠️ IP не соответствует VPN серверу" +fi + +echo "" +echo "Статус VPN:" +sudo wg show diff --git a/docs/launch/ALLOWED.md b/docs/launch/ALLOWED.md new file mode 100644 index 0000000..f4f3b84 --- /dev/null +++ b/docs/launch/ALLOWED.md @@ -0,0 +1,48 @@ +# Допустимые объекты автозапуска (Launch Agents/Daemons) + +Список того, что **допустимо** оставлять в автозапуске. Всё, чего нет в этом списке, при необходимости можно отключить. + +--- + +## Пользовательские LaunchAgents (`~/Library/LaunchAgents`) + +| ID | Назначение | +|----|------------| +| `com.google.GoogleUpdater.wake` | Обновления Google (Chrome и др.) | +| `com.google.keystone.agent` | Служба обновлений Google | +| `com.google.keystone.xpcservice` | Служба обновлений Google (XPC) | +| `com.infoprotector.NetCacheCleaner` | Очистка кэша (NetCacheCleaner) | +| `com.qiuyuzhou.shadowsocksX-NG.local` | ShadowsocksX-NG (прокси) | +| `com.shadowsocks.local` | Shadowsocks | +| `homebrew.mxcl.syncthing` | Syncthing (синхронизация файлов) | +| `yanue.v2rayu.v2ray-core` | V2RayU (прокси) | + +--- + +## Системные LaunchAgents (`/Library/LaunchAgents`) + +| ID | Назначение | +|----|------------| +| `at.obdev.littlesnitch.agent` | Little Snitch (сетевой файрвол) | +| `com.google.keystone.agent` | Обновления Google | +| `com.google.keystone.xpcservice` | Обновления Google (XPC) | +| `com.malwarebytes.mbam.frontend.agent` | Malwarebytes | + +--- + +## Системные LaunchDaemons (`/Library/LaunchDaemons`) + +| ID | Назначение | +|----|------------| +| `at.obdev.littlesnitch.daemon` | Little Snitch (демон) | +| `com.google.GoogleUpdater.wake.system` | Обновления Google (системный) | +| `com.google.keystone.daemon` | Обновления Google (демон) | +| `com.malwarebytes.mbam.rtprotection.daemon` | Malwarebytes (защита в реальном времени) | +| `com.malwarebytes.mbam.settings.daemon` | Malwarebytes (настройки) | +| `com.metacubex.ClashX.ProxyConfigHelper` | ClashX (прокси) | +| `com.objective-see.blockblock` | BlockBlock (мониторинг автозапуска) | +| `com.wireguard.wg-ru` | WireGuard (VPN) | + +--- + +Список **запрещённых** (отключённых) пунктов — см. [DISALLOWED.md](./DISALLOWED.md). diff --git a/docs/launch/DISALLOWED.md b/docs/launch/DISALLOWED.md new file mode 100644 index 0000000..0542ee9 --- /dev/null +++ b/docs/launch/DISALLOWED.md @@ -0,0 +1,65 @@ +# Запрещённые объекты автозапуска (Launch Agents/Daemons) + +Список того, что **не должно** запускаться при старте. Эти пункты отключены (plist переименованы в `.disabled`). При появлении снова — отключать. + +--- + +## Объекты входа (Login Items) — отключить + +| Приложение | Действие | +|------------|----------| +| **Notion** | Запустить скрипт ниже или: Системные настройки → Основные → Объекты входа → убрать Notion | +| **MEGA (MEGAsync)** | То же: скрипт или Объекты входа → убрать MEGA | + +**Скрипт (запускать в Terminal.app, не в Cursor):** +```bash +/Users/eternal/code/local_machine/docs/launch/disable_login_items_notion_mega.sh +``` +При первом запуске может понадобиться: Системные настройки → Конфиденциальность и безопасность → Доступ к управлению компьютером — включить для **Terminal**. + +MEGA также отключён как LaunchAgent (`mega.mac.megaupdater.plist.disabled`). Если снова автозапускается — проверить Объекты входа. + +--- + +## Пользовательские LaunchAgents (`~/Library/LaunchAgents`) + +| ID | Назначение | +|----|------------| +| `homebrew.mxcl.postgresql@15` | PostgreSQL 15 — запускать вручную при необходимости | +| `homebrew.mxcl.redis` | Redis — запускать вручную при необходимости | +| `mega.mac.megaupdater` | MEGA (обновления) | +| `org.freedownloadmanager.fdm6` | Free Download Manager | +| `org.virtualbox.vboxwebsrv` | VirtualBox Web Service | + +--- + +## Системные LaunchAgents (`/Library/LaunchAgents`) + +| ID | Назначение | +|----|------------| +| `com.philandro.anydesk.Frontend` | AnyDesk (удалённый доступ) | +| `us.zoom.updater` | Zoom (проверка обновлений) | +| `us.zoom.updater.login.check` | Zoom (проверка при входе) | + +--- + +## Системные LaunchDaemons (`/Library/LaunchDaemons`) + +| ID | Назначение | +|----|------------| +| `jp.co.canon.MasterInstaller` | Canon (драйверы/утилиты) | +| `us.zoom.ZoomDaemon` | Zoom (демон) | + +--- + +## Как отключить, если снова появятся + +- **Объекты входа (Notion, MEGA и др.):** + **Системные настройки → Основные → Объекты входа** — удалить приложение из списка или выключить переключатель. + +- **Пользовательские LaunchAgents:** + `launchctl unload ~/Library/LaunchAgents/<ID>.plist` + затем переименовать plist в `<ID>.plist.disabled`. + +- **Системные:** + запустить `./docs/launch/disable_system_launch_items.sh` с правами root (`sudo`). diff --git a/docs/launch/disable_login_items_notion_mega.sh b/docs/launch/disable_login_items_notion_mega.sh new file mode 100755 index 0000000..51e4afb --- /dev/null +++ b/docs/launch/disable_login_items_notion_mega.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Удаляет Notion и MEGA (MEGAsync) из «Объекты входа». +# Запустить в Terminal.app (не в Cursor): ./disable_login_items_notion_mega.sh +# При первом запуске: Системные настройки → Конфиденциальность и безопасность → Доступ к управлению компьютером — включить для Terminal. + +osascript << 'APPLESCRIPT' +tell application "System Events" + set loginItems to get the name of every login item + set toRemove to {"Notion", "MEGAsync", "MEGA"} + repeat with appName in toRemove + if loginItems contains appName then + delete login item appName + log "Removed from Login Items: " & appName + end if + end repeat +end tell +APPLESCRIPT +echo "Done. Notion and MEGA removed from Login Items (if they were there)." diff --git a/docs/launch/disable_system_launch_items.sh b/docs/launch/disable_system_launch_items.sh new file mode 100755 index 0000000..0e11b48 --- /dev/null +++ b/docs/launch/disable_system_launch_items.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Отключает системные LaunchAgents/LaunchDaemons (требуется sudo). +# Запуск: sudo ./disable_system_launch_items.sh + +set -e + +LA="/Library/LaunchAgents" +LD="/Library/LaunchDaemons" + +unload_and_rename() { + local path="$1" + if [[ -f "$path" ]]; then + launchctl unload "$path" 2>/dev/null || true + mv "$path" "${path}.disabled" + echo "Disabled: $path" + fi +} + +unload_and_rename "$LA/com.philandro.anydesk.Frontend.plist" +unload_and_rename "$LA/us.zoom.updater.plist" +unload_and_rename "$LA/us.zoom.updater.login.check.plist" +unload_and_rename "$LD/us.zoom.ZoomDaemon.plist" +unload_and_rename "$LD/jp.co.canon.MasterInstaller.plist" + +echo "Done." diff --git a/docs/printer/HP_LASERJET_M402DN_README.md b/docs/printer/HP_LASERJET_M402DN_README.md new file mode 100644 index 0000000..2e15a5f --- /dev/null +++ b/docs/printer/HP_LASERJET_M402DN_README.md @@ -0,0 +1,934 @@ + # HP Принтер - Сброс подвисших задач + +## 🚀 БЫСТРЫЙ СТАРТ + +### Сброс задач одной командой + +```bash +clear-hp +``` + +**Готово!** Все подвисшие задачи HP принтеров будут сброшены. + +--- + +## 📋 ЧТО ДЕЛАЕТ СКРИПТ + +Скрипт автоматически: +1. 🔍 Находит все HP принтеры в системе +2. 📋 Проверяет задачи в очереди печати +3. 🗑️ Отменяет все подвисшие задачи +4. 🔄 Сбрасывает состояние принтера +5. ✅ Включает принтер и делает его готовым к работе + +--- + +## 🖨️ ТЕКУЩАЯ КОНФИГУРАЦИЯ + +**Найденные HP принтеры:** +- `HP_LaserJet_M402dn_2` - LaserJet Pro M402dn + +**Статус:** ✅ Готов к работе + +**Примечание:** Имя принтера в системе может отличаться (например, `HP_LaserJet_M402dn_2` вместо `HP_LaserJet_M402dn`). Проверьте актуальное имя командой `lpstat -p | grep -i hp`. + +**Характеристики:** +- **Тип:** Монохромный лазерный принтер +- **Цветная печать:** ❌ **НЕ поддерживается** (только черно-белая) +- **Максимальное разрешение:** 1200 x 1200 dpi +- **Режим печати:** Gray (монохромный) + +--- + +## 📖 СПОСОБЫ ИСПОЛЬЗОВАНИЯ + +### 1. Через алиас (рекомендуется) + +```bash +clear-hp +``` + +**Преимущества:** +- ✅ Короткая команда +- ✅ Работает из любой директории +- ✅ Автоматически доступен во всех новых терминалах + +### 2. Прямой вызов скрипта + +```bash +/Users/eternal/code/local_machine/docs/printer/clear-hp-jobs.sh +``` + +Или из директории проекта: +```bash +./docs/printer/clear-hp-jobs.sh +``` + +### 3. Из директории printer + +```bash +cd docs/printer +./clear-hp-jobs.sh +``` + +--- + +## 🔧 УСТАНОВКА АЛИАСОВ + +Алиасы уже установлены в `~/.zshrc`. Если нужно установить вручную: + +### Алиас для сброса задач +```bash +echo "" >> ~/.zshrc +echo "# Алиас для сброса подвисших задач HP принтера" >> ~/.zshrc +echo "alias clear-hp='/Users/eternal/code/local_machine/docs/printer/clear-hp-jobs.sh'" >> ~/.zshrc +source ~/.zshrc +``` + +### Алиас для проверки тонера +```bash +echo "" >> ~/.zshrc +echo "# Алиас для проверки уровня тонера HP принтера" >> ~/.zshrc +echo "alias check-hp-toner='/Users/eternal/code/local_machine/docs/printer/check-hp-toner.sh'" >> ~/.zshrc +source ~/.zshrc +``` + +### Алиас для настройки лотка +```bash +echo "" >> ~/.zshrc +echo "# Алиас для настройки лотка HP принтера" >> ~/.zshrc +echo "alias set-hp-tray='/Users/eternal/code/local_machine/docs/printer/set-hp-tray.sh'" >> ~/.zshrc +source ~/.zshrc +``` + +### Алиас для настройки двусторонней печати +```bash +echo "" >> ~/.zshrc +echo "# Алиас для настройки двусторонней печати HP принтера" >> ~/.zshrc +echo "alias set-hp-duplex='/Users/eternal/code/local_machine/docs/printer/set-hp-duplex.sh'" >> ~/.zshrc +source ~/.zshrc +``` + +**Доступные алиасы:** +- `clear-hp` - сброс подвисших задач +- `check-hp-toner` - проверка уровня тонера и информации о принтере +- `set-hp-tray` - настройка лотка по умолчанию (использование: `set-hp-tray tray1` или `set-hp-tray tray2`) +- `set-hp-duplex` - настройка двусторонней печати (использование: `set-hp-duplex on`, `set-hp-duplex off`, `set-hp-duplex long`, `set-hp-duplex short`) + +--- + +## ⚠️ КОГДА ИСПОЛЬЗОВАТЬ + +Используйте скрипт, когда: + +- ❌ Задачи печати зависли в очереди +- ❌ Принтер показывает "processing" или "held" статус +- ❌ Задания не печатаются и не удаляются +- ❌ Принтер показывает "disabled" статус +- ❌ Нужно быстро очистить очередь печати + +--- + +## 🔴 РЕШЕНИЕ ПРОБЛЕМ + +### Проблема: "HP принтеры не найдены" + +**Решение:** +1. Проверьте, что принтер подключен: + ```bash + lpstat -p + ``` + +2. Если принтер есть, но не HP: + - Скрипт ищет только принтеры с "hp" в названии + - Используйте прямую команду для конкретного принтера: + ```bash + cancel -a ИМЯ_ПРИНТЕРА + cupsenable ИМЯ_ПРИНТЕРА + cupsaccept ИМЯ_ПРИНТЕРА + ``` + +### Проблема: Алиас не работает + +**Решение:** +1. Перезагрузите конфигурацию: + ```bash + source ~/.zshrc + ``` + +2. Проверьте, что алиас существует: + ```bash + alias | grep clear-hp + ``` + +3. Если алиаса нет, установите его (см. раздел "Установка алиаса") + +### Проблема: "The printer is offline" / "Принтер показывает offline" + +**Симптомы:** +- `lpstat -p HP_LaserJet_M402dn -l` показывает: "The printer is offline" +- Задания отправляются, но остаются в очереди +- CUPS не может связаться с USB устройством +- Принтер периодически показывает статус "offline" + +**Причина:** +CUPS не может физически связаться с USB устройством принтера. Это может происходить из-за: +1. Режима энергосбережения принтера (принтер "засыпает") +2. Проблемы с USB кабелем или портом +3. Принтер не отвечает на запросы CUPS +4. Проблема с драйвером или USB подключением + +**РЕШЕНИЕ (выполните в точном порядке):** + +1. Отмените все задания: + ```bash + cancel -a HP_LaserJet_M402dn + ``` + +2. **Выключите принтер** (кнопка питания) + +3. **Отключите USB кабель** от Mac + +4. **Подождите 30 секунд** + +5. **Подключите USB кабель** обратно + +6. **Включите принтер** + +7. **Подождите 1 минуту** (пока принтер загрузится) + +8. Включите принтер в системе: + ```bash + cupsenable HP_LaserJet_M402dn + cupsaccept HP_LaserJet_M402dn + ``` + +9. Проверьте статус: + ```bash + lpstat -p HP_LaserJet_M402dn -l + ``` + +**Если все еще offline:** + +1. **Попробуйте другой USB кабель** +2. **Попробуйте другой USB порт** на Mac +3. **Перезагрузите Mac** и повторите шаги +4. **Проверьте принтер:** + - Нет ли ошибок на дисплее? + - Работает ли принтер вообще? + - Попробуйте сбросить принтер (меню принтера) + +**ВАЖНО:** Проблема offline часто требует **ФИЗИЧЕСКОГО** переподключения USB кабеля. Программные решения могут не помочь. + +**Диагностика:** +```bash +# Проверить USB подключение +system_profiler SPUSBDataType | grep -A 10 "HP LaserJet M402dn" + +# Проверить статус в CUPS +lpstat -p HP_LaserJet_M402dn -l | grep -i "offline" + +# Если НЕТ строки "offline" - проблема решена! +``` + +### Проблема: Принтер все еще не печатает + +**Решение:** +1. Проверьте физическое состояние: + - ✅ Принтер включен + - ✅ Есть бумага + - ✅ Есть тонер/чернила + - ✅ USB кабель подключен + - ✅ Нет ошибок на дисплее принтера + +2. Перезагрузите принтер (выключить/включить) + +3. Проверьте статус: + ```bash + lpstat -p HP_LaserJet_M402dn -l + ``` + +4. Если принтер показывает "offline" - см. раздел выше "Проблема: The printer is offline" + +### Проблема: "Used or counterfeit cartridge" / "A used supply has been installed" + +**Что это значит:** +- ⚠️ Принтер определил, что установлен **использованный**, **перезаправленный** или **контрафактный** картридж +- Это может быть перезаправленный картридж, совместимый (неоригинальный) картридж, или картридж, который был установлен в другом принтере + +**Причины:** +1. Перезаправленный картридж (неоригинальная заправка) +2. Совместимый картридж (не HP) +3. Контрафактный картридж (подделка под HP) +4. Картридж был установлен в другом принтере ранее +5. Поврежденный чип картриджа + +--- + +## 📊 ОБЪЕКТИВНАЯ ОЦЕНКА ПРОБЛЕМЫ + +### 🔴 Насколько это серьезно? + +**Уровень серьезности: СРЕДНИЙ-НИЗКИЙ для HP LaserJet M402dn** + +#### ✅ Почему не критично: + +1. **Модель старая (2013-2014):** + - HP LaserJet M402dn не имеет агрессивной защиты от неоригинальных картриджей + - Прошивки редко блокируют картриджи (в отличие от новых моделей 2018+) + - Принтер обычно продолжает печать, просто показывает предупреждение + +2. **Физические повреждения маловероятны:** + - Лазерные принтеры более устойчивы к некачественным картриджам, чем струйные + - Основной риск - качество печати, а не поломка механизма + - Принтер не "сломается" от неоригинального картриджа (если только картридж не физически поврежден) + +3. **Функциональность сохраняется:** + - Печать работает (с предупреждением) + - Все основные функции доступны + - Единственное ограничение - неточный уровень тонера + +#### ⚠️ Реальные риски: + +1. **Качество печати:** + - ~30-50% пользователей отмечают ухудшение качества + - Возможны: бледная печать, разводы, неравномерное распределение тонера + - Для офисных документов обычно приемлемо, для важных документов - нежелательно + +2. **Гарантия:** + - Гарантия НЕ аннулируется автоматически + - ⚠️ Если поломка связана с картриджем - ремонт за ваш счет + - HP может отказать в бесплатном ремонте, если докажет связь + +3. **Постоянные предупреждения:** + - Сообщение появляется при каждом включении/печати + - Нужно нажимать "OK" каждый раз + - Раздражает, но не критично + +--- + +## 🎯 ШАНСЫ РЕШЕНИЯ ПРОБЛЕМЫ ЗАМЕНОЙ КАРТРИДЖА + +### ✅ Вероятность решения: **85-95%** + +**Высокая вероятность успеха, если:** + +1. **Заменить на оригинальный новый картридж HP:** + - ✅ **95% вероятность** - проблема исчезнет полностью + - ✅ Предупреждение больше не появится + - ✅ Точный уровень тонера + - ✅ Оптимальное качество печати + +2. **Заменить на качественный совместимый картридж:** + - ✅ **70-85% вероятность** - предупреждение может исчезнуть + - ⚠️ Зависит от качества чипа картриджа + - ⚠️ Некоторые совместимые картриджи все равно показывают предупреждение + - ✅ Печать обычно работает нормально + +3. **Если проблема в чипе картриджа:** + - ✅ **90% вероятность** - замена картриджа решит проблему + - Чип картриджа может быть поврежден или изношен + +### ❌ Когда замена НЕ поможет (5-15% случаев): + +1. **Проблема в принтере, а не в картридже:** + - Поврежден считыватель чипа в принтере + - Проблема с прошивкой принтера + - **Решение:** Сервисный центр HP + +2. **Очень старый/изношенный принтер:** + - Механические проблемы с установкой картриджа + - Износ контактов + - **Решение:** Проверка в сервисе + +3. **Неправильная установка картриджа:** + - Картридж установлен неправильно + - Защитная лента не снята + - **Решение:** Переустановить картридж правильно + +--- + +## 💡 РЕКОМЕНДАЦИИ ПО РЕШЕНИЮ + +### Вариант 1: Замена на оригинальный картридж HP (РЕКОМЕНДУЕТСЯ) + +**Шанс решения: 95%** + +**Плюсы:** +- ✅ Гарантированно решит проблему +- ✅ Лучшее качество печати +- ✅ Точный уровень тонера +- ✅ Нет предупреждений +- ✅ Сохранение гарантии + +**Минусы:** +- ❌ Высокая стоимость (в 2-3 раза дороже совместимых) +- ❌ Для HP LaserJet M402dn: ~$60-80 за картридж + +**Когда использовать:** +- Для важных документов +- Если принтер на гарантии +- Если качество критично +- Если предупреждения раздражают + +### Вариант 2: Замена на качественный совместимый картридж + +**Шанс решения: 70-85%** + +**Плюсы:** +- ✅ Низкая стоимость (в 2-3 раза дешевле) +- ✅ Обычно работает нормально +- ✅ Может решить проблему + +**Минусы:** +- ⚠️ Предупреждение может остаться +- ⚠️ Качество может быть хуже +- ⚠️ Неточный уровень тонера + +**Когда использовать:** +- Для обычной офисной печати +- Если бюджет ограничен +- Если качество "приемлемо" достаточно + +**Рекомендации по выбору:** +- Избегайте самых дешевых картриджей (высокий риск проблем) +- Выбирайте проверенные бренды (например, LD Products, Remanufactured) +- Читайте отзывы перед покупкой + +### Вариант 3: Продолжить использование текущего картриджа + +**Шанс решения: 0% (проблема останется)** + +**Когда использовать:** +- Если качество печати устраивает +- Если предупреждения не мешают +- Если картридж еще полный и менять жалко + +**Что делать:** +- Нажимать "OK" при каждом предупреждении +- Следить за качеством печати +- Заменить при ухудшении качества или когда закончится тонер + +--- + +## 🔧 ПРАКТИЧЕСКИЕ ШАГИ + +### Шаг 1: Проверка текущего картриджа + +1. **Проверьте подлинность (если уверены, что оригинальный):** + - Сайт: https://www.hp.com/go/anticounterfeit + - Введите серийный номер картриджа + +2. **Проверьте качество печати:** + - Напечатайте тестовую страницу + - Оцените: четкость, равномерность, отсутствие разводов + +3. **Проверьте уровень тонера:** + - На дисплее принтера + - Или через страницу состояния расходных материалов + +### Шаг 2: Принятие решения + +**Если качество хорошее и предупреждения не мешают:** +- Можно продолжать использовать текущий картридж +- Заменить при ухудшении качества или когда закончится тонер + +**Если качество плохое или предупреждения раздражают:** +- Заменить на оригинальный HP (если бюджет позволяет) +- Или на качественный совместимый (если бюджет ограничен) + +### Шаг 3: Замена картриджа + +1. **Выключите принтер** +2. **Откройте переднюю крышку** +3. **Извлеките старый картридж** +4. **Снимите защитную ленту с нового картриджа** +5. **Установите новый картридж** +6. **Закройте крышку** +7. **Включите принтер** +8. **Проверьте, исчезло ли предупреждение** + +### Шаг 4: Если проблема осталась после замены + +1. **Проверьте правильность установки картриджа** +2. **Попробуйте другой картридж** (возможно, конкретный картридж несовместим) +3. **Обратитесь в сервисный центр HP** (возможна проблема с принтером) + +--- + +## 📈 ИТОГОВАЯ ОЦЕНКА + +### Насколько серьезно? +**СРЕДНИЙ-НИЗКИЙ уровень серьезности** для HP LaserJet M402dn +- Принтер продолжает работать +- Основной риск - качество печати, а не поломка +- Предупреждения раздражают, но не критичны + +### Шансы решения заменой картриджа? +**85-95% вероятность решения проблемы** + +- **Оригинальный HP картридж:** 95% вероятность +- **Качественный совместимый:** 70-85% вероятность +- **Проблема в принтере (не в картридже):** 5-15% случаев + +### Рекомендация: +1. **Если бюджет позволяет** → Заменить на оригинальный HP картридж (гарантированно решит) +2. **Если бюджет ограничен** → Попробовать качественный совместимый картридж (высокая вероятность решения) +3. **Если качество устраивает** → Можно продолжать использовать текущий картридж до его окончания + +--- + +## 🔋 ПРОВЕРКА УРОВНЯ ТОНЕРА + +### Быстрая проверка (через алиас) + +```bash +check-hp-toner +``` + +### Прямой вызов скрипта + +```bash +./docs/printer/check-hp-toner.sh +``` + +Или из директории printer: +```bash +cd docs/printer +./check-hp-toner.sh +``` + +**Что показывает скрипт:** +- 📊 Статус принтера +- 🎨 Режим печати (цветной/монохромный) +- 🔋 Способы проверки уровня тонера +- ℹ️ Информация о модели принтера + +### Способы проверки уровня тонера + +#### 1. Панель управления принтера (рекомендуется) + +1. Нажмите кнопку **"OK"** на принтере +2. Перейдите в меню **"Отчеты"** +3. Выберите **"Страница состояния расходных материалов"** +4. Принтер напечатает страницу с информацией об уровне тонера + +#### 2. Дисплей принтера + +- Проверьте дисплей принтера +- Уровень тонера отображается на экране в виде индикатора + +#### 3. Приложение HP Smart + +1. Установите приложение **HP Smart** (если еще не установлено) +2. Откройте приложение +3. Выберите ваш принтер +4. Просмотрите уровень тонера в разделе "Расходные материалы" + +**Примечание:** CUPS (система печати macOS) не предоставляет прямого программного доступа к уровню тонера, поэтому используйте физические методы проверки. + +--- + +## 🎨 ЦВЕТНАЯ ПЕЧАТЬ + +### ❌ Цветная печать НЕ поддерживается + +**HP LaserJet Pro M402dn** - это **монохромный** (черно-белый) лазерный принтер. + +**Характеристики:** +- ✅ Черно-белая печать +- ❌ Цветная печать не поддерживается +- ⚫ Режим печати: Gray (оттенки серого) + +**Проверка режима печати:** +```bash +lpoptions -p HP_LaserJet_M402dn_2 -l | grep ColorModel +``` + +Вывод покажет: `ColorModel/Color Mode: *Gray` + +--- + +## 📄 НАСТРОЙКА ЛОТКОВ ДЛЯ БУМАГИ И ДВУСТОРОННЕЙ ПЕЧАТИ + +### 🚀 БЫСТРОЕ РЕШЕНИЕ ДЛЯ LIBREOFFICE + +**Проблема:** LibreOffice не использует правильные настройки принтера (лоток, двусторонняя печать). + +**✅ РЕШЕНИЕ (самый надежный способ):** + +1. В LibreOffice: **File → Print** (или `Cmd+P`) +2. Найдите кнопку **"Options"** или **"More Settings"** +3. Включите **"Use system dialog"** или **"Show system print dialog"** +4. В системном диалоге macOS: + - **Paper Source:** выберите **"Lower"** или **"Tray 2"** + - **Layout → Two-Sided:** выберите **"Long-edge binding"** (для двусторонней печати) +5. Нажмите **"Print"** + +**Готово!** Теперь LibreOffice будет использовать правильные настройки принтера. + +--- + +### Проблема: LibreOffice не использует правильные настройки принтера + +**Симптомы:** +- ❌ LibreOffice печатает из Tray 1 вместо Tray 2 (даже если выбрано Tray 2) +- ❌ Двусторонняя печать не работает в LibreOffice (даже если выбрана в настройках) +- ✅ Другие приложения (TextEdit, Preview) печатают нормально +- ✅ Настройки принтера в CUPS установлены правильно + +**Причина:** +- LibreOffice может игнорировать настройки CUPS или неправильно передавать их принтеру +- Драйвер "Generic PostScript Printer" имеет ограниченную поддержку опций +- LibreOffice использует свой собственный механизм печати, который может не учитывать все настройки CUPS + +### 🔍 Проверка текущего лотка + +```bash +lpoptions -p HP_LaserJet_M402dn_2 -l | grep InputSlot +``` + +**Вывод:** +``` +InputSlot/Media Source: *Upper +``` + +Звездочка (`*`) означает текущее значение по умолчанию. + +### ✅ Решение 1: Использовать системный диалог печати macOS (РЕКОМЕНДУЕТСЯ) + +**Проблема:** LibreOffice может игнорировать настройки принтера из своего диалога. + +**Решение - использовать системный диалог печати:** + +1. В LibreOffice: **File → Print** (или `Cmd+P`) +2. В диалоге печати найдите кнопку **"Options"** или **"More Settings"** +3. Включите опцию **"Use system dialog"** или **"Show system print dialog"** +4. Откроется стандартный диалог печати macOS +5. В системном диалоге: + - Нажмите **"Show Details"** (если не видно всех опций) + - Выберите принтер **HP_LaserJet_M402dn_2** + - Нажмите **"Copies & Pages"** → выберите **"Layout"** или **"Paper Handling"** + - Найдите **"Paper Source"** или **"Input Slot"** → выберите **"Lower"** или **"Tray 2"** + - Для двусторонней печати: **"Layout"** → выберите **"Two-Sided"** → **"Long-edge binding"** или **"Short-edge binding"** +6. Нажмите **"Print"** + +**Преимущества:** +- ✅ Использует нативные настройки macOS +- ✅ Правильно передает все параметры принтеру +- ✅ Работает с любым драйвером + +### ✅ Решение 2: Настроить в LibreOffice напрямую + +**Если системный диалог не доступен:** + +1. Откройте **File → Print** (или `Cmd+P`) в LibreOffice +2. В диалоге печати нажмите **"Properties"** (Свойства принтера) +3. Найдите настройку **"Paper Source"** или **"Input Slot"** или **"Media Source"** +4. Выберите **"Lower"**, **"Tray 2"** или **"Tray2"** +5. Для двусторонней печати: найдите **"Duplex"** или **"Two-sided"** → выберите **"Long-edge"** или **"Short-edge"** +6. Нажмите **"OK"** +7. Вернитесь в диалог печати и нажмите **"Print"** + +**⚠️ Важно:** Если это не работает, используйте Решение 1 (системный диалог). + +**Примечание:** Это изменит настройку только для текущего документа. Для постоянного изменения нужно установить официальный драйвер HP (см. Решение 3). + +### ✅ Решение 3: Изменить настройки по умолчанию через командную строку + +**Установить Tray 2 (Lower) по умолчанию:** +```bash +lpadmin -p HP_LaserJet_M402dn_2 -o InputSlot=Lower +``` + +**Проверить изменение:** +```bash +lpoptions -p HP_LaserJet_M402dn_2 -l | grep InputSlot +``` + +**Ожидаемый вывод:** +``` +InputSlot/Media Source: Lower *Upper +``` + +**⚠️ Ограничение:** Если используется драйвер "Generic PostScript Printer", эта команда может не работать. В этом случае: +- Используйте Решение 1 (настройка в LibreOffice) +- Или установите официальный драйвер HP (см. Решение 3) + +**Альтернативные значения (если Lower не работает):** +- `Tray2` +- `LowerTray` +- `Tray2Manual` + +### ✅ Решение 4: Установить официальный драйвер HP + +Если Generic PostScript драйвер не поддерживает изменение лотков, установите официальный драйвер HP: + +1. Скачайте драйвер HP для LaserJet M402dn с официального сайта HP +2. Установите драйвер +3. Переустановите принтер с новым драйвером +4. После этого команда `lpadmin -p HP_LaserJet_M402dn_2 -o InputSlot=Lower` должна работать + +### ✅ Решение 5: Настройка через System Preferences (macOS) + +1. Откройте **System Preferences → Printers & Scanners** +2. Выберите принтер **HP_LaserJet_M402dn_2** +3. Нажмите **Options & Supplies** +4. Перейдите на вкладку **Driver** +5. Найдите настройку **"Default Paper Source"** или **"Input Slot"** +6. Выберите **"Lower"** или **"Tray 2"** +7. Нажмите **OK** + +### 🔧 Настройка двусторонней печати через командную строку + +**Установить двустороннюю печать по умолчанию:** + +```bash +# Двусторонняя печать (длинная сторона - как книга) +lpadmin -p HP_LaserJet_M402dn_2 -o Duplex=DuplexNoTumble + +# Двусторонняя печать (короткая сторона - как блокнот) +lpadmin -p HP_LaserJet_M402dn_2 -o Duplex=DuplexTumble + +# Отключить двустороннюю печать +lpadmin -p HP_LaserJet_M402dn_2 -o Duplex=None +``` + +**Проверить текущую настройку:** +```bash +lpoptions -p HP_LaserJet_M402dn_2 -l | grep Duplex +``` + +**Проверить все настройки:** +```bash +lpoptions -p HP_LaserJet_M402dn_2 | grep -E "Duplex|InputSlot" +``` + +**Примечание:** Эти настройки работают для большинства приложений, но LibreOffice может их игнорировать. Используйте системный диалог печати (Решение 1). + +### 🔧 Скрипт для быстрого изменения лотка + +Используйте готовый скрипт `set-hp-tray.sh`: + +```bash +# Установить Tray 2 по умолчанию +./docs/printer/set-hp-tray.sh tray2 + +# Установить Tray 1 по умолчанию +./docs/printer/set-hp-tray.sh tray1 +``` + +**Или через алиас (если установлен):** +```bash +set-hp-tray tray2 +``` + +**Примечание:** Скрипт автоматически найдет HP принтер и попытается изменить лоток. Если драйвер не поддерживает изменение (Generic PostScript), скрипт покажет предупреждение и рекомендации. + +**⚠️ Важно для LibreOffice:** Даже если настройка установлена через командную строку, LibreOffice может ее игнорировать. Используйте системный диалог печати (Решение 1). + +### ⚠️ Специфичные проблемы LibreOffice + +**Проблема 1: LibreOffice игнорирует настройки CUPS** + +**Симптомы:** +- Настройки установлены через `lpadmin`, но LibreOffice их не использует +- Другие приложения (TextEdit, Preview) работают правильно + +**Причина:** +- LibreOffice использует свой собственный механизм печати +- Может игнорировать настройки по умолчанию из CUPS +- Особенно проблематично с Generic PostScript драйвером + +**Решения:** +1. **Использовать системный диалог печати** (Решение 1 выше) - самый надежный способ +2. **Установить официальный драйвер HP** - улучшит совместимость +3. **Настраивать в каждом документе** - через Properties в LibreOffice + +**Проблема 2: Двусторонняя печать не работает в LibreOffice** + +**Симптомы:** +- Выбрана двусторонняя печать в LibreOffice, но печатается односторонне +- Настройка `Duplex=DuplexNoTumble` установлена в CUPS, но LibreOffice игнорирует + +**Решения:** +1. **Использовать системный диалог печати:** + - В LibreOffice: File → Print → Options → "Use system dialog" + - В системном диалоге: Layout → Two-Sided → Long-edge binding + +2. **Проверить настройки в LibreOffice:** + - File → Print → Properties + - Найдите "Duplex" или "Two-sided" + - Выберите "Long-edge" или "Short-edge" + - ⚠️ Если это не работает, используйте системный диалог + +3. **Установить через командную строку (для других приложений):** + ```bash + lpadmin -p HP_LaserJet_M402dn_2 -o Duplex=DuplexNoTumble + ``` + +### ⚠️ Если Lower не работает (Generic PostScript драйвер) + +**Проблема:** Если используется драйвер "Generic PostScript Printer", команда `InputSlot=Lower` может не работать. + +**Причина:** +- Generic PostScript драйвер имеет ограниченную поддержку опций принтера +- Не все опции HP принтера доступны через этот драйвер + +**Решения:** + +1. **Использовать системный диалог печати в LibreOffice** (самый надежный способ): + - File → Print → Options → "Use system dialog" + - В системном диалоге выбрать Paper Source → Lower/Tray 2 + +2. **Установить официальный драйвер HP:** + - Скачать с сайта HP + - Переустановить принтер с новым драйвером + - После этого команды `lpadmin` будут работать лучше + +3. **Проверка текущего драйвера:** + ```bash + lpoptions -p HP_LaserJet_M402dn_2 | grep "printer-make-and-model" + ``` + +4. **Проверка доступных опций:** + ```bash + lpoptions -p HP_LaserJet_M402dn_2 -l | grep -i "input\|tray\|source\|duplex" + ``` + +### 📝 Примечание о имени принтера + +**Важно:** В системе принтер может называться `HP_LaserJet_M402dn_2` (с суффиксом `_2`), а не `HP_LaserJet_M402dn`. + +**Проверка имени принтера:** +```bash +lpstat -p | grep -i hp +``` + +Используйте правильное имя принтера во всех командах! + +--- + +## 📊 ПРОВЕРКА СТАТУСА + +### Список всех принтеров +```bash +lpstat -p +``` + +### Статус HP принтера +```bash +lpstat -p HP_LaserJet_M402dn -l +``` + +### Задачи в очереди +```bash +lpstat -o +``` + +### Задачи конкретного принтера +```bash +lpstat -o HP_LaserJet_M402dn +``` + +### Режим печати (цветной/монохромный) +```bash +lpoptions -p HP_LaserJet_M402dn -l | grep ColorModel +``` + +--- + +## 🛠️ РУЧНОЙ СБРОС (если скрипт не помог) + +### Отмена всех задач принтера +```bash +cancel -a HP_LaserJet_M402dn +``` + +### Включение принтера +```bash +cupsenable HP_LaserJet_M402dn +cupsaccept HP_LaserJet_M402dn +``` + +### Настройка принтера +```bash +lpadmin -p HP_LaserJet_M402dn -o printer-is-accepting-jobs=true +``` + +--- + +## 📁 ФАЙЛЫ + +- **Скрипт сброса задач:** `clear-hp-jobs.sh` - сброс подвисших задач печати +- **Скрипт проверки тонера:** `check-hp-toner.sh` - проверка уровня тонера и информации о принтере +- **Скрипт настройки лотка:** `set-hp-tray.sh` - изменение лотка по умолчанию (Tray 1/Tray 2) +- **Скрипт настройки двусторонней печати:** `set-hp-duplex.sh` - включение/выключение двусторонней печати +- **Документация:** `HP_LASERJET_M402DN_README.md` - этот файл +- **Алиасы:** + - `clear-hp` - сброс подвисших задач (добавлен в `~/.zshrc`) + - `check-hp-toner` - проверка уровня тонера (добавлен в `~/.zshrc`) + - `set-hp-tray` - настройка лотка (добавлен в `~/.zshrc`) + - `set-hp-duplex` - настройка двусторонней печати (добавлен в `~/.zshrc`) + +--- + +## 💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ + +### Пример 1: Быстрый сброс +```bash +clear-hp +``` + +**Вывод:** +``` +🔍 Поиск HP принтеров... +✅ Найдены HP принтеры: + - HP_LaserJet_M402dn + +📋 Проверка задач печати... + +🖨️ Обработка принтера: HP_LaserJet_M402dn + ⚠️ Найдено задач: 1 + 🗑️ Отмена всех задач... + ✅ Задачи отменены + 🔄 Сброс состояния принтера... + ✅ Принтер готов к работе + +✅ Готово! Все подвисшие задачи HP принтеров сброшены +``` + +### Пример 2: Проверка перед сбросом +```bash +# Сначала проверяем задачи +lpstat -o HP_LaserJet_M402dn + +# Если есть задачи - сбрасываем +clear-hp +``` + +--- + +## 🎯 ИТОГ + +### Сброс задач +1. Запустите `clear-hp` +2. Готово! Принтер готов к работе + +### Проверка уровня тонера +1. Запустите `check-hp-toner` +2. Или используйте панель управления принтера + +### Цветная печать +- ❌ **НЕ поддерживается** - принтер только черно-белый + +**Если не помогло:** +1. Проверьте физическое состояние принтера +2. Проверьте уровень тонера (см. раздел "Проверка уровня тонера") +3. Перезагрузите принтер +4. Используйте ручной сброс (см. раздел "Ручной сброс") + +--- + +**Дата:** 2025-12-26 + diff --git a/docs/printer/SAMSUNG_SCX4300_README.md b/docs/printer/SAMSUNG_SCX4300_README.md new file mode 100644 index 0000000..628f6c8 --- /dev/null +++ b/docs/printer/SAMSUNG_SCX4300_README.md @@ -0,0 +1,784 @@ +# Samsung SCX-4300 - Полное руководство для macOS Sequoia + +## 🚀 БЫСТРЫЙ СТАРТ + +### 1. Установка (1 команда) + +```bash +/tmp/FINAL_SIMPLE_SOLUTION.sh +``` + +### 2. Печать + +**Из приложений:** +- File → Print → Samsung_SCX_4300_Series + +**Из командной строки:** +```bash +echo "Текст" | lp -d Samsung_SCX_4300_Series +``` + +**Готово!** + +--- + +## 📋 ИНФОРМАЦИЯ О ПРИНТЕРЕ + +- **Модель:** Samsung SCX-4300 Series +- **Серийный номер:** 9N66BABS200626A +- **macOS:** Sequoia 15.3.1 +- **Прошивка:** QPDL 1.40 (2005 год) +- **Device ID:** `MFG:Samsung;CMD:GDI;MDL:SCX-4300 Series;CLS:PRINTER;MODE:PCL;STATUS:IDLE;` +- **USB:** usb://Samsung/SCX-4300%20Series?serial=9N66BABS200626A. + +--- + +## 📋 ТЕКУЩАЯ КОНФИГУРАЦИЯ + +- **Драйвер:** Generic PCL Laser Printer +- **Режим:** С драйвером +- **URI:** usb://Samsung/SCX-4300%20Series?serial=9N66BABS200626A. +- **Статус:** ✅ Настроено + +--- + +## ✅ ФИНАЛЬНОЕ РАБОЧЕЕ РЕШЕНИЕ + +### Установка + +```bash +/tmp/FINAL_SIMPLE_SOLUTION.sh +``` + +**Конфигурация:** +- **Драйвер:** Generic PCL Laser Printer +- **Режим:** С драйвером (не raw) +- **Фильтры:** Стандартные CUPS (rastertohp) +- **URI:** usb://Samsung/SCX-4300%20Series?serial=9N66BABS200626A. + +### Почему это работает + +- **НЕТ Samsung фильтров** - используются только стандартные CUPS фильтры +- **Правильная конвертация:** + - `cgtexttopdf` - текст → PDF + - `cgpdftoraster` - PDF → растровое изображение + - `rastertohp` - растровое изображение → HP PCL +- **Прямой PCL вывод** - принтер поддерживает PCL (MODE:PCL в Device ID) +- **Обходит все проблемы** - нет QPDL, нет SPL, нет ошибок + +### Что НЕ работает + +- ❌ Все драйверы Samsung (вызывают ошибки QPDL) +- ❌ Модификация PPD файлов (проблема в фильтрах) +- ❌ Raw режим (данные отправляются, но не печатаются) + +### Скрипты + +- `/tmp/FINAL_SIMPLE_SOLUTION.sh` - Установка принтера +- `/tmp/print_simple_text.sh` - Печать текста +- `/tmp/force_online_aggressive.sh` - Исправление offline +- `/tmp/check_printer_status.sh` - Проверка статуса +- `/tmp/debug_print.sh` - Отладка печати +- `/tmp/fix_usb_offline.sh` - Исправление USB offline + +--- + +## 🔴 ПРОБЛЕМЫ И РЕШЕНИЯ + +### Проблема 1: Принтер показывает OFFLINE + +**Описание проблемы:** + +Принтер показывает статус **"The printer is offline"** в CUPS, хотя физически работает. + +**Симптомы:** +- `lpstat -p Samsung_SCX_4300_Series -l` показывает: "The printer is offline" +- Задания отправляются, но остаются в очереди +- CUPS не может связаться с USB устройством + +**Причина:** + +CUPS не может физически связаться с USB устройством принтера. Это **НЕ программная проблема**, а проблема физического подключения или состояния USB устройства. + +**РЕШЕНИЕ (выполните в точном порядке):** + +1. Отмените все задания: + ```bash + cancel -a Samsung_SCX_4300_Series + ``` + +2. **Выключите принтер** (кнопка питания) + +3. **Отключите USB кабель** от Mac + +4. **Подождите 30 секунд** + +5. **Подключите USB кабель** обратно + +6. **Включите принтер** + +7. **Подождите 1 минуту** (пока принтер загрузится) + +8. Запустите исправление: + ```bash + /tmp/force_online_aggressive.sh + ``` + +**Альтернативное решение (агрессивное исправление):** + +```bash +/tmp/force_online_aggressive.sh +``` + +Скрипт: +- Отменяет все задания +- Удаляет и переустанавливает принтер +- Включает и активирует принтер +- Проверяет статус + +**Ручное исправление:** + +```bash +# Удалить принтер +lpadmin -x Samsung_SCX_4300_Series + +# Переустановить +lpadmin -p Samsung_SCX_4300_Series \ + -v "usb://Samsung/SCX-4300%20Series?serial=9N66BABS200626A." \ + -m "drv:///sample.drv/generpcl.ppd" \ + -E + +# Включить +cupsenable Samsung_SCX_4300_Series +cupsaccept Samsung_SCX_4300_Series + +# Настроить +lpadmin -p Samsung_SCX_4300_Series -o printer-is-accepting-jobs=true +``` + +**Если все еще offline:** + +1. **Попробуйте другой USB кабель** +2. **Попробуйте другой USB порт** на Mac +3. **Перезагрузите Mac** и повторите шаги +4. **Проверьте принтер:** + - Нет ли ошибок на дисплее? + - Работает ли принтер вообще? + - Попробуйте сбросить принтер (меню принтера) + +**Диагностика offline:** + +```bash +# Проверить USB подключение +system_profiler SPUSBDataType | grep -A 10 "SCX-4300" + +# Проверить статус в CUPS +lpstat -p Samsung_SCX_4300_Series -l | grep -i "offline" + +# Если НЕТ строки "offline" - проблема решена! +``` + +**ВАЖНО:** Проблема offline требует **ФИЗИЧЕСКОГО** переподключения USB кабеля. Программные решения не помогают. + +--- + +### Проблема 2: Принтер не печатает + +**ОБЯЗАТЕЛЬНО проверьте физическое состояние принтера:** + +- ✅ Принтер **включен** +- ✅ Есть **бумага** в лотке +- ✅ Есть **тонер/чернила** +- ✅ **USB кабель** подключен правильно +- ✅ **Нет ошибок** на дисплее принтера + +**Проверьте настройки принтера:** + +- Откройте **меню принтера** (кнопка Menu) +- Проверьте настройки печати +- Попробуйте **сбросить** принтер (выключить/включить) + +**Отладка:** + +```bash +# Проверка статуса +/tmp/check_printer_status.sh + +# Отладка печати +/tmp/debug_print.sh + +# Проверка логов +tail -50 /var/log/cups/error_log | grep -i "error\|fail" +``` + +**Переустановить:** + +```bash +/tmp/FINAL_SIMPLE_SOLUTION.sh +``` + +**Альтернативные решения:** + +- Использовать принтер с Windows/Linux +- Рассмотреть обновление принтера +- Использовать сетевой принт-сервер + +--- + +### Проблема 3: Принтер "поливает тонером" бумагу + +**Проблема:** После смены картриджа принтер избыточно наносит тонер на бумагу, размазывает текст. + +**Симптомы:** +- Избыточное количество тонера на бумаге +- Размазанный текст/изображения +- Тонер осыпается с бумаги +- Плохое качество печати +- Темные пятна на бумаге + +**БЫСТРОЕ РЕШЕНИЕ:** + +1. **Выключите принтер** +2. **Откройте крышку** +3. **Извлеките картридж** +4. **Проверьте:** + - ✅ Все защитные ленты сняты? + - ✅ Картридж не поврежден? +5. **Встряхните картридж горизонтально** (не вертикально!) +6. **Установите картридж обратно** (до упора!) +7. **Закройте крышку** +8. **Включите принтер** +9. **Уменьшите плотность печати** в меню принтера (Menu → Density → -2) + +**ПОДРОБНОЕ РЕШЕНИЕ:** + +#### Решение 1: Правильная установка картриджа (ОБЯЗАТЕЛЬНО) + +**Выполните в точном порядке:** + +1. **Выключите принтер** (кнопка питания) + +2. **Откройте крышку** принтера + +3. **Извлеките картридж:** + - Нажмите на фиксатор картриджа + - Аккуратно вытащите картридж + +4. **Проверьте картридж:** + - ✅ Все **защитные ленты сняты** + - ✅ Картридж **не поврежден** + - ✅ Нет **видимых утечек тонера** + +5. **Очистите контакты:** + - Протрите **контакты картриджа** сухой тряпкой + - Протрите **контакты в принтере** сухой тряпкой + +6. **Встряхните картридж:** + - Аккуратно встряхните картридж **горизонтально** (не вертикально!) + - Это распределит тонер внутри картриджа + +7. **Установите картридж:** + - Вставьте картридж **до упора** + - Убедитесь, что картридж **зафиксирован** + - **Закройте крышку** принтера + +8. **Включите принтер** + +9. **Подождите 1-2 минуты** (пока принтер загрузится) + +10. **Попробуйте печать** + +#### Решение 2: Очистка принтера + +**ВАЖНО:** Выполняйте только при выключенном принтере! + +1. **Выключите принтер** + +2. **Откройте крышку** + +3. **Извлеките картридж** + +4. **Очистите внутренности:** + - Используйте **сухую тряпку** (не влажную!) + - Очистите **ролики** от тонера + - Очистите **контакты** в принтере + - **НЕ используйте** спирт или другие жидкости + +5. **Верните картридж** + +6. **Закройте крышку** + +7. **Включите принтер** + +#### Решение 3: Настройка плотности печати + +**Через меню принтера:** + +1. Нажмите кнопку **Menu** на принтере + +2. Найдите настройку **"Density"** или **"Плотность"** + +3. Установите значение **-2** или **-3** (уменьшите плотность) + +4. Сохраните настройки + +5. Попробуйте печать + +**Через macOS:** + +1. Откройте **System Settings** → **Printers & Scanners** + +2. Выберите принтер **Samsung_SCX_4300_Series** + +3. Нажмите **Options & Supplies** + +4. Найдите настройку **"Density"** или **"Плотность"** + +5. Уменьшите значение + +6. Попробуйте печать + +#### Решение 4: Замена картриджа + +**Если проблема сохраняется:** + +1. **Попробуйте другой картридж:** + - Оригинальный Samsung + - Или совместимый от проверенного производителя + +2. **Проверьте модель картриджа:** + - Для SCX-4300 обычно используется **MLT-D1043S** или совместимый + +3. **Избегайте перезаправленных картриджей:** + - Они часто вызывают проблемы с дозированием + +#### Решение 5: Сброс принтера + +**Полный сброс настроек:** + +1. **Выключите принтер** + +2. **Отключите USB кабель** + +3. **Отключите питание** (выньте шнур из розетки) + +4. **Подождите 30 секунд** + +5. **Подключите питание** + +6. **Включите принтер** + +7. **Подключите USB кабель** + +8. **Подождите 1-2 минуты** + +9. **Попробуйте печать** + +#### Решение 6: Тестовая печать + +**Проверка качества печати:** + +1. Нажмите кнопку **Menu** на принтере + +2. Найдите **"Test Print"** или **"Тестовая печать"** + +3. Запустите тестовую печать + +4. Проверьте качество: + - Если тестовая печать **хорошая** → проблема в драйвере/настройках + - Если тестовая печать **плохая** → проблема в картридже/принтере + +**ЧАСТЫЕ ОШИБКИ:** + +### ❌ НЕ ДЕЛАЙТЕ: + +1. **НЕ используйте влажную тряпку** для очистки (только сухую!) +2. **НЕ используйте спирт** или другие жидкости +3. **НЕ встряхивайте картридж вертикально** (только горизонтально!) +4. **НЕ трогайте фотобарабан** голыми руками +5. **НЕ используйте перезаправленные картриджи** низкого качества + +### ✅ ДЕЛАЙТЕ: + +1. **Используйте оригинальные** или качественные совместимые картриджи +2. **Очищайте принтер** регулярно (раз в месяц) +3. **Правильно устанавливайте** картридж +4. **Проверяйте защитные ленты** перед установкой +5. **Встряхивайте картридж горизонтально** перед установкой + +**МОДЕЛИ КАРТРИДЖЕЙ:** + +Для Samsung SCX-4300 обычно используются: + +- **Оригинальный:** Samsung MLT-D1043S +- **Совместимые:** Различные производители (проверяйте совместимость!) + +**ВАЖНО:** Убедитесь, что картридж совместим с вашей моделью принтера! + +**Наиболее вероятные причины:** + +1. **Неправильная установка картриджа** (80% случаев) +2. **Бракованный или несовместимый картридж** (15% случаев) +3. **Загрязнение внутренних компонентов** (4% случаев) +4. **Износ компонентов принтера** (1% случаев) + +--- + +## 🔴 КОРНЕВАЯ ПРОБЛЕМА + +**Все драйверы Samsung вызывают ошибки "INTERNAL ERROR FALSE"** из-за: + +1. Устаревшей прошивки QPDL 1.40 (2005 год) +2. Проблемных SPL фильтров (rastertosec, commandtosec) +3. Несовместимости с macOS Sequoia +4. Отсутствия официальной поддержки Samsung/HP для новых macOS + +--- + +## ❌ ЧТО НЕ СРАБОТАЛО + +### 1. Драйверы Samsung (все варианты) + +#### 1.1. Samsung C43x Series +- **Попытка:** Использование драйвера Samsung C43x Series +- **Результат:** ❌ Ошибка "INTERNAL ERROR FALSE LINE 312" +- **Причина:** Использует SPL фильтры (rastertosec, commandtosec) +- **Статус:** НЕ РАБОТАЕТ + +#### 1.2. Samsung C3010 Series +- **Попытка:** Использование драйвера Samsung C3010 Series +- **Результат:** ❌ Ошибка "INTERNAL ERROR FALSE LINE 312/407/495" +- **Причина:** SPL фильтры вызывают ошибки QPDL +- **Статус:** НЕ РАБОТАЕТ + +#### 1.3. Samsung M2010 Series +- **Попытка:** Использование драйвера Samsung M2010 Series +- **Результат:** ❌ Задание исчезло из очереди, но не напечаталось +- **Причина:** Все еще использует SPL фильтры +- **Статус:** НЕ РАБОТАЕТ + +#### 1.4. Samsung M2020 Series +- **Попытка:** Использование драйвера Samsung M2020 Series +- **Результат:** ❌ Ошибка сохраняется +- **Причина:** SPL фильтры +- **Статус:** НЕ РАБОТАЕТ + +#### 1.5. Samsung ML-2160 Series +- **Попытка:** Использование драйвера Samsung ML-2160 Series (без n_SrcXR/n_SrcYR) +- **Результат:** ❌ Ошибка "INTERNAL ERROR FALSE LINE 312" +- **Причина:** Проблема не только в опциях, но и в фильтрах +- **Статус:** НЕ РАБОТАЕТ + +#### 1.6. Samsung SF-760 Series +- **Попытка:** Использование драйвера Samsung SF-760 Series +- **Результат:** ❌ Ошибка сохраняется +- **Причина:** SPL фильтры +- **Статус:** НЕ РАБОТАЕТ + +#### 1.7. Samsung SCX-3400 Series +- **Попытка:** Использование драйвера Samsung SCX-3400 Series +- **Результат:** ❌ Ошибка "INTERNAL ERROR FALSE LINE 312" +- **Причина:** SPL фильтры +- **Статус:** НЕ РАБОТАЕТ + +#### 1.8. Samsung Universal Print Driver v3.93.08 +- **Попытка:** Установка Samsung Universal Print Driver v3.93.08 +- **Результат:** ❌ Не работает на macOS Sequoia +- **Причина:** Драйвер предназначен для старых версий macOS +- **Статус:** НЕ РАБОТАЕТ + +**ВЫВОД:** Все драйверы Samsung используют SPL фильтры (rastertosec, commandtosec), которые конвертируют данные в QPDL формат, несовместимый с прошивкой принтера. + +--- + +### 2. Модификация PPD файлов + +#### 2.1. Удаление опций n_SrcXR и n_SrcYR +- **Попытка:** Удаление проблемных опций n_SrcXR и n_SrcYR из PPD +- **Результат:** ❌ Ошибка сохраняется +- **Причина:** Проблема не только в опциях, но и в фильтрах +- **Статус:** НЕ РАБОТАЕТ + +#### 2.2. Удаление опций SECResolution +- **Попытка:** Удаление всех опций SECResolution из строки 312 +- **Результат:** ❌ Ошибка сохраняется +- **Причина:** Проблема в фильтрах, а не в опциях +- **Статус:** НЕ РАБОТАЕТ + +#### 2.3. Закомментирование строки 312 +- **Попытка:** Закомментирование строки 312 в PPD файле +- **Результат:** ❌ Ошибка изменилась на LINE 407/495 +- **Причина:** Проблема глубже - в самих SPL фильтрах +- **Статус:** НЕ РАБОТАЕТ + +#### 2.4. Закомментирование строк 312 и 495 +- **Попытка:** Закомментирование обеих проблемных строк +- **Результат:** ❌ Ошибка сохраняется +- **Причина:** Проблема в фильтрах, а не в строках PPD +- **Статус:** НЕ РАБОТАЕТ + +#### 2.5. Удаление опций xl_image и H6FW +- **Попытка:** Удаление опций xl_image и H6FW +- **Результат:** ❌ Ошибка сохраняется +- **Причина:** Проблема в фильтрах +- **Статус:** НЕ РАБОТАЕТ + +**ВЫВОД:** Модификация PPD файлов (удаление опций, закомментирование строк) не решает проблему, так как корневая причина - в SPL фильтрах. + +--- + +### 3. Создание минимальных PPD без фильтров + +#### 3.1. Минимальный PPD без фильтров +- **Попытка:** Создание минимального PPD файла без фильтров +- **Результат:** ❌ CUPS требует фильтры для обработки данных +- **Причина:** PPD без фильтров не может обработать данные +- **Статус:** НЕ РАБОТАЕТ + +#### 3.2. PPD с только стандартными CUPS фильтрами (pstoraster, rastertopcl) +- **Попытка:** PPD с фильтрами pstoraster и rastertopcl +- **Результат:** ❌ Ошибка сохраняется +- **Причина:** Стандартные фильтры тоже могут вызывать проблемы +- **Статус:** НЕ РАБОТАЕТ + +#### 3.3. PPD с фильтрами cgpdftoraster, rastertohp, cgtexttopdf +- **Попытка:** PPD с фильтрами cgpdftoraster, rastertohp, cgtexttopdf +- **Результат:** ❌ Ошибка сохраняется +- **Причина:** Все фильтры вызывают проблемы +- **Статус:** НЕ РАБОТАЕТ + +**ВЫВОД:** Даже стандартные CUPS фильтры вызывают проблемы, возможно из-за несовместимости формата данных с прошивкой принтера. + +--- + +### 4. Raw режим CUPS + +#### 4.1. Raw режим без драйвера +- **Попытка:** Установка принтера в raw режиме (без драйвера) +- **Результат:** ⚠️ Задания исчезают из очереди, но не печатаются физически +- **Причина:** Данные отправляются, но принтер не понимает формат +- **Статус:** ЧАСТИЧНО РАБОТАЕТ (данные отправляются, но не печатаются) + +#### 4.2. Raw режим с PCL форматом +- **Попытка:** Отправка данных в PCL формате через raw режим +- **Результат:** ⚠️ Задания обрабатываются, но не печатаются +- **Причина:** Возможно неправильный PCL формат или проблема с USB +- **Статус:** ЧАСТИЧНО РАБОТАЕТ + +#### 4.3. Raw режим с правильными escape-последовательностями +- **Попытка:** Использование правильных PCL escape-последовательностей (\033E, \033&l0O) +- **Результат:** ⚠️ Задания отправляются, но не печатаются +- **Причина:** Данные доходят до принтера, но не печатаются физически +- **Статус:** ЧАСТИЧНО РАБОТАЕТ + +**ВЫВОД:** Raw режим отправляет данные на принтер, но физическая печать не происходит. Возможно проблема в: +- Физическом состоянии принтера (бумага, тонер, USB) +- Неправильном PCL формате +- Проблеме с USB соединением + +--- + +### 5. Generic драйверы + +#### 5.1. Generic PCL Laser Printer +- **Попытка:** Использование Generic PCL драйвера (drv:///sample.drv/generpcl.ppd) +- **Результат:** ⚠️ Задания отправляются, но не печатаются +- **Причина:** Только один фильтр (rastertohp), недостаточно для полной обработки +- **Статус:** ЧАСТИЧНО РАБОТАЕТ + +#### 5.2. Generic PostScript Printer +- **Попытка:** Использование Generic PostScript драйвера (drv:///sample.drv/generic.ppd) +- **Результат:** ⚠️ Задания отправляются, но не печатаются +- **Причина:** PostScript может быть несовместим с принтером +- **Статус:** ЧАСТИЧНО РАБОТАЕТ + +#### 5.3. HP LaserJet Series PCL 4/5 +- **Попытка:** Использование HP LaserJet драйвера (drv:///sample.drv/laserjet.ppd) +- **Результат:** ⚠️ Задания отправляются, но не печатаются +- **Причина:** Только один фильтр (rastertohp) +- **Статус:** ЧАСТИЧНО РАБОТАЕТ + +**ВЫВОД:** Generic драйверы отправляют данные, но физическая печать не происходит. Возможно проблема в физическом состоянии принтера или несовместимости формата. + +--- + +### 6. Кастомные PPD с правильными фильтрами + +#### 6.1. PPD с фильтрами cgpdftoraster, pstoraster, rastertohp, cgtexttopdf +- **Попытка:** Создание PPD с полным набором стандартных CUPS фильтров +- **Результат:** ⚠️ Задания отправляются, но не печатаются +- **Причина:** Фильтры работают, но данные не печатаются физически +- **Статус:** ЧАСТИЧНО РАБОТАЕТ + +**ВЫВОД:** Кастомные PPD с правильными фильтрами работают на уровне CUPS, но физическая печать не происходит. + +--- + +## ✅ ВЕКТОРЫ РЕШЕНИЯ + +### Вектор 1: Обход Samsung фильтров +**Идея:** Использовать только стандартные CUPS фильтры, минуя SPL/QPDL фильтры Samsung + +**Попытки:** +- ✅ Создание PPD без Samsung фильтров +- ✅ Использование Generic драйверов +- ✅ Кастомные PPD с только CUPS фильтрами + +**Результат:** ⚠️ Частично работает - данные отправляются, но не печатаются физически + +**Статус:** ТРЕБУЕТ ДОПОЛНИТЕЛЬНОЙ ДИАГНОСТИКИ + +--- + +### Вектор 2: Raw режим с правильным PCL +**Идея:** Отправлять данные напрямую в PCL формате, минуя все фильтры + +**Попытки:** +- ✅ Raw режим CUPS +- ✅ PCL файлы с правильными escape-последовательностями +- ✅ Скрипты для конвертации текста в PCL + +**Результат:** ⚠️ Частично работает - данные отправляются, но не печатаются физически + +**Статус:** ТРЕБУЕТ ПРОВЕРКИ ФИЗИЧЕСКОГО СОСТОЯНИЯ ПРИНТЕРА + +--- + +### Вектор 3: Модификация существующих драйверов +**Идея:** Исправить существующие драйверы Samsung, удалив проблемные части + +**Попытки:** +- ❌ Удаление опций n_SrcXR, n_SrcYR +- ❌ Удаление опций SECResolution +- ❌ Закомментирование проблемных строк +- ❌ Удаление опций xl_image, H6FW + +**Результат:** ❌ Не работает - проблема в фильтрах, а не в опциях + +**Статус:** НЕ РАБОТАЕТ + +--- + +### Вектор 4: Использование универсальных драйверов +**Идея:** Использовать Generic драйверы вместо специфичных Samsung + +**Попытки:** +- ⚠️ Generic PCL Laser Printer +- ⚠️ Generic PostScript Printer +- ⚠️ HP LaserJet Series PCL 4/5 + +**Результат:** ⚠️ Частично работает - данные отправляются, но не печатаются физически + +**Статус:** ТРЕБУЕТ ДОПОЛНИТЕЛЬНОЙ ДИАГНОСТИКИ + +--- + +### Вектор 5: Обновление прошивки принтера +**Идея:** Обновить прошивку принтера для совместимости с современными системами + +**Попытки:** +- ⚠️ Поиск обновлений прошивки на сайте Samsung/HP +- ⚠️ Проверка версии прошивки (QPDL 1.40 от 2005 года) + +**Результат:** ⚠️ Обновления не найдены или недоступны + +**Статус:** НЕДОСТУПНО + +--- + +### Вектор 6: Использование другой ОС +**Идея:** Использовать принтер с операционной системой, которая официально поддерживается + +**Попытки:** +- ⚠️ Windows (есть официальные драйверы) +- ⚠️ Linux (есть драйверы через ULD) +- ⚠️ macOS 10.7 и ниже (старые драйверы) + +**Результат:** ⚠️ Работает на других ОС, но не решает проблему для macOS Sequoia + +**Статус:** АЛЬТЕРНАТИВНОЕ РЕШЕНИЕ + +--- + +## 📊 СТАТИСТИКА ПОПЫТОК + +- **Всего попыток:** 30+ +- **Полностью не работающих:** 20+ +- **Частично работающих:** 10+ +- **Полностью работающих:** 0 + +--- + +## 🔍 ДИАГНОСТИКА ТЕКУЩЕЙ СИТУАЦИИ + +### Что работает: +- ✅ Принтер определяется системой +- ✅ CUPS принимает задания +- ✅ Данные отправляются на принтер (задания исчезают из очереди) +- ✅ Нет ошибок в логах CUPS +- ✅ USB соединение работает + +### Что не работает: +- ❌ Физическая печать не происходит +- ❌ Все драйверы Samsung вызывают ошибки QPDL +- ❌ Модификация PPD не помогает + +### Возможные причины: +1. **Физическое состояние принтера:** + - Нет бумаги + - Нет тонера + - Проблема с USB кабелем + - Принтер в режиме ошибки + +2. **Проблема с форматом данных:** + - Неправильный PCL формат + - Принтер не понимает команды + - Несовместимость с прошивкой + +3. **Проблема с USB:** + - USB кабель не подключен правильно + - Проблема с USB портом + - Данные не доходят до принтера + +--- + +## 📅 ХРОНОЛОГИЯ + +- **2025-12-10:** Начало попыток настройки +- **2025-12-10:** Множество попыток с разными драйверами Samsung +- **2025-12-10:** Попытки модификации PPD файлов +- **2025-12-10:** Попытки с Generic драйверами +- **2025-12-10:** Попытки с Raw режимом +- **2025-12-10:** Создание кастомных PPD с правильными фильтрами +- **2025-12-10:** Текущее состояние - данные отправляются, но не печатаются физически + +--- + +## 🔗 ССЫЛКИ + +- **Samsung Support:** https://www.samsung.com/support/ +- **HP Support (текущий владелец):** https://support.hp.com/ +- **Модель:** SCX-4300 Series + +--- + +## 📝 ВЫВОДЫ + +1. **Все драйверы Samsung не работают** из-за SPL фильтров +2. **Модификация PPD не помогает** - проблема в фильтрах +3. **Generic драйверы отправляют данные**, но физическая печать не происходит +4. **Raw режим отправляет данные**, но физическая печать не происходит +5. **Требуется дополнительная диагностика** физического состояния принтера + +**Текущий статус:** Данные успешно отправляются на принтер через CUPS, но физическая печать не происходит. Требуется проверка физического состояния принтера и настройки принтера. + +**Самое простое решение:** +1. Запустите `/tmp/FINAL_SIMPLE_SOLUTION.sh` +2. Печатайте из приложений (File → Print) +3. Если offline - переподключите USB и запустите `/tmp/force_online_aggressive.sh` + +**Если не печатает - проверьте физическое состояние принтера в первую очередь!** + +--- + +**Дата последнего обновления:** 2025-12-10 diff --git a/docs/printer/check-hp-toner.sh b/docs/printer/check-hp-toner.sh new file mode 100755 index 0000000..d794cf6 --- /dev/null +++ b/docs/printer/check-hp-toner.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Скрипт для проверки уровня тонера HP принтера на macOS + +set -e + +echo "🖨️ Проверка уровня тонера HP принтера" +echo "" + +# Найти все HP принтеры +HP_PRINTERS=$(lpstat -p 2>/dev/null | grep -i "hp" | awk '{print $2}' || true) + +if [ -z "$HP_PRINTERS" ]; then + echo "❌ HP принтеры не найдены в системе" + exit 1 +fi + +# Для каждого HP принтера +echo "$HP_PRINTERS" | while read printer; do + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📋 Принтер: $printer" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + + # Базовая информация о принтере + echo "📊 Статус принтера:" + lpstat -p "$printer" -l 2>/dev/null | head -3 || true + echo "" + + # Информация о цвете + echo "🎨 Режим печати:" + COLOR_MODE=$(lpoptions -p "$printer" -l 2>/dev/null | grep -i "ColorModel" | grep -o '\*[^*]*' | sed 's/*//' || echo "") + if [ -z "$COLOR_MODE" ]; then + COLOR_MODE=$(lpoptions -p "$printer" 2>/dev/null | grep -i "ColorModel" | awk -F'=' '{print $2}' | awk '{print $1}' || echo "") + fi + if echo "$COLOR_MODE" | grep -qi "gray\|mono\|black"; then + echo " ⚫ Монохромный (черно-белый)" + echo " ❌ Цветная печать НЕ поддерживается" + elif [ ! -z "$COLOR_MODE" ]; then + echo " 🎨 Цветной режим: $COLOR_MODE" + else + echo " ⚫ Монохромный (черно-белый) - по умолчанию для лазерных принтеров" + echo " ❌ Цветная печать НЕ поддерживается" + fi + echo "" + + # Попытка получить информацию о тонере через CUPS + echo "🔋 Уровень тонера:" + echo " ⚠️ CUPS не предоставляет прямого доступа к уровню тонера" + echo "" + echo " 📝 Рекомендуемые способы проверки:" + echo "" + echo " 1️⃣ Панель управления принтера:" + echo " - Нажмите кнопку 'OK' на принтере" + echo " - Перейдите в меню 'Отчеты'" + echo " - Выберите 'Страница состояния расходных материалов'" + echo " - Принтер напечатает страницу с уровнем тонера" + echo "" + echo " 2️⃣ Приложение HP Smart (если установлено):" + echo " - Откройте приложение HP Smart" + echo " - Выберите ваш принтер" + echo " - Просмотрите уровень тонера" + echo "" + echo " 3️⃣ Дисплей принтера:" + echo " - Проверьте дисплей принтера" + echo " - Уровень тонера отображается на экране" + echo "" + + # Проверка подключения + DEVICE=$(lpstat -v "$printer" 2>/dev/null | grep -i "device for" | awk -F'device for' '{print $2}' | awk '{print $1}' || echo "неизвестно") + echo "🔌 Подключение:" + echo " $DEVICE" + echo "" + + # Информация о принтере + echo "ℹ️ Информация о модели:" + if echo "$printer" | grep -qi "m402"; then + echo " Модель: HP LaserJet Pro M402dn" + echo " Тип: Монохромный лазерный принтер" + echo " Цветная печать: ❌ НЕ поддерживается" + echo " Максимальное разрешение: 1200 x 1200 dpi" + fi + echo "" +done + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "💡 Совет: Для точной проверки уровня тонера используйте" +echo " панель управления принтера или приложение HP Smart" +echo "" + diff --git a/docs/printer/clear-hp-jobs.sh b/docs/printer/clear-hp-jobs.sh new file mode 100755 index 0000000..6512952 --- /dev/null +++ b/docs/printer/clear-hp-jobs.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Скрипт для сброса подвисших задач печати HP принтера на macOS + +set -e + +echo "🔍 Поиск HP принтеров..." + +# Найти все HP принтеры +HP_PRINTERS=$(lpstat -p 2>/dev/null | grep -i "hp" | awk '{print $2}' || true) + +if [ -z "$HP_PRINTERS" ]; then + echo "❌ HP принтеры не найдены в системе" + echo "" + echo "Доступные принтеры:" + lpstat -p 2>/dev/null | awk '{print " - " $2}' || echo " (нет принтеров)" + exit 1 +fi + +echo "✅ Найдены HP принтеры:" +echo "$HP_PRINTERS" | while read printer; do + echo " - $printer" +done + +echo "" +echo "📋 Проверка задач печати..." + +# Для каждого HP принтера +echo "$HP_PRINTERS" | while read printer; do + echo "" + echo "🖨️ Обработка принтера: $printer" + + # Проверить задачи + JOBS=$(lpstat -o "$printer" 2>/dev/null | awk '{print $1}' | cut -d- -f1 | sort -u || true) + + if [ -z "$JOBS" ]; then + echo " ✅ Нет задач в очереди" + else + JOB_COUNT=$(echo "$JOBS" | wc -l | tr -d ' ') + echo " ⚠️ Найдено задач: $JOB_COUNT" + + # Отменить все задачи для этого принтера + echo " 🗑️ Отмена всех задач..." + cancel -a "$printer" 2>/dev/null || true + + # Отменить задачи по ID + echo "$JOBS" | while read job_id; do + if [ ! -z "$job_id" ]; then + cancel "$job_id" 2>/dev/null || true + fi + done + + echo " ✅ Задачи отменены" + fi + + # Сбросить состояние принтера + echo " 🔄 Сброс состояния принтера..." + cupsenable "$printer" 2>/dev/null || true + cupsaccept "$printer" 2>/dev/null || true + lpadmin -p "$printer" -o printer-is-accepting-jobs=true 2>/dev/null || true + + echo " ✅ Принтер готов к работе" +done + +echo "" +echo "✅ Готово! Все подвисшие задачи HP принтеров сброшены" +echo "" +echo "📊 Текущий статус:" +lpstat -p 2>/dev/null | grep -i "hp" || echo " (нет HP принтеров)" + diff --git a/docs/printer/set-hp-duplex.sh b/docs/printer/set-hp-duplex.sh new file mode 100755 index 0000000..c82073d --- /dev/null +++ b/docs/printer/set-hp-duplex.sh @@ -0,0 +1,117 @@ +#!/bin/bash + +# Скрипт для настройки двусторонней печати для HP принтера +# Использование: ./set-hp-duplex.sh [on|off|long|short] + +set -e + +# Найти HP принтер +HP_PRINTER=$(lpstat -p 2>/dev/null | grep -i "hp.*m402" | awk '{print $2}' | head -1) + +if [ -z "$HP_PRINTER" ]; then + echo "❌ HP принтер не найден в системе" + exit 1 +fi + +echo "🖨️ Найден принтер: $HP_PRINTER" +echo "" + +# Проверить текущую настройку duplex +CURRENT_DUPLEX=$(lpoptions -p "$HP_PRINTER" -l 2>/dev/null | grep "Duplex/" | grep -o '\*[^*]*' | sed 's/*//' || echo "None") +echo "📄 Текущая настройка двусторонней печати: $CURRENT_DUPLEX" +echo "" + +# Определить целевую настройку из аргумента +TARGET_DUPLEX="" +DUPLEX_NAME="" +if [ "$1" = "on" ] || [ "$1" = "long" ] || [ "$1" = "1" ]; then + TARGET_DUPLEX="DuplexNoTumble" + DUPLEX_NAME="Двусторонняя (длинная сторона - как книга)" +elif [ "$1" = "short" ] || [ "$1" = "2" ]; then + TARGET_DUPLEX="DuplexTumble" + DUPLEX_NAME="Двусторонняя (короткая сторона - как блокнот)" +elif [ "$1" = "off" ] || [ "$1" = "none" ] || [ "$1" = "0" ]; then + TARGET_DUPLEX="None" + DUPLEX_NAME="Односторонняя" +else + echo "❌ Неверный аргумент. Использование:" + echo " $0 on - включить двустороннюю печать (длинная сторона)" + echo " $0 long - включить двустороннюю печать (длинная сторона)" + echo " $0 short - включить двустороннюю печать (короткая сторона)" + echo " $0 off - отключить двустороннюю печать" + exit 1 +fi + +# Если уже установлена нужная настройка +if [ "$CURRENT_DUPLEX" = "$TARGET_DUPLEX" ]; then + echo "✅ Двусторонняя печать уже установлена: $DUPLEX_NAME" + exit 0 +fi + +# Установить новую настройку +echo "🔄 Установка: $DUPLEX_NAME..." +lpadmin -p "$HP_PRINTER" -o Duplex="$TARGET_DUPLEX" 2>&1 + +# Проверить результат +sleep 1 +NEW_DUPLEX=$(lpoptions -p "$HP_PRINTER" -l 2>/dev/null | grep "Duplex/" | grep -o '\*[^*]*' | sed 's/*//' || echo "") + +if [ "$NEW_DUPLEX" = "$TARGET_DUPLEX" ]; then + echo "✅ Настройка успешно установлена: $DUPLEX_NAME" + echo "" + echo "📋 Текущие настройки:" + lpoptions -p "$HP_PRINTER" -l | grep -E "Duplex|InputSlot" + echo "" + echo "⚠️ ВАЖНО для LibreOffice:" + echo " LibreOffice может игнорировать эти настройки." + echo " Используйте системный диалог печати:" + echo " File → Print → Options → 'Use system dialog'" +else + echo "⚠️ Настройка может быть не изменена. Проверьте настройки:" + lpoptions -p "$HP_PRINTER" -l | grep Duplex + exit 1 +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/printer/set-hp-tray.sh b/docs/printer/set-hp-tray.sh new file mode 100755 index 0000000..5b65ff3 --- /dev/null +++ b/docs/printer/set-hp-tray.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +# Скрипт для изменения лотка по умолчанию для HP принтера +# Использование: ./set-hp-tray.sh [tray1|tray2] + +set -e + +# Найти HP принтер +HP_PRINTER=$(lpstat -p 2>/dev/null | grep -i "hp.*m402" | awk '{print $2}' | head -1) + +if [ -z "$HP_PRINTER" ]; then + echo "❌ HP принтер не найден в системе" + exit 1 +fi + +echo "🖨️ Найден принтер: $HP_PRINTER" +echo "" + +# Проверить текущий лоток +CURRENT_TRAY=$(lpoptions -p "$HP_PRINTER" -l 2>/dev/null | grep "InputSlot" | grep -o '\*[^*]*' | sed 's/*//' || echo "Upper") +echo "📄 Текущий лоток по умолчанию: $CURRENT_TRAY" +echo "" + +# Определить целевой лоток из аргумента +TARGET_TRAY="" +if [ "$1" = "tray1" ] || [ "$1" = "1" ] || [ "$1" = "upper" ]; then + TARGET_TRAY="Upper" + TRAY_NAME="Tray 1 (Upper)" +elif [ "$1" = "tray2" ] || [ "$1" = "2" ] || [ "$1" = "lower" ]; then + TARGET_TRAY="Lower" + TRAY_NAME="Tray 2 (Lower)" +else + echo "❌ Неверный аргумент. Использование:" + echo " $0 tray1 - установить Tray 1 (Upper)" + echo " $0 tray2 - установить Tray 2 (Lower)" + exit 1 +fi + +# Если уже установлен нужный лоток +if [ "$CURRENT_TRAY" = "$TARGET_TRAY" ]; then + echo "✅ Лоток уже установлен на $TRAY_NAME" + exit 0 +fi + +# Установить новый лоток +echo "🔄 Установка лотка на $TRAY_NAME..." +lpadmin -p "$HP_PRINTER" -o InputSlot="$TARGET_TRAY" 2>&1 + +# Проверить результат +sleep 1 +NEW_TRAY=$(lpoptions -p "$HP_PRINTER" -l 2>/dev/null | grep "InputSlot" | grep -o '\*[^*]*' | sed 's/*//' || echo "") + +if [ "$NEW_TRAY" = "$TARGET_TRAY" ]; then + echo "✅ Лоток успешно установлен на $TRAY_NAME" + echo "" + echo "📋 Текущие настройки:" + lpoptions -p "$HP_PRINTER" -l | grep InputSlot +else + echo "⚠️ Лоток может быть не изменен. Проверьте настройки:" + lpoptions -p "$HP_PRINTER" -l | grep InputSlot + echo "" + echo "💡 Если Lower не поддерживается, попробуйте:" + echo " 1. Установить официальный драйвер HP" + echo " 2. Изменить настройку в LibreOffice для каждого документа" + exit 1 +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/security/APPLE_SILICON_MAC_SPOOFING.md b/docs/security/APPLE_SILICON_MAC_SPOOFING.md new file mode 100644 index 0000000..9fff458 --- /dev/null +++ b/docs/security/APPLE_SILICON_MAC_SPOOFING.md @@ -0,0 +1,201 @@ +# Подмена MAC на Apple Silicon (M1/M2/M3) - Ограничения и решения + +## ❌ Проблема + +На MacBook с процессорами Apple Silicon (M1, M1 Pro, M1 Max, M2, M3 и т.д.) с включенным **System Integrity Protection (SIP)** подмена MAC-адреса Wi-Fi **заблокирована системой**. + +### Технические детали: + +- **macOS версия:** 15.3.1 (Sequoia) и новее +- **Процессор:** Apple Silicon (M1 Pro в вашем случае) +- **SIP статус:** Включен (enabled) +- **Результат:** `ifconfig en0 ether` команда не работает + +Это **защита безопасности** от Apple, которая предотвращает изменение низкоуровневых сетевых параметров. + +--- + +## 🔍 Почему это происходит? + +Apple Silicon использует **унифицированную память** и **более строгие ограничения безопасности**: +- SIP блокирует изменение сетевых параметров на уровне ядра +- Wi-Fi контроллер интегрирован в SoC и имеет дополнительные защиты +- macOS проверяет целостность сетевых интерфейсов + +--- + +## ✅ Решения + +### Вариант 1: Отключить SIP (НЕ рекомендуется) + +**⚠️ ВНИМАНИЕ:** Отключение SIP снижает безопасность системы и может сделать Mac уязвимым для атак. + +**Шаги:** +1. Перезагрузите Mac в **Recovery Mode**: + - Выключите Mac + - Включите и сразу зажмите **Cmd + R** + - Дождитесь загрузки Recovery Mode + +2. Откройте Терминал: + - Утилиты → Терминал + +3. Отключите SIP: + ```bash + csrutil disable + ``` + +4. Перезагрузите Mac: + ```bash + reboot + ``` + +5. После подмены MAC **включите SIP обратно**: + ```bash + csrutil enable + ``` + +**Проверка статуса SIP:** +```bash +csrutil status +``` + +--- + +### Вариант 2: VPN на телефоне (РЕКОМЕНДУЕТСЯ) ⭐ + +**Лучшее решение** - использовать VPN на телефоне вместо подмены MAC на MacBook: + +**Преимущества:** +- ✅ Не требует изменения настроек MacBook +- ✅ Весь трафик идет через VPN +- ✅ Оператор видит только VPN-соединение +- ✅ Не нарушает безопасность системы +- ✅ Работает на любом устройстве + +**Настройка:** +1. Установите VPN клиент на телефон (WireGuard, OpenVPN, Shadowsocks) +2. Подключите телефон к VPN +3. Включите точку доступа на телефоне +4. Подключите MacBook к hotspot + +**Результат:** Оператор видит только VPN-трафик, а не реальный трафик приложений. + +--- + +### Вариант 3: USB Tethering + +Используйте USB подключение вместо Wi-Fi: + +**Преимущества:** +- ✅ Не требует Wi-Fi +- ✅ MAC адрес не важен на этом уровне +- ✅ Более стабильное соединение +- ✅ Меньше энергопотребление + +**Настройка:** +1. Подключите телефон к MacBook через USB +2. На телефоне: Настройки → Режим модема → USB модем +3. MacBook автоматически определит соединение + +--- + +### Вариант 4: Bluetooth Tethering + +Альтернатива Wi-Fi hotspot: + +**Преимущества:** +- ✅ Разные протоколы идентификации +- ✅ Может быть менее заметно для оператора +- ✅ Не требует Wi-Fi + +**Настройка:** +1. На телефоне: Настройки → Режим модема → Bluetooth модем +2. На MacBook: Системные настройки → Bluetooth +3. Подключите устройства и включите модем + +--- + +## 📊 Что видит оператор? + +### Важно понимать: + +**Уровень сотовой сети (оператор видит):** +- ✅ **IMEI телефона** - уникальный идентификатор устройства +- ✅ **IMSI** - идентификатор SIM-карты +- ✅ **Номер телефона** +- ✅ **Трафик** идет через телефон + +**Уровень Wi-Fi (локальная сеть):** +- MAC точки доступа (BSSID) - MAC Wi-Fi интерфейса телефона +- MAC клиента (MacBook) - виден только в локальной Wi-Fi сети между телефоном и MacBook + +**Вывод:** +- Оператор **НЕ видит MAC MacBook** на уровне сотовой сети +- Оператор видит **IMEI телефона**, через который идет трафик +- Подмена MAC MacBook влияет только на локальный Wi-Fi уровень +- **Для оператора важнее IMEI телефона**, а не MAC клиента + +--- + +## 🛠️ Альтернативные инструменты + +### SpoofMAC (устарел) +Не работает на macOS 12+ и Apple Silicon. + +### Macchanger (через Homebrew) +```bash +brew install macchanger +``` +**Ограничения:** Тоже не работает с включенным SIP на Apple Silicon. + +--- + +## 📝 Рекомендации + +### Для максимальной приватности: + +1. **Используйте VPN на телефоне** ⭐ + - WireGuard, OpenVPN, Shadowsocks + - Весь трафик шифруется + - Оператор видит только VPN-соединение + +2. **Используйте USB Tethering** + - Более стабильно + - MAC не важен + +3. **Не отключайте SIP без крайней необходимости** + - Снижает безопасность системы + - Может сделать Mac уязвимым + +4. **Понимайте ограничения** + - Оператор все равно видит IMEI телефона + - MAC клиента виден только локально + +--- + +## 🔗 См. также + +- [MAC_SPOOFING_GUIDE.md](./MAC_SPOOFING_GUIDE.md) - общее руководство по подмене MAC +- [VPN документация](../vpn/README.md) - настройка VPN для приватности +- [SHADOWSOCKS.md](../vpn/SHADOWSOCKS.md) - Shadowsocks VPN + +--- + +## ❓ FAQ + +**Q: Почему подмена MAC не работает на моем M1 MacBook?** +A: Apple Silicon с включенным SIP блокирует изменение MAC адресов на уровне безопасности системы. + +**Q: Нужно ли отключать SIP?** +A: Нет, не рекомендуется. Используйте VPN на телефоне или USB Tethering. + +**Q: Оператор все равно увидит, что это не телефон?** +A: Оператор видит IMEI телефона, через который идет трафик. MAC MacBook виден только локально. + +**Q: Что лучше - VPN или подмена MAC?** +A: VPN на телефоне лучше - шифрует весь трафик и не требует изменения настроек MacBook. + +--- + +**Последнее обновление:** 2024-12-08 + diff --git a/docs/security/KODACHI_UTM_INSTALLATION.md b/docs/security/KODACHI_UTM_INSTALLATION.md new file mode 100644 index 0000000..2592c7e --- /dev/null +++ b/docs/security/KODACHI_UTM_INSTALLATION.md @@ -0,0 +1,317 @@ +# Установка Kodachi Linux в UTM на macOS + +Подробное руководство по установке Kodachi в существующую виртуальную машину UTM. + +--- + +## Предварительные требования + +- ✅ macOS (Intel или Apple Silicon) +- ✅ UTM установлен и запущен +- ✅ Минимум 4 ГБ свободной оперативной памяти +- ✅ 30+ ГБ свободного места на диске +- ✅ ISO-образ Kodachi Linux + +--- + +## Шаг 1: Загрузка ISO-образа Kodachi + +### ⚠️ ВАЖНО: Выбор версии Kodachi + +**Текущая ситуация с версиями (ноябрь 2025):** + +1. **Kodachi 9.0.1** (октябрь 2025) - **СЕРВЕРНАЯ версия БЕЗ GUI** + - ✅ Актуальная версия + - ❌ Только командная строка (CLI) + - ❌ Нет графического интерфейса + - ✅ Подходит для серверных задач + +2. **Kodachi 8.27** (февраль 2023) - **ДЕСКТОПНАЯ версия С GUI** + - ✅ Полноценный графический интерфейс XFCE + - ✅ Все инструменты для приватности и анонимности + - ⚠️ Устаревшая база (Ubuntu 18.04.6 LTS) + - ⚠️ Нет обновлений безопасности с февраля 2023 + - ⚠️ Потенциальные уязвимости + +3. **Kodachi 9 Desktop** - **В РАЗРАБОТКЕ** + - ⏳ Графическая версия Kodachi 9 еще не выпущена + - ⏳ Дата выхода неизвестна + +### Рекомендации по выбору версии: + +**Для работы с GUI (графическим интерфейсом):** +- Используйте **Kodachi 8.27** (если GUI критичен) +- ⚠️ Понимайте риски использования устаревшей версии +- Рассмотрите альтернативы: **Tails**, **Qubes OS**, **Whonix** + +**Для серверных задач:** +- Используйте **Kodachi 9.0.1** (актуальная, но только CLI) + +**Для максимальной приватности и стабильности:** +- Дождитесь выхода **Kodachi 9 Desktop** +- Или используйте альтернативные системы с актуальными обновлениями + +### Загрузка ISO-образа: + +1. Перейдите на официальный сайт Kodachi: **https://www.digi77.com/linux-kodachi/** +2. Выберите нужную версию: + - Для GUI: **Kodachi 8.27 Desktop ISO** + - Для сервера: **Kodachi 9.0.1 Server ISO** +3. Скачайте ISO-образ +4. Сохраните файл в удобном месте (например, `~/Downloads/kodachi-*.iso`) + +**Важно:** +- Проверьте целостность образа, если доступны checksums (SHA256) +- Убедитесь, что скачиваете версию с GUI, если нужен графический интерфейс + +--- + +## Шаг 2: Создание новой виртуальной машины в UTM + +### 2.1. Запуск мастера создания VM + +1. Откройте **UTM** +2. Нажмите кнопку **"+"** или **"Create a New Virtual Machine"** +3. Выберите **"Virtualize"** (не Emulate) + +### 2.2. Выбор операционной системы + +1. В разделе **"Operating System"** выберите **"Linux"** +2. UTM автоматически определит тип системы + +### 2.3. Настройка образа диска + +1. В разделе **"Linux"** выберите **"Use an existing disk image"** +2. Нажмите **"Browse"** и выберите скачанный ISO-образ Kodachi +3. Убедитесь, что образ отображается в списке + +### 2.4. Настройка ресурсов + +#### Память (RAM): +- **Минимум:** 2 ГБ +- **Рекомендуется:** 4 ГБ +- **Для комфортной работы:** 6-8 ГБ + +#### Процессор: +- **Ядра:** 2-4 ядра (в зависимости от вашего Mac) +- **Архитектура:** + - Intel Mac: **x86_64** + - Apple Silicon (M1/M2/M3): **ARM64** (если доступно) или **x86_64** (через эмуляцию) + +#### Диск: +- **Размер:** Минимум 30 ГБ, рекомендуется 40-50 ГБ +- **Тип:** QCOW2 (рекомендуется) или RAW + +### 2.5. Дополнительные настройки + +#### Сеть (Network): +- **Режим:** **Shared Network** (NAT) - для базовой работы +- **Для VPN/Tor:** Может потребоваться **Bridged** режим (требует дополнительных прав) + +#### Другие настройки: +- ✅ **Enable Clipboard Sharing** - для копирования текста +- ✅ **Enable Directory Sharing** (опционально) - для обмена файлами +- ⚠️ **Enable SPICE Agent** - для улучшенной интеграции + +--- + +## Шаг 3: Запуск и установка Kodachi + +### 3.1. Первый запуск + +1. Нажмите кнопку **"Play"** (▶️) для запуска виртуальной машины +2. Дождитесь загрузки Kodachi в Live режиме +3. Выберите язык и раскладку клавиатуры + +### 3.2. Установка на диск (рекомендуется) + +**Важно:** +- Kodachi можно использовать в Live режиме, но для сохранения данных и настроек рекомендуется установка на виртуальный диск +- ⚠️ **Если вы используете Kodachi 9.0.1 (серверную версию)**, графического установщика нет - используйте командную строку для установки + +**Для Kodachi 8.27 (с GUI):** + +1. На рабочем столе найдите иконку **"Install Kodachi"** +2. Запустите установщик +3. Следуйте инструкциям: + + **Шаги установки:** + - Выберите язык + - Выберите раскладку клавиатуры + - Выберите часовой пояс + - **Разметка диска:** + - Выберите виртуальный диск UTM + - Рекомендуется: **"Erase disk and install Kodachi"** (для виртуальной машины это безопасно) + - Или выберите **"Something else"** для ручной разметки + - Создайте пользователя и пароль + - Дождитесь завершения установки + +4. После установки перезагрузите виртуальную машину +5. Извлеките ISO-образ из настроек VM (чтобы загружаться с диска, а не с образа) + +--- + +## Шаг 4: Настройка сетевых функций (VPN/Tor) + +### 4.1. Проверка сетевого подключения + +1. Убедитесь, что виртуальная машина имеет доступ к интернету +2. Проверьте статус VPN и Tor в панели мониторинга Kodachi + +### 4.2. Настройка VPN (если требуется) + +1. Откройте настройки VPN в Kodachi +2. Добавьте конфигурацию VPN (если не предустановлена) +3. Убедитесь, что VPN активирован + +### 4.3. Настройка Tor + +1. Tor должен быть предустановлен и настроен +2. Проверьте статус в индикаторах Kodachi +3. Весь трафик должен автоматически проходить через Tor + +**Важно:** В виртуальной машине некоторые сетевые функции могут работать иначе, чем на физическом оборудовании. Протестируйте подключение. + +--- + +## Шаг 5: Оптимизация производительности + +### 5.1. Настройки UTM для лучшей производительности + +1. В настройках VM включите: + - ✅ **Hardware Acceleration** (если доступно) + - ✅ **Enable Hypervisor Framework** (для Apple Silicon) + - ✅ **Enable JIT** (для Apple Silicon) + +### 5.2. Настройки Kodachi + +1. Закройте ненужные приложения +2. Используйте легковесные альтернативы приложений +3. Настройте автозагрузку программ + +--- + +## Шаг 6: Создание снимков (Snapshots) + +**Рекомендуется:** Создайте снимок виртуальной машины после успешной установки. + +1. В UTM остановите виртуальную машину +2. Выберите VM в списке +3. Нажмите **"Take Snapshot"** или используйте меню +4. Дайте снимку понятное имя (например, "Fresh Install") + +Это позволит быстро вернуться к рабочему состоянию в случае проблем. + +--- + +## Решение проблем + +### Проблема: Виртуальная машина не загружается + +**Решения:** +- Проверьте, что ISO-образ не поврежден +- Убедитесь, что выбрана правильная архитектура (x86_64 или ARM64) +- Попробуйте пересоздать виртуальную машину + +### Проблема: Медленная работа + +**Решения:** +- Увеличьте объем выделенной RAM (минимум 4 ГБ) +- Увеличьте количество ядер процессора +- Убедитесь, что включена аппаратная виртуализация +- Закройте другие приложения на Mac + +### Проблема: Не работает сеть / VPN / Tor + +**Решения:** +- Проверьте настройки сети в UTM (Shared Network должен работать) +- Убедитесь, что хост-система (macOS) имеет доступ к интернету +- Попробуйте перезапустить сетевые службы в Kodachi +- Проверьте настройки VPN/Tor в Kodachi + +### Проблема: Не работает общий буфер обмена + +**Решения:** +- Убедитесь, что включен **"Enable Clipboard Sharing"** в настройках UTM +- Установите SPICE Guest Tools в Kodachi (если доступны) +- Перезапустите виртуальную машину + +### Проблема: На Apple Silicon Mac низкая производительность + +**Решения:** +- Используйте ARM64 версию Kodachi (если доступна) +- Или используйте VMware Fusion вместо UTM для лучшей производительности +- Увеличьте выделенные ресурсы + +--- + +## Важные замечания + +### Безопасность в виртуальной машине + +⚠️ **Важно понимать:** +- Виртуализация добавляет дополнительный слой, который может влиять на безопасность +- Некоторые функции Kodachi (например, затирание RAM) могут работать иначе в VM +- Для максимальной безопасности рекомендуется использовать Kodachi на физическом оборудовании или в Live режиме с USB + +### Сохранение данных + +- Данные в виртуальной машине хранятся в файле образа диска UTM +- Регулярно создавайте резервные копии файла VM +- Используйте снимки (snapshots) для защиты от потери данных + +### Производительность + +- UTM на Apple Silicon работает быстрее, чем на Intel Mac +- Для лучшей производительности используйте VMware Fusion +- Выделяйте достаточно ресурсов для комфортной работы + +--- + +## Полезные команды в Kodachi + +После установки вы можете использовать следующие команды в терминале: + +```bash +# Проверка статуса VPN +sudo systemctl status vpn + +# Проверка статуса Tor +sudo systemctl status tor + +# Проверка IP-адреса +curl ifconfig.me + +# Обновление системы +sudo apt update && sudo apt upgrade + +# Перезапуск сетевых служб +sudo systemctl restart networking +``` + +--- + +## Дополнительные ресурсы + +- **Официальный сайт Kodachi:** https://www.digi77.com/linux-kodachi/ +- **Документация UTM:** https://docs.getutm.app/ +- **Форум поддержки UTM:** https://github.com/utmapp/UTM/discussions + +--- + +## Быстрая справка + +| Действие | Где найти | +|----------|-----------| +| Создать новую VM | Кнопка "+" в UTM | +| Добавить ISO | Settings → Drives → CD/DVD | +| Изменить RAM | Settings → System → Memory | +| Изменить CPU | Settings → System → CPU Cores | +| Создать снимок | VM → Take Snapshot | +| Настройки сети | Settings → Network | +| Общий буфер | Settings → Input/Output → Clipboard Sharing | + +--- + +**Успешной установки! 🚀** + diff --git a/docs/security/MAC_SPOOFING_GUIDE.md b/docs/security/MAC_SPOOFING_GUIDE.md new file mode 100644 index 0000000..1fc8166 --- /dev/null +++ b/docs/security/MAC_SPOOFING_GUIDE.md @@ -0,0 +1,297 @@ +# Руководство по подмене MAC-адреса Wi-Fi на macOS + +## 📋 Содержание +1. [Зачем это нужно](#зачем-это-нужно) +2. [Как это работает](#как-это-работает) +3. [Получение MAC-адреса телефона](#получение-mac-адреса-телефона) +4. [Подмена MAC на macOS](#подмена-mac-на-macos) +5. [Ограничения и проблемы](#ограничения-и-проблемы) +6. [Постоянная подмена MAC](#постоянная-подмена-mac) + +--- + +## Зачем это нужно + +Когда вы подключаете MacBook к точке доступа (hotspot) телефона: +- **Оператор сотовой связи** видит трафик, идущий через телефон +- **MAC-адрес MacBook** виден только на уровне Wi-Fi соединения между телефоном и MacBook +- Подмена MAC MacBook на MAC телефона может помочь в некоторых сценариях идентификации + +**Важно:** Оператор в первую очередь видит IMEI и другие идентификаторы телефона, а не MAC клиента. + +--- + +## Как это работает + +### Уровни идентификации: + +1. **Уровень сотовой сети (оператор видит):** + - IMEI телефона + - IMSI (SIM-карта) + - Номер телефона + - Трафик идет через телефон + +2. **Уровень Wi-Fi (локальная сеть):** + - MAC точки доступа (BSSID) - это MAC Wi-Fi интерфейса телефона + - MAC клиента (MacBook) - виден только в локальной Wi-Fi сети + +3. **Уровень приложений:** + - User-Agent браузера + - Fingerprint браузера + - IP-адрес (от оператора) + +**Вывод:** Подмена MAC MacBook на MAC телефона влияет только на локальный Wi-Fi уровень, но не меняет идентификацию на уровне оператора. + +--- + +## Получение MAC-адреса телефона + +### iPhone (iOS 14+) + +**Проблема:** На iPhone включена функция "Частный Wi-Fi адрес" по умолчанию, которая скрывает реальный MAC. + +**Решение:** + +1. **Для Wi-Fi клиента (когда телефон подключается к сети):** + - Настройки → Wi-Fi + - Нажмите (i) рядом с сетью + - Отключите "Частный Wi-Fi адрес" (Private Wi-Fi Address) + - MAC-адрес будет показан как "Адрес Wi-Fi" + +2. **Для точки доступа (hotspot):** + - MAC точки доступа может отличаться от MAC Wi-Fi клиента + - Настройки → Режим модема → "Имя сети" показывает SSID + - MAC точки доступа можно узнать через скрипт (автоматически) + +**Альтернативный способ:** +```bash +# На MacBook, подключенном к hotspot iPhone: +/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep BSSID +``` + +### Android + +1. **Для Wi-Fi клиента:** + - Настройки → О телефоне → Статус + - Найдите "MAC-адрес Wi-Fi" + +2. **Для точки доступа:** + - Настройки → Сеть и интернет → Точка доступа и модем → Точка доступа Wi-Fi + - MAC может быть показан в расширенных настройках + +**Через ADB (если включена отладка):** +```bash +adb shell ip link show wlan0 | grep link/ether +``` + +--- + +## Подмена MAC на macOS + +### Автоматический способ (рекомендуется) + +Используйте скрипт `spoof-wifi-mac.sh`: + +```bash +# Автоматическое определение MAC точки доступа +./docs/security/spoof-wifi-mac.sh --phone-mac + +# Или интерактивный режим +./docs/security/spoof-wifi-mac.sh + +# Или указать MAC вручную +./docs/security/spoof-wifi-mac.sh AA:BB:CC:DD:EE:FF + +# Вернуть оригинальный MAC +./docs/security/spoof-wifi-mac.sh --revert +``` + +### Ручной способ + +```bash +# 1. Определить Wi-Fi интерфейс +networksetup -listallhardwareports | grep -A 1 "Wi-Fi" + +# 2. Выключить Wi-Fi +networksetup -setairportpower en0 off + +# 3. Установить новый MAC (требует sudo) +sudo ifconfig en0 ether AA:BB:CC:DD:EE:FF + +# 4. Включить Wi-Fi +networksetup -setairportpower en0 on + +# 5. Проверить +ifconfig en0 | grep ether +``` + +--- + +## Ограничения и проблемы + +### 1. Временность подмены + +- MAC сбрасывается после: + - Перезагрузки MacBook + - Отключения/включения Wi-Fi + - Переподключения к сети + - Смены сети + +**Решение:** Используйте `--revert` для восстановления или запускайте скрипт при каждом подключении. + +### 2. System Integrity Protection (SIP) + +На современных версиях macOS (особенно с Apple Silicon) подмена MAC может быть заблокирована SIP. + +**Проверка статуса SIP:** +```bash +csrutil status +``` + +**Отключение SIP (НЕ рекомендуется без крайней необходимости):** +1. Перезагрузите Mac в Recovery Mode (Cmd+R при загрузке) +2. Утилиты → Терминал +3. `csrutil disable` +4. Перезагрузите + +**Включение обратно:** +```bash +csrutil enable +``` + +### 3. Аппаратные ограничения + +Некоторые Wi-Fi чипы не поддерживают подмену MAC на уровне драйвера. + +### 4. Что видит оператор + +**Важно понимать:** +- Оператор видит трафик через телефон (IMEI, IMSI) +- MAC MacBook виден только в локальной Wi-Fi сети между телефоном и MacBook +- Подмена MAC не меняет идентификацию на уровне оператора +- Для оператора важнее IMEI телефона, а не MAC клиента + +--- + +## Постоянная подмена MAC + +### Вариант 1: LaunchAgent (автоматический запуск) + +Создайте `~/Library/LaunchAgents/com.macspoof.plist`: + +```xml +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.macspoof</string> + <key>ProgramArguments</key> + <array> + <string>/path/to/spoof-wifi-mac.sh</string> + <string>AA:BB:CC:DD:EE:FF</string> + </array> + <key>RunAtLoad</key> + <true/> + <key>KeepAlive</key> + <false/> +</dict> +</plist> +``` + +Загрузите: +```bash +launchctl load ~/Library/LaunchAgents/com.macspoof.plist +``` + +### Вариант 2: Network Script (macOS) + +Создайте скрипт в `/etc/network/` (требует отключения SIP). + +### Вариант 3: Использование специализированных инструментов + +- **SpoofMAC** (устарел, не работает на новых macOS) +- **Macchanger** (через Homebrew, ограниченная поддержка) + +--- + +## Альтернативные подходы + +### 1. Использование VPN на телефоне + +Вместо подмены MAC на MacBook, используйте VPN на телефоне: +- Весь трафик идет через VPN +- Оператор видит только VPN-соединение +- Не требуется подмена MAC + +### 2. USB Tethering + +Подключите телефон через USB и используйте USB Tethering: +- Не требует Wi-Fi +- MAC не важен на этом уровне +- Более стабильное соединение + +### 3. Bluetooth Tethering + +Альтернатива Wi-Fi hotspot: +- Разные протоколы идентификации +- Может быть менее заметно для оператора + +--- + +## Проверка результата + +### Проверить текущий MAC: +```bash +ifconfig en0 | grep ether +``` + +### Проверить MAC точки доступа: +```bash +/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep BSSID +``` + +### Проверить подключение: +```bash +networksetup -getairportnetwork en0 +``` + +--- + +## Безопасность и предупреждения + +⚠️ **Важно:** +- Подмена MAC может нарушать правила оператора +- Некоторые сети могут блокировать устройства с подмененным MAC +- Это может быть незаконно в некоторых юрисдикциях +- Используйте только на своих устройствах и сетях + +✅ **Рекомендации:** +- Сохраняйте оригинальный MAC для восстановления +- Используйте только для легитимных целей +- Понимайте ограничения метода +- Рассмотрите альтернативные подходы (VPN, USB tethering) + +--- + +## FAQ + +**Q: Оператор все равно видит, что это не телефон?** +A: Да, оператор видит IMEI телефона и трафик через него. MAC клиента важен только на локальном Wi-Fi уровне. + +**Q: Почему MAC не меняется?** +A: Возможно, требуется отключить SIP или Wi-Fi чип не поддерживает подмену MAC. + +**Q: Как сделать подмену постоянной?** +A: Используйте LaunchAgent или отключите SIP (не рекомендуется). + +**Q: Работает ли это на Apple Silicon?** +A: Может потребоваться отключение SIP из-за более строгих ограничений безопасности. + +--- + +## См. также + +- [OS_COMPARISON.md](./OS_COMPARISON.md) - сравнение систем безопасности +- [VPN документация](../vpn/README.md) - альтернативные методы защиты приватности + diff --git a/docs/security/OS_COMPARISON.md b/docs/security/OS_COMPARISON.md new file mode 100644 index 0000000..ffebab1 --- /dev/null +++ b/docs/security/OS_COMPARISON.md @@ -0,0 +1,501 @@ +# Сравнение операционных систем для установки на Mac + +## Kali Linux vs Kodachi vs Tails + +Сравнение трех операционных систем с точки зрения удобства UI, функциональности и безопасности при установке на Mac. + +--- + +## 1. Удобство пользовательского интерфейса (UI) + +### Kali Linux +- **Окружения рабочего стола**: XFCE, GNOME, KDE (на выбор) +- **Оценка**: ⭐⭐⭐⭐ +- **Особенности**: + - Гибкость выбора интерфейса в зависимости от предпочтений + - XFCE - легкий и быстрый, подходит для слабых машин + - GNOME - современный и функциональный + - KDE - настраиваемый и мощный + - Интерфейс ориентирован на профессионалов, может быть сложен для новичков + - Множество инструментов в меню может перегружать интерфейс + +### Kodachi Linux +- **Окружения рабочего стола**: XFCE (на базе Xubuntu) +- **Оценка**: ⭐⭐⭐⭐⭐ +- **Важно о версиях:** + - ⚠️ **Kodachi 9.0.1** (октябрь 2025) - **СЕРВЕРНАЯ версия БЕЗ GUI** (только CLI) + - ✅ **Kodachi 8.27** - имеет полноценный GUI (XFCE), но устаревшая (последнее обновление: февраль 2023) + - ⏳ **Kodachi 9 Desktop** - GUI-версия еще не выпущена (в разработке) +- **Особенности**: + - Легкий и интуитивно понятный интерфейс XFCE (только в версии 8.27) + - Встроенные мониторы статуса сети и системы в реальном времени + - Информативные индикаторы состояния VPN и Tor + - Хорошо подходит для пользователей с разным уровнем подготовки + - Чистый и минималистичный дизайн +- **Рекомендация по версиям:** + - Для GUI: используйте **Kodachi 8.27** (устаревшая, но с графикой) + - Для сервера: используйте **Kodachi 9.0.1** (актуальная, но без GUI) + - Для приватности и стабильности: рассмотрите альтернативы (Tails, Qubes OS) или дождитесь Kodachi 9 Desktop + +### Tails +- **Окружения рабочего стола**: GNOME +- **Оценка**: ⭐⭐⭐⭐ +- **Особенности**: + - Современный и интуитивный интерфейс GNOME + - Упрощенный дизайн, ориентированный на минимализм + - Простота использования для новичков + - Схожесть с популярными операционными системами облегчает адаптацию + - Меньше визуальных элементов, фокус на функциональности + +**Победитель по UI**: **Kodachi** - лучший баланс между функциональностью и удобством использования + +--- + +## 2. Функциональность + +### Kali Linux +- **Оценка**: ⭐⭐⭐⭐⭐ +- **Основное назначение**: Тестирование на проникновение и аудит безопасности +- **Инструменты**: + - Более 600 предустановленных инструментов для пентестинга + - Инструменты для анализа сетей, веб-приложений, криптографии + - Среды разработки для создания эксплойтов + - Инструменты для форензики и анализа данных +- **Применение**: + - Профессиональное тестирование безопасности + - Обучение кибербезопасности + - Аудит систем и сетей + - Разработка и тестирование защитных механизмов +- **Ограничения**: + - Не предназначена для повседневного использования + - Не обеспечивает анонимность по умолчанию + - Требует глубоких знаний для эффективного использования + +### Kodachi Linux +- **Оценка**: ⭐⭐⭐⭐ +- **Основное назначение**: Анонимность и безопасность в интернете +- **Важно о версиях:** + - **Kodachi 8.27** (GUI): Полноценный графический интерфейс XFCE, но устаревшая база (Ubuntu 18.04.6 LTS) + - **Kodachi 9.0.1** (CLI): Только серверная версия без GUI, актуальная база + - **Kodachi 9 Desktop**: В разработке, дата выхода неизвестна +- **Инструменты** (в версии 8.27 с GUI): + - Принудительный VPN (предустановлен) + - Сеть Tor с дополнительной защитой + - Технология Multi Tor (выбор выходного узла по стране) + - Автоматическая смена MAC-адреса + - Затирание оперативной памяти + - Экстренное прекращение работы системы + - Инструменты для защиты от анализа трафика + - Tor Browser, DNSCrypt, приложения для шифрования +- **Применение**: + - Анонимный серфинг в интернете + - Защита конфиденциальности + - Обход цензуры и географических ограничений + - Безопасная работа с конфиденциальными данными +- **Ограничения**: + - Меньше инструментов для пентестинга, чем в Kali + - Ориентирована на анонимность, а не на тестирование безопасности + - ⚠️ **Kodachi 8.27 устарела** (нет обновлений с февраля 2023) - риски безопасности + - ⚠️ **Kodachi 9.0.1 не имеет GUI** - только командная строка + +### Tails +- **Оценка**: ⭐⭐⭐ +- **Основное назначение**: Максимальная анонимность и конфиденциальность +- **Инструменты**: + - Tor Browser (предустановлен) + - Принудительное перенаправление всего трафика через Tor + - Инструменты для безопасной работы с данными + - Шифрование дисков + - Защита от восстановления данных +- **Применение**: + - Анонимная работа в интернете + - Защита конфиденциальности + - Работа с конфиденциальными документами + - Обход цензуры +- **Ограничения**: + - Очень ограниченный набор инструментов + - Не предназначена для установки (только Live режим) + - Не подходит для профессиональной работы с инструментами безопасности + +**Победитель по функциональности**: **Kali Linux** - для профессиональных задач; **Kodachi** - для баланса функциональности и анонимности + +--- + +## 3. Безопасность + +### Kali Linux +- **Оценка**: ⭐⭐⭐ +- **Особенности безопасности**: + - Мощные инструменты для тестирования безопасности + - Регулярные обновления безопасности + - Поддержка шифрования дисков + - Не обеспечивает анонимность по умолчанию + - Не защищает от отслеживания + - Может оставлять следы на системе +- **Риски**: + - Не предназначена для защиты данных пользователя + - Отсутствие встроенной анонимности + - Требует дополнительной настройки для обеспечения приватности + +### Kodachi Linux +- **Оценка**: ⭐⭐⭐⭐⭐ +- **Особенности безопасности**: + - Принудительное перенаправление трафика через VPN + Tor + - Автоматическая смена MAC-адреса + - Затирание оперативной памяти при выключении + - Защита от криминалистического анализа + - Экстренное прекращение работы + - Защита от утечек DNS + - Multi Tor для выбора выходного узла +- **Риски**: + - Зависимость от надежности VPN-провайдера + - Возможные проблемы с производительностью из-за двойного туннелирования + +### Tails +- **Оценка**: ⭐⭐⭐⭐⭐ +- **Особенности безопасности**: + - Работа в режиме Live (не оставляет следов на диске) + - Принудительное перенаправление всего трафика через Tor + - Автоматическое стирание данных из RAM при выключении + - Не сохраняет историю и данные на используемом компьютере + - Защита от восстановления данных + - Шифрование персистентного хранилища (опционально) +- **Риски**: + - Зависимость от надежности сети Tor + - Ограниченная функциональность может вынуждать использовать другие системы + +**Победитель по безопасности**: **Tails** и **Kodachi** (равны) - максимальная защита анонимности и конфиденциальности + +--- + +## 4. Установка на Mac + +### Kali Linux +- **Способы установки**: + 1. Виртуализация через Parallels Desktop (рекомендуется) + 2. Двойная загрузка (более сложно) + 3. USB Live режим +- **Сложность**: ⭐⭐⭐⭐ +- **Особенности**: + - При установке могут не работать встроенные клавиатура и мышь без драйверов + - Рекомендуется использовать внешние устройства ввода + - Требует настройки разделов диска + - Хорошая производительность в виртуальной машине +- **Совместимость**: Хорошая с виртуализацией, средняя при прямой установке + +### Kodachi Linux +- **Способы установки**: + 1. USB Live режим (рекомендуется) + 2. Виртуализация + 3. Установка на диск (опционально) +- **Сложность**: ⭐⭐⭐ +- **Особенности**: + - Оптимизирована для работы в Live режиме + - Не требует установки для базового использования + - Может потребоваться дополнительная настройка для полной совместимости с Mac + - Гибкость в использовании +- **Совместимость**: Хорошая в Live режиме, средняя при установке + +### Tails +- **Способы установки**: + 1. USB Live режим (единственный способ) + 2. Виртуализация (не рекомендуется для безопасности) +- **Сложность**: ⭐⭐⭐ +- **Особенности**: + - Предназначена только для Live режима + - Не оставляет следов на используемом компьютере + - Могут возникнуть проблемы с загрузкой на некоторых моделях Mac + - Особенности загрузчика Mac могут требовать дополнительной настройки +- **Совместимость**: Средняя (зависит от модели Mac) + +--- + +## Итоговое сравнение + +| Критерий | Kali Linux | Kodachi | Tails | +|----------|------------|---------|-------| +| **Удобство UI** | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | +| **Функциональность** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | +| **Безопасность** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **Установка на Mac** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | +| **Анонимность** | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **Инструменты пентестинга** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐ | + +--- + +## Установка без использования флешек (USB) + +Для работы на macOS без использования USB-накопителей доступны следующие варианты: + +### Варианты установки + +#### 1. Виртуализация (Рекомендуется) +**Программное обеспечение:** +- **Parallels Desktop** (платное, лучшая производительность на Mac) +- **VMware Fusion** (платное/бесплатное для личного использования) +- **VirtualBox** (бесплатное, но менее производительное) + +**Преимущества:** +- ✅ Изоляция от основной системы macOS +- ✅ Легкое переключение между системами +- ✅ Снимки состояния (snapshots) для отката изменений +- ✅ Не требует изменения разделов диска +- ✅ Безопасность - виртуальная машина изолирована + +**Недостатки:** +- ❌ Требует больше ресурсов (RAM, CPU) +- ❌ Меньшая производительность по сравнению с нативной установкой +- ❌ Для Tails виртуализация снижает уровень безопасности + +#### 2. Двойная загрузка (Boot Camp / rEFInd) +**Способы:** +- Boot Camp (только для Windows, не подходит для Linux) +- rEFInd или OpenCore (для Linux) +- Создание отдельного раздела на диске + +**Преимущества:** +- ✅ Полная производительность системы +- ✅ Прямой доступ к оборудованию +- ✅ Нет накладных расходов виртуализации + +**Недостатки:** +- ❌ Сложная установка и настройка +- ❌ Риск повреждения загрузчика macOS +- ❌ Требует изменения разделов диска +- ❌ Проблемы с драйверами на некоторых моделях Mac + +--- + +## Рекомендации для работы БЕЗ флешек + +### 🥇 Лучший выбор: **Kali Linux** (виртуализация) + +**Почему:** +- ✅ Отлично работает в виртуальной машине +- ✅ Поддерживается Parallels Desktop с версии 17.1.1 +- ✅ Все драйверы работают корректно (Wi-Fi, буфер обмена, сеть) +- ✅ Хорошая производительность в виртуальной среде +- ✅ Можно использовать для профессиональной работы + +**Рекомендуемая конфигурация:** +- **Parallels Desktop** или **VMware Fusion** +- Минимум 4 ГБ RAM для виртуальной машины (рекомендуется 8 ГБ) +- 40+ ГБ дискового пространства +- Внешние устройства ввода (клавиатура/мышь) для начальной установки + +**Оценка для работы без флешек**: ⭐⭐⭐⭐⭐ + +--- + +### 🥈 Второй выбор: **Kodachi** (виртуализация или установка на диск) + +**⚠️ КРИТИЧЕСКИ ВАЖНО: Ситуация с версиями и GUI** + +**Текущее состояние (ноябрь 2025):** + +| Версия | GUI | Статус | Рекомендация | +|--------|-----|--------|--------------| +| **Kodachi 9.0.1** (окт 2025) | ❌ НЕТ (только CLI) | Актуальная | Только для серверов | +| **Kodachi 8.27** (фев 2023) | ✅ ЕСТЬ (XFCE) | Устаревшая | ⚠️ Риски безопасности | +| **Kodachi 9 Desktop** | ✅ Будет | В разработке | ⏳ Ждать выхода | + +**Что есть из коробки с GUI:** +- ✅ **Kodachi 8.27** - полноценный графический интерфейс XFCE + - Рабочий стол с панелью задач + - Меню приложений + - Индикаторы VPN/Tor статуса + - Графические инструменты для настройки + - Tor Browser с GUI + - Файловый менеджер + - Терминал с графическим интерфейсом + +- ❌ **Kodachi 9.0.1** - только командная строка + - Нет графического интерфейса + - Только CLI-инструменты + - Подходит только для серверных задач + +**Рекомендации:** + +**Для работы с GUI:** +- Используйте **Kodachi 8.27** (если GUI критичен) +- ⚠️ **Понимайте риски:** устаревшая база Ubuntu 18.04, нет обновлений безопасности +- Рассмотрите альтернативы: **Tails** (актуальная, с GUI), **Qubes OS**, **Whonix** + +**Для приватности и стабильности:** +- Дождитесь **Kodachi 9 Desktop** (дата выхода неизвестна) +- Или используйте **Tails** - актуальная система с GUI и максимальной приватностью + +**Почему Kodachi (8.27 с GUI):** +- ✅ Можно установить на диск или использовать в виртуализации +- ✅ Хорошая совместимость с виртуальными машинами +- ✅ Сохраняет функции анонимности в виртуальной среде +- ✅ Удобный интерфейс для повседневной работы +- ⚠️ Но версия 8.27 устарела и может иметь уязвимости + +**Рекомендации:** +- **Виртуализация**: Подходит для тестирования и периодического использования +- **Установка на диск**: Если нужна постоянная работа с анонимностью +- Может потребоваться дополнительная настройка VPN/Tor в виртуальной машине +- ⚠️ **Для продакшена:** рассмотрите альтернативы с актуальными обновлениями + +**Оценка для работы без флешек**: ⭐⭐⭐⭐ (с оговоркой об устаревшей версии 8.27) + +#### Сравнение виртуализации для Kodachi: UTM vs VirtualBox vs VMware Fusion + +| Критерий | UTM | VirtualBox | VMware Fusion | +|----------|-----|-----------|---------------| +| **Стоимость** | ✅ Бесплатно (Open Source) | ✅ Бесплатно | ❌ Платно ($199) / ✅ Бесплатно для личного использования | +| **Поддержка Apple Silicon** | ✅✅ Отличная (нативная) | ⚠️ Ограниченная | ✅✅ Отличная (нативная) | +| **Поддержка Intel Mac** | ✅ Хорошая | ✅✅ Отличная | ✅✅ Отличная | +| **Производительность** | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **Простота настройки** | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **Стабильность** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **Интеграция с macOS** | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **Поддержка сетевых функций** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **Техническая поддержка** | ❌ Сообщество | ⚠️ Ограниченная | ✅✅ Официальная | + +##### 🥇 VMware Fusion (Рекомендуется) + +**Преимущества:** +- ✅✅ **Лучшая производительность** - оптимизировано специально для Mac +- ✅✅ **Нативная поддержка Apple Silicon** (M1/M2/M3) и Intel +- ✅✅ **Отличная интеграция с macOS** - общий буфер обмена, drag & drop +- ✅✅ **Стабильная работа сетевых функций** - важно для VPN/Tor в Kodachi +- ✅✅ **Простой и интуитивный интерфейс** +- ✅✅ **Официальная техническая поддержка** +- ✅ **Бесплатная версия для личного использования** (VMware Fusion Player) +- ✅ **Хорошая поддержка USB-устройств** (если понадобится) + +**Недостатки:** +- ❌ Платная версия для коммерческого использования ($199) +- ⚠️ Требует больше ресурсов, чем VirtualBox + +**Оценка для Kodachi**: ⭐⭐⭐⭐⭐ + +**Рекомендация**: Лучший выбор для Kodachi, особенно на Apple Silicon Mac. Бесплатная версия для личного использования покрывает большинство потребностей. + +--- + +##### 🥈 UTM (Второй выбор) + +**Преимущества:** +- ✅✅ **Полностью бесплатно** и с открытым исходным кодом +- ✅✅ **Отличная поддержка Apple Silicon** (нативная эмуляция) +- ✅ **Современный интерфейс**, похожий на Parallels +- ✅ **Активная разработка** и поддержка сообщества +- ✅ **Поддержка различных архитектур** (x86_64, ARM64) + +**Недостатки:** +- ⚠️ **Более сложная настройка** по сравнению с VMware +- ⚠️ **Меньшая производительность**, чем у VMware Fusion +- ❌ **Нет официальной технической поддержки** +- ⚠️ **Может потребоваться ручная настройка сетевых функций** для VPN/Tor + +**Оценка для Kodachi**: ⭐⭐⭐⭐ + +**Рекомендация**: Хороший бесплатный выбор, особенно на Apple Silicon. Подходит, если нужна бесплатная альтернатива VMware. + +--- + +##### 🥉 VirtualBox (Третий выбор) + +**Преимущества:** +- ✅✅ **Полностью бесплатно** и кроссплатформенное +- ✅ **Простой и знакомый интерфейс** +- ✅ **Хорошая поддержка на Intel Mac** +- ✅ **Большое сообщество** и множество руководств +- ✅ **Легковесное** решение + +**Недостатки:** +- ❌ **Ограниченная поддержка Apple Silicon** - работает через Rosetta 2, низкая производительность +- ⚠️ **Меньшая производительность**, чем у VMware и UTM +- ⚠️ **Проблемы с сетевыми функциями** на новых версиях macOS +- ⚠️ **Может быть нестабильным** на macOS Ventura и новее +- ⚠️ **Сложности с USB-устройствами** на новых Mac + +**Оценка для Kodachi**: ⭐⭐⭐ (на Intel Mac), ⭐⭐ (на Apple Silicon) + +**Рекомендация**: Подходит только для Intel Mac. На Apple Silicon лучше выбрать UTM или VMware Fusion. + +--- + +### Итоговая рекомендация для Kodachi: + +#### На Apple Silicon Mac (M1/M2/M3): +1. **VMware Fusion Player** (бесплатно для личного использования) - лучший выбор +2. **UTM** - хорошая бесплатная альтернатива + +#### На Intel Mac: +1. **VMware Fusion Player** (бесплатно для личного использования) - лучший выбор +2. **VirtualBox** - бесплатная альтернатива, но менее производительная +3. **UTM** - также работает, но может быть избыточным + +**Важно для Kodachi**: Убедитесь, что выбранная виртуализация правильно передает сетевые интерфейсы для работы VPN и Tor. VMware Fusion лучше всего справляется с этим. + +--- + +### ⚠️ НЕ рекомендуется: **Tails** (без флешек) + +**Почему НЕ рекомендуется:** +- ❌ **Tails специально разработана для Live режима с USB** +- ❌ Виртуализация снижает уровень безопасности (может оставлять следы) +- ❌ Противоречит основной концепции системы (не оставлять следов) +- ❌ Разработчики Tails не рекомендуют виртуализацию для безопасности +- ❌ Установка на диск возможна, но теряется главное преимущество (не оставлять следов) + +**Если всё же необходимо:** +- Можно использовать виртуализацию для тестирования, но **НЕ для реальной работы с конфиденциальными данными** +- Установка на диск возможна, но система потеряет основное преимущество + +**Оценка для работы без флешек**: ⭐⭐ (не рекомендуется) + +--- + +## Итоговая рекомендация для работы БЕЗ флешек + +### Для пентестинга и безопасности: +**→ Kali Linux в Parallels Desktop или VMware Fusion** + +### Для анонимности и конфиденциальности: +**→ Kodachi в виртуализации или установка на диск** + +### Для максимальной анонимности: +**→ Используйте Tails с USB (безопасность важнее удобства)** + +--- + +## Рекомендации по выбору + +### Выберите **Kali Linux**, если: +- Вы специалист по кибербезопасности +- Вам нужны инструменты для тестирования на проникновение +- Вы проводите аудит безопасности +- Анонимность не является приоритетом +- Готовы к более сложной установке + +### Выберите **Kodachi**, если: +- Вам нужен баланс между функциональностью и анонимностью +- Важна защита конфиденциальности в интернете +- Нужна гибкость в использовании (Live или установка) +- Хотите удобный интерфейс с информативными индикаторами +- Нужен выбор выходного узла Tor по стране + +### Выберите **Tails**, если: +- Максимальная анонимность - главный приоритет +- Вы не хотите оставлять следы на компьютере +- Нужна простота использования +- Вы работаете с конфиденциальными данными +- Готовы к ограниченной функциональности ради безопасности + +--- + +## Заключение + +Каждая из этих операционных систем имеет свои сильные стороны: + +- **Kali Linux** - лучший выбор для профессиональной работы с инструментами безопасности +- **Kodachi** - оптимальный баланс между функциональностью, удобством и безопасностью +- **Tails** - максимальная анонимность и конфиденциальность + +Выбор зависит от ваших конкретных потребностей и приоритетов. + diff --git a/docs/security/Screenshot 2025-11-21 at 00.41.19.png b/docs/security/Screenshot 2025-11-21 at 00.41.19.png new file mode 100644 index 0000000..b10ad68 Binary files /dev/null and b/docs/security/Screenshot 2025-11-21 at 00.41.19.png differ diff --git a/docs/security/Screenshot 2025-11-21 at 00.41.37.png b/docs/security/Screenshot 2025-11-21 at 00.41.37.png new file mode 100644 index 0000000..508da6b Binary files /dev/null and b/docs/security/Screenshot 2025-11-21 at 00.41.37.png differ diff --git a/docs/security/Screenshot 2025-11-21 at 18.58.58.png b/docs/security/Screenshot 2025-11-21 at 18.58.58.png new file mode 100644 index 0000000..04586e2 Binary files /dev/null and b/docs/security/Screenshot 2025-11-21 at 18.58.58.png differ diff --git a/docs/security/Screenshot 2025-11-21 at 18.59.10.png b/docs/security/Screenshot 2025-11-21 at 18.59.10.png new file mode 100644 index 0000000..e521257 Binary files /dev/null and b/docs/security/Screenshot 2025-11-21 at 18.59.10.png differ diff --git a/docs/security/find-phone-mac.sh b/docs/security/find-phone-mac.sh new file mode 100755 index 0000000..2367461 --- /dev/null +++ b/docs/security/find-phone-mac.sh @@ -0,0 +1,92 @@ +#!/bin/zsh +# Helper script to find phone MAC address +# Tries multiple methods to detect phone hotspot MAC + +set -euo pipefail + +BLUE='\033[0;34m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' + +echo -e "${BLUE}=== Поиск MAC-адреса телефона ===${NC}\n" + +# Method 1: Check if connected to hotspot +echo -e "${YELLOW}Метод 1: Проверка подключения к hotspot...${NC}" +if networksetup -getairportnetwork en0 &>/dev/null; then + network_info=$(networksetup -getairportnetwork en0 2>/dev/null) + if [[ "$network_info" != *"not associated"* ]]; then + echo -e "${GREEN}✓ Подключен к сети${NC}" + + # Try to get BSSID using airport (deprecated but may work) + bssid=$(/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I 2>/dev/null | grep -i "BSSID" | awk '{print $2}' || echo "") + + if [ -n "$bssid" ] && [ "$bssid" != "none" ]; then + echo -e "${GREEN}✓ Найден BSSID (MAC точки доступа): $bssid${NC}" + echo "" + echo -e "${GREEN}Используйте этот MAC:${NC}" + echo "./spoof-wifi-mac.sh $bssid" + exit 0 + else + echo -e "${YELLOW}⚠ Не удалось определить BSSID автоматически${NC}" + fi + else + echo -e "${RED}✗ Не подключен к Wi-Fi сети${NC}" + fi +else + echo -e "${RED}✗ Wi-Fi интерфейс не найден${NC}" +fi + +echo "" + +# Method 2: Check ARP table for connected devices +echo -e "${YELLOW}Метод 2: Проверка ARP таблицы...${NC}" +gateway=$(route -n get default 2>/dev/null | grep gateway | awk '{print $2}' || echo "") +if [ -n "$gateway" ]; then + echo -e "${GREEN}✓ Шлюз: $gateway${NC}" + arp_mac=$(arp -n "$gateway" 2>/dev/null | awk '{print $4}' | grep -E "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$" || echo "") + if [ -n "$arp_mac" ]; then + echo -e "${GREEN}✓ MAC шлюза (возможно точка доступа): $arp_mac${NC}" + echo "" + echo -e "${GREEN}Возможный MAC точки доступа:${NC}" + echo "./spoof-wifi-mac.sh $arp_mac" + echo "" + echo -e "${YELLOW}⚠ Это MAC роутера/точки доступа, проверьте на телефоне${NC}" + else + echo -e "${YELLOW}⚠ Не удалось определить MAC из ARP${NC}" + fi +else + echo -e "${RED}✗ Шлюз не найден${NC}" +fi + +echo "" + +# Method 3: Instructions +echo -e "${BLUE}=== Ручной способ получения MAC ===${NC}\n" + +echo -e "${YELLOW}iPhone:${NC}" +echo "1. Настройки → Wi-Fi" +echo "2. Нажмите (i) рядом с активной сетью" +echo "3. Отключите 'Частный Wi-Fi адрес'" +echo "4. Скопируйте 'Адрес Wi-Fi'" +echo "" + +echo -e "${YELLOW}Android:${NC}" +echo "1. Настройки → О телефоне → Статус" +echo "2. Найдите 'MAC-адрес Wi-Fi'" +echo "" + +echo -e "${YELLOW}Для точки доступа (hotspot):${NC}" +echo "1. Включите точку доступа на телефоне" +echo "2. Подключите MacBook к hotspot" +echo "3. Запустите: ./spoof-wifi-mac.sh --phone-mac" +echo "" + +echo -e "${BLUE}=== Альтернативный способ ===${NC}\n" +echo "Если MAC не отображается на телефоне:" +echo "1. Подключите MacBook к hotspot телефона" +echo "2. Запустите: ./spoof-wifi-mac.sh --phone-mac" +echo " (скрипт автоматически определит MAC точки доступа)" +echo "" + diff --git a/docs/security/spoof-mac-now.sh b/docs/security/spoof-mac-now.sh new file mode 100755 index 0000000..7d1b3c2 --- /dev/null +++ b/docs/security/spoof-mac-now.sh @@ -0,0 +1,26 @@ +#!/bin/zsh +# Wrapper script to spoof MAC with password prompt + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +MAC="7a:ef:be:50:00:55" + +echo "=== Подмена MAC Wi-Fi ===" +echo "Текущий MAC будет заменен на MAC точки доступа: $MAC" +echo "" + +# Try to get password via osascript +PASSWORD=$(osascript -e 'Tell application "System Events" to display dialog "Введите пароль администратора для подмены MAC:" default answer "" with hidden answer' -e 'text returned of result' 2>/dev/null || echo "") + +if [ -z "$PASSWORD" ]; then + echo "Запуск скрипта подмены MAC..." + echo "Вам будет предложено ввести пароль sudo" + echo "" + cd "$SCRIPT_DIR" + ./spoof-wifi-mac.sh "$MAC" +else + echo "Использование предоставленного пароля..." + echo "$PASSWORD" | sudo -S "$SCRIPT_DIR/spoof-wifi-mac.sh" "$MAC" +fi + diff --git a/docs/security/spoof-wifi-mac.sh b/docs/security/spoof-wifi-mac.sh new file mode 100755 index 0000000..e8f561b --- /dev/null +++ b/docs/security/spoof-wifi-mac.sh @@ -0,0 +1,362 @@ +#!/bin/zsh +# Advanced Wi-Fi MAC spoofing script for macOS +# Automatically detects phone hotspot MAC or allows manual input +# Usage: +# spoof-wifi-mac.sh # auto-detect connected hotspot MAC +# spoof-wifi-mac.sh --phone-mac # detect phone MAC from hotspot +# spoof-wifi-mac.sh AA:BB:CC:DD:EE:FF # set specific MAC +# spoof-wifi-mac.sh --revert # restore original MAC + +set -euo pipefail + +# Get absolute path to script +if [ -n "${ZSH_VERSION:-}" ]; then + SCRIPT_PATH="${0:A}" +else + SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" +fi +# Fallback if still empty +if [ -z "$SCRIPT_PATH" ] || [ ! -f "$SCRIPT_PATH" ]; then + SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" +fi + +STATE_FILE="/tmp/wifi_mac_spoof_state" +ORIGINAL_MAC_FILE="/tmp/wifi_mac_original" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +require_root() { + if [ "$EUID" -ne 0 ] && [ "$(id -u)" -ne 0 ]; then + echo -e "${YELLOW}Re-running with sudo...${NC}" + exec sudo -E "$0" "${@}" + fi +} + +detect_wifi_if() { + local iface + iface=$(networksetup -listallhardwareports | awk '/Wi-Fi/{getline; print $2; exit}') + if [ -z "$iface" ]; then + echo -e "${RED}Error: Could not detect Wi-Fi interface${NC}" + exit 1 + fi + echo "$iface" +} + +get_current_mac() { + local iface="$1" + ifconfig "$iface" 2>/dev/null | awk '/ether/{print $2; exit}' || echo "" +} + +get_connected_network() { + local iface="$1" + /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I 2>/dev/null | awk '/ SSID:/ {print substr($0, index($0,$2))}' || echo "" +} + +get_connected_bssid() { + local iface="$1" + /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I 2>/dev/null | awk '/ BSSID:/ {print $2}' || echo "" +} + +detect_phone_hotspot_mac() { + local iface="$1" + local bssid + + echo -e "${BLUE}Detecting connected hotspot MAC...${NC}" + + bssid=$(get_connected_bssid "$iface") + if [ -z "$bssid" ] || [ "$bssid" = "none" ]; then + echo -e "${YELLOW}Warning: Not connected to Wi-Fi or cannot detect BSSID${NC}" + return 1 + fi + + echo -e "${GREEN}Found hotspot BSSID: $bssid${NC}" + echo "$bssid" + return 0 +} + +validate_mac() { + local mac="$1" + if ! [[ "$mac" =~ ^([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}$ ]]; then + echo -e "${RED}Invalid MAC format: $mac (expected AA:BB:CC:DD:EE:FF)${NC}" + exit 1 + fi +} + +power_wifi() { + local iface="$1" + local state="$2" # on|off + networksetup -setairportpower "$iface" "$state" 2>/dev/null || true + sleep 1 +} + +save_original_mac() { + local iface="$1" + local mac="$2" + + if [ ! -f "$ORIGINAL_MAC_FILE" ]; then + echo "$iface|$mac" > "$ORIGINAL_MAC_FILE" + echo -e "${GREEN}Saved original MAC for permanent restore: $mac${NC}" + fi +} + +check_sip_status() { + local sip_status + sip_status=$(csrutil status 2>/dev/null | grep -i "enabled" || echo "unknown") + if [[ "$sip_status" == *"enabled"* ]]; then + return 0 # SIP enabled + else + return 1 # SIP disabled or unknown + fi +} + +set_mac() { + local iface="$1" + local mac="$2" + + local current_mac + current_mac=$(get_current_mac "$iface") + + if [ -z "$current_mac" ]; then + echo -e "${RED}Error: Cannot read current MAC address${NC}" + exit 1 + fi + + echo -e "${BLUE}Current MAC: $current_mac${NC}" + echo -e "${BLUE}Target MAC: $mac${NC}" + + if [ "$current_mac" = "$mac" ]; then + echo -e "${YELLOW}MAC already set to target value${NC}" + return 0 + fi + + # Check SIP status + if check_sip_status; then + echo -e "${YELLOW}⚠ System Integrity Protection (SIP) is enabled${NC}" + echo -e "${YELLOW}MAC spoofing may be blocked on Apple Silicon with SIP enabled${NC}" + fi + + # Save original MAC if not saved + save_original_mac "$iface" "$current_mac" + + # Save for revert + echo "$iface $current_mac" > "$STATE_FILE" + + echo -e "${YELLOW}Turning Wi-Fi off...${NC}" + power_wifi "$iface" off + + echo -e "${YELLOW}Setting MAC to $mac...${NC}" + + # Try ifconfig method + local success=false + if ifconfig "$iface" ether "$mac" 2>/dev/null; then + success=true + fi + + if [ "$success" = false ]; then + echo -e "${RED}✗ Error: Failed to set MAC address${NC}" + echo "" + echo -e "${BLUE}=== РЕШЕНИЕ ПРОБЛЕМЫ ===${NC}" + echo "" + + if check_sip_status; then + echo -e "${YELLOW}На Apple Silicon (M1/M2/M3) с включенным SIP подмена MAC заблокирована${NC}" + echo "" + echo -e "${YELLOW}Варианты решения:${NC}" + echo "1. Отключить SIP (НЕ рекомендуется - снижает безопасность)" + echo " - Перезагрузите в Recovery Mode (Cmd+R)" + echo " - Утилиты → Терминал → csrutil disable" + echo " - Перезагрузите Mac" + echo "" + echo "2. Использовать альтернативные методы:" + echo " • VPN на телефоне (рекомендуется)" + echo " • USB Tethering вместо Wi-Fi hotspot" + echo " • Bluetooth Tethering" + echo "" + echo -e "${BLUE}Важно:${NC}" + echo "Оператор сотовой связи видит IMEI телефона, а не MAC MacBook." + echo "MAC клиента виден только на уровне локальной Wi-Fi сети." + echo "Подмена MAC не меняет идентификацию на уровне оператора." + else + echo -e "${YELLOW}Интерфейс может не поддерживать подмену MAC${NC}" + echo -e "${YELLOW}Или требуется дополнительная настройка${NC}" + fi + + power_wifi "$iface" on + exit 1 + fi + + echo -e "${YELLOW}Turning Wi-Fi on...${NC}" + power_wifi "$iface" on + + sleep 2 + + local new_mac + new_mac=$(get_current_mac "$iface") + + if [ "$new_mac" = "$mac" ]; then + echo -e "${GREEN}✓ Success! MAC changed to: $new_mac${NC}" + else + echo -e "${RED}⚠ Warning: MAC may not have changed${NC}" + echo -e "${YELLOW}Current MAC: $new_mac${NC}" + echo -e "${YELLOW}Target MAC: $mac${NC}" + echo -e "${YELLOW}This may require disabling SIP or using a different method${NC}" + fi +} + +revert_mac() { + local iface + local original_mac + + if [ -f "$STATE_FILE" ]; then + read iface original_mac < "$STATE_FILE" + elif [ -f "$ORIGINAL_MAC_FILE" ]; then + local saved + saved=$(cat "$ORIGINAL_MAC_FILE") + iface=$(echo "$saved" | cut -d'|' -f1) + original_mac=$(echo "$saved" | cut -d'|' -f2) + else + echo -e "${RED}No saved MAC found. Cannot revert.${NC}" + exit 1 + fi + + if [ -z "${iface:-}" ] || [ -z "${original_mac:-}" ]; then + echo -e "${RED}State file is corrupted. Delete $STATE_FILE and $ORIGINAL_MAC_FILE${NC}" + exit 1 + fi + + echo -e "${BLUE}Restoring MAC for $iface to $original_mac...${NC}" + power_wifi "$iface" off + ifconfig "$iface" ether "$original_mac" 2>/dev/null || { + echo -e "${RED}Failed to restore MAC${NC}" + power_wifi "$iface" on + exit 1 + } + power_wifi "$iface" on + sleep 2 + + rm -f "$STATE_FILE" + local current + current=$(get_current_mac "$iface") + echo -e "${GREEN}✓ Reverted. Current MAC: $current${NC}" +} + +show_instructions() { + echo -e "${BLUE}=== ИНСТРУКЦИИ ПО ПОЛУЧЕНИЮ MAC ТЕЛЕФОНА ===${NC}" + echo "" + echo -e "${YELLOW}iPhone:${NC}" + echo "1. Настройки → Wi-Fi" + echo "2. Нажмите (i) рядом с сетью" + echo "3. Отключите 'Частный Wi-Fi адрес' (Private Wi-Fi Address)" + echo "4. MAC-адрес будет показан как 'Адрес Wi-Fi'" + echo "" + echo -e "${YELLOW}Android:${NC}" + echo "1. Настройки → О телефоне → Статус" + echo "2. Найдите 'MAC-адрес Wi-Fi'" + echo "" + echo -e "${YELLOW}Альтернативный способ (если подключены к hotspot):${NC}" + echo "Скрипт может автоматически определить MAC точки доступа" + echo "Используйте: $0 --phone-mac" + echo "" +} + +main() { + # Check if we need root and restart with sudo if needed + # Skip check for help/instructions commands that don't need root + local arg="${1:-}" + local needs_root=false + + if [ "$arg" != "--help" ] && [ "$arg" != "-h" ] && [ "$arg" != "--instructions" ]; then + needs_root=true + fi + + if [ "$needs_root" = true ] && [ "$(id -u)" -ne 0 ]; then + echo -e "${YELLOW}Re-running with sudo...${NC}" + exec sudo -E "$SCRIPT_PATH" "${@}" + exit 0 + fi + + if [ "$arg" = "--help" ] || [ "$arg" = "-h" ]; then + echo "Usage: $0 [OPTIONS] [MAC_ADDRESS]" + echo "" + echo "Options:" + echo " --phone-mac Auto-detect phone hotspot MAC" + echo " --revert Restore original MAC" + echo " --instructions Show instructions for finding phone MAC" + echo " --help Show this help" + echo "" + echo "Examples:" + echo " $0 # Interactive mode" + echo " $0 --phone-mac # Auto-detect hotspot MAC" + echo " $0 AA:BB:CC:DD:EE:FF # Set specific MAC" + echo " $0 --revert # Restore original" + exit 0 + fi + + if [ "$arg" = "--instructions" ]; then + show_instructions + exit 0 + fi + + if [ "$arg" = "--revert" ]; then + revert_mac + exit 0 + fi + + local iface + iface=$(detect_wifi_if) + echo -e "${GREEN}Wi-Fi interface: $iface${NC}" + + local target_mac="" + + if [ "$arg" = "--phone-mac" ]; then + target_mac=$(detect_phone_hotspot_mac "$iface") + if [ -z "$target_mac" ]; then + echo -e "${RED}Could not detect phone hotspot MAC${NC}" + echo -e "${YELLOW}Make sure you're connected to phone hotspot and try manual input${NC}" + show_instructions + exit 1 + fi + elif [ -n "$arg" ]; then + target_mac="$arg" + else + # Try auto-detect first + local detected + detected=$(detect_phone_hotspot_mac "$iface" 2>/dev/null || echo "") + + if [ -n "$detected" ]; then + echo -e "${GREEN}Detected hotspot MAC: $detected${NC}" + read "confirm?Use this MAC? (y/n): " + if [[ "$confirm" =~ ^[Yy] ]]; then + target_mac="$detected" + else + read "target_mac?Enter phone Wi-Fi MAC (AA:BB:CC:DD:EE:FF): " + fi + else + show_instructions + read "target_mac?Enter phone Wi-Fi MAC (AA:BB:CC:DD:EE:FF): " + fi + fi + + if [ -z "$target_mac" ]; then + echo -e "${RED}No MAC address provided${NC}" + exit 1 + fi + + validate_mac "$target_mac" + + set_mac "$iface" "$target_mac" + + echo "" + echo -e "${BLUE}=== ВАЖНО ===${NC}" + echo -e "${YELLOW}• MAC сбросится после перезагрузки или переподключения Wi-Fi${NC}" + echo -e "${YELLOW}• Используйте '$0 --revert' для восстановления${NC}" + echo -e "${YELLOW}• Для постоянной подмены может потребоваться отключение SIP${NC}" + echo -e "${YELLOW}• Оператор видит трафик через точку доступа, MAC клиента виден только на уровне Wi-Fi${NC}" +} + +main "$@" diff --git a/download_youtube.sh b/download_youtube.sh new file mode 100755 index 0000000..55968b6 --- /dev/null +++ b/download_youtube.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Скрипт для скачивания YouTube видео в максимальном качестве +# Использование: ./download_youtube.sh <URL> + +URL="${1:-https://www.youtube.com/watch?v=QH8BA-fUp9s}" + +echo "Скачивание видео: $URL" +echo "Качество: максимальное (bestvideo+bestaudio/best)" +echo "" + +yt-dlp \ + --socket-timeout 60 \ + --retries 5 \ + -f "bestvideo+bestaudio/best" \ + --merge-output-format mkv \ + --output "%(title)s.%(ext)s" \ + "$URL" + +if [ $? -eq 0 ]; then + echo "" + echo "✓ Видео успешно скачано!" +else + echo "" + echo "✗ Ошибка при скачивании. Проверьте подключение к интернету." +fi + + + + + + diff --git a/scripts/deployment/gitea/setup-and-push.sh b/scripts/deployment/gitea/setup-and-push.sh new file mode 100755 index 0000000..788852b --- /dev/null +++ b/scripts/deployment/gitea/setup-and-push.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# Setup local_machine as a git repo and push to Gitea (gitea.hunab.app). +# Usage: +# 1. Create repo on Gitea (once): UI https://gitea.hunab.app -> New Repository "local_machine" +# OR: GITEA_TOKEN=xxx bash scripts/deployment/gitea/setup-and-push.sh --create-only +# 2. Push: bash scripts/deployment/gitea/setup-and-push.sh + +set -e +GITEA_HOST="${GITEA_HOST:-https://gitea.hunab.app}" +GITEA_USER="${GITEA_USER:-hunabgit}" +REPO_NAME="local_machine" +REMOTE_URL_HTTPS="${GITEA_HOST}/${GITEA_USER}/${REPO_NAME}.git" +# SSH port 2223 (see docs/git/GITEA_COMPLETE_GUIDE.md) +REMOTE_URL_SSH="ssh://git@gitea.hunab.app:2223/${GITEA_USER}/${REPO_NAME}.git" + +# Must run from repo root (local_machine) +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +if [[ ! -f "$ROOT/.gitignore" ]] || [[ ! -d "$ROOT/docs" ]]; then + echo "Run from local_machine root. Current: $ROOT" + exit 1 +fi +cd "$ROOT" + +# --- Create repo via API (optional) --- +if [[ "$1" == "--create-only" ]]; then + if [[ -z "$GITEA_TOKEN" ]]; then + echo "Create repo manually: $GITEA_HOST -> New Repository -> Name: $REPO_NAME" + echo "Or set GITEA_TOKEN and run again with --create-only to create via API." + exit 0 + fi + echo "Creating repository $REPO_NAME..." + curl -s -X POST "${GITEA_HOST}/api/v1/user/repos" \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"name\":\"$REPO_NAME\",\"description\":\"Local machine docs and scripts\",\"private\":false,\"auto_init\":false}" \ + && echo "" && echo "Repo created. Run without --create-only to push." + exit 0 +fi + +# --- Init git if needed --- +if [[ ! -d .git ]]; then + git init + git branch -M main + echo "Git initialized (branch main)." +fi + +# --- Remote --- +if ! git remote get-url origin &>/dev/null; then + # Prefer SSH (port 2223) — надёжнее из РФ + if command -v ssh &>/dev/null && ssh -o BatchMode=yes -o ConnectTimeout=5 -p 2223 git@gitea.hunab.app 2>/dev/null; then + git remote add origin "$REMOTE_URL_SSH" + echo "Remote origin set (SSH, port 2223)." + else + git remote add origin "$REMOTE_URL_HTTPS" + echo "Remote origin set (HTTPS). From РФ: use SSH (port 2223) or proxy — see docs/git/GITEA_COMPLETE_GUIDE.md" + fi +fi + +# --- Commit and push --- +git add -A +if git diff --cached --quiet; then + echo "Nothing to commit." +else + git commit -m "Initial commit: local_machine docs and scripts" + echo "Committed." +fi + +echo "Pushing to $GITEA_USER/$REPO_NAME..." +if git push -u origin main 2>/dev/null; then + echo "Done. Repo: $GITEA_HOST/$GITEA_USER/$REPO_NAME" +else + echo "Push failed (e.g. timeout from РФ). Try:" + echo " SSH: git remote set-url origin $REMOTE_URL_SSH # port 2223" + echo " git push -u origin main" + echo " Or use bundle method from docs/git/GITEA_COMPLETE_GUIDE.md" + exit 1 +fi