mirror of
https://github.com/andrey271192/PCA_Phobos.git
synced 2026-09-20 11:55:32 +00:00
feat: private dev/beta channels via subscriber token (repo split)
Closed channels (beta, dev) now live in a separate PRIVATE repository andrey271192/PCA_Phobos-dev. Access is gated by a read-only subscriber GH_TOKEN (distributed via Boosty) instead of a shared hash key — the token both authenticates the private raw fetch AND acts as the gate, so there is a single secret and the code is genuinely hidden (public repo holds stable/main only). install.sh: CHANNEL=beta|dev -> private repo, requires GH_TOKEN, persists it to $PANEL_DIR/.gh_token + writes .channel. stable stays public/no-token. update.sh: per-ref repo routing (repo_for), gh_curl injects the token for private channels, token read from env or saved .gh_token, --check/--versions reflect public vs private, stable path unchanged and tokenless. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
49
install.sh
49
install.sh
@@ -25,31 +25,31 @@ PANEL_PASS="${PANEL_PASS:-OcAdmin2026!}"
|
|||||||
TG_TOKEN="${TG_TOKEN:-}"
|
TG_TOKEN="${TG_TOKEN:-}"
|
||||||
TG_CHAT="${TG_CHAT:-}"
|
TG_CHAT="${TG_CHAT:-}"
|
||||||
OBF_PORTS="${OBF_PORTS:-2083,5443,993}"
|
OBF_PORTS="${OBF_PORTS:-2083,5443,993}"
|
||||||
# Каналы: stable (открытый, ветка main) · beta (тест) · dev (разработка).
|
# Каналы: stable (открытый, публичный repo) · beta (тест) · dev (разработка).
|
||||||
# beta и dev ЗАКРЫТЫ ключом подписчика PHOBOS_KEY (по подписке Boosty). stable — без ключа.
|
# beta и dev живут в ПРИВАТНОМ repo PCA_Phobos-dev — доступ по токену подписчика
|
||||||
|
# (GH_TOKEN, read-only, выдаётся по подписке Boosty). stable — без токена.
|
||||||
|
GH_TOKEN="${GH_TOKEN:-}"
|
||||||
|
PUB_REPO="andrey271192/PCA_Phobos"
|
||||||
|
DEV_REPO="andrey271192/PCA_Phobos-dev"
|
||||||
CHANNEL="${CHANNEL:-stable}"
|
CHANNEL="${CHANNEL:-stable}"
|
||||||
if [ -z "${PCA_BRANCH:-}" ]; then
|
case "$CHANNEL" in
|
||||||
case "$CHANNEL" in beta) PCA_BRANCH="beta";; dev) PCA_BRANCH="dev";; stable|main|"") PCA_BRANCH="main";; *) PCA_BRANCH="$CHANNEL";; esac
|
beta) REPO="$DEV_REPO"; PCA_BRANCH="${PCA_BRANCH:-beta}";;
|
||||||
fi
|
dev) REPO="$DEV_REPO"; PCA_BRANCH="${PCA_BRANCH:-dev}";;
|
||||||
PHOBOS_KEY_HASH="cb3ce498b8d2c67ec7b57a9b08ed2fb410c881bcb9bc9cf50d09be1d9727333a"
|
stable|main|"") REPO="$PUB_REPO"; PCA_BRANCH="${PCA_BRANCH:-main}";;
|
||||||
case "$PCA_BRANCH" in
|
*) REPO="$PUB_REPO"; PCA_BRANCH="${PCA_BRANCH:-$CHANNEL}";;
|
||||||
beta|dev)
|
|
||||||
_got=$(printf %s "${PHOBOS_KEY:-}" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -d' ' -f1)
|
|
||||||
if [ "$_got" != "$PHOBOS_KEY_HASH" ]; then
|
|
||||||
echo "Канал '$CHANNEL' закрыт — это $([ "$CHANNEL" = dev ] && echo 'разработка (нестабильно)' || echo 'бета (тест)')."
|
|
||||||
echo "Нужен ключ подписчика:"
|
|
||||||
echo " PHOBOS_KEY=ваш_ключ CHANNEL=$CHANNEL bash <(curl -fsSL https://raw.githubusercontent.com/andrey271192/PCA_Phobos/main/install.sh)"
|
|
||||||
echo "Ключ выдаётся по подписке: https://boosty.to/andrey27"
|
|
||||||
echo "Стабильная версия ставится без ключа (CHANNEL=stable, по умолчанию)."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Ключ принят — канал '$CHANNEL'."
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
GH_TOKEN="${GH_TOKEN:-}" # set for private-repo installs; empty for public
|
if [ "$REPO" = "$DEV_REPO" ] && [ -z "$GH_TOKEN" ]; then
|
||||||
|
echo "Канал '$CHANNEL' закрыт — это $([ "$CHANNEL" = dev ] && echo 'разработка (нестабильно)' || echo 'бета (тест)'), приватный репозиторий."
|
||||||
|
echo "Нужен read-only токен подписчика:"
|
||||||
|
echo " GH_TOKEN=ваш_токен CHANNEL=$CHANNEL bash <(curl -fsSL https://raw.githubusercontent.com/$PUB_REPO/main/install.sh)"
|
||||||
|
echo "Токен выдаётся по подписке: https://boosty.to/andrey27"
|
||||||
|
echo "Стабильная версия ставится без токена (CHANNEL=stable, по умолчанию)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
[ "$REPO" = "$DEV_REPO" ] && echo "Токен принят — закрытый канал '$CHANNEL' (приватный repo)."
|
||||||
PHOBOS_DIR="/opt/Phobos"
|
PHOBOS_DIR="/opt/Phobos"
|
||||||
PANEL_DIR="/opt/phobos-panel"
|
PANEL_DIR="/opt/phobos-panel"
|
||||||
RAW="https://raw.githubusercontent.com/andrey271192/PCA_Phobos/${PCA_BRANCH}"
|
RAW="https://raw.githubusercontent.com/${REPO}/${PCA_BRANCH}"
|
||||||
|
|
||||||
[ "$EUID" -eq 0 ] || { echo "Run as root"; exit 1; }
|
[ "$EUID" -eq 0 ] || { echo "Run as root"; exit 1; }
|
||||||
|
|
||||||
@@ -260,6 +260,13 @@ if [ -f "$PHOBOS_DIR/server/phobos-router-watchdog.py" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
sleep 2
|
sleep 2
|
||||||
|
# persist channel + subscriber token so phobos-update can reach private channels
|
||||||
|
mkdir -p "$PANEL_DIR"
|
||||||
|
echo "$CHANNEL" > "$PANEL_DIR/.channel" 2>/dev/null || true
|
||||||
|
if [ "$REPO" = "$DEV_REPO" ] && [ -n "$GH_TOKEN" ]; then
|
||||||
|
( umask 077; printf %s "$GH_TOKEN" > "$PANEL_DIR/.gh_token" )
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "============================================"
|
echo "============================================"
|
||||||
echo " Installation complete"
|
echo " Installation complete"
|
||||||
|
|||||||
110
update.sh
110
update.sh
@@ -2,24 +2,47 @@
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
# PCA Phobos — updater / rollback
|
# PCA Phobos — updater / rollback
|
||||||
#
|
#
|
||||||
# phobos-update # обновить до последней версии (main)
|
# phobos-update # обновить до стабильной (канал stable / main)
|
||||||
# phobos-update v1.1.0 # обновить до конкретной версии (git tag)
|
# phobos-update stable # стабильный канал (публичный, без токена)
|
||||||
|
# GH_TOKEN=... phobos-update beta # бета-канал (приватный, по токену подписчика)
|
||||||
|
# GH_TOKEN=... phobos-update dev # канал разработки (приватный, по токену)
|
||||||
|
# phobos-update v1.2.4 # конкретная версия (git tag)
|
||||||
# phobos-update --rollback # откатить на предыдущую версию (из бэкапа)
|
# phobos-update --rollback # откатить на предыдущую версию (из бэкапа)
|
||||||
# phobos-update --version # показать установленную и последнюю версию
|
# phobos-update --check # установленная + версии всех каналов
|
||||||
# phobos-update --list # список бэкапов для отката
|
# phobos-update --list # список бэкапов для отката
|
||||||
#
|
#
|
||||||
# Обновляет ТОЛЬКО PCA-слой (панель + скрипты онбординга/служебные).
|
# Каналы:
|
||||||
# НЕ трогает ключи WireGuard, server.env, клиентов — они сохраняются.
|
# stable -> публичный репозиторий andrey271192/PCA_Phobos (открыт)
|
||||||
# Перед каждым обновлением делает бэкап; откат восстанавливает его.
|
# beta / dev -> приватный andrey271192/PCA_Phobos-dev (только подписчики)
|
||||||
|
# Для beta/dev нужен read-only токен подписчика: env GH_TOKEN или файл
|
||||||
|
# $PANEL_DIR/.gh_token (сохраняется при установке закрытого канала).
|
||||||
|
#
|
||||||
|
# Обновляет ТОЛЬКО PCA-слой (панель + скрипты). НЕ трогает ключи WireGuard,
|
||||||
|
# server.env, клиентов. Перед каждым обновлением — бэкап; откат восстанавливает.
|
||||||
# ============================================================
|
# ============================================================
|
||||||
set -e
|
set -e
|
||||||
PHOBOS_DIR=/opt/Phobos
|
PHOBOS_DIR=/opt/Phobos
|
||||||
PANEL_DIR=/opt/phobos-panel
|
PANEL_DIR=/opt/phobos-panel
|
||||||
REPO=andrey271192/PCA_Phobos
|
PUB_REPO=andrey271192/PCA_Phobos
|
||||||
RAW="https://raw.githubusercontent.com/$REPO"
|
DEV_REPO=andrey271192/PCA_Phobos-dev
|
||||||
BACKUPS="$PHOBOS_DIR/updates"
|
BACKUPS="$PHOBOS_DIR/updates"
|
||||||
VERFILE="$PANEL_DIR/.version"
|
VERFILE="$PANEL_DIR/.version"
|
||||||
CUR=$(cat "$VERFILE" 2>/dev/null || echo "unknown")
|
CUR=$(cat "$VERFILE" 2>/dev/null || echo "unknown")
|
||||||
|
# Токен подписчика для приватных каналов: env > сохранённый файл
|
||||||
|
GH_TOKEN="${GH_TOKEN:-$(cat "$PANEL_DIR/.gh_token" 2>/dev/null || true)}"
|
||||||
|
|
||||||
|
# repo for a ref/channel: beta/dev/*-beta/*-dev -> private, остальное -> public
|
||||||
|
repo_for() { case "$1" in beta|dev|*-beta|*-dev) echo "$DEV_REPO";; *) echo "$PUB_REPO";; esac; }
|
||||||
|
is_private() { case "$1" in beta|dev|*-beta|*-dev) return 0;; *) return 1;; esac; }
|
||||||
|
# curl with token header only when ref is a private channel
|
||||||
|
gh_curl() { # $1=ref, rest=curl args
|
||||||
|
local ref="$1"; shift
|
||||||
|
if is_private "$ref" && [ -n "$GH_TOKEN" ]; then
|
||||||
|
curl -H "Authorization: token $GH_TOKEN" "$@"
|
||||||
|
else
|
||||||
|
curl "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
managed_files() {
|
managed_files() {
|
||||||
cat <<LIST
|
cat <<LIST
|
||||||
@@ -35,7 +58,13 @@ $PHOBOS_DIR/server/update.sh|update.sh
|
|||||||
LIST
|
LIST
|
||||||
}
|
}
|
||||||
|
|
||||||
latest_version() { curl -fsSL -m10 "$RAW/main/VERSION" 2>/dev/null | tr -d ' \r\n'; }
|
# fetch VERSION of a channel (public repos / or private if token present)
|
||||||
|
chan_version() { # $1 = ref(channel)
|
||||||
|
local repo; repo=$(repo_for "$1"); local repo_ref="$1"
|
||||||
|
if is_private "$1" && [ -z "$GH_TOKEN" ]; then echo ""; return; fi
|
||||||
|
gh_curl "$1" -fsSL -m8 "https://raw.githubusercontent.com/$repo/$1/VERSION" 2>/dev/null | tr -d ' \r\n'
|
||||||
|
}
|
||||||
|
latest_version() { curl -fsSL -m10 "https://raw.githubusercontent.com/$PUB_REPO/main/VERSION" 2>/dev/null | tr -d ' \r\n'; }
|
||||||
|
|
||||||
do_backup() {
|
do_backup() {
|
||||||
local dir="$BACKUPS/${CUR}-$(date +%Y%m%d-%H%M%S)"
|
local dir="$BACKUPS/${CUR}-$(date +%Y%m%d-%H%M%S)"
|
||||||
@@ -48,10 +77,12 @@ do_backup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply_ref() {
|
apply_ref() {
|
||||||
local ref="$1"
|
local ref="$1"; local repo; repo=$(repo_for "$ref")
|
||||||
|
local repo_ref="$ref"
|
||||||
|
local RAW="https://raw.githubusercontent.com/$repo/$ref"
|
||||||
managed_files | while IFS='|' read -r lp rp; do
|
managed_files | while IFS='|' read -r lp rp; do
|
||||||
local tmp; tmp=$(mktemp)
|
local tmp; tmp=$(mktemp)
|
||||||
if curl -fsSL -m25 "$RAW/$ref/$rp" -o "$tmp" && [ -s "$tmp" ]; then
|
if gh_curl "$ref" -fsSL -m25 "$RAW/$rp" -o "$tmp" && [ -s "$tmp" ]; then
|
||||||
mkdir -p "$(dirname "$lp")"; mv "$tmp" "$lp"
|
mkdir -p "$(dirname "$lp")"; mv "$tmp" "$lp"
|
||||||
case "$lp" in *.sh|*.py) chmod +x "$lp" 2>/dev/null || true;; esac
|
case "$lp" in *.sh|*.py) chmod +x "$lp" 2>/dev/null || true;; esac
|
||||||
else
|
else
|
||||||
@@ -60,21 +91,33 @@ apply_ref() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
ref_exists() { curl -fsSL -m12 "$RAW/$1/app.py" -o /dev/null 2>/dev/null; }
|
ref_exists() {
|
||||||
|
local repo; repo=$(repo_for "$1"); local repo_ref="$1"
|
||||||
|
gh_curl "$1" -fsSL -m12 "https://raw.githubusercontent.com/$repo/$1/app.py" -o /dev/null 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
--version|-v|--check)
|
--version|-v|--check)
|
||||||
echo "Установлено: $CUR"
|
echo "Установлено: $CUR"
|
||||||
echo "Стабильная: $(latest_version)"
|
echo "Стабильная: $(latest_version) [открытый]"
|
||||||
beta=$(curl -fsSL -m8 "$RAW/beta/VERSION" 2>/dev/null | tr -d ' \r\n')
|
b=$(chan_version beta); d=$(chan_version dev)
|
||||||
[ -n "$beta" ] && echo "Бета (beta): $beta [закрыт ключом]"
|
if [ -n "$GH_TOKEN" ]; then
|
||||||
dev=$(curl -fsSL -m8 "$RAW/dev/VERSION" 2>/dev/null | tr -d ' \r\n')
|
[ -n "$b" ] && echo "Бета (beta): $b [приватный, токен ок]"
|
||||||
[ -n "$dev" ] && echo "Разработка(dev):$dev [закрыт ключом]"
|
[ -n "$d" ] && echo "Разработка(dev):$d [приватный, токен ок]"
|
||||||
|
else
|
||||||
|
echo "Бета (beta): — [приватный: нужен GH_TOKEN подписчика]"
|
||||||
|
echo "Разработка(dev):— [приватный: нужен GH_TOKEN подписчика]"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
--versions|--tags)
|
--versions|--tags)
|
||||||
echo "Доступные версии (git tags):"
|
echo "Стабильные версии (публичные теги):"
|
||||||
curl -fsSL -m10 "https://api.github.com/repos/$REPO/tags?per_page=100" 2>/dev/null \
|
curl -fsSL -m10 "https://api.github.com/repos/$PUB_REPO/tags?per_page=100" 2>/dev/null \
|
||||||
| grep -oE '"name": *"[^"]+"' | sed 's/.*"name": *"\(.*\)"/ \1/' || echo " (нет данных)"
|
| grep -oE '"name": *"[^"]+"' | sed 's/.*"name": *"\(.*\)"/ \1/' || echo " (нет данных)"
|
||||||
|
if [ -n "$GH_TOKEN" ]; then
|
||||||
|
echo "Закрытые версии (приватные теги, beta/dev):"
|
||||||
|
curl -fsSL -m10 -H "Authorization: token $GH_TOKEN" "https://api.github.com/repos/$DEV_REPO/tags?per_page=100" 2>/dev/null \
|
||||||
|
| grep -oE '"name": *"[^"]+"' | sed 's/.*"name": *"\(.*\)"/ \1/' || echo " (нет данных)"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
--list)
|
--list)
|
||||||
echo "Бэкапы (для отката):"
|
echo "Бэкапы (для отката):"
|
||||||
@@ -95,24 +138,25 @@ case "${1:-}" in
|
|||||||
*)
|
*)
|
||||||
ref="${1:-main}"
|
ref="${1:-main}"
|
||||||
case "$ref" in latest|stable) ref="main";; esac
|
case "$ref" in latest|stable) ref="main";; esac
|
||||||
# Каналы beta/dev закрыты ключом подписчика PHOBOS_KEY (Boosty)
|
# Каналы beta/dev — приватный репозиторий, нужен токен подписчика
|
||||||
case "$ref" in
|
if is_private "$ref" && [ -z "$GH_TOKEN" ]; then
|
||||||
beta|dev|*-beta|*-dev)
|
echo "Канал '$ref' закрыт (бета/разработка) — приватный репозиторий."
|
||||||
_got=$(printf %s "${PHOBOS_KEY:-}" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -d' ' -f1)
|
echo "Нужен read-only токен подписчика:"
|
||||||
if [ "$_got" != "cb3ce498b8d2c67ec7b57a9b08ed2fb410c881bcb9bc9cf50d09be1d9727333a" ]; then
|
echo " GH_TOKEN=ваш_токен phobos-update $ref"
|
||||||
echo "Канал '$ref' закрыт (бета/разработка). Нужен ключ подписчика:"
|
echo "Токен — по подписке: https://boosty.to/andrey27 . Стабильная (без токена): phobos-update stable"
|
||||||
echo " PHOBOS_KEY=ваш_ключ phobos-update $ref"
|
exit 1
|
||||||
echo "Ключ — по подписке: https://boosty.to/andrey27 . Стабильная: phobos-update stable"
|
fi
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
if ! ref_exists "$ref"; then
|
if ! ref_exists "$ref"; then
|
||||||
echo "Версия/ветка '$ref' не найдена на GitHub. Обновление отменено (текущая $CUR не тронута)."
|
echo "Версия/ветка '$ref' не найдена (или токен неверный). Обновление отменено (текущая $CUR не тронута)."
|
||||||
echo "Доступные: phobos-update --versions · стабильная: $(latest_version)"
|
echo "Доступные: phobos-update --versions · стабильная: $(latest_version)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
target=$(curl -fsSL -m10 "$RAW/$ref/VERSION" 2>/dev/null | tr -d ' \r\n'); [ -z "$target" ] && target="$ref"
|
# сохранить токен для будущих обновлений приватного канала
|
||||||
|
if is_private "$ref" && [ -n "$GH_TOKEN" ]; then
|
||||||
|
( umask 077; printf %s "$GH_TOKEN" > "$PANEL_DIR/.gh_token" )
|
||||||
|
fi
|
||||||
|
repo_ref="$ref"
|
||||||
|
target=$(gh_curl "$ref" -fsSL -m10 "https://raw.githubusercontent.com/$(repo_for "$ref")/$ref/VERSION" 2>/dev/null | tr -d ' \r\n'); [ -z "$target" ] && target="$ref"
|
||||||
echo "Текущая: $CUR -> целевая: $target ($ref)"
|
echo "Текущая: $CUR -> целевая: $target ($ref)"
|
||||||
b=$(do_backup); echo "Бэкап: $b"
|
b=$(do_backup); echo "Бэкап: $b"
|
||||||
apply_ref "$ref"
|
apply_ref "$ref"
|
||||||
|
|||||||
Reference in New Issue
Block a user