Collection of scripts used to monitor bird sessions and route limits
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
5.3KB

  1. #!/bin/sh
  2. # Copyright 2019 alarig <alarig@grifon.fr>
  3. #
  4. # BSD-3-Clause licence
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions are met:
  8. #
  9. # 1. Redistributions of source code must retain the above copyright notice,
  10. # this list of conditions and the following disclaimer.
  11. #
  12. # 2. Redistributions in binary form must reproduce the above copyright notice,
  13. # this list of conditions and the following disclaimer in the documentation
  14. # and/or other materials provided with the distribution.
  15. #
  16. # 3. Neither the name of the copyright holder nor the names of its contributors
  17. # may be used to endorse or promote products derived from this software without
  18. # specific prior written permission.
  19. #
  20. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  24. # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25. # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26. # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. # POSSIBILITY OF SUCH DAMAGE.
  31. # For debuggin purpose, uncomment the next line and `tail -F` the file.
  32. #exec 2> /tmp/check_bgp.log
  33. # This scipt works with bird2 only
  34. CONF_IGNORE_FILE="/usr/local/etc/nrpe-bird/ignore.cfg"
  35. usage() {
  36. printf "Usage:\n"
  37. printf "Must be run with user account able to use birdc/birdc6 or "
  38. printf "specify -s to use birdc with sudo.\n"
  39. printf "To ignore sessions, put one per line in ${CONF_IGNORE_FILE}.\n"
  40. }
  41. args=$(getopt hs $*)
  42. if [ $? -ne 0 ]; then
  43. usage
  44. exit 3
  45. fi
  46. set -- $args
  47. while :; do
  48. case "$1" in
  49. -h)
  50. usage
  51. exit 0
  52. shift;;
  53. -s)
  54. SUDO='sudo'
  55. shift;;
  56. --)
  57. shift;
  58. break;;
  59. esac
  60. done
  61. birdc="${SUDO} birdc"
  62. test_route_limit() {
  63. if [ "${ROUTE_HIT_IN}" != "" ]; then
  64. printf "${protocol_name} has hit import route " >> \
  65. ${DIR}/CRITICAL.txt
  66. printf "limit\n" >> ${DIR}/CRITICAL.txt
  67. elif [ "${ROUTE_HIT_OUT}" != "" ]; then
  68. printf "${protocol_name} has hit export route " >> \
  69. ${DIR}/CRITICAL.txt
  70. printf "limit\n" >> ${DIR}/CRITICAL.txt
  71. elif [ ${RATIO_IN} -gt 92 ]; then
  72. printf "${protocol_name} import route limit is " >> \
  73. ${DIR}/WARNING.txt
  74. printf "over threshold\n" >> ${DIR}/WARNING.txt
  75. fi
  76. }
  77. # path expansion for birdc and sudo of FreeBSD
  78. PATH="$PATH:/usr/local/sbin/:/usr/local/bin/"
  79. DIR="$(mktemp -d '/tmp/nrpe-bird.XXXX')"
  80. #$birdc 'show protocols' | awk '$2 ~ "BGP" && $4 !~ "down" { print $0 }' > \
  81. # ${DIR}/bgp_protocols_up.txt
  82. # The sed removes the first two lines (BIRD 2.0.2 ready and Name Proto blah)
  83. $birdc 'show protocols all' 2>${DIR}/bird-err | sed '1,2d;$d' | \
  84. awk -v RS= -v DIR=$DIR '{print > (DIR "/" $1 ".txt")}'
  85. if [ "$(cat ${DIR}/bird-err)" != '' ]; then
  86. printf "ERROR: $(cat ${DIR}/bird-err)\n"
  87. rm -r ${DIR}
  88. exit 2
  89. else
  90. rm ${DIR}/bird-err
  91. fi
  92. for protocol in $(cat ${CONF_IGNORE_FILE}); do
  93. rm "${DIR}/${protocol}.txt"
  94. done
  95. for protocol in $(find ${DIR} -type f); do
  96. protocol_name=$(echo ${protocol} | cut -d / -f 4 | cut -d . -f 1)
  97. STATE="$(head -n 1 ${protocol} | awk '{ print $6 }')"
  98. ROUTE_LIMIT_IN="$(awk '/Import limit/ { print $3 }' ${protocol})"
  99. ROUTES_IMPORTED="$(grep 'Routes:' ${protocol} | \
  100. sed -Ee '/imported/{ s/^.* ([0-9]+) imported.*$/\1/; p;}' -e d)"
  101. ROUTE_HIT_IN="$(grep -E 'Receive limit:.*HIT' ${protocol})"
  102. if [ -z ${ROUTE_LIMIT_IN} ]; then
  103. # There is no import limit, so no ratio either
  104. RATIO_IN=0
  105. else
  106. RATIO_IN=$(echo "(${ROUTES_IMPORTED}*100)/${ROUTE_LIMIT_IN}" \
  107. | bc)
  108. fi
  109. ROUTE_HIT_OUT="$(grep -E 'Export limit:.*HIT' ${protocol})"
  110. # Plugin return codes:
  111. # https://nagios-plugins.org/doc/guidelines.html#AEN78
  112. case ${STATE} in
  113. # BGP
  114. # Session states:
  115. # https://gitlab.labs.nic.cz/labs/bird/blob/master/proto/bgp/bgp.h#L601
  116. Established | Passive)
  117. test_route_limit
  118. ;;
  119. OpenSent | OpenConfirm)
  120. printf "${protocol_name} is in ${STATE} state\n" >> \
  121. ${DIR}/WARNING.txt
  122. ;;
  123. Idle | Connect | Active)
  124. printf "${protocol_name} is in ${STATE} state\n" \
  125. >> ${DIR}/CRITICAL.txt
  126. ;;
  127. # OSPF
  128. # https://gitlab.labs.nic.cz/labs/bird/blob/master/proto/ospf/ospf.c#L532
  129. Running)
  130. test_route_limit
  131. ;;
  132. Alone)
  133. printf "${protocol_name} is in ${STATE} state\n" >> \
  134. ${DIR}/WARNING.txt
  135. ;;
  136. # Or what
  137. *)
  138. if [ -z ${STATE} ]; then
  139. printf "Empty state for ${protocol_name}\n" \
  140. >> ${DIR}/UNKNOWN.txt
  141. else
  142. printf "Unknown state ${STATE} for " >> \
  143. ${DIR}/UNKNOWN.txt
  144. printf "${protocol_name}\n" >> ${DIR}/UNKNOWN.txt
  145. fi
  146. ;;
  147. esac
  148. done
  149. if [ -f ${DIR}/CRITICAL.txt ]; then
  150. printf "CRITICAL: $(cat ${DIR}/CRITICAL.txt)\n"
  151. rm -r ${DIR}
  152. exit 2
  153. elif [ -f ${DIR}/WARNING.txt ]; then
  154. printf "WARNING: $(cat ${DIR}/WARNING.txt)\n"
  155. rm -r ${DIR}
  156. exit 1
  157. elif [ -f ${DIR}/UNKNOWN.txt ]; then
  158. printf "UNKNOWN: $(cat ${DIR}/UNKNOWN.txt)\n"
  159. rm -r ${DIR}
  160. exit 3
  161. else
  162. printf "OK: This is fine\n"
  163. rm -r ${DIR}
  164. exit 0
  165. fi