changing the bootstrap process
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
home.stateVersion = "25.11";
|
home.stateVersion = "26.05";
|
||||||
|
|
||||||
programs.home-manager.enable = true;
|
programs.home-manager.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
networking.hostName = "desktop";
|
networking.hostName = "desktop";
|
||||||
|
|
||||||
|
users.users.root.hashedPassword = null;
|
||||||
|
|
||||||
users.users.user = {
|
users.users.user = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
home = "/home/user";
|
home = "/home/user";
|
||||||
@@ -29,5 +31,5 @@
|
|||||||
users.user = import ../../home/user.nix;
|
users.user = import ../../home/user.nix;
|
||||||
};
|
};
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
system.stateVersion = "26.05";
|
||||||
}
|
}
|
||||||
|
|||||||
+83
-124
@@ -1,168 +1,127 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
REPO_DIR="/home/user/nixos-config"
|
umask 077
|
||||||
PERSIST_DIR="/persist"
|
|
||||||
KEY_DIR="${PERSIST_DIR}/keys"
|
|
||||||
HOST_KEY="${KEY_DIR}/host-age.key"
|
|
||||||
|
|
||||||
SOPS_TEMPLATE="${REPO_DIR}/.sops.yaml.template"
|
# Repository containing this script.
|
||||||
LOCAL_SOPS="${REPO_DIR}/.sops.yaml"
|
REPO="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
|
||||||
echo "==> NixOS host bootstrap"
|
# Mounted target system.
|
||||||
|
TARGET="/mnt"
|
||||||
|
PERSIST="$TARGET/persist"
|
||||||
|
|
||||||
if [[ "${EUID}" -ne 0 ]]; then
|
KEY_DIR="$PERSIST/keys"
|
||||||
echo "ERROR: Dieses Script muss als root ausgeführt werden."
|
HOST_KEY="$KEY_DIR/host-age.key"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v age-keygen >/dev/null 2>&1; then
|
SOPS_TEMPLATE="$REPO/.sops.yaml.template"
|
||||||
echo "ERROR: age-keygen wurde nicht gefunden."
|
SOPS_CONFIG="$REPO/.sops.yaml"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v sops >/dev/null 2>&1; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
echo "ERROR: sops wurde nicht gefunden."
|
echo "ERROR: run this script as root."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "${SOPS_AGE_KEY_FILE:-}" ]]; then
|
if [[ -z "${SOPS_AGE_KEY_FILE:-}" ]]; then
|
||||||
echo "ERROR: SOPS_AGE_KEY_FILE ist nicht gesetzt."
|
echo "ERROR: SOPS_AGE_KEY_FILE is not set."
|
||||||
echo
|
echo
|
||||||
echo "Beispiel:"
|
echo "Example:"
|
||||||
|
echo " sudo env SOPS_AGE_KEY_FILE=age/yubikey-a.txt ./scripts/bootstrap-host.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$SOPS_AGE_KEY_FILE" ]]; then
|
||||||
|
echo "ERROR: YubiKey identity file not found:"
|
||||||
|
echo " $SOPS_AGE_KEY_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$PERSIST" ]]; then
|
||||||
|
echo "ERROR: /mnt/persist is not mounted."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$SOPS_TEMPLATE" ]]; then
|
||||||
|
echo "ERROR: missing SOPS template:"
|
||||||
|
echo " $SOPS_TEMPLATE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e "$HOST_KEY" ]]; then
|
||||||
|
echo "ERROR: host age key already exists:"
|
||||||
|
echo " $HOST_KEY"
|
||||||
echo
|
echo
|
||||||
echo " SOPS_AGE_KEY_FILE=${REPO_DIR}/age/yubikey-a.txt \\"
|
echo "Refusing to overwrite it."
|
||||||
echo " sudo -E ${REPO_DIR}/scripts/bootstrap-host.sh"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -f "${SOPS_AGE_KEY_FILE}" ]]; then
|
if [[ -e "$SOPS_CONFIG" ]]; then
|
||||||
echo "ERROR: SOPS_AGE_KEY_FILE existiert nicht:"
|
echo "ERROR: local .sops.yaml already exists:"
|
||||||
echo " ${SOPS_AGE_KEY_FILE}"
|
echo " $SOPS_CONFIG"
|
||||||
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
|
||||||
echo "Es wird nichts überschrieben."
|
echo "Refusing to overwrite it."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -e "${LOCAL_SOPS}" ]]; then
|
echo "==> Checking SOPS access through YubiKey..."
|
||||||
echo "ERROR: Lokale .sops.yaml existiert bereits:"
|
|
||||||
echo " ${LOCAL_SOPS}"
|
if ! sops --config "$SOPS_TEMPLATE" decrypt \
|
||||||
echo
|
"$REPO/secrets/user-password.yaml" >/dev/null; then
|
||||||
echo "Es wird nichts überschrieben."
|
echo "ERROR: SOPS could not decrypt the test secret."
|
||||||
|
echo "Check the YubiKey and SOPS_AGE_KEY_FILE."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
echo " YubiKey SOPS access: OK"
|
||||||
echo "==> SOPS identity:"
|
|
||||||
echo " ${SOPS_AGE_KEY_FILE}"
|
|
||||||
|
|
||||||
echo
|
echo "==> Creating host age key..."
|
||||||
echo "==> Erzeuge Host-age-Key"
|
|
||||||
|
|
||||||
install -d -m 0700 "${KEY_DIR}"
|
install -d -m 0700 "$KEY_DIR"
|
||||||
|
|
||||||
age-keygen -o "${HOST_KEY}"
|
age-keygen -o "$HOST_KEY"
|
||||||
|
|
||||||
chmod 0600 "${HOST_KEY}"
|
chmod 0600 "$HOST_KEY"
|
||||||
chown root:root "${HOST_KEY}"
|
chown root:root "$HOST_KEY"
|
||||||
|
|
||||||
HOST_RECIPIENT="$(age-keygen -y "${HOST_KEY}")"
|
HOST_RECIPIENT="$(age-keygen -y "$HOST_KEY")"
|
||||||
|
|
||||||
echo
|
echo " Host recipient:"
|
||||||
echo "==> Host recipient:"
|
echo " $HOST_RECIPIENT"
|
||||||
echo
|
|
||||||
echo " ${HOST_RECIPIENT}"
|
|
||||||
|
|
||||||
echo
|
echo "==> Creating local .sops.yaml..."
|
||||||
echo "==> Erzeuge lokale .sops.yaml"
|
|
||||||
|
|
||||||
sed "s/AGE_HOST_D/${HOST_RECIPIENT}/g" \
|
sed \
|
||||||
"${SOPS_TEMPLATE}" > "${LOCAL_SOPS}"
|
"s|AGE_HOST_D|$HOST_RECIPIENT|g" \
|
||||||
|
"$SOPS_TEMPLATE" \
|
||||||
|
> "$SOPS_CONFIG"
|
||||||
|
|
||||||
chmod 0600 "${LOCAL_SOPS}"
|
chmod 0600 "$SOPS_CONFIG"
|
||||||
|
|
||||||
echo
|
echo "==> Rekeying secrets..."
|
||||||
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
|
export SOPS_CONFIG
|
||||||
|
|
||||||
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
|
shopt -s nullglob
|
||||||
secret_files=( "${REPO_DIR}"/secrets/*.yaml )
|
secrets=( "$REPO"/secrets/*.yaml )
|
||||||
shopt -u nullglob
|
|
||||||
|
|
||||||
if [[ "${#secret_files[@]}" -eq 0 ]]; then
|
if (( ${#secrets[@]} == 0 )); then
|
||||||
echo
|
echo " No secrets found."
|
||||||
echo "Keine secrets/*.yaml gefunden."
|
else
|
||||||
echo "Host-Key wurde erfolgreich erzeugt."
|
for secret in "${secrets[@]}"; do
|
||||||
exit 0
|
echo " Updating $(basename "$secret")"
|
||||||
|
|
||||||
|
sops updatekeys --yes "$secret"
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "==> Rekeye Secrets"
|
echo "==> Bootstrap complete."
|
||||||
|
|
||||||
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
|
||||||
echo "Host key:"
|
echo "Host key:"
|
||||||
echo " ${HOST_KEY}"
|
echo " $HOST_KEY"
|
||||||
echo
|
echo
|
||||||
echo "SOPS config:"
|
echo "SOPS configuration:"
|
||||||
echo " ${LOCAL_SOPS}"
|
echo " $SOPS_CONFIG"
|
||||||
|
echo
|
||||||
|
echo "You can now run:"
|
||||||
|
echo
|
||||||
|
echo " nixos-install --flake $REPO#desktop"
|
||||||
|
|||||||
Reference in New Issue
Block a user