#!/bin/bash # ====================================================================== # # Check DNS response time # requirements: # - netstat # # ---------------------------------------------------------------------- # 2020-06-17 v1.0 <axel.hahn@iml.unibe.ch> # 2021-11-12 v1.1 <axel.hahn@iml.unibe.ch> check fqd instead of fixed value # test tcp 53 first # check result depends on 1st nameserver only # 2022-10-24 v1.2 <axel.hahn@unibe.ch> shell fixes; remove pipe char in output # 2023-07-27 v1.3 <axel.hahn@unibe.ch> shell fixes; add help page # 2023-10-13 v1.4 <axel.hahn@unibe.ch> fix syntax error in export # 2025-02-10 v1.5 <axel.hahn@unibe.ch> harden sourcing files # ====================================================================== # shellcheck source=/dev/null . "$( dirname "$0" )/inc_pluginfunctions" || exit 1 export self_APPVERSION=1.5 tmpfile=/tmp/check_netstat_out_$$ infofile=/tmp/check_netstat_out_2_$$ myHost=$( hostname -f ) # set default / override from command line params typeset -i iWarnLimit; iWarnLimit=$( ph.getValueWithParam 300 w "$@") typeset -i iCriticalLimit; iCriticalLimit=$( ph.getValueWithParam 1000 c "$@") rm -f $tmpfile $infofile 2>/dev/null typeset -i iMax=0 typeset -i iTime=0 typeset -i iCounter=0 typeset -i iNotReachable=0 # show help function showHelp(){ local _self; _self="$( basename "$0" )" cat <<EOF $( ph.showImlHelpHeader ) Loop over all defined dns servers (in /etc/resolv.conf) and check each: - detect of port 53 is available (DNS service) - 5x check time of a nslookup for current host (${myHost}) The a warning / critical response will be reached if the maximum time of nslookup on the first dns server reaches a limit. The critical response will be returned if the first of the nameservers is not available. An unknown response will be returned if the current hostname (hostname -f) is no FQDN. SYNTAX: $_self [ -w VALUE -c VALUE -h ] OPTIONS: -w VALUE warning level (default: 300) -c VALUE critical level (default: 1000) -h or --help Show this help. EOF } # ---------------------------------------------------------------------- # MAIN # ---------------------------------------------------------------------- # --- check param -h case "$1" in "--help"|"-h") showHelp exit 0 ;; *) esac if ! echo $myHost | cut -f 3- -d "." | grep "\." >/dev/null; then ph.setStatus unknown ph.status "DNS check for [$myHost] - SKIP: hostname -f returned a FQDN with less than 2 dots" ph.exit fi ph.require nslookup for mydns in $(grep ^nameserver /etc/resolv.conf | awk '{ print $2 } ' ) do iCounter=$iCounter+1 typeset -i iSrvMax=0 echo "" >>$infofile echo "---------- $iCounter - $mydns " >>$infofile # todo loop if ! >/dev/tcp/${mydns}/53 >>$infofile 2>&1; then iNotReachable=$iNotReachable+1 test $iCounter -eq 1 && ph.setStatus critical echo "ERROR: ${mydns} is not reachable on tcp 53" >>$infofile else for i in $(seq 5) do (time nslookup ${myHost} $mydns) >$tmpfile 2>&1 iTime=$(cat $tmpfile | grep "^real.*m.*\..*s" | cut -f 2 -d "m" | sed "s#[\.s]##g" | sed "s#^0*##g" ) echo "$mydns #$i >>> $iTime ms" >>$infofile test $iTime -ge $iWarnLimit && cat $tmpfile | grep -vE "^(real|user|sys)" >> $infofile test $iTime -gt $iSrvMax && iSrvMax=$iTime done echo "max: $iSrvMax ms" >>$infofile # --- set status test $iCounter -eq 1 && ph.setStatusByLimit $iSrvMax $iWarnLimit $iCriticalLimit label=${mydns//\./-} ph.perfadd "response-$label" "${iSrvMax}" test $iSrvMax -gt $iMax && iMax=$iSrvMax fi test $iCounter -eq 1 && (echo " ^"; echo " :"; echo " +--- 1st nameserver is relevant for total status of the check. Limits are warning=$iWarnLimit and critical=$iCriticalLimit") >>$infofile echo "" >>$infofile done test $iNotReachable -eq 0 && ph.status "DNS check for $myHost - found maximum was $iMax ms - OK: all nameservers are reachable" test $iNotReachable -ne 0 && ph.status "DNS check for $myHost - found maximum was $iMax ms - INFO: $iNotReachable of $iCounter nameservers not reachable" cat $infofile rm -f $tmpfile $infofile ph.exit # ----------------------------------------------------------------------