Archived
fix(ipa): SSH as wayne with sudo instead of root on domain controller #77
@@ -17,17 +17,19 @@
|
|||||||
#
|
#
|
||||||
# Options:
|
# Options:
|
||||||
# --ip <addr> Register this IP with the IPA host record (optional).
|
# --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).
|
# 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.
|
# --dry-run Print what would be done without making any changes.
|
||||||
# -h, --help Show this message.
|
# -h, --help Show this message.
|
||||||
#
|
#
|
||||||
# Prereqs:
|
# Prereqs:
|
||||||
# 1. Run from the repo root (so .sops.yaml and secrets/ are found).
|
# 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).
|
# 2. SSH access to the domain controller as --dc-user (default: wayne)
|
||||||
# If there's no valid Kerberos ticket on the DC, the script runs
|
# with passwordless sudo (or sudo cached). IPA commands and kinit run
|
||||||
# `kinit admin` there interactively — you'll be prompted for the IPA
|
# 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.
|
# admin password once. The password never touches this script.
|
||||||
# 3. The host's age key(s) must already be in .sops.yaml. Run
|
# 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
|
# scripts/secrets/sync-host-keys.sh <flake-target> first so the host
|
||||||
@@ -47,7 +49,7 @@ source "${SCRIPT_DIR}/../env.sh"
|
|||||||
# --- Argument parsing ---
|
# --- Argument parsing ---
|
||||||
|
|
||||||
DC_HOST="${IPA_SERVER}"
|
DC_HOST="${IPA_SERVER}"
|
||||||
DC_USER="root"
|
DC_USER="wayne"
|
||||||
IP_ADDR=""
|
IP_ADDR=""
|
||||||
DRY_RUN=false
|
DRY_RUN=false
|
||||||
HOSTNAME=""
|
HOSTNAME=""
|
||||||
@@ -183,16 +185,15 @@ fi
|
|||||||
log "Adding FreeIPA host account: ${FQDN}"
|
log "Adding FreeIPA host account: ${FQDN}"
|
||||||
|
|
||||||
# Ensure there's a valid admin Kerberos ticket on the DC.
|
# 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
|
# ipa host-add and ipa-getkeytab both need one. All IPA commands run via
|
||||||
# expired, run kinit admin interactively over SSH (ssh -t allocates a PTY so
|
# sudo so the ticket must be in root's cache — check and refresh as root.
|
||||||
# kinit can prompt for the password normally — no password ever touches this
|
# ssh -t allocates a PTY so kinit (and sudo if needed) can prompt normally;
|
||||||
# script or the shell history on either machine).
|
# no password ever touches this script or the shell history.
|
||||||
if ! $DRY_RUN; then
|
if ! $DRY_RUN; then
|
||||||
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 kinit admin"
|
log "No valid Kerberos ticket on ${DC_HOST} — running sudo kinit admin"
|
||||||
ssh -t "${DC_USER}@${DC_HOST}" "kinit admin"
|
ssh -t "${DC_USER}@${DC_HOST}" "sudo kinit admin"
|
||||||
# Verify it actually worked before proceeding.
|
if ! ssh "${DC_USER}@${DC_HOST}" "sudo klist -s" &>/dev/null; then
|
||||||
if ! ssh "${DC_USER}@${DC_HOST}" "klist -s" &>/dev/null; then
|
|
||||||
echo "Error: kinit admin failed or produced no valid ticket." >&2
|
echo "Error: kinit admin failed or produced no valid ticket." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -207,7 +208,7 @@ IP_FLAG=""
|
|||||||
# --force: create the host record even if DNS doesn't resolve it yet.
|
# --force: create the host record even if DNS doesn't resolve it yet.
|
||||||
# Pipe through grep to suppress the "already exists" warning without
|
# Pipe through grep to suppress the "already exists" warning without
|
||||||
# hiding real errors (ipa exits 1 for real errors, 0 for already-exists).
|
# 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"
|
tee /dev/stderr | grep -q 'already exists' && echo '(host already registered)' || true"
|
||||||
dc_run "bash -c \"${HOST_ADD_CMD}\""
|
dc_run "bash -c \"${HOST_ADD_CMD}\""
|
||||||
|
|
||||||
@@ -215,7 +216,7 @@ dc_run "bash -c \"${HOST_ADD_CMD}\""
|
|||||||
|
|
||||||
log "Fetching keytab for host/${FQDN}"
|
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
|
if $DRY_RUN; then
|
||||||
echo "[dry-run] Would scp ${DC_USER}@${DC_HOST}:${DC_TMP} ${KEYTAB_SECRET}"
|
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}"
|
scp "${DC_USER}@${DC_HOST}:${DC_TMP}" "${KEYTAB_SECRET}"
|
||||||
|
|
||||||
logn "Removing temp file on ${DC_HOST}"
|
logn "Removing temp file on ${DC_HOST}"
|
||||||
dc_run "rm -f '${DC_TMP}'"
|
dc_run "sudo rm -f '${DC_TMP}'"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Step 4: Encrypt in-place ---
|
# --- Step 4: Encrypt in-place ---
|
||||||
|
|||||||
Reference in New Issue
Block a user