For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

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
No CommentsBe the first to comment