#!/usr/bin/env bash # certificates and key stores generated by this script CERTIFICATES="/etc/hirs/certificates" CA_CERT=${CERTIFICATES}/hirs.ca.cert INTERNAL_P12=${CERTIFICATES}/hirs.p12 KEYSTORE_JKS=${CERTIFICATES}/keyStore.jks TRUSTSTORE_JKS=${CERTIFICATES}/TrustStore.jks CA_CERT_DIR_ESCAPED=\\/etc\\/hirs\\/certificates # 'private' data generated by this script CA_PEM=${CERTIFICATES}/private/hirs.ca.pem P12_DATA=${CERTIFICATES}/private/p12.data echo 'Checking SSL configuration for HIRS' # Check if we're in a Docker container if [ -f /.dockerenv ]; then DOCKER_CONTAINER=true else DOCKER_CONTAINER=false fi ################# # Key Generation ################# # if the CA PEM file does not exist, generate the HIRS CA file and associated keystore and truststores if ! [ -f $CA_PEM ]; then echo 'Generating certificates' # create directory structure mkdir -p ${CERTIFICATES}/private # Generate our random key store password. We need to do this before configuring Tomcat, as we'll # need to add it to Tomcat's configuration file. Read a block of raw data bytes from /dev/urandom # and convert it to text characters. Not the greatest, but hey: echo 'Creating random key material' P12_PASSWORD=$(head -c 64 /dev/urandom | md5sum | tr -dc 'a-zA-Z0-9') # generate a key and certificate. The key is the private key used to sign the well known CA cert. echo 'Creating 2048 bit key' openssl req -x509 -nodes -days 3652 -newkey rsa:2048 -keyout ${CA_PEM} -out ${CA_CERT} -subj "/C=US/O=HIRS/OU=Common/CN=$(hostname)" # export the certificate and key as a p12 file echo 'Exporting key' openssl pkcs12 -export -in ${CA_CERT} -inkey ${CA_PEM} -out ${INTERNAL_P12} -passout pass:${P12_PASSWORD} # create a key store using the pk12 file. echo 'Configuring keystore' keytool -importkeystore -srckeystore ${INTERNAL_P12} -destkeystore ${KEYSTORE_JKS} -srcstoretype pkcs12 -srcstorepass ${P12_PASSWORD} -deststoretype jks -deststorepass ${P12_PASSWORD} -noprompt # import the root CA certificate into the trust store. echo 'Configuring truststore' keytool -import -keystore ${TRUSTSTORE_JKS} -storepass password -file ${CA_CERT} -noprompt # write P12 password to file echo $P12_PASSWORD > $P12_DATA # set appropriate permissions on certificates chmod 775 /etc/hirs/certificates/ chmod -R 664 /etc/hirs/certificates/* chmod 700 /etc/hirs/certificates/private chmod -R 600 /etc/hirs/certificates/private/* else # if the certificate was previously generated, grab the P12 password out of the file P12_PASSWORD=`cat $P12_DATA` fi ################# # ActiveMQ ################# if [[ $1 = "server" ]]; then if [ -f "/srv/activemq/current/conf/activemq.xml" ] ; then if [[ -n `grep -o "keyStorePassword=\"\"" /srv/activemq/current/conf/activemq.xml` ]]; then echo "Configuring ActiveMQ SSL" # set the key store password for the messaging service sed -i -r "s/keyStorePassword=\"\w*\"/keyStorePassword=\"${P12_PASSWORD}\"/g" /srv/activemq/current/conf/activemq.xml fi fi fi ################# # Tomcat ################# if [[ $1 = "server" ]]; then # determine which version of tomcat is installed rpm -q tomcat6 if [[ $? -eq 0 ]]; then TOMCAT_VERSION=`rpm -q --qf="%{VERSION}" tomcat6` else TOMCAT_VERSION=`rpm -q --qf="%{VERSION}" tomcat` fi TOMCAT_MAJOR_VERSION=`echo $TOMCAT_VERSION | head -c 1` if [[ $TOMCAT_MAJOR_VERSION = '6' ]]; then CATALINA_HOME=/usr/share/tomcat6 TOMCAT_SERVICE=tomcat6 TOMCAT_CONF=${CATALINA_HOME}/conf/tomcat6.conf elif [[ $TOMCAT_MAJOR_VERSION = '7' ]] ; then CATALINA_HOME=/usr/share/tomcat TOMCAT_SERVICE=tomcat TOMCAT_CONF=${CATALINA_HOME}/conf/tomcat.conf else echo "Unsupported Tomcat version: ${TOMCAT_MAJOR_VERSION}" exit 1 fi if [[ -z `grep -o "keystoreFile=\"${CA_CERT_DIR_ESCAPED}\/keyStore.jks\"" $CATALINA_HOME/conf/server.xml` ]]; then echo "Configuring Tomcat SSL" chown -R root:tomcat /etc/hirs/certificates/ # create an alias in the keystore for tomcat alias=$(keytool -list -v -keystore ${KEYSTORE_JKS} -storepass ${P12_PASSWORD} | grep -B2 'PrivateKeyEntry' | grep 'Alias name:') keytool -changealias -alias ${alias#*:} -destalias tomcat -v -keystore ${KEYSTORE_JKS} -storepass ${P12_PASSWORD} # Set up Tomcat. We need to ensure that Tomcat is running as a service chkconfig ${TOMCAT_SERVICE} on # Configure the server.xml file such that it uses our key store and trust store if [ $DOCKER_CONTAINER = true ]; then # If in Docker container, avoid services that invoke the D-Bus if [[ $(pgrep -c -f /usr/share/tomcat) -ne 0 ]]; then echo "Tomcat is running, so we stop it." /usr/libexec/tomcat/server stop fi else service ${TOMCAT_SERVICE} stop fi # Configure Tomcat SSL properly. The method for doing this changes from 6.0.38 onward. rpmdev-vercmp 6.0.38 $TOMCAT_VERSION VERCMP_STATUS=$? if [[ $VERCMP_STATUS -eq 0 ]] || [[ $VERCMP_STATUS -eq 12 ]]; then # Tomcat v 6.0.38 or newer sed -i "s/.*<\/Service>/<\/Service>/" $CATALINA_HOME/conf/server.xml elif [[ $VERCMP_STATUS -eq 11 ]]; then # Older than Tomcat 6.0.38 sed -i "s/.*<\/Service>/<\/Service>/" $CATALINA_HOME/conf/server.xml else echo "Unknown rpmdev-vercmp exit code: ${VERCMP_STATUS}" exit 1 fi sed -i 's/.*<\/tomcat-users>/ <\/tomcat-users>/' $CATALINA_HOME/conf/tomcat-users.xml # ensure tomcat is using the trust store and key store for all other SSL operations. cat << EOF >> ${TOMCAT_CONF} #begin-hirs-conf JAVA_OPTS="-Djavax.sql.DataSource.Factory=org.apache.commons.dbcp.BasicDataSourceFactory -Xmx1536m -Djavax.net.ssl.keyStore=${KEYSTORE_JKS} -Djavax.net.ssl.keyStorePassword=${P12_PASSWORD} -Djavax.net.ssl.trustStore=${TRUSTSTORE_JKS} -Djavax.net.ssl.trustStorePassword=password" #end-hirs-conf EOF # (3) set tomcat user as owner of tomcat installation chgrp -R tomcat ${CATALINA_HOME} if [ $DOCKER_CONTAINER = true ]; then # If in Docker container, avoid services that invoke the D-Bus (/usr/libexec/tomcat/server start) & # Wait for Tomcat to boot completely until [ "`curl --silent --connect-timeout 1 -I http://localhost:8080 | grep 'Coyote'`" != "" ]; do : done else service ${TOMCAT_SERVICE} start fi fi fi ################# # Appraiser ################# if [[ $1 = "appraiser" ]]; then APPRAISER_SCRIPT="/opt/hirs/appraiser/bin/HIRS_Appraiser" if [[ -z `grep -o "\-Djavax.net.ssl.keyStorePassword" $APPRAISER_SCRIPT` ]]; then echo "Configuring Appraiser SSL" # grab the line number of the JVM options for the client script VM_OPTS=$(awk '/DEFAULT_JVM_OPTS/{print NR; exit }' ${APPRAISER_SCRIPT}) # append the key store password to the client startup script sed -i "${VM_OPTS}s/'$/ \"-Djavax.net.ssl.keyStorePassword=${P12_PASSWORD}\"\'/" ${APPRAISER_SCRIPT} fi fi ################# # MySQL/MariaDB ################# if [[ $1 = "server" ]]; then MYSQL_CERT_DIR=/etc/hirs/certificates/mysql/ if ! [[ -d $MYSQL_CERT_DIR ]]; then echo "Configuring MySQL SSL" # apply MySQL SSL configuration: mkdir -p $MYSQL_CERT_DIR # copy CA cert over cp $CA_CERT $MYSQL_CERT_DIR/ # convert p12 key to pem openssl pkcs12 -in $INTERNAL_P12 -out $MYSQL_CERT_DIR/hirs.pem -nodes -passin pass:${P12_PASSWORD} -passout pass: # extract cert from pem into its own file openssl x509 -in $MYSQL_CERT_DIR/hirs.pem -outform PEM -out $MYSQL_CERT_DIR/hirs-cert.pem # extract key from pem into its own file openssl pkey -in $MYSQL_CERT_DIR/hirs.pem -outform PEM -out $MYSQL_CERT_DIR/hirs-key.pem # make readable to user named 'mysql' chgrp -R mysql $MYSQL_CERT_DIR chmod -R 770 $MYSQL_CERT_DIR # update MySQL/MariaDB SSL and index configuration if [[ -f /etc/redhat-release ]] ; then CENTOS_VER=`/opt/hirs/scripts/common/get_centos_major_version.sh` elif [[ -f /etc/os-release ]] ; then AMAZON_VER=`/opt/hirs/scripts/common/get_amazon_linux_major_version.sh` fi if [ $CENTOS_VER -eq "6" ] ; then MYSQL_ADDITIONS_FILE=/opt/hirs/scripts/common/my.cnf.el6 elif [ $CENTOS_VER -eq "7" ] || [ $AMAZON_VER -eq "2" ] ; then MYSQL_ADDITIONS_FILE=/opt/hirs/scripts/common/my.cnf.el7 else echo "Unsupported Linux detected" exit 1 fi sed -i "/\[mysqld\]/r $MYSQL_ADDITIONS_FILE" /etc/my.cnf if [ $DOCKER_CONTAINER = true ]; then # If in Docker container, avoid services that invoke the D-Bus if [[ $(pgrep -c -u mysql mysqld) -ne 0 ]]; then echo "MariaDB is running, so we'll need to restart it." mysqladmin shutdown /usr/libexec/mariadb-prepare-db-dir nohup /usr/bin/mysqld_safe --basedir=/usr &>/dev/null & MYSQLD_PID=$(pgrep -u mysql mysqld) /usr/libexec/mariadb-wait-ready $MYSQLD_PID fi else SQL_SERVICE=`/opt/hirs/scripts/common/get_db_service.sh` service $SQL_SERVICE restart fi fi fi