@@ -762,6 +762,145 @@ if [[ -f ~/.ssh-agent/environment ]]; then
762762fi
763763EOF
764764
765+ # ##################################
766+ # Setup Knox certificate auto-renewal
767+ # ##################################
768+ # Knox Gateway SSL certificates expire. Setup annual renewal
769+ # to prevent Component Gateway web interfaces from becoming inactive.
770+
771+ emit " Setting up Knox Gateway certificate auto-renewal..."
772+
773+ readonly KNOX_REGEN_SCRIPT=" /usr/local/bin/regenerate-knox-cert.sh"
774+ readonly KNOX_CRON_FILE=" /etc/cron.d/knox-cert-regeneration"
775+
776+ # Create the regeneration script
777+ cat << 'KNOX_REGEN_EOF ' > "${KNOX_REGEN_SCRIPT}"
778+ #!/bin/bash
779+ #
780+ # Name: regenerate-knox-cert.sh
781+ #
782+ # Description:
783+ # Script to regenerate the Knox Gateway SSL certificate on a Dataproc cluster.
784+ #
785+ # Reference:
786+ # https://docs.cloud.google.com/dataproc/docs/concepts/accessing/dataproc-gateways#regenerate
787+ #
788+
789+ set -o errexit
790+ set -o nounset
791+ set -o pipefail
792+ set -o xtrace
793+
794+ # Knox keystore configuration
795+ readonly KNOX_KEYSTORE="/var/lib/knox/security/keystores/gateway.jks"
796+ readonly BACKUP_DIR="/var/lib/knox/security/keystores/backup"
797+ readonly BACKUP_TIMESTAMP=$(date +%Y%m%d_%H%M%S)
798+ readonly BACKUP_FILE="${BACKUP_DIR}/gateway_${BACKUP_TIMESTAMP}.jks"
799+
800+ #######################################
801+ # Emit a message with a timestamp
802+ # Logs are captured by systemd journal when run via cron
803+ #######################################
804+ function emit() {
805+ echo "$(date '+%Y-%m-%d %H:%M:%S') $*"
806+ }
807+ readonly -f emit
808+
809+ emit "Starting Knox Gateway SSL certificate regeneration check..."
810+
811+ # Only run on the dataproc master node. Exit with error if otherwise.
812+ ROLE="$(/usr/share/google/get_metadata_value attributes/dataproc-role)"
813+ if [[ "${ROLE}" != 'Master' ]]; then
814+ emit "ERROR: This script must be run on the Dataproc master node. Current role: ${ROLE}"
815+ exit 1
816+ fi
817+ readonly ROLE
818+
819+ emit "Running on Dataproc master node."
820+
821+ # Check if keystore exists
822+ if [[ ! -f "${KNOX_KEYSTORE}" ]]; then
823+ emit "ERROR: Knox keystore not found at ${KNOX_KEYSTORE}"
824+ exit 1
825+ fi
826+
827+ # Check certificate year before proceeding
828+ emit "Checking certificate year..."
829+ CERT_INFO=$(echo "" | keytool -list -v -keystore "${KNOX_KEYSTORE}" 2>&1)
830+
831+ # Extract the certificate creation date and year
832+ CERT_CREATION_DATE=$(echo "${CERT_INFO}" | grep -i "Creation date:" | head -n 1 | sed 's/.*Creation date: //')
833+
834+ if [[ -z "${CERT_CREATION_DATE}" ]]; then
835+ emit "WARNING: Could not extract certificate creation date. Proceeding with regeneration."
836+ else
837+ # Extract year from certificate date (last token)
838+ CERT_YEAR=$(echo "${CERT_CREATION_DATE}" | awk '{print $NF}')
839+ CURRENT_YEAR=$(date +%Y)
840+
841+ emit "Certificate creation date: ${CERT_CREATION_DATE}"
842+ emit "Certificate year: ${CERT_YEAR}"
843+ emit "Current year: ${CURRENT_YEAR}"
844+
845+ # Only regenerate if certificate is from a previous year
846+ if [[ "${CERT_YEAR}" == "${CURRENT_YEAR}" ]]; then
847+ emit "Certificate was created this year (${CURRENT_YEAR}). Skipping regeneration."
848+ exit 0
849+ fi
850+
851+ emit "Certificate is from year ${CERT_YEAR}. Proceeding with regeneration..."
852+ fi
853+
854+ # Create backup directory if it doesn't exist
855+ mkdir -p "${BACKUP_DIR}"
856+
857+ # Backup the current keystore
858+ emit "Backing up current keystore to ${BACKUP_FILE}"
859+ cp "${KNOX_KEYSTORE}" "${BACKUP_FILE}"
860+
861+ if [[ ! -f "${BACKUP_FILE}" ]]; then
862+ emit "ERROR: Failed to create backup of keystore"
863+ exit 1
864+ fi
865+
866+ emit "Backup created successfully."
867+
868+ # Remove the old keystore to trigger regeneration
869+ emit "Removing old keystore..."
870+ rm -f "${KNOX_KEYSTORE}"
871+
872+ # Restart Knox service to generate new certificate
873+ emit "Restarting Knox service to generate new certificate..."
874+ systemctl restart knox
875+
876+ emit "Knox Gateway SSL certificate regeneration completed successfully."
877+
878+ exit 0
879+ KNOX_REGEN_EOF
880+
881+ chmod +x " ${KNOX_REGEN_SCRIPT} "
882+
883+ # Create cron job
884+ # Use systemd-cat to send output to journalctl with identifier 'knox-cert-regen'
885+ cat << EOF > "${KNOX_CRON_FILE} "
886+ # Knox Gateway SSL Certificate Regeneration
887+ # Checks certificate year and regenerates if from previous year
888+ # Logs are sent to journalctl and can be viewed with: journalctl -t knox-cert-regen
889+
890+ # Check annually at 2 AM on January 1st (ensures cert is regenerated yearly)
891+ 0 2 1 1 * root systemd-cat -t knox-cert-regen ${KNOX_REGEN_SCRIPT}
892+
893+ # Also check on reboot (regenerates only if cert is from previous year)
894+ @reboot root sleep 60 && systemd-cat -t knox-cert-regen ${KNOX_REGEN_SCRIPT}
895+ EOF
896+
897+ chmod 644 " ${KNOX_CRON_FILE} "
898+
899+ emit " Knox certificate auto-renewal configured successfully"
900+ emit " Cron job created at ${KNOX_CRON_FILE} "
901+ emit " Certificate year will be checked at 2 AM on January 1st every year and on reboot."
902+ emit " Certificate will be regenerated only if from a previous year."
903+
765904# ############################
766905# Setup instance boot service
767906# ############################
0 commit comments