128 lines
2.5 KiB
Bash
Executable File
128 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
umask 077
|
|
|
|
# Repository containing this script.
|
|
REPO="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
# Mounted target system.
|
|
TARGET="/mnt"
|
|
PERSIST="$TARGET/persist"
|
|
|
|
KEY_DIR="$PERSIST/keys"
|
|
HOST_KEY="$KEY_DIR/host-age.key"
|
|
|
|
SOPS_TEMPLATE="$REPO/.sops.yaml.template"
|
|
SOPS_CONFIG="$REPO/.sops.yaml"
|
|
|
|
if [[ $EUID -ne 0 ]]; then
|
|
echo "ERROR: run this script as root."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "${SOPS_AGE_KEY_FILE:-}" ]]; then
|
|
echo "ERROR: SOPS_AGE_KEY_FILE is not set."
|
|
echo
|
|
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 "Refusing to overwrite it."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -e "$SOPS_CONFIG" ]]; then
|
|
echo "ERROR: local .sops.yaml already exists:"
|
|
echo " $SOPS_CONFIG"
|
|
echo
|
|
echo "Refusing to overwrite it."
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> Checking SOPS access through YubiKey..."
|
|
|
|
if ! sops --config "$SOPS_TEMPLATE" decrypt \
|
|
"$REPO/secrets/user-password.yaml" >/dev/null; then
|
|
echo "ERROR: SOPS could not decrypt the test secret."
|
|
echo "Check the YubiKey and SOPS_AGE_KEY_FILE."
|
|
exit 1
|
|
fi
|
|
|
|
echo " YubiKey SOPS access: OK"
|
|
|
|
echo "==> Creating 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 " Host recipient:"
|
|
echo " $HOST_RECIPIENT"
|
|
|
|
echo "==> Creating local .sops.yaml..."
|
|
|
|
sed \
|
|
"s|AGE_HOST_D|$HOST_RECIPIENT|g" \
|
|
"$SOPS_TEMPLATE" \
|
|
> "$SOPS_CONFIG"
|
|
|
|
chmod 0600 "$SOPS_CONFIG"
|
|
|
|
echo "==> Rekeying secrets..."
|
|
|
|
export SOPS_CONFIG
|
|
|
|
shopt -s nullglob
|
|
secrets=( "$REPO"/secrets/*.yaml )
|
|
|
|
if (( ${#secrets[@]} == 0 )); then
|
|
echo " No secrets found."
|
|
else
|
|
for secret in "${secrets[@]}"; do
|
|
echo " Updating $(basename "$secret")"
|
|
|
|
sops updatekeys --yes "$secret"
|
|
done
|
|
fi
|
|
|
|
echo
|
|
echo "==> Bootstrap complete."
|
|
echo
|
|
echo "Host key:"
|
|
echo " $HOST_KEY"
|
|
echo
|
|
echo "SOPS configuration:"
|
|
echo " $SOPS_CONFIG"
|
|
echo
|
|
echo "You can now run:"
|
|
echo
|
|
echo " nixos-install --flake $REPO#desktop"
|