97 lines
3.5 KiB
Bash
97 lines
3.5 KiB
Bash
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# 05a-kerberos.sh — Install Kerberos client, stage keytab, and install a
|
|
# systemd timer that renews the TGT on a schedule.
|
|
#
|
|
# The app service reads KRB5CCNAME from its .env file and uses the shared
|
|
# ticket cache when opening SQL Server connections via pyodbc/SQLAlchemy.
|
|
# =============================================================================
|
|
|
|
require_vars APP_USER APP_GROUP \
|
|
KRB_PRINCIPAL KRB_KEYTAB_SRC KRB_KEYTAB_PATH KRB_CCACHE_PATH \
|
|
|| return 1
|
|
|
|
KRB_RENEW_INTERVAL="${KRB_RENEW_INTERVAL:-30min}"
|
|
KRB_RENEWAL_SERVICE="${APP_SERVICE_NAME:-recon-ranger}-kerberos-renewal"
|
|
|
|
# ---- Install the Kerberos client ------------------------------------------
|
|
if ! command -v kinit &>/dev/null; then
|
|
log_info "Installing krb5-workstation"
|
|
dnf install -y krb5-workstation \
|
|
|| { log_error "Failed to install krb5-workstation"; return 1; }
|
|
else
|
|
log_info "krb5-workstation already installed"
|
|
fi
|
|
|
|
# ---- Sanity check /etc/krb5.conf ------------------------------------------
|
|
if [[ ! -s /etc/krb5.conf ]] || ! grep -q "default_realm" /etc/krb5.conf; then
|
|
log_error "/etc/krb5.conf missing or has no default_realm — configure the realm first"
|
|
return 1
|
|
fi
|
|
|
|
# ---- Stage the keytab at the target path ----------------------------------
|
|
if [[ ! -f "$KRB_KEYTAB_SRC" ]]; then
|
|
log_error "Keytab source not found: $KRB_KEYTAB_SRC"
|
|
return 1
|
|
fi
|
|
|
|
install -d -o "$APP_USER" -g "$APP_GROUP" -m 0750 "$(dirname "$KRB_KEYTAB_PATH")"
|
|
install -o "$APP_USER" -g "$APP_GROUP" -m 0600 "$KRB_KEYTAB_SRC" "$KRB_KEYTAB_PATH"
|
|
|
|
# Show what is inside the keytab so deploy logs record the principals/enctypes.
|
|
log_info "Keytab contents:"
|
|
klist -ekt "$KRB_KEYTAB_PATH" || log_warn "Could not list keytab contents"
|
|
|
|
# ---- Prepare the ticket cache directory -----------------------------------
|
|
install -d -o "$APP_USER" -g "$APP_GROUP" -m 0700 "$(dirname "$KRB_CCACHE_PATH")"
|
|
|
|
# ---- Prime the cache immediately ------------------------------------------
|
|
log_info "Running initial kinit as $APP_USER"
|
|
sudo -u "$APP_USER" \
|
|
kinit -k -t "$KRB_KEYTAB_PATH" -c "FILE:$KRB_CCACHE_PATH" "$KRB_PRINCIPAL" \
|
|
|| { log_error "Initial kinit failed for $KRB_PRINCIPAL"; return 1; }
|
|
|
|
sudo -u "$APP_USER" klist -c "FILE:$KRB_CCACHE_PATH" \
|
|
|| log_warn "klist failed after kinit"
|
|
|
|
# ---- Renewal service (oneshot, fires kinit) -------------------------------
|
|
RENEWAL_UNIT="/etc/systemd/system/${KRB_RENEWAL_SERVICE}.service"
|
|
RENEWAL_TIMER="/etc/systemd/system/${KRB_RENEWAL_SERVICE}.timer"
|
|
|
|
log_info "Writing $RENEWAL_UNIT"
|
|
cat > "$RENEWAL_UNIT" <<UNITEOF
|
|
[Unit]
|
|
Description=Kerberos TGT renewal for ${APP_SERVICE_NAME:-recon-ranger}
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
User=${APP_USER}
|
|
Group=${APP_GROUP}
|
|
ExecStart=/usr/bin/kinit -k -t ${KRB_KEYTAB_PATH} -c FILE:${KRB_CCACHE_PATH} ${KRB_PRINCIPAL}
|
|
UNITEOF
|
|
|
|
log_info "Writing $RENEWAL_TIMER"
|
|
cat > "$RENEWAL_TIMER" <<TIMEREOF
|
|
[Unit]
|
|
Description=Periodic Kerberos TGT renewal for ${APP_SERVICE_NAME:-recon-ranger}
|
|
|
|
[Timer]
|
|
OnBootSec=1min
|
|
OnUnitActiveSec=${KRB_RENEW_INTERVAL}
|
|
Unit=${KRB_RENEWAL_SERVICE}.service
|
|
Persistent=true
|
|
|
|
[Install]
|
|
WantedBy=timers.target
|
|
TIMEREOF
|
|
|
|
systemctl daemon-reload \
|
|
|| { log_error "systemctl daemon-reload failed"; return 1; }
|
|
|
|
systemctl enable --now "${KRB_RENEWAL_SERVICE}.timer" \
|
|
|| { log_error "Failed to enable ${KRB_RENEWAL_SERVICE}.timer"; return 1; }
|
|
|
|
systemctl --no-pager status "${KRB_RENEWAL_SERVICE}.timer" || true
|