fix(ipa): SSH as wayne with sudo instead of root on domain controller
Check NixOS configurations / eval-hosts (pull_request) Successful in 10m23s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 09:02:32 +10:00
co-authored by Claude Sonnet 4.6
parent 6c1891812e
commit 27a8c7fad9
+19 -18
View File
@@ -17,17 +17,19 @@
#
# Options:
# --ip <addr> Register this IP with the IPA host record (optional).
# --dc <host> SSH as root to this host for ipa-getkeytab.
# --dc <host> SSH to this host for ipa-getkeytab.
# Default: $IPA_SERVER (from env.sh / environment).
# --dc-user <u> SSH user on the domain controller. Default: root.
# --dc-user <u> 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 <flake-target> 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 ---