Add kiosk setup and deployment scripts (Phases 5 + 9)
Phase 5 — RPi Kiosk: - setup_kiosk.sh: full RPi OS Lite setup (X11, Chromium kiosk mode, auto-login, DPMS disabled, GPU memory split, screen rotation) - kiosk.service: systemd unit for reliable auto-start - update_kiosk.sh: reconfigure URL/rotation/resolution without re-setup - Handles both Bullseye and Bookworm RPi OS versions Phase 9 — Hardening + Deployment: - install.sh: full server setup (apt/pacman, vigilar user, venv, directories, permissions, mosquitto config, systemd units) - gen_cert.sh: TLS cert via mkcert or openssl fallback - gen_vapid_keys.sh: VAPID keys for Web Push notifications - setup_nut.sh: NUT configuration with USB UPS auto-detection - backup.sh: SQLite snapshot + config archive, cron-ready - uninstall.sh: clean removal with data preservation option - vigilar.service: hardened systemd unit (ProtectSystem, NoNewPrivileges, PrivateTmp, syscall filtering) - vigilar-mosquitto.conf: localhost-only MQTT broker config All scripts idempotent, bash -n validated, support Debian + Arch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
100
scripts/gen_vapid_keys.sh
Executable file
100
scripts/gen_vapid_keys.sh
Executable file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Vigilar — VAPID key generator for Web Push notifications
|
||||
# Uses py-vapid (from the vigilar venv) or falls back to openssl.
|
||||
|
||||
VENV_DIR="/opt/vigilar/venv"
|
||||
SECRETS_DIR="/etc/vigilar/secrets"
|
||||
PRIVATE_KEY_FILE="${SECRETS_DIR}/vapid_private.pem"
|
||||
PUBLIC_KEY_FILE="${SECRETS_DIR}/vapid_public.txt"
|
||||
VIGILAR_GROUP="vigilar"
|
||||
|
||||
info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; }
|
||||
ok() { printf '\033[1;32m[ OK ]\033[0m %s\n' "$*"; }
|
||||
warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; }
|
||||
fail() { printf '\033[1;31m[FAIL]\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
generate_with_py_vapid() {
|
||||
info "Generating VAPID keys with py-vapid"
|
||||
local python="${VENV_DIR}/bin/python"
|
||||
|
||||
"$python" -c "
|
||||
from py_vapid import Vapid
|
||||
import base64
|
||||
|
||||
v = Vapid()
|
||||
v.generate_keys()
|
||||
v.save_key('${PRIVATE_KEY_FILE}')
|
||||
|
||||
raw = v.public_key.public_bytes(
|
||||
encoding=__import__('cryptography.hazmat.primitives.serialization', fromlist=['Encoding']).Encoding.X962,
|
||||
format=__import__('cryptography.hazmat.primitives.serialization', fromlist=['PublicFormat']).PublicFormat.UncompressedPoint,
|
||||
)
|
||||
pub_b64 = base64.urlsafe_b64encode(raw).rstrip(b'=').decode()
|
||||
print(pub_b64)
|
||||
" | tee "$PUBLIC_KEY_FILE"
|
||||
}
|
||||
|
||||
generate_with_openssl() {
|
||||
info "Generating VAPID keys with openssl"
|
||||
|
||||
# Generate ECDSA P-256 private key in PEM format
|
||||
openssl ecparam -name prime256v1 -genkey -noout -out "$PRIVATE_KEY_FILE" 2>/dev/null
|
||||
|
||||
# Extract the public key in uncompressed point format, base64url-encode it
|
||||
local pub_b64
|
||||
pub_b64="$(openssl ec -in "$PRIVATE_KEY_FILE" -pubout -outform DER 2>/dev/null \
|
||||
| tail -c 65 \
|
||||
| base64 -w 0 \
|
||||
| tr '+/' '-_' \
|
||||
| tr -d '=')"
|
||||
|
||||
echo "$pub_b64" | tee "$PUBLIC_KEY_FILE"
|
||||
}
|
||||
|
||||
main() {
|
||||
info "=== Vigilar VAPID Key Generator ==="
|
||||
|
||||
sudo mkdir -p "$SECRETS_DIR"
|
||||
|
||||
if [[ -f "$PRIVATE_KEY_FILE" ]]; then
|
||||
warn "VAPID private key already exists at ${PRIVATE_KEY_FILE}"
|
||||
read -rp "Overwrite? [y/N] " answer
|
||||
if [[ ! "$answer" =~ ^[Yy]$ ]]; then
|
||||
info "Keeping existing key"
|
||||
if [[ -f "$PUBLIC_KEY_FILE" ]]; then
|
||||
info "Public key (base64url):"
|
||||
cat "$PUBLIC_KEY_FILE"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
local public_key
|
||||
if [[ -x "${VENV_DIR}/bin/python" ]] && "${VENV_DIR}/bin/python" -c "import py_vapid" 2>/dev/null; then
|
||||
public_key="$(generate_with_py_vapid)"
|
||||
elif command -v openssl &>/dev/null; then
|
||||
public_key="$(generate_with_openssl)"
|
||||
else
|
||||
fail "Neither py-vapid nor openssl found."
|
||||
fi
|
||||
|
||||
# Secure the private key
|
||||
sudo chown root:root "$PRIVATE_KEY_FILE"
|
||||
sudo chmod 0600 "$PRIVATE_KEY_FILE"
|
||||
|
||||
# Public key file is not sensitive
|
||||
sudo chown root:"${VIGILAR_GROUP}" "$PUBLIC_KEY_FILE"
|
||||
sudo chmod 0644 "$PUBLIC_KEY_FILE"
|
||||
|
||||
echo
|
||||
ok "VAPID keys generated"
|
||||
info " Private key: ${PRIVATE_KEY_FILE}"
|
||||
info " Public key (base64url):"
|
||||
echo " ${public_key}"
|
||||
echo
|
||||
info "Use the public key above in your web app's push subscription config."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user