#!/bin/bash # shellcheck disable=SC2207,SC2009,SC2076 usage() { cat << EOL Usage : $0 --master X,Y --backup Z -m|--master ID_MASTER # VRRP ID that should be master, separated by a comma "," -b|--backup ID_BACKUP # VRRP ID that should be backup, separated by a comma "," [--vrrpd] # Check for vrrpd daemon (default) [--uvrrpd] # Check for uvrrpd daemon EOL } unset ID_master unset ID_backup vrrpd_option="unset" uvrrpd_option="unset" unset critical_output critical_state="unset" unset warning_output warning_state="unset" unset ok_output ok_state="unset" exit_code=0 used_daemon="vrrpd" IFS=" " # If no argument then show usage if [ "$#" -eq 0 ]; then usage exit 2 fi while :; do case $1 in -h|-\?|--help) # Call a "usage" function to display a synopsis, then exit. usage exit ;; -m|--master) # Takes an option argument, ensuring it has been specified. if [ -n "$2" ]; then ID_master=($(echo "$2" | tr "," "\n")) # Make an array with values separated by "," shift else printf 'ERROR: "--master" requires a non-empty option argument.\n' >&2 exit 2 fi ;; -b|--backup) # Takes an option argument, ensuring it has been specified. if [ -n "$2" ]; then ID_backup=($(echo "$2" | tr "," "\n")) # Make an array with values separated by "," shift else printf 'ERROR: "--backup" requires a non-empty option argument.\n' >&2 exit 2 fi ;; --vrrpd) used_daemon="vrrpd" vrrpd_option="set" ;; --uvrrpd) used_daemon="uvrrpd" uvrrpd_option="set" ;; -?*) printf 'WARNING: Unknown option (ignored): %s\n' "$1" >&2 ;; *) # Default case: If no more options then break out of the loop. break esac shift done # Make sure that each given ID is given once only all_ID=("${ID_master[@]}" "${ID_backup[@]}") uniqueNum=$(printf '%s\n' "${all_ID[@]}"|awk '!($0 in seen){seen[$0];c++} END {print c}') if [ "$uniqueNum" != ${#all_ID[@]} ]; then echo "ERROR : At least one VRRP ID is given multiple times" exit 2 fi # Make sure --vrrpd and --uvrrpd are not both set if [ $vrrpd_option = "set" ] && [ $uvrrpd_option = "set" ]; then echo "ERROR : You cannot set both parameters --vrrpd and --uvrrpd" exit 2 fi # Make sure no sysclt parameter "rp_filter" is set to 1 if grep -q 1 /proc/sys/net/ipv4/conf/*/rp_filter; then critical_output="${critical_output}CRITICAL - rp_filter is set to 1 at least for one interface\n" critical_state="set" fi vrrpd_processes_number=$((${#ID_master[@]}+${#ID_backup[@]})) # Number of vrrpd processes that should be running = length of arrays ID_master + ID_backup regex_ipv4="((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])" regex_ipv6="(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" vrrpd_processes=$(ps auwx | grep "$used_daemon" | grep -v -e grep -e check) ID_running_vrrpd=($(for i in ${vrrpd_processes}; do echo "$i" | grep -Eo -- "-v [0-9]+" | awk '{print $2}'; done)) # Check the number of running vrrpd processes in comparison to the number of ID given if ! sudo /usr/lib/nagios/plugins/check_procs -C "$used_daemon" -c $vrrpd_processes_number:$vrrpd_processes_number >/dev/null; then critical_output="${critical_output}CRITICAL : $vrrpd_processes_number VRRP ID are given but $(ps auwx | grep "$used_daemon" | grep -v -e grep -e check -c) $used_daemon processes are running\n" if pgrep uvrrp >/dev/null && [ $uvrrpd_option = "unset" ]; then critical_output="${critical_output}It seems that uvrrpd is running. Use parameter --uvrrpd\n" fi critical_state="set" fi IFS=" " # For each ID_master, make sure a process exist if [ ${#ID_master[@]} -ne 0 ]; then for i in "${ID_master[@]}"; do # If array contains the current ID, then a process exist, and we have to make sure the corresponding interface exists if [[ " ${ID_running_vrrpd[*]} " =~ " $i " ]]; then vrrpd_current_proccess=$(echo "$vrrpd_processes" | grep -E -- "-v $i ") INT_current_vrrpd=$(echo "$vrrpd_current_proccess" | grep -Eo -- "-i \S+" | awk '{print $2}') IP_current_vrrpd=$(echo "$vrrpd_current_proccess" | grep -Eo "${regex_ipv4}|${regex_ipv6}") if [ "$used_daemon" = "vrrpd" ]; then int_name="vrrp_${i}_${INT_current_vrrpd}" elif [ "$used_daemon" = "uvrrpd" ]; then int_name="${INT_current_vrrpd}_${i}" fi if /sbin/ifconfig "$int_name" 2> /dev/null | grep -q "$IP_current_vrrpd"; then ok_output="${ok_output}OK - ID $i has a process and $IP_current_vrrpd is master\n" ok_state="set" else warning_output="${warning_output}WARNING - The IP $IP_current_vrrpd for ID $i is backup while it should be master\n" warning_state="set" fi else critical_output="${critical_output}CRITICAL - No process is running for VRRP ID $i\n" critical_state="set" fi done fi # For each ID_backup, make sure a process exist if [ ${#ID_backup[@]} -ne 0 ]; then for i in "${ID_backup[@]}"; do # If array contains the current ID, then a process exist, and we have to make sure the corresponding interface does not exist if [[ " ${ID_running_vrrpd[*]} " =~ " $i " ]]; then vrrpd_current_proccess=$(echo "$vrrpd_processes" | grep -E -- "-v $i ") INT_current_vrrpd=$(echo "$vrrpd_current_proccess" | grep -Eo -- "-i \S+" | awk '{print $2}') IP_current_vrrpd=$(echo "$vrrpd_current_proccess" | grep -Eo "${regex_ipv4}|${regex_ipv6}") if [ "$used_daemon" = "vrrpd" ]; then int_name="vrrp_${i}_${INT_current_vrrpd}" elif [ "$used_daemon" = "uvrrpd" ]; then int_name="${INT_current_vrrpd}_${i}" fi if ! /sbin/ifconfig "$int_name" 2> /dev/null | grep -q "$IP_current_vrrpd"; then ok_output="${ok_output}OK - ID $i has a process and $IP_current_vrrpd is backup\n" ok_state="set" else warning_output="${warning_output}WARNING - The IP $IP_current_vrrpd for ID $i is master while it should be backup\n" warning_state="set" fi else critical_output="${critical_output}CRITICAL - No process is running for VRRP ID $i\n" critical_state="set" fi done fi # Make $exit_code the highest set if [ "$critical_state" = "set" ]; then exit_code=2 elif [ "$warning_state" = "set" ]; then exit_code=1 elif [ "$ok_state" = "set" ]; then exit_code=0 fi # Echo most critical output first, least last if [ -n "$critical_output" ]; then echo -e "$critical_output" | grep -v "^$" fi if [ -n "$warning_output" ]; then echo -e "$warning_output" | grep -v "^$" fi if [ -n "$ok_output" ]; then echo -e "$ok_output" | grep -v "^$" fi exit $exit_code