Custom HTTPS External Monitor

Problem this snippet solves:

Contributed by Leonardo Souza.

This monitor works around limitations with built-in monitor in selecting tls version for server monitoring. Details in this article.

Code :

#!/bin/sh

# Leonardo Souza - 20/10/2016
# HTTPS External Monitor
# Version 1.0.0

# Using openssl s_client because curl only accepts tlsv1.0/tlsv1.1/tlsv1.2 from version 7.34.0 (v12.1.1 HF1 uses 7.19.7 for example)
# For protocol and cipher options go to this link:
# https://www.openssl.org/docs/manmaster/apps/s_client.html

# External Monitor example
#ltm monitor external https_monitor {
#    defaults-from external
#    destination *:*
#    interval 5
#    run /Common/https_external_script
#    time-until-up 0
#    timeout 16
#    user-defined cipher DEFAULT
#    user-defined debug enable
#    user-defined protocol tls1
#    user-defined receive_string Welcome
#    user-defined receive_string_down Moved
#    user-defined send_string "GET /"
#}

# If debug mode is enabled, log to /var/log/ltm
# debug=enable to enable debug, debug=disable to disable debug
# If debug variable is not set, debug will be disabled

# File to save OpenSSL output
output=`mktemp`

# File to save OpenSSL output error
output_error=`mktemp`

# Variable to save OpenSSL output exit code
output_code=""

# Variable to store the monitor result
result=""

# $1 = Pool member IP in IPv6 format, need to remove :ffff:
# $2 = Pool member port
ip=${1/#::ffff:}
port=$2

# Script name
script=`basename $0`

# Script pid
pid="/var/run/$script-$1:$2.pid"

# Check if there is any instance of the script running
# Kill the instance if is running
# Create pid file
[ -f "$pid" ] && kill -9 `cat $pidfile` > /dev/null 2>&1
echo "$$" > $pid

# OpenSSL command
echo $send_string | openssl s_client -quiet -$protocol -cipher $cipher -connect ${ip}:${port} 1> $output 2> $output_error
output_code=$?

# If receive_string or receive_string_down is not defined, mark pool member up as long as OpenSSL command was successful
if [ $output_code -eq 0 ]
then
  result="up"
  [ $debug = "enable" ] && logger -p local0.notice "$script ${ip}:${port} - OpenSSL: Pool member up" &> /dev/null
else
  result="down"
  if [ $debug = "enable" ]
  then
    logger -p local0.notice "$script ${ip}:${port} - OpenSSL: Pool member down" &> /dev/null
    logger -p local0.notice "$script ${ip}:${port} - OpenSSL: `cat $output_error | head -n1`" &> /dev/null
    logger -p local0.notice "$script ${ip}:${port} - OpenSSL: `cat $output_error | tail -n1`" &> /dev/null
  fi
fi

# If receive_string_down is set, perform some tests
# If string is not in the output, mask pool member as up
if [ -n "$receive_string_down" ]
then
  cat $output | grep "$receive_string_down" &> /dev/null
  if [ $? -ne 0 ]
  then
    result="up"
    [ $debug = "enable" ] && logger -p local0.notice "$script ${ip}:${port} - Receive String Down: Pool member up" &> /dev/null
  else
    result="down"
    [ $debug = "enable" ] && logger -p local0.notice "$script ${ip}:${port} - Receive String Down: Pool member down" &> /dev/null
  fi
fi

# If receive_string is set, perform some tests
# If string is in the output, mask pool member as up
# If string is not in the output, mask pool member as down
if [ -n "$receive_string" ]
then
  cat $output | grep "$receive_string" &> /dev/null
  if [ $? -eq 0 ]
  then
    result="up"
    [ $debug = "enable" ] && logger -p local0.notice "$script ${ip}:${port} - Receive String: Pool member up" &> /dev/null
  else
    result="down"
    [ $debug = "enable" ] && logger -p local0.notice "$script ${ip}:${port} - Receive String: Pool member down" &> /dev/null
  fi
fi

# Remove temporary files
rm -f $output
rm -f $output_error

# Remove pid file
rm -f $pid

# echo result is up
[ $result = "up" ] && echo "up"
Published Oct 27, 2016
Version 1.0

Was this article helpful?

No CommentsBe the first to comment