#!/bin/bash # deploy-wireguard-credentials.sh — деплой конфига WireGuard в CT 109 # Секреты из Vaultwarden (объект LOCAL_VPN_SERVER_WG, поле wg0_conf — полный конфиг). # # Использование: # /root/scripts/deploy-wireguard-credentials.sh # /root/scripts/deploy-wireguard-credentials.sh --dry-run # # Перед первым запуском: создать в Vaultwarden запись LOCAL_VPN_SERVER_WG, # добавить кастомное поле wg0_conf (hidden) с полным содержимым /etc/wireguard/wg0.conf. # # Ротация: сменил ключи в Vaultwarden → запустил скрипт → systemctl restart wg-quick@wg0 # # Требования: bw, jq, /root/.bw-master (chmod 600) set -e CT_ID=109 WG_CONF_PATH="/etc/wireguard/wg0.conf" 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() { WG_CONF=$(bw get item "LOCAL_VPN_SERVER_WG" 2>/dev/null | jq -r '.fields[] | select(.name=="wg0_conf") | .value // empty') if [ -z "$WG_CONF" ]; then err "LOCAL_VPN_SERVER_WG not found or missing wg0_conf field. Create it in Vaultwarden, add field wg0_conf with full wg0.conf content." exit 1 fi if ! echo "$WG_CONF" | grep -q '\[Interface\]'; then err "wg0_conf: invalid format (expected [Interface] section)" exit 1 fi } push_conf() { local tmp tmp=$(mktemp) echo "$WG_CONF" > "$tmp" pct push "$CT_ID" "$tmp" "${WG_CONF_PATH}.tmp" rm -f "$tmp" pct exec "$CT_ID" -- bash -c "chmod 600 ${WG_CONF_PATH}.tmp && mv ${WG_CONF_PATH}.tmp ${WG_CONF_PATH}" log "wg0.conf written (atomic), chmod 600" } restart_wg() { pct exec "$CT_ID" -- systemctl restart wg-quick@wg0 log "wg-quick@wg0 restarted" } main() { log "deploy-wireguard-credentials start (dry_run=$DRY_RUN)" ensure_bw_unlocked get_secrets if [ "$DRY_RUN" = true ]; then log "DRY-RUN: would push wg0.conf and restart WireGuard" log " wg0_conf: $(echo "$WG_CONF" | head -3)..." exit 0 fi push_conf restart_wg log "done" } main