BBlack has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/198110

Change subject: Local OCSP updates to the filesystem
......................................................................

Local OCSP updates to the filesystem

WIP, Needs:
  1) puppet hookups to optionally do sslcert::ocsp for a given 
install_certificate
  2) nginx hookups to define ssl_stapling params iff the cert has sslcert::ocsp

Change-Id: If19dc78a8743cdcfff18b702a6c4502eeedcf393
---
A modules/sslcert/files/update-ocsp.sh
M modules/sslcert/manifests/init.pp
A modules/sslcert/manifests/ocsp.pp
3 files changed, 112 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/puppet 
refs/changes/10/198110/1

diff --git a/modules/sslcert/files/update-ocsp.sh 
b/modules/sslcert/files/update-ocsp.sh
new file mode 100644
index 0000000..a090beb
--- /dev/null
+++ b/modules/sslcert/files/update-ocsp.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+#
+# This fetches and validates an OCSP response for a cert, creating/updating a
+# file named /var/ssl/ocsp/${CERT_NAME}.ocsp which can be used with the nginx
+# ssl_stapling_file directive.
+#
+# The sole argument is the ${CERT_NAME}, which should match an input 
certificate
+# stored at /etc/ssl/localcerts/${CERT_NAME}.crt.
+#
+# If any step of this process fails, a temporary output dir may be left behind
+# at a pathname like /var/ssl/ocsp/ocsp.tmp.XXXXXXXX, where the X are random.
+#
+# If the date range check was the source of failure, there should be a file
+# named ${CERT_NAME}.ocsp within, which can be decoded with ...
+#     openssl ocsp -respin $tempfile -resp_text
+# ... to see why the request may have failed (compare various timestamps with
+# the creation timestamp of the file).
+#
+
+# Fail fast on any subcommand failure, to avoid clobbering a good OCSP file
+set -e
+set -o pipefail
+
+# Input args
+CERT_NAME=$1
+
+# Basic variables / constants
+THISUP_FUTURE_OFFSET="1 minute"
+NEXTUP_FUTURE_OFFSET="1 hour"
+CERT_DIR=/etc/ssl/localcerts
+ISSUER_DIR=/etc/ssl/certs
+OUT_DIR=/var/ssl/ocsp
+CERT_PATH=${CERT_DIR}/${CERT_NAME}.crt
+
+# umask / directories / output pathnames
+umask 022
+mkdir -p $OUT_DIR
+OUT_DIR_TEMP=$(mktemp -d ${OUT_DIR}/ocsp.tmp.XXXXXXXX)
+OUT_TEMP=${OUT_DIR_TEMP}/${CERT_NAME}.ocsp
+OUT_FINAL=${OUT_DIR}/${CERT_NAME}.ocsp
+
+# Fetch the OCSP URL and the issuer hash from the cert
+OCSP_URL=$(openssl x509 -in ${CERT_PATH} -text 2>/dev/null | grep "OCSP - 
URI:" | cut -d: -f2,3)
+ISSUER_PATH="${ISSUER_DIR}/$(openssl x509 -in ${CERT_PATH} -out /dev/null 
-issuer_hash 2>/dev/null).0"
+
+# actual ocsp fetch, outputs to temporary file
+openssl ocsp -nonce -respout ${OUT_TEMP} -issuer ${ISSUER_PATH} -cert 
${CERT_PATH} -path $OCSP_URL -host webproxy.esams.wmnet:8080 >/dev/null 2>&1
+
+# Validate thisUpdate/nextUpdate window
+OCSP_TEXT=$(openssl ocsp -noverify -respin ${OUT_TEMP} -resp_text)
+THISUP_RAW=$(echo "$OCSP_TEXT" | grep -i 'This Update:' | cut -d: -f2-)
+NEXTUP_RAW=$(echo "$OCSP_TEXT" | grep -i 'Next Update:' | cut -d: -f2-)
+THISUP_UNIX=$(date -d "$THISUP_RAW" +%s)
+NEXTUP_UNIX=$(date -d "$NEXTUP_RAW" +%s)
+THISUP_CMP=$(date -d "+${THISUP_FUTURE_OFFSET}" +%s)
+NEXTUP_CMP=$(date -d "+${NEXTUP_FUTURE_OFFSET}" +%s)
+if [ $THISUP_UNIX -gt $THISUP_CMP ]; then
+    echo "Failing; thisUpdate is greater than ${THISUP_FUTURE_OFFSET} into the 
future"
+    exit 1
+fi
+if [ $NEXTUP_UNIX -lt $NEXTUP_CMP ]; then
+    echo "Failing; nextUpdate is less than ${NEXTUP_FUTURE_OFFSET} into the 
future"
+    exit 1
+fi
+
+# Move new OCSP response into path for nginx pickup
+mv -f ${OUT_TEMP} ${OUT_FINAL}
+
+# clean up temporary dir
+rmdir ${OUT_DIR_TEMP}
diff --git a/modules/sslcert/manifests/init.pp 
b/modules/sslcert/manifests/init.pp
index d671fe9..f034004 100644
--- a/modules/sslcert/manifests/init.pp
+++ b/modules/sslcert/manifests/init.pp
@@ -30,6 +30,14 @@
         require => Package['ssl-cert'],
     }
 
+    # Script used by multiple instantiations of sslcert::ocsp
+    file { '/usr/local/sbin/update-ocsp.sh':
+        mode    => '0555',
+        owner   => 'root',
+        group   => 'root',
+        source  => 'puppet:///modules/sslcert/update-ocsp.sh',
+    }
+
     # Limit AppArmor support to just Ubuntu, for now
     if $::operatingsystem == 'Ubuntu' {
         include apparmor
diff --git a/modules/sslcert/manifests/ocsp.pp 
b/modules/sslcert/manifests/ocsp.pp
new file mode 100644
index 0000000..0b48cd8
--- /dev/null
+++ b/modules/sslcert/manifests/ocsp.pp
@@ -0,0 +1,34 @@
+# == Define: sslcert::ocsp
+#
+# This creates a cronjob that creates/refreshes an ocsp stapling file (for use
+# with nginx oscp_stapling_file) once an hour for a given certificate with a
+# filename of the form /var/ssl/ocsp/${certname}.ocsp.  It also creates the
+# file immediately if it doesn't already exist.  The hourly time offsets are
+# randomized based on both the host fqdn and the certname.
+#
+# === Examples
+#
+#  sslcert::ocsp { 'pinkunicorn.wikimedia.org': }
+#
+
+define sslcert::ocsp(
+) {
+    require sslcert
+
+    $create_cmd = "/usr/local/sbin/update-ocsp.sh ${title}"
+
+    exec { "${title}_create_ocsp":
+        command => $create_cmd,
+        creates => "/var/ssl/ocsp/${title}.ocsp",
+        before => Cron["${title}_update_ocsp"],
+        require => [
+            File['/usr/local/sbin/update-ocsp.sh'],
+            Sslcert::Certificate[$title],
+        ],
+    }
+
+    cron { "${title}_update_ocsp":
+        command => $create_cmd,
+        minute  => fqdn_rand(60, $title),
+    }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/198110
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If19dc78a8743cdcfff18b702a6c4502eeedcf393
Gerrit-PatchSet: 1
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: BBlack <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to