#!/bin/bash # deploy-beget-credentials.sh — деплой кредов Beget для certbot DNS-01 в CT 100 # Секреты из Vaultwarden (объект beget). Атомарная запись beget.ini. # # Использование: # /root/scripts/deploy-beget-credentials.sh # деплой # /root/scripts/deploy-beget-credentials.sh --dry-run # проверка без записи # # Ротация: сменил пароль в Vaultwarden → запустил скрипт → готово. # # Требования: bw, jq, /root/.bw-master (chmod 600) set -e CT_ID=100 BEGET_INI_PATH="/root/.secrets/certbot/beget.ini" BW_MASTER_FILE="${BW_MASTER_PASSWORD_FILE:-/root/.bw-master}" DRY_RUN=false for arg in "$@"; do case "$arg" in --dry-run) DRY_RUN=true ;; esac done export PATH="/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH}" log() { echo "[$(date -Iseconds)] $*"; } err() { echo "[$(date -Iseconds)] ERROR: $*" >&2; } ensure_bw_unlocked() { local status status=$(bw status 2>/dev/null | jq -r '.status' 2>/dev/null || echo "unknown") if [ "$status" = "unlocked" ]; then log "bw already unlocked, reusing session" return 0 fi if [ ! -f "$BW_MASTER_FILE" ]; then err "Missing $BW_MASTER_FILE" exit 1 fi export BW_SESSION=$(bw unlock --passwordfile "$BW_MASTER_FILE" --raw 2>/dev/null) || { err "bw unlock failed" exit 1 } log "bw unlocked" } get_secrets() { BEGET_USER=$(bw get username "beget" 2>/dev/null) BEGET_PASS=$(bw get password "beget" 2>/dev/null) if [ -z "$BEGET_USER" ] || [ -z "$BEGET_PASS" ]; then err "beget: missing username or password in Vaultwarden" exit 1 fi } gen_ini() { local tmp tmp=$(mktemp) cat > "$tmp" << EOF dns_beget_api_username = ${BEGET_USER} dns_beget_api_password = ${BEGET_PASS} EOF echo "$tmp" } push_ini_atomic() { local tmp="$1" local dir dir=$(dirname "$BEGET_INI_PATH") pct exec "$CT_ID" -- mkdir -p "$dir" pct push "$CT_ID" "$tmp" "${BEGET_INI_PATH}.tmp" pct exec "$CT_ID" -- bash -c "mv ${BEGET_INI_PATH}.tmp ${BEGET_INI_PATH} && chmod 600 ${BEGET_INI_PATH} && chown root:root ${BEGET_INI_PATH}" log "beget.ini written (atomic), chmod 600, owner root" } deploy_pre_hook() { local hook_path="/etc/letsencrypt/renewal-hooks/pre/check-beget-credentials.sh" local hook_src hook_src="$(cd "$(dirname "$0")" && pwd)/certbot-hooks/check-beget-credentials.sh" if [ ! -f "$hook_src" ]; then log "pre-hook source not found ($hook_src), skip" return 0 fi if pct exec "$CT_ID" -- test -f "$hook_path" 2>/dev/null; then pct push "$CT_ID" "$hook_src" "$hook_path" pct exec "$CT_ID" -- chmod +x "$hook_path" log "pre-hook updated" else pct push "$CT_ID" "$hook_src" "$hook_path" pct exec "$CT_ID" -- chmod +x "$hook_path" log "pre-hook deployed" fi } main() { log "deploy-beget-credentials start (dry_run=$DRY_RUN)" ensure_bw_unlocked get_secrets if [ "$DRY_RUN" = true ]; then log "DRY-RUN: would push beget.ini and deploy pre-hook" log " dns_beget_api_username=$BEGET_USER" log " dns_beget_api_password=***" exit 0 fi tmp=$(gen_ini) trap "rm -f $tmp" EXIT push_ini_atomic "$tmp" deploy_pre_hook log "done" } main