#!/bin/bash # GoTelegram v2.2 — Генерация TOML конфигурации для telemt # ── Популярные домены (не заблокированные в РФ) ────────────────────────────── QUICK_DOMAINS=( "google.com" "microsoft.com" "cloudflare.com" "apple.com" "amazon.com" "github.com" "stackoverflow.com" "medium.com" "wikipedia.org" "coursera.org" "udemy.com" "habr.com" "stepik.org" "duolingo.com" "khanacademy.org" "bbc.com" "reuters.com" "nytimes.com" "ted.com" "zoom.us" ) # ── Генерация TOML конфига ─────────────────────────────────────────────────── generate_telemt_toml() { local secret="$1" local port="${2:-443}" local mask_mode="${3:-quick}" # quick | stealth local mask_host="${4:-google.com}" local mask_port="${5:-443}" local output="${6:-$TELEMT_CONFIG}" mkdir -p "$(dirname "$output")" cat > "$output" << EOTOML # GoTelegram v${GOTELEGRAM_VERSION} — telemt configuration # Сгенерировано: $(date -Iseconds) # Режим: ${mask_mode} # ── Основные настройки ─────────────────────────────────────────────────────── [stats] statsd_address = "" # ── Секреты ────────────────────────────────────────────────────────────────── [[users]] name = "main" secret = "${secret}" # ── Привязка ───────────────────────────────────────────────────────────────── [listen] bind_to = "0.0.0.0:${port}" # ── TLS маскировка ─────────────────────────────────────────────────────────── [security] # Маскировочный хост — куда перенаправлять неопознанные подключения # quick: внешний сайт | stealth: локальный nginx host = "${mask_host}:${mask_port}" EOTOML chmod 600 "$output" log_success "Конфиг telemt записан: $output" log_dim "Режим: $mask_mode, маскировка: $mask_host:$mask_port" } # ── Добавление дополнительного секрета ─────────────────────────────────────── add_secret_to_config() { local name="$1" local secret="$2" local config="${3:-$TELEMT_CONFIG}" if [ ! -f "$config" ]; then log_error "Конфиг не найден: $config" return 1 fi # Добавляем новый блок [[users]] cat >> "$config" << EOSECRET [[users]] name = "${name}" secret = "${secret}" EOSECRET log_success "Добавлен секрет: $name" } # ── Чтение текущего конфига ────────────────────────────────────────────────── get_config_value() { local key="$1" local config="${2:-$TELEMT_CONFIG}" if [ ! -f "$config" ]; then return 1; fi case "$key" in secret) grep -m1 'secret\s*=' "$config" | sed 's/.*=\s*"\(.*\)"/\1/' | tr -d ' ' ;; port) grep 'bind_to\s*=' "$config" | sed 's/.*:\([0-9]*\)".*/\1/' ;; mask_host) grep -A10 '\[security\]' "$config" | grep 'host\s*=' | sed 's/.*=\s*"\(.*\)".*/\1/' ;; *) grep "$key" "$config" | head -1 | sed 's/.*=\s*"\?\(.*\)"\?/\1/' | tr -d ' "' ;; esac } # ── Валидация конфига ──────────────────────────────────────────────────────── validate_telemt_config() { local config="${1:-$TELEMT_CONFIG}" if [ ! -f "$config" ]; then log_error "Конфиг не найден: $config" return 1 fi # Проверяем обязательные поля local secret port host secret=$(get_config_value secret "$config") port=$(get_config_value port "$config") host=$(get_config_value mask_host "$config") local errors=0 if [ -z "$secret" ]; then log_error "Не задан secret" ((errors++)) elif [ ${#secret} -lt 32 ]; then log_warning "Secret слишком короткий (${#secret} символов, рекомендуется 32+)" fi if [ -z "$port" ]; then log_error "Не задан порт (bind_to)" ((errors++)) elif [ "$port" -lt 1 ] || [ "$port" -gt 65535 ] 2>/dev/null; then log_error "Порт вне диапазона: $port" ((errors++)) fi if [ -z "$host" ]; then log_error "Не задан маскировочный хост (security.host)" ((errors++)) fi if [ $errors -gt 0 ]; then log_error "Найдено ошибок: $errors" return 1 fi log_success "Конфиг валиден" return 0 } # ── Выбор домена (интерактивный) ───────────────────────────────────────────── select_quick_domain() { echo "" >&2 echo -e " ${BOLD}${WHITE}🌐 Выберите домен для маскировки (Fake TLS):${NC}" >&2 echo -e " ${DIM}$(printf '─%.0s' {1..50})${NC}" >&2 local i=1 local row="" for d in "${QUICK_DOMAINS[@]}"; do printf " ${CYAN}%2d)${NC} %-25s" "$i" "$d" >&2 if (( i % 2 == 0 )); then echo "" >&2 fi ((i++)) done if (( (i-1) % 2 != 0 )); then echo "" >&2; fi echo -e " ${DIM}$(printf '─%.0s' {1..50})${NC}" >&2 echo -ne " ${WHITE}Выбор (1-${#QUICK_DOMAINS[@]}):${NC} " >&2 read -r choice if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#QUICK_DOMAINS[@]} ]; then echo "${QUICK_DOMAINS[$((choice-1))]}" return 0 fi log_error "Неверный выбор" return 1 } # ── Выбор порта (интерактивный) ────────────────────────────────────────────── select_port() { echo "" >&2 echo -e " ${BOLD}${WHITE}🔌 Выберите порт:${NC}" >&2 # Проверяем стандартные порты local busy_443 busy_8443 busy_443=$(check_port 443) busy_8443=$(check_port 8443) local label_443="443 (рекомендуется)" local label_8443="8443" [ -n "$busy_443" ] && label_443="443 ⚠️ занят" [ -n "$busy_8443" ] && label_8443="8443 ⚠️ занят" echo -e " ${CYAN}1)${NC} $label_443" >&2 echo -e " ${CYAN}2)${NC} $label_8443" >&2 echo -e " ${CYAN}3)${NC} Свой порт" >&2 if [ -n "$busy_443" ]; then echo -e " ${DIM} ⚠ Порт 443 занят: $(echo "$busy_443" | head -c 60)${NC}" >&2 fi echo -ne " ${WHITE}Выбор:${NC} " >&2 read -r choice case "$choice" in 1) echo "443" ;; 2) echo "8443" ;; 3) echo -ne " Введите порт (1-65535): " >&2 read -r custom_port if [[ "$custom_port" =~ ^[0-9]+$ ]] && [ "$custom_port" -ge 1 ] && [ "$custom_port" -le 65535 ]; then echo "$custom_port" else log_error "Неверный порт" return 1 fi ;; *) echo "443" ;; esac } # ── Генерация ссылки tg://proxy ────────────────────────────────────────────── generate_proxy_link() { local ip="${1:-$(get_server_ip)}" local port="${2:-443}" local secret="$3" echo "tg://proxy?server=${ip}&port=${port}&secret=${secret}" } # ── Вывод информации о прокси ──────────────────────────────────────────────── show_proxy_info() { local config="${1:-$TELEMT_CONFIG}" local secret port mask_host ip link status secret=$(get_config_value secret "$config") port=$(get_config_value port "$config") mask_host=$(get_config_value mask_host "$config") ip=$(get_server_ip) link=$(generate_proxy_link "$ip" "$port" "$secret") status=$(telemt_status) local mode mode=$(config_get mode 2>/dev/null || echo "quick") local status_icon status_text case "$status" in running) status_icon="✅"; status_text="Работает" ;; stopped) status_icon="⏸️"; status_text="Остановлен" ;; *) status_icon="❌"; status_text="Не установлен" ;; esac echo "" echo -e " ${BOLD}${WHITE}${status_icon} Статус прокси: ${status_text}${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..50})${NC}" echo -e " ${WHITE}Ядро:${NC} telemt (Rust)" echo -e " ${WHITE}IP:${NC} ${CYAN}${ip}${NC}" echo -e " ${WHITE}Порт:${NC} ${CYAN}${port}${NC}" echo -e " ${WHITE}Режим:${NC} ${CYAN}${mode}${NC}" echo -e " ${WHITE}Маскировка:${NC} ${CYAN}${mask_host}${NC}" echo -e " ${WHITE}Secret:${NC} ${CYAN}${secret:0:16}...${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..50})${NC}" echo -e " ${WHITE}Ссылка:${NC}" echo -e " ${GREEN}${link}${NC}" echo "" # QR если доступен if command -v qrencode &>/dev/null; then qrencode -t UTF8 -m 2 "$link" 2>/dev/null fi }