mirror of
https://github.com/anten-ka/gotelegram_pro.git
synced 2026-05-19 13:26:02 +00:00
v2.5.0: maintenance and bot user management
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.4 — backup and restore (i18n-aware)
|
||||
# GoTelegram v2.5.0 — backup and restore (i18n-aware)
|
||||
|
||||
# ── Создание бекапа ──────────────────────────────────────────────────────────
|
||||
create_backup() {
|
||||
@@ -35,13 +35,16 @@ create_backup() {
|
||||
cp "$NGINX_SITE_CONF" "$tmp_dir/nginx.conf"
|
||||
fi
|
||||
|
||||
# SSL сертификаты
|
||||
# SSL сертификаты и renewal metadata для переносов между VPS
|
||||
local domain
|
||||
domain=$(config_get domain 2>/dev/null)
|
||||
if [ -n "$domain" ] && [ -d "/etc/letsencrypt/live/$domain" ]; then
|
||||
mkdir -p "$tmp_dir/certs"
|
||||
cp "/etc/letsencrypt/live/$domain/fullchain.pem" "$tmp_dir/certs/" 2>/dev/null
|
||||
cp "/etc/letsencrypt/live/$domain/privkey.pem" "$tmp_dir/certs/" 2>/dev/null
|
||||
mkdir -p "$tmp_dir/letsencrypt/live" "$tmp_dir/letsencrypt/archive" "$tmp_dir/letsencrypt/renewal"
|
||||
cp -a "/etc/letsencrypt/live/$domain" "$tmp_dir/letsencrypt/live/" 2>/dev/null
|
||||
[ -d "/etc/letsencrypt/archive/$domain" ] && \
|
||||
cp -a "/etc/letsencrypt/archive/$domain" "$tmp_dir/letsencrypt/archive/" 2>/dev/null
|
||||
[ -f "/etc/letsencrypt/renewal/$domain.conf" ] && \
|
||||
cp -a "/etc/letsencrypt/renewal/$domain.conf" "$tmp_dir/letsencrypt/renewal/" 2>/dev/null
|
||||
log_dim "SSL сертификаты включены"
|
||||
fi
|
||||
|
||||
@@ -52,6 +55,28 @@ create_backup() {
|
||||
log_dim "$(_t_or backup_site_included 'Шаблон сайта включён')"
|
||||
fi
|
||||
|
||||
# Custom templates and catalog
|
||||
if [ -d "$GOTELEGRAM_DIR/custom_templates" ]; then
|
||||
mkdir -p "$tmp_dir/custom_templates"
|
||||
cp -a "$GOTELEGRAM_DIR/custom_templates/." "$tmp_dir/custom_templates/" 2>/dev/null
|
||||
fi
|
||||
if [ -f "$GOTELEGRAM_DIR/templates_catalog.json" ]; then
|
||||
cp "$GOTELEGRAM_DIR/templates_catalog.json" "$tmp_dir/templates_catalog.json" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Bot state (.env has BotFather token, so encrypted backups are strongly recommended)
|
||||
if [ -d "$BOT_DIR" ]; then
|
||||
mkdir -p "$tmp_dir/bot"
|
||||
[ -f "$BOT_DIR/.env" ] && cp "$BOT_DIR/.env" "$tmp_dir/bot/.env" 2>/dev/null
|
||||
[ -f "$BOT_DIR/i18n.py" ] && cp "$BOT_DIR/i18n.py" "$tmp_dir/bot/i18n.py" 2>/dev/null
|
||||
[ -d "$BOT_DIR/lang" ] && cp -a "$BOT_DIR/lang" "$tmp_dir/bot/" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Traffic history
|
||||
if [ -f "$GOTELEGRAM_DIR/stats_history.csv" ]; then
|
||||
cp "$GOTELEGRAM_DIR/stats_history.csv" "$tmp_dir/stats_history.csv" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Метаданные
|
||||
local ip mode engine lang port domain
|
||||
ip=$(get_server_ip)
|
||||
@@ -65,7 +90,7 @@ create_backup() {
|
||||
|
||||
cat > "$tmp_dir/metadata.json" << EOMETA
|
||||
{
|
||||
"backup_version": "1.1",
|
||||
"backup_version": "1.2",
|
||||
"gotelegram_version": "$GOTELEGRAM_VERSION",
|
||||
"created_at": "$(date -Iseconds)",
|
||||
"hostname": "$(hostname)",
|
||||
@@ -231,8 +256,14 @@ restore_backup() {
|
||||
log_success "$(_t_or backup_restored_nginx 'nginx конфиг восстановлен')"
|
||||
fi
|
||||
|
||||
# Восстанавливаем SSL
|
||||
if [ -d "$backup_dir/certs" ]; then
|
||||
# Восстанавливаем SSL / Let's Encrypt structure
|
||||
if [ -d "$backup_dir/letsencrypt" ]; then
|
||||
mkdir -p /etc/letsencrypt/live /etc/letsencrypt/archive /etc/letsencrypt/renewal
|
||||
[ -d "$backup_dir/letsencrypt/live" ] && cp -a "$backup_dir/letsencrypt/live/." /etc/letsencrypt/live/ 2>/dev/null
|
||||
[ -d "$backup_dir/letsencrypt/archive" ] && cp -a "$backup_dir/letsencrypt/archive/." /etc/letsencrypt/archive/ 2>/dev/null
|
||||
[ -d "$backup_dir/letsencrypt/renewal" ] && cp -a "$backup_dir/letsencrypt/renewal/." /etc/letsencrypt/renewal/ 2>/dev/null
|
||||
log_success "$(_t_or backup_restored_ssl 'SSL сертификаты восстановлены')"
|
||||
elif [ -d "$backup_dir/certs" ]; then
|
||||
local domain
|
||||
domain=$(config_get domain 2>/dev/null)
|
||||
if [ -n "$domain" ]; then
|
||||
@@ -251,11 +282,38 @@ restore_backup() {
|
||||
log_success "$(_t_or backup_restored_site 'Шаблон сайта восстановлен')"
|
||||
fi
|
||||
|
||||
# Восстанавливаем custom templates/catalog/statistics
|
||||
if [ -d "$backup_dir/custom_templates" ]; then
|
||||
mkdir -p "$GOTELEGRAM_DIR/custom_templates"
|
||||
cp -a "$backup_dir/custom_templates/." "$GOTELEGRAM_DIR/custom_templates/" 2>/dev/null
|
||||
log_success "Пользовательские шаблоны восстановлены"
|
||||
fi
|
||||
if [ -f "$backup_dir/templates_catalog.json" ]; then
|
||||
cp "$backup_dir/templates_catalog.json" "$GOTELEGRAM_DIR/templates_catalog.json" 2>/dev/null
|
||||
fi
|
||||
if [ -f "$backup_dir/stats_history.csv" ]; then
|
||||
cp "$backup_dir/stats_history.csv" "$GOTELEGRAM_DIR/stats_history.csv" 2>/dev/null
|
||||
log_success "История статистики восстановлена"
|
||||
fi
|
||||
|
||||
# Восстанавливаем состояние бота
|
||||
if [ -d "$backup_dir/bot" ]; then
|
||||
mkdir -p "$BOT_DIR"
|
||||
[ -f "$backup_dir/bot/.env" ] && cp "$backup_dir/bot/.env" "$BOT_DIR/.env" 2>/dev/null && chmod 600 "$BOT_DIR/.env"
|
||||
[ -d "$backup_dir/bot/lang" ] && cp -a "$backup_dir/bot/lang" "$BOT_DIR/" 2>/dev/null
|
||||
[ -f "$backup_dir/bot/i18n.py" ] && cp "$backup_dir/bot/i18n.py" "$BOT_DIR/i18n.py" 2>/dev/null
|
||||
log_success "Конфигурация Telegram-бота восстановлена"
|
||||
fi
|
||||
|
||||
# Запускаем сервисы
|
||||
if is_telemt_installed && [ ! -f "/etc/systemd/system/${TELEMT_SERVICE}.service" ]; then
|
||||
install_telemt_service
|
||||
fi
|
||||
if is_telemt_installed; then
|
||||
start_telemt
|
||||
fi
|
||||
systemctl start nginx 2>/dev/null
|
||||
command -v nginx &>/dev/null && systemctl start nginx 2>/dev/null
|
||||
systemctl restart gotelegram-bot 2>/dev/null || true
|
||||
|
||||
# Очистка
|
||||
rm -rf "$tmp_dir"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.4 — common utilities
|
||||
# GoTelegram v2.5.0 — common utilities
|
||||
# Colors, logging, spinner, system helpers, v1 compat, i18n-aware
|
||||
|
||||
# ── Version ───────────────────────────────────────────────────────────────────
|
||||
GOTELEGRAM_VERSION="2.4.6"
|
||||
GOTELEGRAM_VERSION="2.5.0"
|
||||
GOTELEGRAM_NAME="GoTelegram"
|
||||
|
||||
# ── Пути ──────────────────────────────────────────────────────────────────────
|
||||
@@ -333,6 +333,7 @@ apt_pkg_for_cmd() {
|
||||
ss) echo "iproute2" ;;
|
||||
netstat) echo "net-tools" ;;
|
||||
flock) echo "util-linux" ;;
|
||||
iptables) echo "iptables" ;;
|
||||
*) echo "$1" ;; # команда == имя пакета
|
||||
esac
|
||||
}
|
||||
@@ -344,6 +345,7 @@ dnf_pkg_for_cmd() {
|
||||
ss) echo "iproute" ;;
|
||||
netstat) echo "net-tools" ;;
|
||||
flock) echo "util-linux" ;;
|
||||
iptables) echo "iptables" ;;
|
||||
*) echo "$1" ;;
|
||||
esac
|
||||
}
|
||||
@@ -355,7 +357,7 @@ ensure_deps() {
|
||||
# change-lite-domain из бота).
|
||||
local critical=(curl jq openssl git xxd tar dig flock)
|
||||
# Желательные — есть fallback, устанавливать всё равно, но не падать если не смогли
|
||||
local optional=(qrencode bc)
|
||||
local optional=(qrencode bc iptables)
|
||||
|
||||
local missing_critical=() missing_optional=() cmd
|
||||
for cmd in "${critical[@]}"; do
|
||||
@@ -463,6 +465,46 @@ check_port() {
|
||||
return 1 # свободен
|
||||
}
|
||||
|
||||
detect_3xui() {
|
||||
if systemctl list-unit-files 2>/dev/null | grep -Eq '^(x-ui|3x-ui)\.service'; then
|
||||
return 0
|
||||
fi
|
||||
[ -d /etc/x-ui ] || [ -d /usr/local/x-ui ] || [ -f /etc/x-ui/x-ui.db ]
|
||||
}
|
||||
|
||||
detect_3xui_443_listener() {
|
||||
ss -ltnp 2>/dev/null | grep -E '(:|])443[[:space:]]' | grep -Eiq '(xray|x-ui|3x-ui)'
|
||||
}
|
||||
|
||||
warn_3xui_443_conflict() {
|
||||
detect_3xui_443_listener || return 1
|
||||
log_warning "Обнаружен 3x-ui/Xray, который уже слушает TCP/443."
|
||||
log_warning "GoTelegram не будет молча останавливать или переписывать 3x-ui."
|
||||
log_dim "Для настоящего shared-443 нужен один фронтовой TLS/SNI-диспетчер и разные SNI-домены для Xray и GoTelegram."
|
||||
mkdir -p "$GOTELEGRAM_DIR" 2>/dev/null
|
||||
cat > "$GOTELEGRAM_DIR/shared-443-3xui.md" <<'EOF' 2>/dev/null || true
|
||||
# GoTelegram + 3x-ui on one TCP/443
|
||||
|
||||
GoTelegram detected that 3x-ui/Xray already owns TCP/443. Two independent
|
||||
processes cannot bind the same IP:port at the same time. A safe shared setup
|
||||
needs one front TLS/SNI dispatcher on 443 and internal backends, for example:
|
||||
|
||||
- dispatcher: 0.0.0.0:443
|
||||
- GoTelegram telemt: 127.0.0.1:7443
|
||||
- 3x-ui/Xray inbound: 127.0.0.1:9443
|
||||
- GoTelegram nginx mask site: 127.0.0.1:8443
|
||||
|
||||
The dispatcher must route Xray SNI domains to Xray and route the GoTelegram
|
||||
SNI domain to telemt. If Xray and GoTelegram use the same SNI domain, automatic
|
||||
sharing is not reliable: the first TLS ClientHello is intentionally identical.
|
||||
|
||||
GoTelegram intentionally does not rewrite the 3x-ui SQLite database or generated
|
||||
Xray config without explicit operator confirmation, because 3x-ui can overwrite
|
||||
manual JSON edits on the next panel change.
|
||||
EOF
|
||||
return 0
|
||||
}
|
||||
|
||||
check_disk_space() {
|
||||
local min_mb="${1:-500}"
|
||||
local avail_mb
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.4 — i18n engine
|
||||
# GoTelegram v2.5.0 — i18n engine
|
||||
# Internationalization support: EN (English) / RU (Русский)
|
||||
#
|
||||
# Usage:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.4 — English translations
|
||||
# GoTelegram v2.5.0 — English translations
|
||||
# shellcheck disable=SC2034,SC2148
|
||||
|
||||
# ── Common words ────────────────────────────────────────────────────────
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.4 — Russian translations
|
||||
# GoTelegram v2.5.0 — Russian translations
|
||||
# shellcheck disable=SC2034,SC2148
|
||||
|
||||
# ── Common words ────────────────────────────────────────────────────────
|
||||
|
||||
22
lib/stats.sh
22
lib/stats.sh
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# stats.sh — Traffic statistics module for GoTelegram
|
||||
# stats.sh — Traffic statistics module for GoTelegram v2.5.0
|
||||
# Tracks proxy (telemt port 443) and site (nginx port 8443) traffic
|
||||
# Uses iptables counters + real-time snapshots + historical CSV
|
||||
|
||||
@@ -18,6 +18,11 @@ CONFIG_FILE="/opt/gotelegram/config.json"
|
||||
|
||||
# Initialize stats infrastructure
|
||||
stats_init() {
|
||||
if ! command -v iptables &>/dev/null; then
|
||||
log_warning "iptables не найден: установите пакет iptables или запустите установку зависимостей"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create runtime directory
|
||||
mkdir -p "$STATS_DIR" "$SNAPSHOTS_DIR" 2>/dev/null
|
||||
chmod 755 "$STATS_DIR" "$SNAPSHOTS_DIR" 2>/dev/null
|
||||
@@ -57,6 +62,13 @@ stats_collect() {
|
||||
local ts=$(date +%s)
|
||||
local temp_file=$(mktemp)
|
||||
|
||||
if ! command -v iptables &>/dev/null; then
|
||||
mkdir -p "$STATS_DIR" 2>/dev/null
|
||||
echo "{\"ts\":$ts,\"proxy_bytes\":0,\"proxy_pkts\":0,\"site_bytes\":0,\"site_pkts\":0,\"error\":\"iptables_missing\"}" > "$CURRENT_SNAPSHOT" 2>/dev/null
|
||||
rm -f "$temp_file" 2>/dev/null
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Parse iptables output: format is "pkts bytes target"
|
||||
# We need to extract bytes (2nd column) for each rule
|
||||
local iptables_output=$(iptables -L GOTELEGRAM_STATS -v -n -x 2>/dev/null)
|
||||
@@ -350,6 +362,14 @@ install_stats_collector() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! command -v iptables &>/dev/null; then
|
||||
log_info "Установка iptables для подсчёта трафика..."
|
||||
install_pkg "$(apt_pkg_for_cmd iptables)" || {
|
||||
echo "Не удалось установить iptables" >&2
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
# Get script directory (resolve symlinks)
|
||||
local script_dir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
|
||||
local lib_dir=$(dirname "$script_dir")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.2 — Управление telemt binary
|
||||
# GoTelegram v2.5.0 — Управление telemt binary
|
||||
# Скачивание, обновление, запуск, остановка через systemd
|
||||
|
||||
TELEMT_GITHUB="telemt/telemt"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.2 — Генерация TOML конфигурации для telemt
|
||||
# GoTelegram v2.5.0 — Генерация TOML конфигурации для telemt
|
||||
|
||||
# ── Популярные домены (не заблокированные в РФ) ──────────────────────────────
|
||||
QUICK_DOMAINS=(
|
||||
@@ -48,15 +48,38 @@ generate_telemt_toml() {
|
||||
# Сгенерировано: $(date -Iseconds)
|
||||
# Режим: ${mask_mode}
|
||||
|
||||
[general]
|
||||
use_middle_proxy = true
|
||||
log_level = "normal"
|
||||
|
||||
[general.modes]
|
||||
classic = false
|
||||
secure = false
|
||||
tls = true
|
||||
|
||||
[general.links]
|
||||
show = "*"
|
||||
public_port = ${port}
|
||||
|
||||
[server]
|
||||
port = ${port}
|
||||
listen_addr_ipv4 = "0.0.0.0"
|
||||
metrics_listen = "127.0.0.1:9090"
|
||||
metrics_whitelist = ["127.0.0.1/32", "::1/128"]
|
||||
|
||||
[server.api]
|
||||
enabled = true
|
||||
listen = "127.0.0.1:9091"
|
||||
whitelist = ["127.0.0.1/32", "::1/128"]
|
||||
minimal_runtime_enabled = false
|
||||
minimal_runtime_cache_ttl_ms = 1000
|
||||
|
||||
[censorship]
|
||||
tls_domain = "${mask_domain}"
|
||||
mask = true
|
||||
mask_port = ${mask_port}
|
||||
tls_emulation = $([ "$mask_mode" = "pro" ] && echo "false" || echo "true")
|
||||
unknown_sni_action = "mask"
|
||||
|
||||
[access.users]
|
||||
main = "${secret}"
|
||||
@@ -106,21 +129,57 @@ get_config_value() {
|
||||
case "$key" in
|
||||
secret)
|
||||
# [access.users] main = "..."
|
||||
grep -A5 '\[access.users\]' "$config" | grep -m1 '=' | sed 's/.*=\s*"\(.*\)"/\1/' | tr -d ' '
|
||||
awk '
|
||||
/^\[access\.users\]/ { in_users=1; next }
|
||||
/^\[/ && in_users { exit }
|
||||
in_users && $1 == "main" {
|
||||
sub(/^[^=]*=[[:space:]]*"/, "")
|
||||
sub(/".*$/, "")
|
||||
print
|
||||
exit
|
||||
}
|
||||
' "$config" | tr -d ' '
|
||||
;;
|
||||
port)
|
||||
# [server] port = 443
|
||||
grep -A5 '\[server\]' "$config" | grep 'port\s*=' | head -1 | sed 's/.*=\s*\([0-9]*\)/\1/' | tr -d ' '
|
||||
awk '
|
||||
/^\[server\]/ { in_server=1; next }
|
||||
/^\[/ && in_server { exit }
|
||||
in_server && $1 == "port" {
|
||||
sub(/^[^=]*=[[:space:]]*/, "")
|
||||
gsub(/[[:space:]]/, "")
|
||||
print
|
||||
exit
|
||||
}
|
||||
' "$config"
|
||||
;;
|
||||
mask_host|tls_domain)
|
||||
# [censorship] tls_domain = "..."
|
||||
grep -A10 '\[censorship\]' "$config" | grep 'tls_domain\s*=' | sed 's/.*=\s*"\(.*\)"/\1/'
|
||||
awk '
|
||||
/^\[censorship\]/ { in_cens=1; next }
|
||||
/^\[/ && in_cens { exit }
|
||||
in_cens && $1 == "tls_domain" {
|
||||
sub(/^[^=]*=[[:space:]]*"/, "")
|
||||
sub(/".*$/, "")
|
||||
print
|
||||
exit
|
||||
}
|
||||
' "$config"
|
||||
;;
|
||||
mask_port)
|
||||
grep -A10 '\[censorship\]' "$config" | grep 'mask_port\s*=' | sed 's/.*=\s*\([0-9]*\)/\1/' | tr -d ' '
|
||||
awk '
|
||||
/^\[censorship\]/ { in_cens=1; next }
|
||||
/^\[/ && in_cens { exit }
|
||||
in_cens && $1 == "mask_port" {
|
||||
sub(/^[^=]*=[[:space:]]*/, "")
|
||||
gsub(/[[:space:]]/, "")
|
||||
print
|
||||
exit
|
||||
}
|
||||
' "$config"
|
||||
;;
|
||||
*)
|
||||
grep "$key" "$config" | head -1 | sed 's/.*=\s*"\?\(.*\)"\?/\1/' | tr -d ' "'
|
||||
grep "$key" "$config" | head -1 | sed 's/^[^=]*=[[:space:]]*//; s/^"//; s/"$//' | tr -d ' '
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.4 — website templates catalog
|
||||
# GoTelegram v2.5.0 — website templates catalog
|
||||
# Pick from ~1800 templates, preview links, git sparse-checkout downloads,
|
||||
# + custom git URL templates (user-supplied public repos)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# GoTelegram v2.2 — Управление сайтом (nginx + certbot + шаблоны)
|
||||
# GoTelegram v2.5.0 — Управление сайтом (nginx + certbot + шаблоны)
|
||||
|
||||
# ── Установка nginx ──────────────────────────────────────────────────────────
|
||||
install_nginx() {
|
||||
@@ -39,7 +39,7 @@ generate_nginx_config() {
|
||||
mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled
|
||||
|
||||
cat > "$NGINX_SITE_CONF" << 'EONGINX'
|
||||
# GoTelegram v2.3 — nginx config
|
||||
# GoTelegram v2.5.0 — nginx config
|
||||
# Pro: nginx на 127.0.0.1:8443 (внутренний), telemt на 0.0.0.0:443 (внешний)
|
||||
# Обычный браузер → :443 → telemt → 127.0.0.1:8443 → nginx (сайт)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user