Kerberos auth Airflow supports kerberos auth. To configure it we need standard Service account (gMSA is not supported). in this example BRANCH\zGDSAppDEV user will be used to configure arflow follow next steps: use airflow user to perform configuration sudo -iu airflow pwd you should be located in home directory of the airflow user we now need to create keytab file which will be used to authenticate our service account ktutil add_entry -password -p zGDSAppDEV@PROD.ASBGROUP.CO.NZ -k 1 -e aes256-cts-hmac-sha1-96 wkt airflow.keytab quit have your service account ready as above commands will ask to enter service account password check that file was created and you can see content of keytab file which holds Pricipal klist -ekt airflow.keytab initiate ticket for airflow user sudo -u airflow kinit zAirflowDEV@PROD.ASBGROUP.CO.NZ -V -k -t /opt/airflow/airflow.keytab -c /opt/airflow/airflow-krb5-ticket.cache now we need configure airflow to use this keytab file. Open airflow configuration file vim airflow.cfg Then change following keys in config file security = kerberos ccache = /tmp/airflow_krb5_ccache principal = zAirflowDEV@PROD.ASBGROUP.CO.NZ keytab = /home/airflow/airflow.keytab using your cmf account restart both airflow-scheduler and airflow-webserver services sudo systemctl restart airflow-scheduler airflow-webserver test that ticket is assigned to airflow user sudo -u airflow klist configure systemd unit to renew kerberos ticket periodically sudo vim /etc/systemd/system/airflow-kerberos-renewal.service [Unit] Description=Airflow Kerberos Ticket Renewal Process Requires=network-online.target After=network-online.target [Service] Type=simple Environment="PATH=$PATH:/opt/airflow/.venv:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin" Environment="AIRFLOW_HOME=/opt/airflow" User=airflow Group=airflow ExecStart=/usr/bin/bash -c 'source /opt/airflow/.venv/bin/activate ; airflow kerberos' Restart=always RestartSec=5s PrivateTmp=true [Install] WantedBy=multi-user.target Reload daemons sudo systemctl daemon-reload Start service sudo systemctl enable --now airflow-kerberos-renewal Check status sudo systemctl status airflow-kerberos-renewal Useful information for troubleshooting in journal sudo journalctl -u airflow-kerberos-renewal -f ```bash #!/usr/bin/env bash # ============================================================================= # deploy.sh — Recon Ranger deployment orchestrator # ============================================================================= # # Usage: sudo ./deploy.sh [--clean] [path/to/deploy.conf] # # Options: # --clean Remove and recreate the Python venv before installing deps. # Useful when a previous deploy left the venv in a broken state. # # This script sources deploy.conf for all configuration, then runs each # deployment step in order. It uses a roll-forward strategy: if a step fails, # the error is logged and the remaining steps continue. # # See deploy.conf.example for the full list of configuration variables. # ============================================================================= set -uo pipefail # --------------------------------------------------------------------------- # Resolve our own location so relative paths work regardless of cwd. # --------------------------------------------------------------------------- DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # --------------------------------------------------------------------------- # Load shared functions # --------------------------------------------------------------------------- source "${DEPLOY_DIR}/lib/common.sh" # --------------------------------------------------------------------------- # Parse arguments # --------------------------------------------------------------------------- DEPLOY_CLEAN=false while [[ $# -gt 0 ]]; do case "$1" in --clean) DEPLOY_CLEAN=true; shift ;; *) break ;; esac done # --------------------------------------------------------------------------- # Root check # --------------------------------------------------------------------------- if [[ $EUID -ne 0 ]]; then log_error "This script must be run as root (or via sudo)" return 1 2>/dev/null || exit 1 fi # --------------------------------------------------------------------------- # Load configuration # --------------------------------------------------------------------------- CONF_FILE="${1:-${DEPLOY_DIR}/deploy.conf}" # Resolve to absolute path so step scripts can find it regardless of cwd. CONF_FILE="$(readlink -f "$CONF_FILE")" if [[ ! -f "$CONF_FILE" ]]; then log_error "Config file not found: $CONF_FILE" log_error "Copy deploy.conf.example to deploy.conf and fill in your values." return 1 2>/dev/null || exit 1 fi log_info "Loading configuration from: $CONF_FILE" source "$CONF_FILE" # --------------------------------------------------------------------------- # Resolve APP_ROOT (repo root + optional subdirectory) # --------------------------------------------------------------------------- if [[ -n "${APP_SUBDIR:-}" ]]; then APP_ROOT="${APP_DIR}/${APP_SUBDIR}" log_info "APP_SUBDIR set — app root resolved to: $APP_ROOT" else APP_ROOT="${APP_DIR}" fi # Track whether tests passed — used to gate service restart DEPLOY_TESTS_PASSED=true # --------------------------------------------------------------------------- # Run deployment steps # --------------------------------------------------------------------------- log_step "Application Deployment — $(date)" run_step "0. Proxy Setup" "${DEPLOY_DIR}/steps/00-proxy-setup.sh" run_step "1. User Setup" "${DEPLOY_DIR}/steps/01-user-setup.sh" if [[ "${APP_SSL_ENABLED:-true}" == "true" ]]; then run_step "2. SSL Certificates" "${DEPLOY_DIR}/steps/02-ssl-certs.sh" else log_info "Skipping SSL certificates (APP_SSL_ENABLED=false)" fi run_step "3. App Install" "${DEPLOY_DIR}/steps/03-app-install.sh" run_step "3a. App Environment" "${DEPLOY_DIR}/steps/03a-app-env.sh" run_step "3b. DB Migrations" "${DEPLOY_DIR}/steps/03b-db-migrate.sh" run_step "3c. Tests" "${DEPLOY_DIR}/steps/03c-tests.sh" run_step "4. Firewall" "${DEPLOY_DIR}/steps/04-firewall.sh" if [[ -n "${CIFS_MOUNTS:-}" ]]; then run_step "5. Network Mounts" "${DEPLOY_DIR}/steps/05-network-mounts.sh" else log_info "Skipping network mounts (CIFS_MOUNTS not set)" fi run_step "6. App Service" "${DEPLOY_DIR}/steps/06-app-service.sh" # --------------------------------------------------------------------------- # Summary # --------------------------------------------------------------------------- echo "" echo "=====================================================================" if [[ $DEPLOY_HAS_ERRORS -ne 0 ]]; then log_warn "Deployment completed with errors — review the log above," log_warn "fix the issue(s), and re-run this script." return 1 2>/dev/null || exit 1 else log_info "Deployment completed successfully." fi echo "=====================================================================" ``` ```bash #!/usr/bin/env bash # ============================================================================= # 01-user-setup.sh — Create the application system user and group # ============================================================================= require_vars APP_USER APP_GROUP || return 1 # ---- Group ---- if getent group "$APP_GROUP" &>/dev/null; then log_info "Group already exists: $APP_GROUP" else log_info "Creating system group: $APP_GROUP" groupadd --system "$APP_GROUP" || { log_error "Failed to create group: $APP_GROUP"; return 1; } fi # ---- User ---- if id "$APP_USER" &>/dev/null; then log_info "User already exists: $APP_USER" else log_info "Creating system user: $APP_USER (group: $APP_GROUP, shell: /sbin/nologin)" useradd \ --system \ --gid "$APP_GROUP" \ --shell /sbin/nologin \ --no-create-home \ "$APP_USER" \ || { log_error "Failed to create user: $APP_USER"; return 1; } fi ``` ```bash #!/usr/bin/env bash # ============================================================================= # 06-app-service.sh — Create and enable the systemd service unit # ============================================================================= require_vars APP_SERVICE_NAME APP_ROOT APP_DIR APP_ENV_DIR APP_HOST APP_PORT \ APP_USER APP_GROUP APP_MODULE || return 1 # APP_ENV_DIR defaults to APP_ROOT if not explicitly set in config APP_ENV_DIR="${APP_ENV_DIR:-$APP_ROOT}" UNIT_FILE="/etc/systemd/system/${APP_SERVICE_NAME}.service" # ---- Build the After= line ---- AFTER_TARGETS="network.target" if [[ -n "${CIFS_MOUNTS:-}" ]]; then AFTER_TARGETS="network.target remote-fs.target" fi # ---- Capability for privileged ports ---- CAP_LINE="" if (( APP_PORT < 1024 )); then CAP_LINE="AmbientCapabilities=CAP_NET_BIND_SERVICE" log_info "Port ${APP_PORT} < 1024 — adding CAP_NET_BIND_SERVICE" fi # ---- Verify uvicorn is installed ---- if ! "${APP_ROOT}/.venv/bin/python" -c "import uvicorn" &>/dev/null; then log_error "uvicorn not importable in ${APP_ROOT}/.venv — was step 3 (App Install) successful?" return 1 fi # ---- Build ExecStart command ---- # Use the venv python to run uvicorn as a module, avoiding shebang path issues. EXEC_START="${APP_ROOT}/.venv/bin/python -m uvicorn ${APP_MODULE} --host ${APP_HOST} --port ${APP_PORT}" if [[ "${APP_SSL_ENABLED:-true}" == "true" ]]; then EXEC_START="${EXEC_START} --ssl-keyfile \${SSL_KEYFILE} --ssl-certfile \${SSL_CERTFILE}" fi # ---- Write the unit file ---- log_info "Writing systemd unit file: $UNIT_FILE" cat > "$UNIT_FILE" <-kerberos-renewal.service. Verify after deploy: systemctl list-timers | grep kerberos sudo -u recon-ranger klist -c FILE:/var/lib/recon-ranger/krb5_ccache sudo -u recon-ranger KRB5CCNAME=FILE:/var/lib/recon-ranger/krb5_ccache \ /opt/recon-ranger/.venv/bin/python /opt/recon-ranger/scripts/mssql_probe.py