mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-07-27 02:48:24 +00:00
update 1.2.2.3 beta
This commit is contained in:
@@ -652,6 +652,7 @@ _bk_manage_destinations() {
|
||||
1 "$(translate "Proxmox Backup Server (PBS) destinations")" \
|
||||
2 "$(translate "Borg repositories")" \
|
||||
3 "$(translate "Local archive targets (paths + USB mount/unmount)")" \
|
||||
4 "$(translate "PBS encryption keyfile (show / replace / remove)")" \
|
||||
0 "$(translate "Return")" \
|
||||
3>&1 1>&2 2>&3) || break
|
||||
|
||||
@@ -666,11 +667,202 @@ _bk_manage_destinations() {
|
||||
3)
|
||||
_bk_manage_local_destinations
|
||||
;;
|
||||
4)
|
||||
_bk_manage_pbs_encryption_keyfile
|
||||
;;
|
||||
0) break ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Backup the current keyfile + its paired files to /root under a
|
||||
# timestamped prefix. Returns the timestamp on success (empty on
|
||||
# failure). Never overwrites existing files. Used before any
|
||||
# destructive change (replace / remove) so the operator can still
|
||||
# decrypt pre-existing backups if they need to.
|
||||
_bk_pbs_backup_keyfile_to_root() {
|
||||
local ts key_file="$HB_STATE_DIR/pbs-key.conf"
|
||||
local pass_file="$HB_STATE_DIR/pbs-key.pass"
|
||||
local recovery_enc="$HB_STATE_DIR/pbs-key.recovery.enc"
|
||||
[[ -f "$key_file" ]] || { echo ""; return 1; }
|
||||
ts=$(date +%Y%m%d_%H%M%S)
|
||||
umask 077
|
||||
cp -f "$key_file" "/root/pbs-key.old-${ts}.conf" 2>/dev/null || { echo ""; return 1; }
|
||||
chmod 600 "/root/pbs-key.old-${ts}.conf" 2>/dev/null || true
|
||||
if [[ -f "$pass_file" ]]; then
|
||||
cp -f "$pass_file" "/root/pbs-key.old-${ts}.pass" 2>/dev/null || true
|
||||
chmod 600 "/root/pbs-key.old-${ts}.pass" 2>/dev/null || true
|
||||
fi
|
||||
if [[ -f "$recovery_enc" ]]; then
|
||||
cp -f "$recovery_enc" "/root/pbs-key.old-${ts}.recovery.enc" 2>/dev/null || true
|
||||
chmod 600 "/root/pbs-key.old-${ts}.recovery.enc" 2>/dev/null || true
|
||||
fi
|
||||
echo "$ts"
|
||||
}
|
||||
|
||||
# Wipe local keyfile + pass + recovery. Never touches PBS.
|
||||
_bk_pbs_wipe_local_keyfile() {
|
||||
rm -f "$HB_STATE_DIR/pbs-key.conf" \
|
||||
"$HB_STATE_DIR/pbs-key.pass" \
|
||||
"$HB_STATE_DIR/pbs-key.recovery.enc" 2>/dev/null
|
||||
}
|
||||
|
||||
# Dedicated management submenu for the PBS encryption keyfile.
|
||||
# Available as option 4 of "Configure backup destinations". All
|
||||
# destructive actions offer a backup-to-/root step first and require
|
||||
# an explicit confirmation before touching disk.
|
||||
_bk_manage_pbs_encryption_keyfile() {
|
||||
local key_file="$HB_STATE_DIR/pbs-key.conf"
|
||||
local pass_file="$HB_STATE_DIR/pbs-key.pass"
|
||||
local recovery_enc="$HB_STATE_DIR/pbs-key.recovery.enc"
|
||||
while true; do
|
||||
local installed=0
|
||||
[[ -s "$key_file" ]] && installed=1
|
||||
|
||||
local preview=""
|
||||
if (( installed )); then
|
||||
local fp="" kdf_hint="unknown" installed_at=""
|
||||
if command -v proxmox-backup-client >/dev/null 2>&1; then
|
||||
fp=$(proxmox-backup-client key info --output-format json "$key_file" 2>/dev/null \
|
||||
| grep -oE '"fingerprint"[[:space:]]*:[[:space:]]*"[^"]*"' \
|
||||
| head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
||||
fi
|
||||
if grep -q '"kdf":[[:space:]]*"None"' "$key_file" 2>/dev/null; then
|
||||
kdf_hint="none"
|
||||
elif grep -q '"Scrypt"' "$key_file" 2>/dev/null; then
|
||||
kdf_hint="scrypt"
|
||||
fi
|
||||
installed_at=$(date -r "$key_file" '+%Y-%m-%d %H:%M' 2>/dev/null || echo "")
|
||||
preview="$(hb_translate "Installed:") \Zb\Z2$(hb_translate "yes")\Zn"$'\n'
|
||||
preview+="$(hb_translate "Path:") $key_file"$'\n'
|
||||
[[ -n "$installed_at" ]] && preview+="$(hb_translate "Installed at:") $installed_at"$'\n'
|
||||
preview+="$(hb_translate "KDF:") $kdf_hint"$'\n'
|
||||
[[ -n "$fp" ]] && preview+="$(hb_translate "Fingerprint:") $fp"$'\n'
|
||||
preview+="$(hb_translate "Keyfile passphrase stored:") "
|
||||
[[ -s "$pass_file" ]] && preview+="\Zb\Z2$(hb_translate "yes")\Zn"$'\n' || preview+="\Zb$(hb_translate "no")\Zn"$'\n'
|
||||
preview+="$(hb_translate "Recovery escrow present:") "
|
||||
[[ -s "$recovery_enc" ]] && preview+="\Zb\Z2$(hb_translate "yes")\Zn"$'\n' || preview+="\Zb$(hb_translate "no")\Zn"$'\n'
|
||||
else
|
||||
preview="$(hb_translate "No keyfile installed on this host.")"$'\n\n'
|
||||
preview+="$(hb_translate "PBS encrypted backups won't work until one is generated or imported. Both actions happen during job creation the first time you tick 'Encrypt backups'.")"
|
||||
fi
|
||||
|
||||
local choice
|
||||
if (( installed )); then
|
||||
choice=$(dialog --backtitle "ProxMenux" --colors \
|
||||
--title "$(translate "Manage PBS encryption keyfile")" \
|
||||
--menu "\n${preview}\n" \
|
||||
"$HB_UI_MENU_H" "$HB_UI_MENU_W" "$HB_UI_MENU_LIST" \
|
||||
"info" "$(hb_translate "Show detailed keyfile info")" \
|
||||
"pass" "$(hb_translate "Update stored keyfile passphrase")" \
|
||||
"replace" "$(hb_translate "Replace keyfile (generate new or import)")" \
|
||||
"remove" "$(hb_translate "Remove keyfile from this host")" \
|
||||
"back" "$(hb_translate "← Return")" \
|
||||
3>&1 1>&2 2>&3) || break
|
||||
else
|
||||
choice=$(dialog --backtitle "ProxMenux" --colors \
|
||||
--title "$(translate "Manage PBS encryption keyfile")" \
|
||||
--menu "\n${preview}\n" \
|
||||
"$HB_UI_MENU_H" "$HB_UI_MENU_W" "$HB_UI_MENU_LIST" \
|
||||
"back" "$(hb_translate "← Return")" \
|
||||
3>&1 1>&2 2>&3) || break
|
||||
fi
|
||||
|
||||
case "$choice" in
|
||||
info)
|
||||
# Full `key info` output (may need passphrase for scrypt).
|
||||
local info_out
|
||||
info_out=$(proxmox-backup-client key info "$key_file" 2>&1)
|
||||
dialog --backtitle "ProxMenux" \
|
||||
--title "$(hb_translate "Keyfile info")" \
|
||||
--msgbox "$info_out" 20 80
|
||||
;;
|
||||
pass)
|
||||
local new_pass new_pass2
|
||||
while true; do
|
||||
new_pass=$(dialog --backtitle "ProxMenux" --title "$(hb_translate "Update keyfile passphrase")" \
|
||||
--insecure --passwordbox "$(hb_translate "New passphrase used to unlock the keyfile (leave blank to remove the stored passphrase — for kdf=none keyfiles):")" \
|
||||
"$HB_UI_PASS_H" "$HB_UI_PASS_W" "" 3>&1 1>&2 2>&3) || { new_pass=""; break; }
|
||||
if [[ -z "$new_pass" ]]; then
|
||||
new_pass2=""
|
||||
break
|
||||
fi
|
||||
new_pass2=$(dialog --backtitle "ProxMenux" --title "$(hb_translate "Update keyfile passphrase")" \
|
||||
--insecure --passwordbox "$(hb_translate "Confirm new passphrase:")" \
|
||||
"$HB_UI_PASS_H" "$HB_UI_PASS_W" "" 3>&1 1>&2 2>&3) || { new_pass=""; break; }
|
||||
[[ "$new_pass" == "$new_pass2" ]] && break
|
||||
dialog --backtitle "ProxMenux" \
|
||||
--msgbox "$(hb_translate "Passphrases do not match. Try again.")" 8 50
|
||||
done
|
||||
if [[ -n "$new_pass" ]]; then
|
||||
umask 077
|
||||
printf '%s' "$new_pass" > "$pass_file"
|
||||
chmod 600 "$pass_file" 2>/dev/null || true
|
||||
dialog --backtitle "ProxMenux" \
|
||||
--msgbox "$(hb_translate "Stored keyfile passphrase updated.")" 8 60
|
||||
else
|
||||
rm -f "$pass_file" 2>/dev/null
|
||||
dialog --backtitle "ProxMenux" \
|
||||
--msgbox "$(hb_translate "Stored keyfile passphrase removed.")" 8 60
|
||||
fi
|
||||
;;
|
||||
replace|remove)
|
||||
local action_title="$(hb_translate "Replace keyfile")"
|
||||
[[ "$choice" == "remove" ]] && action_title="$(hb_translate "Remove keyfile")"
|
||||
# Destructive warning + confirmation
|
||||
local warn_body
|
||||
warn_body="\Zb\Z1$(hb_translate "This is a destructive action")\Zn"$'\n\n'
|
||||
warn_body+="$(hb_translate "Backups already stored on PBS were encrypted with the current keyfile. After this action:")"$'\n'
|
||||
warn_body+=" • $(hb_translate "New backups will use the new (or no) keyfile.")"$'\n'
|
||||
warn_body+=" • $(hb_translate "Downloading pre-existing encrypted backups from this host will fail unless you keep a copy of the current key.")"$'\n'
|
||||
warn_body+=" • $(hb_translate "Existing recovery blobs on PBS stay intact — they still recover the old key with its original passphrase.")"$'\n\n'
|
||||
warn_body+="$(hb_translate "Continue?")"
|
||||
if ! dialog --backtitle "ProxMenux" --colors --yesno "$warn_body" 16 80; then
|
||||
continue
|
||||
fi
|
||||
local do_backup=1
|
||||
if ! dialog --backtitle "ProxMenux" \
|
||||
--title "$(hb_translate "Backup current key")" \
|
||||
--yesno "$(hb_translate "Save a copy of the current keyfile + passphrase + recovery blob under /root/pbs-key.old-<timestamp>.* before ${action_title,,}?")" \
|
||||
10 78; then
|
||||
do_backup=0
|
||||
fi
|
||||
local ts=""
|
||||
if (( do_backup )); then
|
||||
ts=$(_bk_pbs_backup_keyfile_to_root)
|
||||
if [[ -z "$ts" ]]; then
|
||||
dialog --backtitle "ProxMenux" \
|
||||
--msgbox "$(hb_translate "Backup to /root failed. Aborting.")" 8 60
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
_bk_pbs_wipe_local_keyfile
|
||||
if [[ "$choice" == "replace" ]]; then
|
||||
# Delegate to the yes/no + generate/import flow.
|
||||
# HB_ASK_ENCRYPT_INSTRUCTIONS is unused here, we
|
||||
# directly call the two helpers.
|
||||
local rmenu
|
||||
rmenu=$(dialog --backtitle "ProxMenux" \
|
||||
--title "$(hb_translate "Replace keyfile")" \
|
||||
--menu "$(hb_translate "How should the new keyfile be set up?")" \
|
||||
10 78 2 \
|
||||
"new" "$(hb_translate "Generate a new keyfile (per host — safest isolation)")" \
|
||||
"import" "$(hb_translate "Import an existing keyfile from a path (shared across hosts)")" \
|
||||
3>&1 1>&2 2>&3) || rmenu=""
|
||||
case "$rmenu" in
|
||||
new) _hb_pbs_create_new_keyfile || true ;;
|
||||
import) _hb_pbs_import_dialog || true ;;
|
||||
esac
|
||||
fi
|
||||
local done_msg="$action_title $(hb_translate "completed.")"
|
||||
[[ -n "$ts" ]] && done_msg+=$'\n\n'"$(hb_translate "Backup saved with prefix:") /root/pbs-key.old-${ts}"
|
||||
dialog --backtitle "ProxMenux" --msgbox "$done_msg" 10 78
|
||||
;;
|
||||
back|"") break ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
_bk_manage_extra_paths() {
|
||||
while true; do
|
||||
local -a paths=()
|
||||
|
||||
Reference in New Issue
Block a user