Présentation
Toujours pour l’association grifon, j’ai eu besoin d’écrire un script afin de pouvoir remonter l’état de nos session BGP dans notre monitoring, c’est à dire un icinga2. Comme icinga est un fork de nagios, ça devrait marcher avec tous les outils de monitoring compatibles avec nagios.
Installation
La procédure d’installation a été réalisée sous FreeBSD, mais le script fonctionne aussi sous Linux, il suffit d’adapter les chemins
Récupération du script
     Pour commencer, copiez le script si dessous dans le dossier contenant tous
     les plugins nagios sous le nom check_bgp. Vous devez donc
     obtenir un truc du genre /usr/local/libexec/nagios/check_bgp
     ou /usr/lib/nagios/plugins/check_bgp en fonction de votre OS.
    
     Ensuite, rendez-le exécutable avec un petit chmod +x.
    
Configuration de sudo
     Les plugins nagios tournent avec les droits de l’utilisateur
     nagios mais les droits sur le socket de bird sont très souvent
     limités à root. Il faut donc soit modifier les droits, soit utiliser sudo
     sans mot de passe. Voici une ligne de configuration sudo pour permettre à
     nagios d’exécuter birdc et birdc6 : nagios ALL=(ALL) NOPASSWD:
     /usr/local/sbin/birdc, /usr/local/sbin/birdc6.
    
Configuration de nrpe
     Si nrpe n’est pas installé, installez-le avec pkg install
     nrpe-ssl. La configuration se fait dans
     /usr/local/etc/nrpe.cfg.
     Il faut ajouter l’IP de la machine de monitoring dans
     allowed_hosts. Il est possible d’en mettre plusieurs séparée
     par des virgules. Par exemple : allowed_hosts=127.0.0.1,
     2001:67c:1740:9032::229, 193.200.42.229.
     Il faut ensuite ajouter les sessions que nous allons monitorées. Il faut
     obligatoirement utiliser -4 ou -6 pour préciser
     si on monitore une session IPv4 ou IPv6 ainsi que -p
     $protocol. L’option -s permet d’utiliser sudo pour
     avoir accès au socket de bird, elle n’est pas obligatoire. Par exemple,
     pour les sessions entre mon serveur et les routeurs de grifon s’appelle
     « bgp_alarig » aussi bien en IPv4 qu’en IPv6, je vais donc utiliser ces
     arguments :
command[check_bgp_ipv4_alarig]=/usr/local/libexec/nagios/check_bgp -4 -s -p bgp_alarig
command[check_bgp_ipv6_alarig]=/usr/local/libexec/nagios/check_bgp -6 -s -p bgp_alarig
Configuration de icinga2
     Enfin, on va dire à icinga d’aller utiliser les commandes que l’on vient de
     créer :
object Service "nrpe-bgp-ipv4-alarig" {
  import "generic-service"
  host_name = "budic.grifon.fr"
  check_command = "nrpe"
  vars.nrpe_command = "check_bgp_ipv4_alarig"
  vars.sla = "24x7"
}
object Service "nrpe-bgp-ipv6-alarig" {
  import "generic-service"
  host_name = "budic.grifon.fr"
  check_command = "nrpe"
  vars.nrpe_command = "check_bgp_ipv6_alarig"
  vars.sla = "24x7"
}
On recharge les confs, et normalement on a un beau check qui vient de s’ajouter.
Code
Et voici le script à utiliser :
#!/bin/sh
# Copyright 2017 alarig <alarig@grifon.fr>
#
# 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
usage() {
        printf "Usage:\n"
        printf "check_bgp [-4|-6] -p session\n"
        printf "Must be run with user account able to use birdc/birdc6 or use"
        printf "-s to use birdc with sudo.\n"
}
args=$(getopt 46hsp: $*)
if [ $? -ne 0 ]; then
        usage
        exit 3
fi
set -- $args
while :; do
        case "$1" in
                -h)
                        usage
                        exit 0
                        shift
                        ;;
                -4)
                        VERSION="IPv4"
                        shift
                        ;;
                -6)
                        VERSION="IPv6"
                        shift
                        ;;
                -s)
                        SUDO='sudo'
                        shift
                        ;;
                -p)
                        SESSION="$2"
                        shift; shift
                        ;;
                --)
                        shift; break
                        ;;
        esac
done
# path expansion for birdc and sudo of FreeBSD
PATH="$PATH:/usr/local/sbin/:/usr/local/bin/"
if [ "${VERSION}" = "IPv4" ]; then
        birdc="${SUDO} birdc -r"
elif [ "${VERSION}" = "IPv6" ]; then
        birdc="${SUDO} birdc6 -r"
else
        printf "CRITICAL: Invalid IP version, use -4 for IPv4 and -6 for IPv6\n"
        exit 2
fi
if [ -z ${SESSION} ]; then
        printf "CRITICAL: No session name supplied, use -p \$session.\n"
        exit 2
fi
STATE="$($birdc show protocol ${SESSION} | awk -v session=${SESSION} '$0 ~ session { print $6 }')"
# Session states: https://gitlab.labs.nic.cz/labs/bird/blob/master/proto/bgp/bgp.c#L1465
# Plugin return codes: https://nagios-plugins.org/doc/guidelines.html#AEN78
case ${STATE} in
        Established)
                printf "OK: ${SESSION} is ${STATE}\n"
                exit 0
                ;;
        OpenSent | OpenConfirm)
                printf "WARNING: ${SESSION} is in ${STATE} state\n"
                exit 1
                ;;
        Idle | Connect | Active)
                printf "CRITICAL: ${SESSION} is in ${STATE} state\n"
                exit 2
                ;;
        *)
                printf "Unknown state: ${STATE}\n"
                exit 3
                ;;
esac