Skip to content

Instantly share code, notes, and snippets.

@teridon
Last active December 12, 2022 22:03
Show Gist options
  • Save teridon/b25c9041dc3486b3fa33a5dbbb3e1b03 to your computer and use it in GitHub Desktop.
Save teridon/b25c9041dc3486b3fa33a5dbbb3e1b03 to your computer and use it in GitHub Desktop.
tests the validity period of your CA-signed SSH host keys (nagios plugin output)
#!/bin/bash
# If $host has a certificate, `ssh -v` will output something like:
# debug1: Server host certificate: [email protected] SHA256:QD2N2jIKh14Ef3A9yfu9Jw2NOpPtDT01aFRP9/rNI+E, serial 0 ID "gs483-fwdev01 host key" CA ssh-rsa SHA256:ws/24503Ukwp2mVwxe18LRKz63A2elSm5a1FeLqAV70 valid from 2019-12-19T10:05:16 to 2020-12-24T10:10:16
# StrictHostKeyChecking=no so that ssh doesn't hang prompting to accept keys
# but UserKnownHostsFile=/tmp/check_ssh_cert_known_hosts to prevent adding keys to the user's known_hosts file
check_exe="ssh -v -o PreferredAuthentications=none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/tmp/check_ssh_cert_known_hosts"
# If you have multiple certs (one for each algorithm) you need to connect multiple times to see them all
# for ESXi hosts, you only want to check RSA keys; i.e. "-a [email protected]"
algolist="[email protected] [email protected] [email protected]"
port=22
ssh_timeout=5
warn=30
crit=5
exitval=0
SCRIPTNAME=$(basename $0)
usage() {
echo "Usage: "
echo " $SCRIPTNAME -h HOST [ -p port ] [ -e check_program ] [ -t ssh_timeout ] "
echo " [ -a quoted, space-separated HostKeyAlgorithms list \(man ssh_config\) ]"
echo " [ -w warning (days) ] [ -c critical (days) ]"
}
while getopts ":a:h:w:c:p:e:t:" opt; do
case $opt in
a)
algolist=${OPTARG}
;;
h)
host=${OPTARG}
;;
w)
warn=${OPTARG}
;;
c)
crit=${OPTARG}
;;
e)
check_exe=${OPTARG}
;;
p)
port=${OPTARG}
;;
t)
ssh_timeout=${OPTARG}
;;
\?)
echo "${SCRIPTNAME}: Invalid option: -${OPTARG}" >&2
usage && exit 3
;;
:)
echo "${SCRIPTNAME}: option -${OPTARG} requires an argument." >&2
usage && exit 3
esac
done
if [ -z ${host} ]; then
echo "${SCRIPTNAME}: option -h is REQUIRED"
usage && exit 3
fi
set -o pipefail
for algo in $algolist ; do
expire_date=$( 2>&1 ${check_exe} -o ConnectTimeout=${ssh_timeout} -o HostKeyAlgorithms=${algo} ${host} -p${port} | awk -F' from | to ' '/Server host certificate/ {print $3}' )
if [ -z "$expire_date" ]; then
err+="failure for $host on port $port using algorithm $algo "
exitval=2
fi
expire=$(date -d "${expire_date}" "+%s")
now=$(date +%s)
diff_in_days=$(( ( $expire - $now )/86400 ))
if [ $diff_in_days -lt $crit ]; then
err+="certificate for algorithm $algo expires in $diff_in_days days | expiredays=$diff_in_days warn=$warn crit=$crit "
if [ $exitval -le 2 ]; then exitval=2 ; fi
fi
if [ $diff_in_days -lt $warn ]; then
err+="certificate for algorithm $algo expires in $diff_in_days days | expiredays=$diff_in_days warn=$warn crit=$crit "
if [ $exitval -le 1 ]; then exitval=1 ; fi
else
err+="certificate for algorithm $algo expires in $diff_in_days days | expiredays=$diff_in_days warn=$warn crit=$crit "
fi
done
case $exitval in
0)
stat="OK"
;;
1)
stat="WARNING"
;;
2)
stat="CRITICAL"
;;
3)
stat="UNKNOWN"
;;
esac
echo "${SCRIPTNAME} ${stat} | $err"
exit $exitval
@teridon
Copy link
Author

teridon commented Dec 12, 2022

output should look like:
check_ssh_cert.sh OK | certificate for algorithm [email protected] expires in 356 days | expiredays=356 warn=30 crit=5 certificate for algorithm [email protected] expires in 356 days | expiredays=356 warn=30 crit=5 certificate for algorithm [email protected] expires in 356 days | expiredays=356 warn=30 crit=5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment