Refactor README, architecture, and backup documentation to emphasize the use of Vaultwarden for credential management across various services. Update scripts for Nextcloud, Gitea, Paperless, and others to reference Vaultwarden for sensitive information. Remove outdated references to previous backup strategies and ensure clarity on credential retrieval processes. This improves security practices and streamlines backup operations.
96 lines
2.7 KiB
Bash
96 lines
2.7 KiB
Bash
#!/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
|