#!/usr/bin/env bash set -euo pipefail REPO_DIR="/home/user/nixos-config" PERSIST_DIR="/persist" KEY_DIR="${PERSIST_DIR}/keys" HOST_KEY="${KEY_DIR}/host-age.key" SOPS_TEMPLATE="${REPO_DIR}/.sops.yaml.template" LOCAL_SOPS="${REPO_DIR}/.sops.yaml" echo "==> NixOS host bootstrap" if [[ "${EUID}" -ne 0 ]]; then echo "ERROR: Dieses Script muss als root ausgeführt werden." exit 1 fi if ! command -v age-keygen >/dev/null 2>&1; then echo "ERROR: age-keygen wurde nicht gefunden." exit 1 fi if ! command -v sops >/dev/null 2>&1; then echo "ERROR: sops wurde nicht gefunden." exit 1 fi if [[ -z "${SOPS_AGE_KEY_FILE:-}" ]]; then echo "ERROR: SOPS_AGE_KEY_FILE ist nicht gesetzt." echo echo "Beispiel:" echo echo " SOPS_AGE_KEY_FILE=${REPO_DIR}/age/yubikey-a.txt \\" echo " sudo -E ${REPO_DIR}/scripts/bootstrap-host.sh" exit 1 fi if [[ ! -f "${SOPS_AGE_KEY_FILE}" ]]; then echo "ERROR: SOPS_AGE_KEY_FILE existiert nicht:" echo " ${SOPS_AGE_KEY_FILE}" exit 1 fi if ! mountpoint -q "${PERSIST_DIR}"; then echo "ERROR: ${PERSIST_DIR} ist nicht gemountet." exit 1 fi if [[ ! -d "${REPO_DIR}" ]]; then echo "ERROR: Repository fehlt:" echo " ${REPO_DIR}" exit 1 fi if [[ ! -f "${SOPS_TEMPLATE}" ]]; then echo "ERROR: SOPS template fehlt:" echo " ${SOPS_TEMPLATE}" exit 1 fi if [[ -e "${HOST_KEY}" ]]; then echo "ERROR: Host-Key existiert bereits:" echo " ${HOST_KEY}" echo echo "Es wird nichts überschrieben." exit 1 fi if [[ -e "${LOCAL_SOPS}" ]]; then echo "ERROR: Lokale .sops.yaml existiert bereits:" echo " ${LOCAL_SOPS}" echo echo "Es wird nichts überschrieben." exit 1 fi echo echo "==> SOPS identity:" echo " ${SOPS_AGE_KEY_FILE}" echo echo "==> Erzeuge Host-age-Key" install -d -m 0700 "${KEY_DIR}" age-keygen -o "${HOST_KEY}" chmod 0600 "${HOST_KEY}" chown root:root "${HOST_KEY}" HOST_RECIPIENT="$(age-keygen -y "${HOST_KEY}")" echo echo "==> Host recipient:" echo echo " ${HOST_RECIPIENT}" echo echo "==> Erzeuge lokale .sops.yaml" sed "s/AGE_HOST_D/${HOST_RECIPIENT}/g" \ "${SOPS_TEMPLATE}" > "${LOCAL_SOPS}" chmod 0600 "${LOCAL_SOPS}" echo echo "============================================================" echo "Der Host-Key wurde erzeugt." echo echo "Private Key:" echo " ${HOST_KEY}" echo echo "Lokale SOPS-Konfiguration:" echo " ${LOCAL_SOPS}" echo echo "Jetzt werden die vorhandenen Secrets auf" echo "YubiKey A + YubiKey B + Recovery + Host" echo "rekeyed." echo "============================================================" echo read -r -p "Rekeying jetzt durchführen? [y/N] " answer if [[ "${answer}" != "y" && "${answer}" != "Y" ]]; then echo echo "Abgebrochen." echo echo "Der Host-Key und .sops.yaml wurden bereits erzeugt." echo "Das Rekeying wurde NICHT durchgeführt." exit 0 fi shopt -s nullglob secret_files=( "${REPO_DIR}"/secrets/*.yaml ) shopt -u nullglob if [[ "${#secret_files[@]}" -eq 0 ]]; then echo echo "Keine secrets/*.yaml gefunden." echo "Host-Key wurde erfolgreich erzeugt." exit 0 fi echo echo "==> Rekeye Secrets" for secret in "${secret_files[@]}"; do echo echo "Updating:" echo " ${secret}" SOPS_AGE_KEY_FILE="${SOPS_AGE_KEY_FILE}" \ sops updatekeys --yes "${secret}" done echo echo "==> Bootstrap abgeschlossen." echo echo "Host recipient:" echo " ${HOST_RECIPIENT}" echo echo "Host key:" echo " ${HOST_KEY}" echo echo "SOPS config:" echo " ${LOCAL_SOPS}"