fix(deploy): age-ключ генерируется без age-keygen -o (он читает stdin и ломал sudo -S)

Формируем AGE-SECRET-KEY в bech32 сами, публичный ключ получаем через
age-keygen -y </dev/null. Устраняет зависание установки через sudo -S.
This commit is contained in:
2026-09-19 20:30:23 +03:00
parent 8ff7831dc7
commit 4b3a90ad7f
+54 -7
View File
@@ -479,6 +479,55 @@ install_docker() {
# --- секреты и конфиги ----------------------------------------------------
# generate_age_key создаёт файл ключа age (X25519) без вызова age-keygen -o:
# age-keygen без терминала читает stdin и при запуске через `sudo -S`
# высасывает пайп с паролем, из-за чего установщик зависает.
generate_age_key() {
local dst="$1"
local raw pub
raw="$(openssl rand 32 | od -An -tx1 | tr -d ' \n')"
if ! have age-keygen; then
warn "age-keygen не найден: бэкапы будут без шифрования"
return 0
fi
pub="$(printf 'AGE-SECRET-KEY-1%s\n' "$(bech32_encode "$raw" | tr 'a-z' 'A-Z')" >"$dst.tmp" && age-keygen -y "$dst.tmp" </dev/null 2>/dev/null || true)"
if [ -z "$pub" ]; then
rm -f "$dst.tmp"
warn "не удалось сгенерировать age-ключ"
return 0
fi
{
printf '# created: %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
printf '# public key: %s\n' "$pub"
cat "$dst.tmp"
} >"$dst"
rm -f "$dst.tmp"
}
# bech32_encode кодирует 32-байтовый ключ (hex) в data-часть bech32 (BIP-173).
bech32_encode() {
local hex="$1"
python3 - "$hex" <<'PYEOF'
import sys
hexs = sys.argv[1]
data = bytes.fromhex(hexs)
# convertbits(8 -> 5)
bits = 0
value = 0
out = []
for byte in data:
value = (value << 8) | byte
bits += 8
while bits >= 5:
bits -= 5
out.append((value >> bits) & 31)
if bits:
out.append((value << (5 - bits)) & 31)
charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
print("".join(charset[d] for d in out))
PYEOF
}
generate_secrets() {
info "секреты"
local env_existing=0
@@ -520,17 +569,15 @@ generate_secrets() {
AGE_KEY_FILE="${GLCHAT_DATA_DIR}/backups/age-key.txt"
else
AGE_KEY_FILE="${GLCHAT_DATA_DIR}/backups/age-key.txt"
if have age-keygen; then
age-keygen -o "$AGE_KEY_FILE" >/dev/null 2>&1
else
warn "age-keygen не найден: создаём ed25519-ключ через openssl"
openssl genpkey -algorithm ED25519 -out "$AGE_KEY_FILE" 2>/dev/null
fi
generate_age_key "$AGE_KEY_FILE"
fi
chmod 600 "$AGE_KEY_FILE"
AGE_RECIPIENT="$(grep -o 'age1[0-9a-z]*' "$AGE_KEY_FILE" | head -1 || true)"
if [ -z "$AGE_RECIPIENT" ] && have age-keygen; then
AGE_RECIPIENT="$(age-keygen -y "$AGE_KEY_FILE" 2>/dev/null || true)"
AGE_RECIPIENT="$(age-keygen -y "$AGE_KEY_FILE" </dev/null 2>/dev/null || true)"
fi
if [ -z "$AGE_RECIPIENT" ]; then
warn "не удалось определить публичный age-ключ: бэкапы будут без шифрования"
fi
ok "age-ключ бэкапов: ${AGE_KEY_FILE}"
}