diff --git a/check_bird2_oneshot b/check_bird2_oneshot new file mode 100755 index 0000000..5489e96 --- /dev/null +++ b/check_bird2_oneshot @@ -0,0 +1,179 @@ +#!/bin/sh + +# Copyright 2019 alarig +# +# BSD-3-Clause licence +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# For debuggin purpose, uncomment the next line and `tail -F` the file. +#exec 2> /tmp/check_bgp.log + +# This scipt works with bird2 only + +CONF_IGNORE_FILE="/usr/local/etc/nrpe-bird/ignore.cfg" + +usage() { + printf "Usage:\n" + printf "Must be run with user account able to use birdc/birdc6 or " + printf "specify -s to use birdc with sudo.\n" + printf "To ignore sessions, put one per line in ${CONF_IGNORE_FILE}.\n" +} + +args=$(getopt hs $*) + +if [ $? -ne 0 ]; then + usage + exit 3 +fi +set -- $args + +while :; do + case "$1" in + -h) + usage + exit 0 + shift;; + -s) + SUDO='sudo' + shift;; + --) + shift; + break;; + esac +done + +test_route_limit() { + if [ "${ROUTE_HIT_IN}" != "" ]; then + printf "${protocol} has hit import route " >> \ + ${DIR}/CRITICAL.txt + printf "limit\n" >> ${DIR}/CRITICAL.txt + elif [ "${ROUTE_HIT_OUT}" != "" ]; then + printf "${protocol} has hit export route " >> \ + ${DIR}/CRITICAL.txt + printf "limit\n" >> ${DIR}/CRITICAL.txt + elif [ ${RATIO_IN} -gt 92 ]; then + printf "${protocol} import route limit is " >> \ + ${DIR}/WARNING.txt + printf "over threshold\n" >> ${DIR}/WARNING.txt + fi +} + +# path expansion for birdc and sudo of FreeBSD +PATH="$PATH:/usr/local/sbin/:/usr/local/bin/" + +DIR="$(mktemp -d '/tmp/nrpe-bird.XXXX')" + +#$birdc 'show protocols' | awk '$2 ~ "BGP" && $4 !~ "down" { print $0 }' > \ +# ${DIR}/bgp_protocols_up.txt + +# The sed removes the first two lines (BIRD 2.0.2 ready and Name Proto blah) +birdc 'show protocols all' | sed '1,2d;$d' | \ + awk -v RS= -v DIR=$DIR '{print > (DIR "/" $1 ".txt")}' + +for protocol in $(cat ${CONF_IGNORE_FILE}); do + rm "${DIR}/${protocol}.txt" +done + +for protocol in $(find ${DIR} -type f); do + protocol_name=$(echo ${protocol} | cut -d / -f 4 | cut -d . -f 1) + STATE="$(head -n 1 ${protocol} | awk '{ print $6 }')" + ROUTE_LIMIT_IN="$(awk '/Import limit/ { print $3 }' ${protocol})" + ROUTES_IMPORTED="$(grep 'Routes:' ${protocol} | \ + sed -Ee '/imported/{ s/^.* ([0-9]+) imported.*$/\1/; p;}' -e d)" + ROUTE_HIT_IN="$(grep -E 'Receive limit:.*HIT' ${protocol})" + + if [ -z ${ROUTE_LIMIT_IN} ]; then + # There is no import limit, so no ratio either + RATIO_IN=0 + else + RATIO_IN=$(echo "(${ROUTES_IMPORTED}*100)/${ROUTE_LIMIT_IN}" \ + | bc) + fi + + ROUTE_HIT_OUT="$(grep -E 'Export limit:.*HIT' ${protocol})" + + # Plugin return codes: + # https://nagios-plugins.org/doc/guidelines.html#AEN78 + case ${STATE} in + # BGP + # Session states: + # https://gitlab.labs.nic.cz/labs/bird/blob/master/proto/bgp/bgp.h#L601 + Established) + test_route_limit + ;; + OpenSent | OpenConfirm) + printf "${protocol} is in ${STATE} state\n" >> \ + ${DIR}/WARNING.txt + ;; + Idle | Connect | Active) + printf "CRITICAL: ${protocol} is in ${STATE} state\n" \ + >> ${DIR}/CRITICAL.txt + ;; + + # OSPF + # https://gitlab.labs.nic.cz/labs/bird/blob/master/proto/ospf/ospf.c#L532 + Running) + test_route_limit + ;; + Alone) + printf "${protocol} is in ${STATE} state\n" >> \ + ${DIR}/WARNING.txt + exit 1 + ;; + + # Or what + *) + if [ -z ${STATE} ]; then + printf "Empty state for ${protocol_name}\n" \ + >> ${DIR}/UNKNOWN.txt + else + printf "Unknown state ${STATE} for " >> \ + ${DIR}/UNKNOWN.txt + printf "${protocol}\n" >> ${DIR}/UNKNOWN.txt + fi + ;; + esac +done + +if [ -f ${DIR}/CRITICAL.txt ]; then + printf "CRITICAL: $(cat ${DIR}/CRITICAL.txt)\n" + rm -r ${DIR} + exit 2 +elif [ -f ${DIR}/WARNING.txt ]; then + printf "WARNING: $(cat ${DIR}/WARNING.txt)\n" + rm -r ${DIR} + exit 1 +elif [ -f ${DIR}/UNKNOWN.txt ]; then + printf "UNKNOWN: $(cat ${DIR}/UNKNOWN.txt)\n" + rm -r ${DIR} + exit 3 +else + printf "OK: This is fine\n" + rm -r ${DIR} + exit 0 +fi