Created
June 14, 2018 03:20
-
-
Save kohenkatz/7d896c3d120f9a0c67a8aad64a5de172 to your computer and use it in GitHub Desktop.
A nagios `check_dns` alternative that uses dig instead of nslookup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"fmt" | |
"os" | |
"os/exec" | |
"sort" | |
"strconv" | |
"strings" | |
"github.com/simonleung8/flags" | |
) | |
func main() { | |
fc := flags.New() | |
fc.NewBoolFlag("help", "h", "Print detailed help screen") | |
fc.NewStringFlag("hostname", "H", "The name or address you want to query") | |
fc.NewStringFlag("server", "s", "Optional DNS server you want to use for the lookup") | |
fc.NewStringFlag("querytype", "q", "Optional DNS record query type where TYPE =(A, AAAA, SRV, TXT, MX, ANY)\nThe default query type is 'A' (IPv4 host entry)") | |
fc.NewStringFlag("expected-address", "a", "Optional IP-ADDRESS you expect the DNS server to return. HOST must end with a dot (.). This option can be repeated multiple times (Returns OK if any value match). If multiple addresses are returned at once, you have to match the whole string of addresses separated with commas (sorted alphabetically).\nIf you would like to test for the presence of a cname, combine with -n param.") | |
fc.NewBoolFlag("expect-authority", "A", "Optionally expect the DNS server to be authoritative for the lookup") | |
fc.NewBoolFlag("accept-cname", "n", "Optionally accept cname responses as a valid result to a query\nThe default is to ignore cname responses as part of the result") | |
fc.NewIntFlag("warning", "w", "Return warning if elapsed time exceeds value. Default off") | |
fc.NewIntFlag("critical", "c", "Return critical if elapsed time exceeds value. Default off") | |
fc.NewStringFlag("timeout", "t", "Seconds before connection times out (default: 10)\nOptional \":<timeout state>\" can be a state integer (0,1,2,3) or a state STRING") | |
err := fc.Parse(os.Args...) | |
if err != nil { | |
fmt.Println("UNKNOWN - Parsing error:", err) | |
os.Exit(3) | |
} | |
if fc.IsSet("help") { | |
fmt.Println(fc.ShowUsage(10)) | |
os.Exit(0) | |
} | |
path, err := exec.LookPath("dig") | |
if err != nil { | |
fmt.Println("UNKNOWN - Could not find 'dig' command on PATH") | |
os.Exit(3) | |
} | |
if ! fc.IsSet("hostname") { | |
fmt.Println("CRITICAL - Missing required -H HOST argument") | |
os.Exit(2) | |
} | |
hostname := fc.String("hostname") | |
q := "A" | |
if fc.IsSet("querytype") { | |
q = fc.String("querytype") | |
} | |
args := []string{"+short", hostname, "-t", q} | |
if fc.IsSet("timeout") { | |
args = append(args, "+time=" + strconv.Itoa(fc.Int("timeout"))) | |
} | |
if fc.IsSet("server") { | |
args = append(args, "@" + fc.String("server")) | |
} | |
cmd := exec.Command(path, args...) | |
var out bytes.Buffer | |
cmd.Stdout = &out | |
err = cmd.Run() | |
if err != nil { | |
fmt.Println("UNKNOWN - Error running dig") | |
fmt.Println(err) | |
os.Exit(3) | |
} | |
results := strings.Split(out.String(), "\n") | |
// If there is a blank last element, remove it | |
if len(results) > 1 && len(results[len(results)-1]) == 0 { | |
results = results[:len(results)-1] | |
} | |
for i := range(results) { | |
s := results[i] | |
sz := len(s) | |
if sz > 0 && s[sz-1] == '.' { | |
results[i] = s[:sz-1] | |
} | |
} | |
sort.Strings(results) | |
if fc.IsSet("expected-address") { | |
expected := strings.Split(fc.String("expected-address"), ",") | |
if ! Equal(results, expected) { | |
fmt.Printf("CRITICAL - DNS lookup result different from expected\n") | |
fmt.Printf("Expected:\t%s\n", fc.String("expected-address")) | |
fmt.Printf("Got:\t%s\n", strings.Join(results, ",")) | |
os.Exit(2) | |
} | |
fmt.Println("OK") | |
} | |
fmt.Printf("%v\n", results) | |
} | |
func Equal(a, b []string) bool { | |
if len(a) != len(b) { | |
return false | |
} | |
for i, v := range a { | |
if v != b[i] { | |
return false | |
} | |
} | |
return true | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See https://github.com/ymkatz/nagios_check_dns_cloudflare for a greatly expanded use of this code