From 27a8c7fad94be4c1e4ec727c96bbb8df81834958 Mon Sep 17 00:00:00 2001 From: beatzaplenty Date: Tue, 28 Jul 2026 09:02:32 +1000 Subject: [PATCH] fix(ipa): SSH as wayne with sudo instead of root on domain controller Co-Authored-By: Claude Sonnet 4.6 --- scripts/ipa/create-nixos-ipa-host-account.sh | 37 ++++++++++---------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/scripts/ipa/create-nixos-ipa-host-account.sh b/scripts/ipa/create-nixos-ipa-host-account.sh index fbe4dd3..ceb3bcb 100755 --- a/scripts/ipa/create-nixos-ipa-host-account.sh +++ b/scripts/ipa/create-nixos-ipa-host-account.sh @@ -17,17 +17,19 @@ # # Options: # --ip Register this IP with the IPA host record (optional). -# --dc SSH as root to this host for ipa-getkeytab. +# --dc SSH to this host for ipa-getkeytab. # Default: $IPA_SERVER (from env.sh / environment). -# --dc-user SSH user on the domain controller. Default: root. +# --dc-user SSH user on the domain controller. Default: wayne. # --dry-run Print what would be done without making any changes. # -h, --help Show this message. # # Prereqs: # 1. Run from the repo root (so .sops.yaml and secrets/ are found). -# 2. SSH access to the domain controller as --dc-user (default: root). -# If there's no valid Kerberos ticket on the DC, the script runs -# `kinit admin` there interactively — you'll be prompted for the IPA +# 2. SSH access to the domain controller as --dc-user (default: wayne) +# with passwordless sudo (or sudo cached). IPA commands and kinit run +# as root via sudo so the Kerberos ticket is in root's cache where all +# ipa tools expect it. If there's no valid ticket, the script runs +# `sudo kinit admin` interactively — you'll be prompted for the IPA # admin password once. The password never touches this script. # 3. The host's age key(s) must already be in .sops.yaml. Run # scripts/secrets/sync-host-keys.sh first so the host @@ -47,7 +49,7 @@ source "${SCRIPT_DIR}/../env.sh" # --- Argument parsing --- DC_HOST="${IPA_SERVER}" -DC_USER="root" +DC_USER="wayne" IP_ADDR="" DRY_RUN=false HOSTNAME="" @@ -183,16 +185,15 @@ fi log "Adding FreeIPA host account: ${FQDN}" # Ensure there's a valid admin Kerberos ticket on the DC. -# ipa host-add and ipa-getkeytab both need one. If the ticket is missing or -# expired, run kinit admin interactively over SSH (ssh -t allocates a PTY so -# kinit can prompt for the password normally — no password ever touches this -# script or the shell history on either machine). +# ipa host-add and ipa-getkeytab both need one. All IPA commands run via +# sudo so the ticket must be in root's cache — check and refresh as root. +# ssh -t allocates a PTY so kinit (and sudo if needed) can prompt normally; +# no password ever touches this script or the shell history. if ! $DRY_RUN; then - if ! ssh "${DC_USER}@${DC_HOST}" "klist -s" &>/dev/null; then - log "No valid Kerberos ticket on ${DC_HOST} — running kinit admin" - ssh -t "${DC_USER}@${DC_HOST}" "kinit admin" - # Verify it actually worked before proceeding. - if ! ssh "${DC_USER}@${DC_HOST}" "klist -s" &>/dev/null; then + if ! ssh "${DC_USER}@${DC_HOST}" "sudo klist -s" &>/dev/null; then + log "No valid Kerberos ticket on ${DC_HOST} — running sudo kinit admin" + ssh -t "${DC_USER}@${DC_HOST}" "sudo kinit admin" + if ! ssh "${DC_USER}@${DC_HOST}" "sudo klist -s" &>/dev/null; then echo "Error: kinit admin failed or produced no valid ticket." >&2 exit 1 fi @@ -207,7 +208,7 @@ IP_FLAG="" # --force: create the host record even if DNS doesn't resolve it yet. # Pipe through grep to suppress the "already exists" warning without # hiding real errors (ipa exits 1 for real errors, 0 for already-exists). -HOST_ADD_CMD="ipa host-add '${FQDN}' ${IP_FLAG} --force 2>&1 | \ +HOST_ADD_CMD="sudo ipa host-add '${FQDN}' ${IP_FLAG} --force 2>&1 | \ tee /dev/stderr | grep -q 'already exists' && echo '(host already registered)' || true" dc_run "bash -c \"${HOST_ADD_CMD}\"" @@ -215,7 +216,7 @@ dc_run "bash -c \"${HOST_ADD_CMD}\"" log "Fetching keytab for host/${FQDN}" -dc_run "ipa-getkeytab -s '${DC_HOST}' -p 'host/${FQDN}' -k '${DC_TMP}'" +dc_run "sudo ipa-getkeytab -s '${DC_HOST}' -p 'host/${FQDN}' -k '${DC_TMP}'" if $DRY_RUN; then echo "[dry-run] Would scp ${DC_USER}@${DC_HOST}:${DC_TMP} ${KEYTAB_SECRET}" @@ -224,7 +225,7 @@ else scp "${DC_USER}@${DC_HOST}:${DC_TMP}" "${KEYTAB_SECRET}" logn "Removing temp file on ${DC_HOST}" - dc_run "rm -f '${DC_TMP}'" + dc_run "sudo rm -f '${DC_TMP}'" fi # --- Step 4: Encrypt in-place --- -- 2.54.0