diff --git a/federation/scripts/generate-certificates.sh b/federation/scripts/generate-certificates.sh index 707b20f..bcd2b1b 100755 --- a/federation/scripts/generate-certificates.sh +++ b/federation/scripts/generate-certificates.sh @@ -7,6 +7,23 @@ OCSP_URL="http://ocsp.localhost.example:8888" # Base directory for all certificate-related files # All paths in this script will be relative to this directory CERT_DIR="./_data/certs" +XMPP_BASE_DIR="./_data/xmpp" + +# Function to check which server directories exist +get_server_instances() { + local instances=() + # Look for numbered directories in the xmpp base directory + for dir in "$XMPP_BASE_DIR"/*/; do + if [[ -d "$dir" ]]; then + # Extract the number from the directory name + local num=$(basename "$dir") + if [[ "$num" =~ ^[0-9]+$ ]]; then + instances+=("$num") + fi + fi + done + echo "${instances[@]}" +} # Create the PKI directory structure: # We only need: @@ -53,15 +70,16 @@ openssl x509 -req -in "${CERT_DIR}/ca/intermediate-ca/intermediate.csr" \ # Function to generate a server certificate and add it to the certificate database # Parameters: -# $1: instance number (1 or 2 for xmpp1/xmpp2) +# $1: instance number (1, 2, or 3 for xmpp1/xmpp2/xmpp3) generate_server_cert() { local instance=$1 + local server_name="xmpp${instance}" # Generate server private key and CSR - openssl genrsa -out "${CERT_DIR}/server${instance}.key" 2048 + openssl genrsa -out "${CERT_DIR}/${server_name}.key" 2048 # Create OpenSSL config file for SAN support - cat > "${CERT_DIR}/server${instance}.cnf" << EOF + cat > "${CERT_DIR}/${server_name}.cnf" << EOF [req] distinguished_name = req_distinguished_name req_extensions = v3_req @@ -72,7 +90,7 @@ C = GB ST = London L = London O = Test Openfire -CN = xmpp${instance}.localhost.example +CN = ${server_name}.localhost.example [v3_req] basicConstraints = CA:FALSE @@ -81,17 +99,17 @@ extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] -DNS.1 = xmpp${instance}.localhost.example -DNS.2 = *.xmpp${instance}.localhost.example +DNS.1 = ${server_name}.localhost.example +DNS.2 = *.${server_name}.localhost.example EOF # Generate CSR with the config file - openssl req -new -key "${CERT_DIR}/server${instance}.key" \ - -out "${CERT_DIR}/server${instance}.csr" \ - -config "${CERT_DIR}/server${instance}.cnf" + openssl req -new -key "${CERT_DIR}/${server_name}.key" \ + -out "${CERT_DIR}/${server_name}.csr" \ + -config "${CERT_DIR}/${server_name}.cnf" # Create OpenSSL config for certificate signing - cat > "${CERT_DIR}/server${instance}_sign.cnf" << EOF + cat > "${CERT_DIR}/${server_name}_sign.cnf" << EOF basicConstraints = critical,CA:false keyUsage = critical,digitalSignature,keyEncipherment extendedKeyUsage = serverAuth @@ -99,31 +117,33 @@ subjectAltName = @alt_names authorityInfoAccess = OCSP;URI:${OCSP_URL} [alt_names] -DNS.1 = xmpp${instance}.localhost.example -DNS.2 = *.xmpp${instance}.localhost.example +DNS.1 = ${server_name}.localhost.example +DNS.2 = *.${server_name}.localhost.example EOF # Sign the server certificate with the Intermediate CA - openssl x509 -req -in "${CERT_DIR}/server${instance}.csr" \ + openssl x509 -req -in "${CERT_DIR}/${server_name}.csr" \ -CA "${CERT_DIR}/ca/intermediate-ca/intermediate.crt" \ -CAkey "${CERT_DIR}/ca/intermediate-ca/private/intermediate.key" -CAcreateserial \ - -out "${CERT_DIR}/server${instance}.crt" -days 365 \ - -extfile "${CERT_DIR}/server${instance}_sign.cnf" + -out "${CERT_DIR}/${server_name}.crt" -days 365 \ + -extfile "${CERT_DIR}/${server_name}_sign.cnf" # Create the full certificate chain - cat "${CERT_DIR}/server${instance}.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt" "${CERT_DIR}/ca/root-ca/ca.crt" > "${CERT_DIR}/chain${instance}.pem" + cat "${CERT_DIR}/${server_name}.crt" \ + "${CERT_DIR}/ca/intermediate-ca/intermediate.crt" \ + "${CERT_DIR}/ca/root-ca/ca.crt" > "${CERT_DIR}/${server_name}_chain.pem" # Add to certificate database - SERIAL=$(openssl x509 -in "${CERT_DIR}/server${instance}.crt" -noout -serial | cut -d'=' -f2) - SUBJECT=$(openssl x509 -in "${CERT_DIR}/server${instance}.crt" -noout -subject | cut -d'=' -f2-) + SERIAL=$(openssl x509 -in "${CERT_DIR}/${server_name}.crt" -noout -serial | cut -d'=' -f2) + SUBJECT=$(openssl x509 -in "${CERT_DIR}/${server_name}.crt" -noout -subject | cut -d'=' -f2-) printf 'V\t%s\t\t%s\tunknown\t%s\n' "$(date -u +%y%m%d%H%M%SZ)" "$SERIAL" "$SUBJECT" >> "${CERT_DIR}/ca/intermediate-ca/index.txt" # Clean up temporary config files - rm -f "${CERT_DIR}/server${instance}.cnf" "${CERT_DIR}/server${instance}_sign.cnf" + rm -f "${CERT_DIR}/${server_name}.cnf" "${CERT_DIR}/${server_name}_sign.cnf" # Display the certificate's subject and SANs for verification - echo "Certificate generated for instance ${instance}:" - openssl x509 -in "${CERT_DIR}/server${instance}.crt" -noout -subject -ext subjectAltName + echo "Certificate generated for ${server_name}:" + openssl x509 -in "${CERT_DIR}/${server_name}.crt" -noout -subject -ext subjectAltName } # Generate the OCSP responder certificate @@ -144,17 +164,36 @@ openssl x509 -req -in "${CERT_DIR}/ca/ocsp-responder/ocsp.csr" \ -out "${CERT_DIR}/ca/ocsp-responder/ocsp.crt" -days 365 \ -extfile <(printf 'basicConstraints=critical,CA:false\nkeyUsage=critical,digitalSignature\nextendedKeyUsage=OCSPSigning') -# Generate certificates for both Openfire instances -generate_server_cert 1 -generate_server_cert 2 +# Get the list of server instances that exist +SERVER_INSTANCES=($(get_server_instances)) + +if [ ${#SERVER_INSTANCES[@]} -eq 0 ]; then + echo "Error: No server directories found in ${XMPP_BASE_DIR}" + exit 1 +fi + +echo "Found server directories for instances: ${SERVER_INSTANCES[*]}" + +# Generate certificates for each existing server instance +for instance in "${SERVER_INSTANCES[@]}"; do + echo "Generating certificates for xmpp${instance}" + generate_server_cert "$instance" +done # Verify the certificate chain for all generated certificates # This ensures that all certificates are properly signed and trusted echo "Verifying certificates..." openssl verify -CAfile "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt" -openssl verify -CAfile <(cat "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt") "${CERT_DIR}/server1.crt" -openssl verify -CAfile <(cat "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt") "${CERT_DIR}/server2.crt" -openssl verify -CAfile <(cat "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt") "${CERT_DIR}/ca/ocsp-responder/ocsp.crt" + +# Verify each server certificate +for instance in "${SERVER_INSTANCES[@]}"; do + openssl verify -CAfile <(cat "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt") \ + "${CERT_DIR}/xmpp${instance}.crt" +done + +openssl verify -CAfile <(cat "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt") \ + "${CERT_DIR}/ca/ocsp-responder/ocsp.crt" printf '\nCertificate generation complete.' -printf '\nOCSP URL configured as: %s\n\n' "$OCSP_URL" \ No newline at end of file +printf '\nOCSP URL configured as: %s\n' "$OCSP_URL" +printf 'Generated certificates for servers: %s\n\n' "${SERVER_INSTANCES[*]}" diff --git a/federation/scripts/import-certificates.sh b/federation/scripts/import-certificates.sh index 2433d07..0a1729c 100755 --- a/federation/scripts/import-certificates.sh +++ b/federation/scripts/import-certificates.sh @@ -7,17 +7,35 @@ KEYSTORE_PASSWORD="changeit" # Base directory where certificates were generated # This should match the CERT_DIR from the certificate generation script CERT_DIR="./_data/certs" +XMPP_BASE_DIR="./_data/xmpp" + +# Function to check which server directories exist +get_server_instances() { + local instances=() + # Look for numbered directories in the xmpp base directory + for dir in "$XMPP_BASE_DIR"/*/; do + if [[ -d "$dir" ]]; then + # Extract the number from the directory name + local num=$(basename "$dir") + if [[ "$num" =~ ^[0-9]+$ ]]; then + instances+=("$num") + fi + fi + done + echo "${instances[@]}" +} # Function to import certificates and set up keystores/truststores for one Openfire instance # Parameters: -# $1: instance number (1 or 2 for xmpp1/xmpp2) +# $1: instance number (1, 2, or 3 for xmpp1/xmpp2/xmpp3) import_certificates() { local instance=$1 + local server_name="xmpp${instance}" # Directory where Openfire expects to find its certificates local conf_dir="_data/xmpp/${instance}/conf/security" - echo "Importing certificates for Openfire instance ${instance}..." + echo "Importing certificates for ${server_name}..." # Ensure the security directory exists mkdir -p "${conf_dir}" @@ -25,7 +43,7 @@ import_certificates() { # Remove any existing keystore to start fresh rm -f "${conf_dir}/keystore" - echo "Creating new keystore for instance ${instance}" + echo "Creating new keystore for ${server_name}" # Create a new empty keystore by generating and immediately deleting a temporary keypair # This ensures the keystore is properly initialized with the correct format keytool -genkeypair \ @@ -46,12 +64,12 @@ import_certificates() { # First convert them to PKCS12 format which can be imported into a Java keystore echo "Importing server certificate and private key..." openssl pkcs12 -export \ - -in "${CERT_DIR}/server${instance}.crt" \ - -inkey "${CERT_DIR}/server${instance}.key" \ + -in "${CERT_DIR}/${server_name}.crt" \ + -inkey "${CERT_DIR}/${server_name}.key" \ -chain \ - -CAfile "${CERT_DIR}/chain${instance}.pem" \ - -name "xmpp${instance}.localhost.example" \ - -out "${CERT_DIR}/server${instance}.p12" \ + -CAfile "${CERT_DIR}/${server_name}_chain.pem" \ + -name "${server_name}.localhost.example" \ + -out "${CERT_DIR}/${server_name}.p12" \ -password "pass:${KEYSTORE_PASSWORD}" # Import the PKCS12 file into the keystore @@ -59,15 +77,15 @@ import_certificates() { -deststorepass "${KEYSTORE_PASSWORD}" \ -destkeypass "${KEYSTORE_PASSWORD}" \ -destkeystore "${conf_dir}/keystore" \ - -srckeystore "${CERT_DIR}/server${instance}.p12" \ + -srckeystore "${CERT_DIR}/${server_name}.p12" \ -srcstoretype PKCS12 \ -srcstorepass "${KEYSTORE_PASSWORD}" \ - -alias "xmpp${instance}.localhost.example" + -alias "${server_name}.localhost.example" # Create or update truststore # truststore - used by the server to verify other servers if [ ! -f "${conf_dir}/truststore" ]; then - echo "Creating new truststore for instance ${instance}" + echo "Creating new truststore for ${server_name}" # Initialize a new truststore with a dummy entry keytool -importpass \ -keystore "${conf_dir}/truststore" \ @@ -106,21 +124,34 @@ import_certificates() { echo "Intermediate CA already exists in truststore" fi - echo "Certificate import completed for instance ${instance}" + echo "Certificate import completed for ${server_name}" } # Main script execution - echo "Starting certificate import process..." -# Import certificates for both Openfire instances -import_certificates 1 -import_certificates 2 +# Get the list of server instances that exist +SERVER_INSTANCES=($(get_server_instances)) + +if [ ${#SERVER_INSTANCES[@]} -eq 0 ]; then + echo "Error: No server directories found in ${XMPP_BASE_DIR}" + exit 1 +fi + +echo "Found server directories for instances: ${SERVER_INSTANCES[*]}" + +# Import certificates for each existing server instance +for instance in "${SERVER_INSTANCES[@]}"; do + echo "Importing certificates for xmpp${instance}" + import_certificates "$instance" +done # Clean up temporary PKCS12 files that were created during the import process rm -f "${CERT_DIR}"/*.p12 # Display commands that can be used to verify the keystore contents echo -e "\nTo verify the keystores, run:" -echo "keytool -list -keystore _data/xmpp/1/conf/security/keystore -storepass ${KEYSTORE_PASSWORD}" -echo "keytool -list -keystore _data/xmpp/1/conf/security/truststore -storepass ${KEYSTORE_PASSWORD}" \ No newline at end of file +for instance in "${SERVER_INSTANCES[@]}"; do + echo "keytool -list -keystore _data/xmpp/${instance}/conf/security/keystore -storepass ${KEYSTORE_PASSWORD}" + echo "keytool -list -keystore _data/xmpp/${instance}/conf/security/truststore -storepass ${KEYSTORE_PASSWORD}" +done \ No newline at end of file