#!/bin/bash # Variables MINNS=1 declare -a AUTHNS # Functions # Name: usage # Description: shows how the script should be used and exists usage() { echo "Usage: $0 -z (-h )" exit 2 } # Name: getns # Description: add hidden nameserver to an array if declared; # then retrives authoritative nameservers for the zone to add them to the same array getns() { [[ -n "$HIDDENNS" ]] && AUTHNS+=("$HIDDENNS") for PUBNS in $(/usr/bin/retry -t 5 -d 1,2,3 -- /usr/bin/dig -4 "$ZONE" NS +short +tcp +tries=1 +timeout=1); do AUTHNS+=("$PUBNS") done } # Name: getsoa # Description: retrieve zone serial from all discovered authoritative nameservers getsoa() { local i=0 for NS in "${AUTHNS[@]}"; do SOA[i]=$(/usr/bin/retry -t 5 -d 1,2,3 -- /usr/bin/dig -4 @"$NS" "$ZONE" SOA +short +tcp +tries=1 +timeout=1 | /usr/bin/awk '{print $3}') i=$(( i + 1 )) done } # Name: soaoutput # Description: generates script output soaoutput() { local i=0 for OUTPUT in "${AUTHNS[@]}"; do echo "$OUTPUT: ${SOA[i]}" i=$(( i + 1 )) done } # Main while getopts ":z:h:" o; do case "${o}" in z) ZONE="${OPTARG}" ;; h) HIDDENNS="${OPTARG}" ;; :) echo "ERROR: Option -${OPTARG} requires an argument" usage ;; *) echo "ERROR: Invalid option -${OPTARG}" usage ;; esac done # -z is required [[ -z "$ZONE" ]] && usage # If the user declares a hidden, we expect at least 2 nameservers [[ -n "$HIDDENNS" ]] && MINNS=2 getns # Error out if we failed to retrive nameservers for the zone if [[ ${#AUTHNS[@]} -lt $MINNS ]]; then echo "CRITICAL: Could not retrive authoritative NS for zone $ZONE" exit 2 fi getsoa for ALLSOA in "${SOA[@]}"; do # Error out if we failed to retrive one or more serials for the zone if ! [[ $ALLSOA =~ [[:digit:]]+ ]]; then echo "CRITICAL: Could not fetch SOA on at least one DNS server for zone $ZONE" exit 2 fi # Compare all serials to the first one we retrived if [[ $ALLSOA != "${SOA[0]}" ]]; then INCONSISTENTSERIAL="true" fi done if [[ -n $INCONSISTENTSERIAL ]]; then echo "WARNING: Serials are inconsistent for zone $ZONE" soaoutput exit 1 else echo "OK: Serials are consistent for zone $ZONE" soaoutput exit 0 fi