Skip to content

Instantly share code, notes, and snippets.

@tofi86
Last active August 24, 2022 17:48
Show Gist options
  • Save tofi86/d8c990ebfaa4b529974e to your computer and use it in GitHub Desktop.
Save tofi86/d8c990ebfaa4b529974e to your computer and use it in GitHub Desktop.
Nagios/Icinga command to check fritzbox status for "uptime", "upstream", "downstream", "connection" and "external ip". This is a fork of http://blog.gmeiners.net/2013/09/fritzbox-mit-nagios-uberwachen.html
#!/bin/bash
#
# Example configuration
#
# commands.cfg:
#
# define command {
# command_name check_fritz_uptime
# command_line $USER1$/check_fritz -h $HOSTADDRESS$ -f linkuptime
# }
#
# FRITZ!Box monitoring largely based on the works of
# http://terranas.qcloudnas.com/wordpress/nagios-fritzbox-uber-upnp-uberwachen/
#
RC_OK=0
RC_WARN=1
RC_CRIT=2
RC_UNKNOWN=3
CURL=/usr/bin/curl
usage()
{
echo "usage: check_fritz -d -h hostname -f <function> [-w <warn>] [-c <crit>] [-i <checkIP>]"
echo " -d: enable debug output"
echo " -w: warn limit, depends on function"
echo " -c: critical limit, depends on function"
echo " -i: IP address which should be matched in externalip function"
echo "functions:"
echo " linkuptime = connection time in seconds"
echo " connection = connection status"
echo " upstream = maximum upstream on current connection"
echo " downstream = maximum downstream on current connection"
echo " externalip = get external ip address"
exit ${RC_UNKNOWN}
}
require_number()
{
VAR=$1
MSG=$2
if [[ ! "${VAR}" =~ ^[0-9]+$ ]] ; then
echo "ERROR - ${MSG} (${VAR})"
exit ${RC_UNKNOWN}
fi
}
require_ip_address()
{
VAR=$1
MSG=$2
if [[ ! "${VAR}" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] ; then
echo "ERROR - ${MSG} (${VAR})"
exit ${RC_UNKNOWN}
fi
}
find_xml_value()
{
XML=$1
VAL=$2
echo "${XML}" | grep "${VAL}" | sed "s/<${VAL}>\([^<]*\)<\/${VAL}>/\1/"
}
check_greater()
{
VAL=$1
WARN=$2
CRIT=$3
MSG=$4
if [ ${VAL} -gt ${WARN} ] || [ ${WARN} -eq 0 ]; then
echo "OK - ${MSG}"
exit ${RC_OK}
elif [ ${VAL} -gt ${CRIT} ] || [ ${CRIT} -eq 0 ]; then
echo "WARNING - ${MSG}"
exit ${RC_WARN}
else
echo "CRITICAL - ${MSG}"
exit ${RC_CRIT}
fi
}
HOSTNAME=fritz.box
PORT=49000
CHECK=linkuptime
DEBUG=0
WARN=0
CRIT=0
IPCHECK=0
while getopts h:f:w:c:i:d OPTNAME; do
case "${OPTNAME}" in
h)
HOSTNAME="${OPTARG}"
;;
f)
CHECK="${OPTARG}"
;;
d)
DEBUG=1
;;
w)
WARN="${OPTARG}"
;;
c)
CRIT="${OPTARG}"
;;
i)
IPCHECK="${OPTARG}"
;;
*)
usage
;;
esac
done
case ${CHECK} in
linkuptime|connection)
VERB=GetStatusInfo
URL=WANIPConn1
NS=WANIPConnection
;;
downstream|upstream)
VERB=GetCommonLinkProperties
URL=WANCommonIFC1
NS=WANCommonInterfaceConfig
;;
externalip)
VERB=GetExternalIPAddress
URL=WANIPConn1
NS=WANIPConnection
;;
*)
echo "ERROR - Unknown service check ${CHECK}"
exit ${RC_UNKNOWN}
;;
esac
STATUS=`curl "http://${HOSTNAME}:${PORT}/igdupnp/control/${URL}" \
-H "Content-Type: text/xml; charset="utf-8"" \
-H "SoapAction:urn:schemas-upnp-org:service:${NS}:1#${VERB}" \
-d "<?xml version='1.0' encoding='utf-8'?> <s:Envelope s:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'> <s:Body> <u:${VERB} xmlns:u="urn:schemas-upnp-org:service:${NS}:1" /> </s:Body> </s:Envelope>" \
-s`
if [ "$?" -ne "0" ]; then
echo "ERROR - Could not retrieve status from FRITZ!Box"
exit ${RC_CRIT}
fi
if [ ${DEBUG} -eq 1 ]; then
echo "DEBUG - Status:"
echo "${STATUS}"
fi
case ${CHECK} in
linkuptime)
UPTIME=$(find_xml_value "${STATUS}" NewUptime)
require_number "${UPTIME}" "Could not parse uptime"
DAYS=$((${UPTIME}/86400))
HOURS=$(((${UPTIME}-(${DAYS}*86400))/3600))
MINUTES=$(((${UPTIME}-(${DAYS}*86400)-(${HOURS}*3600))/60))
SECONDS=$((${UPTIME}-(${DAYS}*86400)-(${HOURS}*3600)-(${MINUTES}*60)))
RESULT="Link uptime ${UPTIME} seconds (${DAYS}d ${HOURS}h ${MINUTES}m ${SECONDS}s)"
check_greater ${UPTIME} 1 0 "${RESULT}"
;;
upstream)
UPSTREAM=$(find_xml_value "${STATUS}" NewLayer1UpstreamMaxBitRate)
require_number "${UPSTREAM}" "Could not parse upstream"
MBIT=$((${UPSTREAM}/1000000))
RESULT="Upstream ${UPSTREAM} bits/s (${MBIT} Mbit/s)"
check_greater ${UPSTREAM} ${WARN} ${CRIT} "${RESULT}"
;;
downstream)
DOWNSTREAM=$(find_xml_value "${STATUS}" NewLayer1DownstreamMaxBitRate)
require_number "${DOWNSTREAM}" "Could not parse downstream"
MBIT=$((${DOWNSTREAM}/1000000))
RESULT="Downstream ${DOWNSTREAM} bits/s (${MBIT} Mbit/s)"
check_greater ${DOWNSTREAM} ${WARN} ${CRIT} "${RESULT}"
;;
connection)
STATE=$(find_xml_value "${STATUS}" NewConnectionStatus)
case ${STATE} in
Connected)
echo "OK - Connected"
exit ${RC_OK}
;;
Connecting | Disconnected)
echo "WARNING - Connection lost"
exit ${RC_WARN}
;;
*)
echo "ERROR - Unknown connection state ${STATE}"
exit ${RC_UNKNOWN}
;;
esac
;;
externalip)
EXTERNALIP=$(find_xml_value "${STATUS}" NewExternalIPAddress)
require_ip_address "${EXTERNALIP}" "Could not parse external ip address"
if [ ${IPCHECK} == "0" ]; then
echo "OK - ${EXTERNALIP} (but no check IP is set (-i))"
exit ${RC_OK}
elif [ "${EXTERNALIP}" == "${IPCHECK}" ]; then
echo "OK - ${EXTERNALIP} (external IP matches requirement)"
exit ${RC_OK}
else
echo "CRITICAL - ${EXTERNALIP} (external IP doesn't match requirement ${IPCHECK})"
exit ${RC_CRIT}
fi
;;
*)
echo "ERROR - Unknown service check ${CHECK}"
exit ${RC_UNKNOWN}
esac
@tofi86
Copy link
Author

tofi86 commented Aug 24, 2022

I don’t know, I don‘t use this script anymore…

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