diff --git a/Dockerfile b/Dockerfile index 3ae3fc2..391a9ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,9 +8,9 @@ FROM centos:centos7 ENV TOMCAT_MAJOR=9 \ TOMCAT_VERSION=9.0.19 \ ##shib-idp \ - VERSION=3.4.3 \ + VERSION=3.4.4 \ ##TIER \ - TIERVERSION=20190201 \ + TIERVERSION=20190502 \ ################## \ ### OTHER VARS ### \ ################## \ @@ -32,6 +32,10 @@ ENV TOMCAT_TGZ_URL=https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOM ENV ENV=dev \ USERTOKEN=nothing +#The environment variable below controls whether or not the IdP's data sealer is automatically rotated daily. +# Set to False if you supply this file dynamically via secrets (or some other similar mechanism). +ENV ENABLE_SEALER_KEY_ROTATION=True + #set labels LABEL Vendor="Internet2" \ ImageType="Shibboleth IDP Release" \ @@ -159,6 +163,8 @@ ADD container_files/tomcat/robots.txt /usr/local/tomcat/webapps/ROOT ADD container_files/tomcat/keystore.jks /opt/certs/ # Copy TIER helper scripts +ADD container_files/idp/rotateSealerKey.sh /opt/shibboleth-idp/bin/rotateSealerKey.sh +RUN chmod +x /opt/shibboleth-idp/bin/rotateSealerKey.sh ADD container_files/system/startup.sh /usr/bin/ ADD container_files/bin/setenv.sh /opt/tier/setenv.sh ADD container_files/bin/setupcron.sh /usr/bin/setupcron.sh diff --git a/container_files/bin/setupcron.sh b/container_files/bin/setupcron.sh index ee1ec96..8612b09 100644 --- a/container_files/bin/setupcron.sh +++ b/container_files/bin/setupcron.sh @@ -8,6 +8,8 @@ CRONFILE=/opt/tier/tier-cron #build crontab file with random start time between midnight and 3:59am echo "#send daily beacon to TIER Central" > ${CRONFILE} echo $(expr $RANDOM % 59) $(expr $RANDOM % 3) "* * * /usr/bin/sendtierbeacon.sh >> /var/log/cron.log 2>&1" >> ${CRONFILE} +echo "#rotate IdP data sealer key" >> ${CRONFILE} +echo "0 1 * * * /opt/shibboleth-idp/bin/rotateSealerKey.sh >> /var/log/cron.log 2>&1" >> ${CRONFILE} chmod 644 ${CRONFILE} #install crontab diff --git a/container_files/idp/idp.installer.properties b/container_files/idp/idp.installer.properties index 321a842..b02bae0 100644 --- a/container_files/idp/idp.installer.properties +++ b/container_files/idp/idp.installer.properties @@ -1,4 +1,4 @@ -idp.src.dir=/tmp/shibboleth/shibboleth-identity-provider-3.4.3 +idp.src.dir=/tmp/shibboleth/shibboleth-identity-provider-3.4.4 idp.target.dir=/opt/shibboleth-idp idp.host.name=idp.example.org idp.sealer.password=changeit diff --git a/container_files/idp/rotateSealerKey.sh b/container_files/idp/rotateSealerKey.sh new file mode 100644 index 0000000..25df465 --- /dev/null +++ b/container_files/idp/rotateSealerKey.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -e +set -u + +if [ ${ENABLE_SEALER_KEY_ROTATION:=True} = 'True' ] +then + + # Default IDP_HOME if not already set + if [ ! -d "${IDP_HOME:=/opt/shibboleth-idp}" ] + then + echo "ERROR: Directory does not exist: ${IDP_HOME}" >&2 + exit 1 + fi + + # Default JAVA_HOME if not already set + if [ -d "${JAVA_HOME:=/usr}" ] + then + export JAVA_HOME=${JAVA_HOME:=/usr} + else + echo "ERROR: JAVA_HOME Directory does not exist: ${JAVA_HOME:=/usr}" >&2 + exit 1 + fi + + function get_config { + # Key to lookup (escape . for regex lookup) + local KEY=${1:?"No key provided to look up value"} + # Passed default value + local DEFAULT="${2:-}" + # Lookup key, strip spaces, replace idp.home with IDP_HOME value + local RESULT=$(sed -rn '/^'"${KEY//./\\.}"'\s*=/ { s|^[^=]*=(.*)\s*$|\1|; s|%\{idp\.home\}|'"${IDP_HOME}"'|g; p}' ${IDP_HOME}/conf/idp.properties) + # Set if no result with default - exit if no default + echo ${RESULT:-${DEFAULT:?"No value in config and no default defined for: '${KEY}'"}} + } + + # Get config values + ## Official config items ## + storefile=$(get_config idp.sealer.storeResource) + versionfile=$(get_config idp.sealer.versionResource) + storepass=$(get_config idp.sealer.storePassword) + alias=$(get_config idp.sealer.aliasBase secret) + ## Extended config items ## + count=$(get_config idp.sealer._count 30) + # default cannot be empty - so "self" is the default (self is skipped for syncing) + sync_hosts=$(get_config idp.sealer._sync_hosts ${HOSTNAME}) + + # Run the keygen utility + ${0%/*}/runclass.sh net.shibboleth.utilities.java.support.security.BasicKeystoreKeyStrategyTool \ + --storefile "${storefile}" \ + --storepass "${storepass}" \ + --versionfile "${versionfile}" \ + --alias "${alias}" \ + --count "${count}" + + # Display current version + echo "INFO: $(tac "${versionfile}" | tr "\n" " ")" >&2 + + for EACH in ${sync_hosts} + do + if [ "${HOSTNAME}" == "${EACH}" ] + then + echo "INFO: Host '${EACH}' is myself - skipping" >&2 + elif ! ping -q -c 1 -W 3 ${EACH} >/dev/null 2>&1 + then + echo "ERROR: Host '${EACH}' not reachable - skipping" >&2 + else + # run scp in the background + scp "${storefile}" "${versionfile}" "${EACH}:${IDP_HOME}/credentials/" & + fi + done + +fi diff --git a/test-compose/idp/Dockerfile b/test-compose/idp/Dockerfile index fa8ed18..513790d 100644 --- a/test-compose/idp/Dockerfile +++ b/test-compose/idp/Dockerfile @@ -1,4 +1,5 @@ -FROM tier/shib-idp:3.4.2_181201 +FROM tier/shib-idp:latest +#FROM tier/shib-idp:3.4.4_20190502 # The build args below can be used at build-time to tell the build process where to find your config files. This is for a completely burned-in config. ARG TOMCFG=config/tomcat