#!/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 конфига (telemt v3 формат) ─────────────────────────────── generate_telemt_toml() { local secret="$1" local port="${2:-443}" local mask_mode="${3:-lite}" # lite | pro local mask_domain="${4:-google.com}" local mask_port="${5:-443}" local output="${6:-$TELEMT_CONFIG}" mkdir -p "$(dirname "$output")" # DNS override для pro: домен резолвится в 127.0.0.1 # чтобы mask-трафик шёл на локальный nginx, а не в интернет local dns_line="" if [ "$mask_mode" = "pro" ]; then dns_line="dns_overrides = [\"${mask_domain}:${mask_port}:127.0.0.1\"]" fi cat > "$output" << EOTOML # GoTelegram v${GOTELEGRAM_VERSION} — telemt v3 configuration # Сгенерировано: $(date -Iseconds) # Режим: ${mask_mode} [server] port = ${port} listen_addr_ipv4 = "0.0.0.0" [censorship] tls_domain = "${mask_domain}" mask = true mask_port = ${mask_port} tls_emulation = $([ "$mask_mode" = "pro" ] && echo "false" || echo "true") [access.users] main = "${secret}" [network] ${dns_line} EOTOML chmod 600 "$output" log_success "Конфиг telemt записан: $output" log_dim "Режим: $mask_mode, домен: $mask_domain, порт mask: $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 # telemt v3: добавляем ключ в секцию [access.users] # Формат: name = "secret" под блоком [access.users] if grep -q '\[access\.users\]' "$config"; then sed -i "/\[access\.users\]/a ${name} = \"${secret}\"" "$config" else cat >> "$config" << EOSECRET [access.users] ${name} = "${secret}" EOSECRET fi log_success "Добавлен секрет: $name" } # ── Чтение текущего конфига (telemt v3 формат) ────────────────────────────── get_config_value() { local key="$1" local config="${2:-$TELEMT_CONFIG}" if [ ! -f "$config" ]; then return 1; fi case "$key" in secret) # [access.users] main = "..." grep -A5 '\[access.users\]' "$config" | grep -m1 '=' | sed 's/.*=\s*"\(.*\)"/\1/' | tr -d ' ' ;; port) # [server] port = 443 grep -A5 '\[server\]' "$config" | grep 'port\s*=' | head -1 | sed 's/.*=\s*\([0-9]*\)/\1/' | tr -d ' ' ;; mask_host|tls_domain) # [censorship] tls_domain = "..." grep -A10 '\[censorship\]' "$config" | grep 'tls_domain\s*=' | sed 's/.*=\s*"\(.*\)"/\1/' ;; mask_port) grep -A10 '\[censorship\]' "$config" | grep 'mask_port\s*=' | sed 's/.*=\s*\([0-9]*\)/\1/' | tr -d ' ' ;; *) 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 "Не задан маскировочный хост (censorship.tls_domain)" ((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 server="${1:-$(get_server_ip)}" local port="${2:-443}" local secret="$3" local mask_host="${4:-}" # Если указан mask_host (fake-TLS), формируем ee-секрет if [ -n "$mask_host" ]; then local domain_hex domain_hex=$(printf '%s' "$mask_host" | xxd -p | tr -d '\n') secret="ee${secret}${domain_hex}" fi echo "tg://proxy?server=${server}&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) status=$(telemt_status) local mode domain mode=$(config_get mode 2>/dev/null || echo "lite") domain=$(config_get domain 2>/dev/null || echo "") # Генерация ссылки: оба режима используют ee-секрет с mask_host if [ "$mode" = "pro" ] && [ -n "$domain" ]; then link=$(generate_proxy_link "$domain" "$port" "$secret" "$domain") else link=$(generate_proxy_link "$ip" "$port" "$secret" "$mask_host") fi local status_icon status_text case "$status" in running) status_icon="✅"; status_text="$(t info_status_running)" ;; stopped) status_icon="⏸️"; status_text="$(t info_status_stopped)" ;; *) status_icon="❌"; status_text="$(t info_status_not_installed)" ;; esac echo "" echo -e " ${BOLD}${WHITE}${status_icon} $(t info_proxy_status): ${status_text}${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..50})${NC}" echo -e " ${WHITE}$(t info_engine):${NC} telemt (Rust)" if [ "$mode" = "pro" ] && [ -n "$domain" ]; then echo -e " ${WHITE}$(t info_domain):${NC} ${CYAN}${domain}${NC}" else echo -e " ${WHITE}$(t info_ip):${NC} ${CYAN}${ip}${NC}" fi echo -e " ${WHITE}$(t info_port):${NC} ${CYAN}${port}${NC}" echo -e " ${WHITE}$(t info_mode):${NC} ${CYAN}${mode}${NC}" echo -e " ${WHITE}$(t info_mask):${NC} ${CYAN}${mask_host}${NC}" echo -e " ${WHITE}$(t info_secret):${NC} ${CYAN}${secret:0:16}...${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..50})${NC}" echo -e " ${WHITE}$(t info_link):${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 } # ── Вывод информации о прокси (Pro-режим) ────────────────────────────────── # В pro-режиме ссылка содержит домен (не IP) и fake-TLS секрет (ee...) show_proxy_info_pro() { local domain="$1" local faketls_secret="$2" local link="tg://proxy?server=${domain}&port=443&secret=${faketls_secret}" echo "" echo -e " ${BOLD}${WHITE}✅ $(t info_proxy_status): $(t info_status_running) (Pro)${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" echo -e " ${WHITE}$(t info_engine):${NC} telemt (Rust)" echo -e " ${WHITE}$(t info_domain):${NC} ${CYAN}${domain}${NC}" echo -e " ${WHITE}$(t info_port):${NC} ${CYAN}443${NC} (telemt)" echo -e " ${WHITE}$(t info_mode):${NC} ${MAGENTA}Pro (fake-TLS)${NC}" echo -e " ${WHITE}nginx:${NC} ${CYAN}127.0.0.1:8443${NC}" echo -e " ${WHITE}$(t info_secret):${NC} ${CYAN}${faketls_secret:0:20}...${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" echo -e " ${WHITE}$(t info_link):${NC}" echo -e " ${GREEN}${link}${NC}" echo "" echo -e " ${DIM}ISP sees: HTTPS → ${domain}:443${NC}" echo -e " ${DIM}Telegram client masquerades as TLS${NC}" echo "" # QR если доступен if command -v qrencode &>/dev/null; then qrencode -t UTF8 -m 2 "$link" 2>/dev/null fi }