Skip to content

Commit 74cd654

Browse files
authored
Regenerate knox gateway SSL certificate annually (#326)
Needed for Dataproc component gateway
1 parent 7c1a2f4 commit 74cd654

1 file changed

Lines changed: 139 additions & 0 deletions

File tree

startupscript/dataproc/startup.sh

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,145 @@ if [[ -f ~/.ssh-agent/environment ]]; then
762762
fi
763763
EOF
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

Comments
 (0)