
Signed-off-by: Roman Zabaluev <rzabaluev@provectus.com> Co-authored-by: Ruslan Ibragimov <ruibragimov@provectus.com>
175 lines
6 KiB
Bash
175 lines
6 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
set -eu
|
|
|
|
KEYSTORE_FILENAME="kafka.keystore.jks"
|
|
VALIDITY_IN_DAYS=3650
|
|
DEFAULT_TRUSTSTORE_FILENAME="kafka.truststore.jks"
|
|
TRUSTSTORE_WORKING_DIRECTORY="truststore"
|
|
KEYSTORE_WORKING_DIRECTORY="keystore"
|
|
CA_CERT_FILE="ca-cert"
|
|
KEYSTORE_SIGN_REQUEST="cert-file"
|
|
KEYSTORE_SIGN_REQUEST_SRL="ca-cert.srl"
|
|
KEYSTORE_SIGNED_CERT="cert-signed"
|
|
|
|
export COUNTRY=US
|
|
export STATE=IL
|
|
export ORGANIZATION_UNIT=SE
|
|
export CITY=Chicago
|
|
export PASSWORD=secret
|
|
|
|
COUNTRY=$COUNTRY
|
|
STATE=$STATE
|
|
OU=$ORGANIZATION_UNIT
|
|
CN=kafka0 # COMMON NAME VERIFICATION GOES BRR
|
|
LOCATION=$CITY
|
|
PASS=$PASSWORD
|
|
|
|
function file_exists_and_exit() {
|
|
echo "'$1' cannot exist. Move or delete it before"
|
|
echo "re-running this script."
|
|
exit 1
|
|
}
|
|
|
|
if [ -e "$KEYSTORE_WORKING_DIRECTORY" ]; then
|
|
file_exists_and_exit $KEYSTORE_WORKING_DIRECTORY
|
|
fi
|
|
|
|
if [ -e "$CA_CERT_FILE" ]; then
|
|
file_exists_and_exit $CA_CERT_FILE
|
|
fi
|
|
|
|
if [ -e "$KEYSTORE_SIGN_REQUEST" ]; then
|
|
file_exists_and_exit $KEYSTORE_SIGN_REQUEST
|
|
fi
|
|
|
|
if [ -e "$KEYSTORE_SIGN_REQUEST_SRL" ]; then
|
|
file_exists_and_exit $KEYSTORE_SIGN_REQUEST_SRL
|
|
fi
|
|
|
|
if [ -e "$KEYSTORE_SIGNED_CERT" ]; then
|
|
file_exists_and_exit $KEYSTORE_SIGNED_CERT
|
|
fi
|
|
|
|
echo "Welcome to the Kafka SSL keystore and trust store generator script."
|
|
|
|
trust_store_file=""
|
|
trust_store_private_key_file=""
|
|
|
|
if [ -e "$TRUSTSTORE_WORKING_DIRECTORY" ]; then
|
|
file_exists_and_exit $TRUSTSTORE_WORKING_DIRECTORY
|
|
fi
|
|
|
|
mkdir $TRUSTSTORE_WORKING_DIRECTORY
|
|
echo
|
|
echo "OK, we'll generate a trust store and associated private key."
|
|
echo
|
|
echo "First, the private key."
|
|
echo
|
|
|
|
openssl req -new -x509 -keyout $TRUSTSTORE_WORKING_DIRECTORY/ca-key \
|
|
-out $TRUSTSTORE_WORKING_DIRECTORY/ca-cert -days $VALIDITY_IN_DAYS -nodes \
|
|
-subj "/C=$COUNTRY/ST=$STATE/L=$LOCATION/O=$OU/CN=$CN"
|
|
|
|
trust_store_private_key_file="$TRUSTSTORE_WORKING_DIRECTORY/ca-key"
|
|
|
|
echo
|
|
echo "Two files were created:"
|
|
echo " - $TRUSTSTORE_WORKING_DIRECTORY/ca-key -- the private key used later to"
|
|
echo " sign certificates"
|
|
echo " - $TRUSTSTORE_WORKING_DIRECTORY/ca-cert -- the certificate that will be"
|
|
echo " stored in the trust store in a moment and serve as the certificate"
|
|
echo " authority (CA). Once this certificate has been stored in the trust"
|
|
echo " store, it will be deleted. It can be retrieved from the trust store via:"
|
|
echo " $ keytool -keystore <trust-store-file> -export -alias CARoot -rfc"
|
|
|
|
echo
|
|
echo "Now the trust store will be generated from the certificate."
|
|
echo
|
|
|
|
keytool -keystore $TRUSTSTORE_WORKING_DIRECTORY/$DEFAULT_TRUSTSTORE_FILENAME \
|
|
-alias CARoot -import -file $TRUSTSTORE_WORKING_DIRECTORY/ca-cert \
|
|
-noprompt -dname "C=$COUNTRY, ST=$STATE, L=$LOCATION, O=$OU, CN=$CN" -keypass $PASS -storepass $PASS -storetype JKS
|
|
|
|
trust_store_file="$TRUSTSTORE_WORKING_DIRECTORY/$DEFAULT_TRUSTSTORE_FILENAME"
|
|
|
|
echo
|
|
echo "$TRUSTSTORE_WORKING_DIRECTORY/$DEFAULT_TRUSTSTORE_FILENAME was created."
|
|
|
|
# don't need the cert because it's in the trust store.
|
|
rm $TRUSTSTORE_WORKING_DIRECTORY/$CA_CERT_FILE
|
|
|
|
echo
|
|
echo "Continuing with:"
|
|
echo " - trust store file: $trust_store_file"
|
|
echo " - trust store private key: $trust_store_private_key_file"
|
|
|
|
mkdir $KEYSTORE_WORKING_DIRECTORY
|
|
|
|
echo
|
|
echo "Now, a keystore will be generated. Each broker and logical client needs its own"
|
|
echo "keystore. This script will create only one keystore. Run this script multiple"
|
|
echo "times for multiple keystores."
|
|
echo
|
|
echo " NOTE: currently in Kafka, the Common Name (CN) does not need to be the FQDN of"
|
|
echo " this host. However, at some point, this may change. As such, make the CN"
|
|
echo " the FQDN. Some operating systems call the CN prompt 'first / last name'"
|
|
|
|
# To learn more about CNs and FQDNs, read:
|
|
# https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/X509ExtendedTrustManager.html
|
|
|
|
keytool -keystore $KEYSTORE_WORKING_DIRECTORY/$KEYSTORE_FILENAME \
|
|
-alias localhost -validity $VALIDITY_IN_DAYS -genkey -keyalg RSA \
|
|
-noprompt -dname "C=$COUNTRY, ST=$STATE, L=$LOCATION, O=$OU, CN=$CN" -keypass $PASS -storepass $PASS -storetype JKS
|
|
|
|
echo
|
|
echo "'$KEYSTORE_WORKING_DIRECTORY/$KEYSTORE_FILENAME' now contains a key pair and a"
|
|
echo "self-signed certificate. Again, this keystore can only be used for one broker or"
|
|
echo "one logical client. Other brokers or clients need to generate their own keystores."
|
|
|
|
echo
|
|
echo "Fetching the certificate from the trust store and storing in $CA_CERT_FILE."
|
|
echo
|
|
|
|
keytool -keystore $trust_store_file -export -alias CARoot -rfc -file $CA_CERT_FILE -keypass $PASS -storepass $PASS
|
|
|
|
echo
|
|
echo "Now a certificate signing request will be made to the keystore."
|
|
echo
|
|
keytool -keystore $KEYSTORE_WORKING_DIRECTORY/$KEYSTORE_FILENAME -alias localhost \
|
|
-certreq -file $KEYSTORE_SIGN_REQUEST -keypass $PASS -storepass $PASS
|
|
|
|
echo
|
|
echo "Now the trust store's private key (CA) will sign the keystore's certificate."
|
|
echo
|
|
openssl x509 -req -CA $CA_CERT_FILE -CAkey $trust_store_private_key_file \
|
|
-in $KEYSTORE_SIGN_REQUEST -out $KEYSTORE_SIGNED_CERT \
|
|
-days $VALIDITY_IN_DAYS -CAcreateserial
|
|
# creates $KEYSTORE_SIGN_REQUEST_SRL which is never used or needed.
|
|
|
|
echo
|
|
echo "Now the CA will be imported into the keystore."
|
|
echo
|
|
keytool -keystore $KEYSTORE_WORKING_DIRECTORY/$KEYSTORE_FILENAME -alias CARoot \
|
|
-import -file $CA_CERT_FILE -keypass $PASS -storepass $PASS -noprompt
|
|
rm $CA_CERT_FILE # delete the trust store cert because it's stored in the trust store.
|
|
|
|
echo
|
|
echo "Now the keystore's signed certificate will be imported back into the keystore."
|
|
echo
|
|
keytool -keystore $KEYSTORE_WORKING_DIRECTORY/$KEYSTORE_FILENAME -alias localhost -import \
|
|
-file $KEYSTORE_SIGNED_CERT -keypass $PASS -storepass $PASS
|
|
|
|
echo
|
|
echo "All done!"
|
|
echo
|
|
echo "Deleting intermediate files. They are:"
|
|
echo " - '$KEYSTORE_SIGN_REQUEST_SRL': CA serial number"
|
|
echo " - '$KEYSTORE_SIGN_REQUEST': the keystore's certificate signing request"
|
|
echo " (that was fulfilled)"
|
|
echo " - '$KEYSTORE_SIGNED_CERT': the keystore's certificate, signed by the CA, and stored back"
|
|
echo " into the keystore"
|
|
|
|
rm $KEYSTORE_SIGN_REQUEST_SRL
|
|
rm $KEYSTORE_SIGN_REQUEST
|
|
rm $KEYSTORE_SIGNED_CERT
|