Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions INSTALLER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ sudo ./IGProxy

## Экраны мастера

Перед установкой ядра первым вариантом предлагается последний стабильный релиз
telemt. Закреплённая версия остаётся отдельным запасным вариантом. На старых
дистрибутивах, где GNU-бинарнику не хватает новой glibc, мастер автоматически
переходит на официальную статическую musl-сборку той же версии и сохраняет
проверку SHA-256.

### 1. Роль сервера

- **Центр управления + прокси** — первый сервер сети. Здесь работают единый
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ sudo ./IGProxy
- проверяет новые службы и сайт;
- автоматически откатывает изменения при ошибке.

По умолчанию мастер предлагает последний стабильный релиз ядра telemt.
Если GNU-сборка не запускается на старой glibc, IGProxy показывает сообщение
системного загрузчика и автоматически проверяет официальную статическую
musl-сборку той же версии. SHA-256 проверяется для каждого скачанного архива.

## После установки

Открыть серверное меню:
Expand Down
22 changes: 11 additions & 11 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,8 @@ MaxFileSec=1day"
}

# ── Выбор версии ядра telemt ─────────────────────────────────────────────────
# Дефолт — протестированный пин (TELEMT_PINNED_VERSION), а не latest, чтобы битый
# свежий релиз ядра не ломал установки. Сохраняем выбор в config.json telemt_version.
# Дефолт — последний стабильный релиз. Протестированный пин остаётся запасным
# вариантом для ручного отката и недоступного GitHub API.
choose_telemt_version() {
local meta latest latest_meta pin_meta pin_d pin_f lat_d lat_f src ans v
meta=$(_telemt_releases_meta 2>/dev/null || echo "")
Expand All @@ -521,28 +521,28 @@ choose_telemt_version() {
[ -n "$cur" ] && [ "$cur" = "$latest" ] && m2=" ${GREEN}← установлена${NC}"
src=""; if [ -t 0 ]; then src=/dev/stdin; elif [ -r /dev/tty ]; then src=/dev/tty; fi
if [ -z "$src" ]; then
TELEMT_VERSION_PREF="${TELEMT_PINNED_VERSION}"
bot_update_config_field telemt_version "${TELEMT_PINNED_VERSION}" >/dev/null 2>&1 || true
TELEMT_VERSION_PREF="latest"
bot_update_config_field telemt_version "latest" >/dev/null 2>&1 || true
return 0
fi
echo "" >&2
echo -e " ${BOLD}Версия ядра telemt${NC}" >&2
echo -e " ${DIM}Установлено сейчас: ${cur:-нет} · настройка: ${curpref:-рекомендованная}${NC}" >&2
echo -e " ${GREEN}1)${NC} Рекомендованная — ${TELEMT_PINNED_VERSION}${pin_d:+ · $pin_d}${pin_f:+ · $pin_f} ${DIM}(протестирована)${NC}${m1}" >&2
echo -e " ${GREEN}2)${NC} Последняя — ${latest}${lat_d:+ · $lat_d}${lat_f:+ · $lat_f}${m2}" >&2
echo -e " ${GREEN}1)${NC} Последняя стабильная — ${latest}${lat_d:+ · $lat_d}${lat_f:+ · $lat_f} ${DIM}(рекомендуется)${NC}${m2}" >&2
echo -e " ${GREEN}2)${NC} Проверенная запасная — ${TELEMT_PINNED_VERSION}${pin_d:+ · $pin_d}${pin_f:+ · $pin_f}${m1}" >&2
echo -e " ${GREEN}3)${NC} Выбрать из списка / ввести тег" >&2
printf ' > ' >&2; read -r ans < "$src" || ans=1
case "$ans" in
2) TELEMT_VERSION_PREF="latest"; bot_update_config_field telemt_version "latest" >/dev/null 2>&1 || true
log_info "Версия ядра: последняя (${latest}, ${lat_f:-?}, ${lat_d:-?})" >&2 ;;
2) TELEMT_VERSION_PREF="${TELEMT_PINNED_VERSION}"; bot_update_config_field telemt_version "${TELEMT_PINNED_VERSION}" >/dev/null 2>&1 || true
log_info "Версия ядра: запасная (${TELEMT_PINNED_VERSION}, ${pin_f:-?}, ${pin_d:-?})" >&2 ;;
3) echo " Доступные версии (новые сверху):" >&2
printf '%s\n' "$meta" | head -12 | awk -F'|' '{printf " %-9s · %s · %s\n",$1,$2,$3}' >&2
printf ' Введите тег (напр. %s): ' "$TELEMT_PINNED_VERSION" >&2; read -r v < "$src" || v=""
v=$(echo "$v" | tr -d '[:space:]')
if [ -n "$v" ]; then TELEMT_VERSION_PREF="$v"; bot_update_config_field telemt_version "$v" >/dev/null 2>&1 || true; log_info "Версия ядра: ${v}" >&2
else TELEMT_VERSION_PREF="${TELEMT_PINNED_VERSION}"; bot_update_config_field telemt_version "${TELEMT_PINNED_VERSION}" >/dev/null 2>&1 || true; fi ;;
*) TELEMT_VERSION_PREF="${TELEMT_PINNED_VERSION}"; bot_update_config_field telemt_version "${TELEMT_PINNED_VERSION}" >/dev/null 2>&1 || true
log_info "Версия ядра: рекомендованная (${TELEMT_PINNED_VERSION})" >&2 ;;
else TELEMT_VERSION_PREF="latest"; bot_update_config_field telemt_version "latest" >/dev/null 2>&1 || true; fi ;;
*) TELEMT_VERSION_PREF="latest"; bot_update_config_field telemt_version "latest" >/dev/null 2>&1 || true
log_info "Версия ядра: последняя стабильная (${latest})" >&2 ;;
esac
return 0
}
Expand Down
2 changes: 1 addition & 1 deletion lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Colors, logging, spinner, system helpers, v1 compat, i18n-aware

# ── Version ───────────────────────────────────────────────────────────────────
GOTELEGRAM_VERSION="2.15.7"
GOTELEGRAM_VERSION="2.15.8"
GOTELEGRAM_NAME="IGProxy"

# ── Пути ──────────────────────────────────────────────────────────────────────
Expand Down
58 changes: 48 additions & 10 deletions lib/telemt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ _telemt_releases_meta() {

get_telemt_download_url() {
local version="${1:-}"
local libc_flavor="${2:-gnu}"
local api="$TELEMT_RELEASE_API"
if [ -n "$version" ] && [ "$version" != "latest" ]; then
api="https://api.github.com/repos/${TELEMT_GITHUB}/releases/tags/${version}"
Expand All @@ -47,11 +48,17 @@ get_telemt_download_url() {
*) arch_pattern="${arch}" ;;
esac

case "$libc_flavor" in
gnu|musl) ;;
*) return 1 ;;
esac

echo "$resp" | jq -r ".assets[].browser_download_url" 2>/dev/null \
| grep -iE "$arch_pattern" \
| grep -i "linux" \
| grep -v "sha256" \
| grep "gnu" \
| grep -vi -- "-v3-" \
| grep -i -- "linux-${libc_flavor}" \
| head -1
}

Expand All @@ -69,25 +76,37 @@ is_telemt_installed() {
}

# Целевая версия ядра: из config.json telemt_version, иначе глобал TELEMT_VERSION_PREF,
# иначе пин. "latest" -> резолвится в актуальный тег. Возвращает КОНКРЕТНЫЙ тег.
# иначе последний стабильный релиз. Пин остаётся аварийным fallback.
telemt_target_version() {
local v
v=$(read_config_or_default telemt_version "" 2>/dev/null)
[ -z "$v" ] && v="${TELEMT_VERSION_PREF:-}"
case "$v" in
""|recommended|pinned) echo "${TELEMT_PINNED_VERSION:-3.4.25}" ;;
latest) get_latest_telemt_version ;;
""|latest|recommended)
get_latest_telemt_version 2>/dev/null || echo "${TELEMT_PINNED_VERSION:-3.4.25}"
;;
pinned) echo "${TELEMT_PINNED_VERSION:-3.4.25}" ;;
*) echo "$v" ;;
esac
}

telemt_system_libc() {
if ldd --version 2>&1 | grep -qi musl; then
printf 'musl\n'
else
printf 'gnu\n'
fi
}

# ── Скачивание и установка ───────────────────────────────────────────────────
download_telemt() {
local version="${1:-$(telemt_target_version)}"
local libc_flavor="${2:-$(telemt_system_libc)}"
local allow_musl_fallback="${3:-1}"
local url
url=$(get_telemt_download_url "$version")
url=$(get_telemt_download_url "$version" "$libc_flavor")
if [ -z "$url" ]; then
log_error "Не найден бинарник telemt для архитектуры $(get_arch)"
log_error "Не найден ${libc_flavor}-бинарник telemt для архитектуры $(get_arch)"
return 1
fi

Expand All @@ -97,7 +116,7 @@ download_telemt() {
tmp_file="$tmp_dir/asset"
checksum_file="$tmp_dir/asset.sha256"
extract_dir="$tmp_dir/extract"
log_info "Скачивание telemt ${version}: $url"
log_info "Скачивание telemt ${version} (${libc_flavor}): $url"

if ! curl -L -s --max-time 120 -o "$tmp_file" "$url"; then
log_error "Ошибка скачивания telemt"
Expand Down Expand Up @@ -180,13 +199,32 @@ download_telemt() {
rm -rf -- "$tmp_dir"
return 1
}
if ! install -m 755 "$extracted" "$staged_bin" || \
! "$staged_bin" --version 2>/dev/null | grep -Fq "$version"; then
log_error "Скачанный бинарник telemt не прошёл проверку запуска/версии"
local probe_output="" probe_rc=0
if ! install -m 755 "$extracted" "$staged_bin"; then
log_error "Не удалось подготовить бинарник telemt к запуску"
rm -f -- "$staged_bin"
rm -rf -- "$tmp_dir"
return 1
fi
if probe_output=$("$staged_bin" --version 2>&1); then
probe_rc=0
else
probe_rc=$?
fi
if [ "$probe_rc" -ne 0 ] || ! printf '%s\n' "$probe_output" | grep -Fq "$version"; then
probe_output=$(printf '%s' "${probe_output:-нет сообщения от загрузчика}" \
| tr '\r\n\t' ' ' | sed -E 's/[[:space:]]+/ /g' | cut -c1-320)
log_warning "Сборка telemt (${libc_flavor}) не запустилась: ${probe_output} (code: ${probe_rc})."
rm -f -- "$staged_bin"
rm -rf -- "$tmp_dir"
if [ "$libc_flavor" = "gnu" ] && [ "$allow_musl_fallback" = "1" ]; then
log_info "Пробую совместимую статическую musl-сборку telemt той же версии."
download_telemt "$version" "musl" "0"
return $?
fi
log_error "Скачанный бинарник telemt не прошёл проверку запуска/версии"
return 1
fi
if [ -x "$TELEMT_BIN" ]; then
backup_tmp=$(mktemp "${TELEMT_BIN}.rollback.XXXXXX") || {
rm -f -- "$staged_bin"
Expand Down
35 changes: 33 additions & 2 deletions tests/test_installer_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,13 +516,21 @@ def test_selected_ports_are_checked_against_firewall(self):
self.assertNotIn("ufw allow ${port}/tcp >/dev/null", wizard)
self.assertNotIn("firewall-cmd --permanent --add-port=${port}/tcp >/dev/null", wizard)

def test_telemt_3425_is_pinned_with_verified_download_and_split_mss(self):
def test_telemt_latest_is_default_with_verified_musl_fallback(self):
common = (ROOT / "lib" / "common.sh").read_text(encoding="utf-8")
telemt = (ROOT / "lib" / "telemt.sh").read_text(encoding="utf-8")
install = INSTALL.read_text(encoding="utf-8")
config = (ROOT / "lib" / "telemt_config.sh").read_text(encoding="utf-8")

self.assertIn('TELEMT_PINNED_VERSION="3.4.25"', common)
self.assertIn('${TELEMT_PINNED_VERSION:-3.4.25}', telemt)
self.assertIn('""|latest|recommended)', telemt)
self.assertIn('TELEMT_VERSION_PREF="latest"', install)
self.assertIn('bot_update_config_field telemt_version "latest"', install)
self.assertIn('local libc_flavor="${2:-gnu}"', telemt)
self.assertIn('"linux-${libc_flavor}"', telemt)
self.assertIn('download_telemt "$version" "musl" "0"', telemt)
self.assertIn("Пробую совместимую статическую musl-сборку", telemt)
self.assertIn('"$staged_bin" --version 2>&1', telemt)
self.assertIn('"${url}.sha256"', telemt)
self.assertIn('sha256sum "$tmp_file"', telemt)
self.assertIn("mktemp -d /tmp/telemt-download.XXXXXX", telemt)
Expand All @@ -532,6 +540,29 @@ def test_telemt_3425_is_pinned_with_verified_download_and_split_mss(self):
self.assertIn('local client_mss_bulk="1400"', config)
self.assertIn('client_mss_bulk = \\"${client_mss_bulk}\\"', config)

def test_telemt_target_defaults_to_latest_but_preserves_explicit_pin(self):
telemt = (ROOT / "lib" / "telemt.sh").as_posix()
script = f"""
TELEMT_BIN=/tmp/unused-telemt
TELEMT_PINNED_VERSION=3.4.25
TELEMT_VERSION_PREF=
source {telemt!r}
read_config_or_default() {{ printf '%s\\n' "${{CONFIG_PREF:-}}"; }}
get_latest_telemt_version() {{ printf '9.9.9\\n'; }}
CONFIG_PREF=
telemt_target_version
CONFIG_PREF=pinned
telemt_target_version
"""
result = subprocess.run(
["bash", "-c", script],
text=True,
capture_output=True,
check=False,
)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout.splitlines(), ["9.9.9", "3.4.25"])


if __name__ == "__main__":
unittest.main()
Loading