6
\$\begingroup\$

I needed a test to know which firewall in out HA environment was currently active. We have a webFilter connected to our "primary" so if the firewall fails over the webfilter is taking out of path and internet access is completely open during that time.

I have a bash script that will feed two IP addresses. I am aware there is no data validation. This was done to reduce processing time. Run the trace using the first IP address and see if we can grep the second from the result. If the result is a non-zero string then return and OK result else return a Critical result. The exit codes are used by the Nagios Monitoring system to determine state and actions which is why there are custom error codes.

#!/usr/bin/env bash

# Nagios exit codes. These are used to determine state
nagiosStateOK=0
nagiosStateWarning=1
nagiosStateCritical=2
nagiosStateUnknown=3

# Initialize result
traceResult=''

# The address that we are going to run the tracert to
target="$1"
# Check for this address in the trace
locate="$2"

traceResult=$(traceroute -n -w 2 $target | grep $locate)

if [[ -n "$traceResult" ]];then
        echo "$locate found in path. Still running on primary"
        exit $nagiosStateOK
else
        echo "$locate not found in path. Probably failed over"
        exit $nagiosStateCritical
fi
\$\endgroup\$
  • \$\begingroup\$ Why do you introduce nagiosStateUnknown=3 if it's never used in the script? \$\endgroup\$ – πάντα ῥεῖ Jan 6 '17 at 12:52
  • \$\begingroup\$ Its a shared block used in other "nagios" scripts. If I needed to change the states of the outcome then I would be ready without having to remember or go somewhere else. \$\endgroup\$ – Matt Jan 6 '17 at 12:53
  • \$\begingroup\$ If it's commonly used from a set of scripts you could use the source directive instead of copy pasting. See stackoverflow.com/questions/10823635/… \$\endgroup\$ – πάντα ῥεῖ Jan 6 '17 at 13:01
4
\$\begingroup\$

Your use of $locate as a regular expression for grep is sloppy. If $locate is 2.3.45.25, for example, a hop through 70.233.45.251 would be considered successful.

I suggest using grep -F " $locate " — with -F to interpret the argument as a fixed string rather than as a regex, and with spaces before and after the IP address.

\$\endgroup\$
3
\$\begingroup\$

As from your comment:

Its a shared block used in other "nagios" scripts.

# Nagios exit codes. These are used to determine state
nagiosStateOK=0
nagiosStateWarning=1
nagiosStateCritical=2
nagiosStateUnknown=3

You should put shared code with other scripts rather into an included source file like

 source nagios_shared_stuff.inc

or

 . nagios_shared_stuff.inc

instead of copying that every time.

\$\endgroup\$
  • \$\begingroup\$ Good to know. I always want to keep my "check" scripts as simple as possible for performance but an include probably wont break the bank. I will have to look into what actually happens during a source to be sure. Something else to learn. Thanks. \$\endgroup\$ – Matt Jan 6 '17 at 13:10
3
\$\begingroup\$

You need to quote your variables:

traceResult=$(traceroute -n -w 2 "$target" | grep "$locate")

ref: Security implications of forgetting to quote a variable in bash/POSIX shells

\$\endgroup\$
3
\$\begingroup\$

Instead of storing the output of the traceroute | grep pipeline in a variable and checking that it's not empty, it would be better to work with the exit code of the pipeline directly:

if traceroute -n -w 2 "$target" | grep -q "$locate"; then
    echo "$locate found in path. Still running on primary"
    exit $nagiosStateOK
else
    echo "$locate not found in path. Probably failed over"
    exit $nagiosStateCritical
fi

I added the -q flag to suppress the output of grep, to use only the exit code.

\$\endgroup\$
  • \$\begingroup\$ That certainly looks better \$\endgroup\$ – Matt Jan 17 '17 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.