File check_sftp.sh of Package monitoring-plugins-sftp
#!/bin/bash
################################################################################
# Script: check_sftp.sh #
# Author: Claudio Kuenzler www.claudiokuenzler.com #
# Purpose: Monitor SFTP server (connection, upload, download) #
# Repository: https://github.com/Napsty/check_sftp #
# License: GPLv3 (see LICENSE file in same git repository #
# #
# GNU General Public Licence (GPL) http://www.gnu.org/ #
# This program is free software; you can redistribute it and/or #
# modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation, either version 3 #
# of the License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, see <https://www.gnu.org/licenses/>. #
# #
# Copyright 2022 Claudio Kuenzler #
# #
# History/Changelog: #
# 20221223 1.0.0: Public release #
# 20221223 1.0.1: Add private key authentication with passphrase (issue #1) #
# 20221227 1.0.2: Adjust help, add key auth commands requirement, debug clean #
################################################################################
#Variables and defaults
version=1.0.2
STATE_OK=0 # define the exit code if status is OK
STATE_WARNING=1 # define the exit code if status is Warning
STATE_CRITICAL=2 # define the exit code if status is Critical
STATE_UNKNOWN=3 # define the exit code if status is Unknown
export PATH=$PATH:/usr/local/bin:/usr/bin:/bin # Set path
port=22
user=$USER
directory=monitoring
tmpdir=/tmp
verbose=false
sftpoptions="-o StrictHostKeyChecking=no "
################################################################################
#Functions
help () {
echo -e "$0 $version (c) 2022 Claudio Kuenzler and contributors (open source rulez!)
Usage: ./check_sftp.sh -H SFTPServer [-P port] [-u username] [-p password] [-i privatekey] [-o options] [-d remotedir] [-t tmpdir] [-v]
Options:
* -H Hostname or ip address of SFTP Server
-P Port (default: 22)
-u Username (default: \$USER from environment)
-p Password or passphrase of private key when used in combination with -i
-i Identity file/Private Key for Key Authentication (example: '~/.ssh/id_rsa')
-o Additional SSH options (-o ...) to be added (default: '-o StrictHostKeyChecking=no ')
-d Remote directory to use for upload/download (default: monitoring)
-t Local temp directory (default: /tmp)
-v Verbose mode (shows sftp commands and output)
-h Shows this help
*mandatory options
Requirements: sftp, sshpass (when using a password)"
exit $STATE_UNKNOWN;
}
################################################################################
# Check for people who need help - aren't we all nice ;-)
if [ "${1}" = "--help" -o "${#}" = "0" ]; then help; exit $STATE_UNKNOWN; fi
################################################################################
# Get user-given variables
while getopts "H:P:u:p:i:o:d:t:vh" Input
do
case ${Input} in
H) host=${OPTARG};;
P) port=${OPTARG:=22};;
u) user=${OPTARG};;
p) export SSHPASS="${OPTARG}"; usepass="sshpass -e ";;
i) keyfile="${OPTARG}";;
o) sftpoptions+="${OPTARG} ";;
d) directory=${OPTARG:="monitoring"};;
t) tmpdir=${OPTARG:=/tmp};;
v) verbose=true;;
*) help;;
esac
done
################################################################################
# Input checks and requirements
for cmd in sftp; do
if ! `which ${cmd} >/dev/null 2>&1`; then
echo "CHECK_SFTP UNKNOWN: ${cmd} does not exist, please check if command exists and PATH is correct"
exit ${STATE_UNKNOWN}
fi
done
# When using password authentication, we need sshpass
if [[ -n ${usepass} ]] && [[ -z ${keyfile} ]]; then
if ! `which sshpass >/dev/null 2>&1`; then
echo "CHECK_SFTP UNKNOWN: command 'sshpass' does not exist, please check if command exists and PATH is correct"
exit ${STATE_UNKNOWN}
fi
fi
if [[ -z ${host} ]]; then
echo "CHECK_SFTP UNKNOWN: Missing SFTP Host (-H)"
exit ${STATE_UNKNOWN}
fi
if [ "${verbose}" = true ]; then
stdoutredir="/dev/stderr"
else
stdoutredir='/dev/null'
fi
# When using key authentication, add SSH key to ssh-agent
if [[ -n "${keyfile}" ]]; then
for cmd in ssh-agent ssh-add; do
if ! `which ${cmd} >/dev/null 2>&1`; then
echo "CHECK_SFTP UNKNOWN: ${cmd} does not exist, please check if command exists and PATH is correct"
exit ${STATE_UNKNOWN}
fi
done
if ! [[ -r "${keyfile}" ]]; then
echo "CHECK_SFTP CRITICAL: Cannot read private key file (${keyfile}). Check permissions."
exit ${STATE_CRITICAL}
fi
identityfile="-i ${keyfile}"
usepass=""
agentrc=$?
if [[ ${agentrc} -gt 0 ]]; then
eval "$(ssh-agent)" > /dev/null
trap 'ssh-agent -k > /dev/null' EXIT
echo "exec cat" > ${tmpdir}/check_sftp_ap.sh
chmod 755 ${tmpdir}/check_sftp_ap.sh
export DISPLAY=1
echo "${SSHPASS}" | SSH_ASKPASS=${tmpdir}/check_sftp_ap.sh ssh-add ${keyfile} >/dev/null 2>&1
rm -f ${tmpdir}/check_sftp_ap.sh
fi
fi
# When using password authentication, add special SSH options
if [[ -n "${usepass}" ]] && [[ -z "${keyfile}" ]]; then
sftpoptions+="-o PubkeyAuthentication=no -o BatchMode=no "
fi
################################################################################
# Create a local file with current timestamp
ts=$(date +%s)
file=mon.${ts}
touch ${tmpdir}/${file}
# Establish connection and make sure the directory exists on the SFTP server
${usepass} sftp -P ${port} ${identityfile} ${sftpoptions} -b - ${user}@${host} <<EOF >${stdoutredir} 2>&1
cd ${directory}
exit
EOF
# Handle exit code from sftp above
# 0: All worked
# 1: Directory does not exist
# 127: Permission denied (likely related to publickey)
# 255: SFTP connection failed
exitcode=$?
# Communication failed, alert and exit
if [[ ${exitcode} -eq 255 ]]; then
echo "CHECK_SFTP CRITICAL: Unable to establish a connection to SFTP server with given credentials"
exit $STATE_CRITICAL
fi
if [[ ${exitcode} -eq 127 ]]; then
echo "CHECK_SFTP CRITICAL: Unable to establish a connection to SFTP server with given credentials"
exit $STATE_CRITICAL
fi
if [[ ${exitcode} -gt 1 ]]; then
echo "CHECK_SFTP CRITICAL: Unable to establish a connection to SFTP server with given credentials"
exit $STATE_CRITICAL
fi
# Create directory if not exists
if [[ ${exitcode} -eq 1 ]]; then
createdircmd="mkdir ${directory}"
fi
# Continue with check
${usepass} sftp -P ${port} ${identityfile} ${sftpoptions} -b - ${user}@${host} <<EOF >${stdoutredir} 2>&1
${createdircmd}
cd ${directory}
lcd ${tmpdir}
put ${tmpdir}/${file}
get ${file}
rm ${file}
exit
EOF
exitcode=$?
case "${exitcode}" in
0) output="CHECK_SFTP OK: Communication to ${host} worked. Upload, Download and Removal of file (${file}) into/from remote directory (${directory}) worked."
exitcode=${STATE_OK}
;;
1) output="CHECK_SFTP WARNING: At least one of the SFTP commands (cd/put/get) failed."
exitcode=${STATE_WARNING}
;;
*) output="CHECK_SFTP CRITICAL: Unknown error."
exitcode=${STATE_CRITICAL}
;;
esac
# Remove local files
rm -f ${file}
rm -f ${tmpdir}/${file}
# Some performance data because graphs are nice to look at
duration=$(( $(date +%s) - ${ts} ))
echo "${output}|checktime=${duration}s;;;;"
exit ${exitcode}