diff options
author | Jonny007-MKD <nospam@jonny007-mkd.de> | 2020-02-23 15:02:43 +0100 |
---|---|---|
committer | Sven Nierlein <sven@nierlein.org> | 2021-09-02 09:56:39 +0200 |
commit | 70f55ca9db87f639856e0548a57081c886e09d14 (patch) | |
tree | 30447f835c82feab6f281c07c1db4705aeb51ab9 | |
parent | 9fa291d9918722ce3e3a43ad61da572e271f4f83 (diff) | |
download | monitoring-plugins-70f55ca9db87f639856e0548a57081c886e09d14.tar.gz |
check_dns: add --expect-nxdomain
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | plugins/check_dns.c | 61 | ||||
-rw-r--r-- | plugins/t/check_dns.t | 12 |
3 files changed, 56 insertions, 18 deletions
@@ -13,6 +13,7 @@ This file documents the major additions and syntax changes between releases. | |||
13 | check_dns: Accept CIDR | 13 | check_dns: Accept CIDR |
14 | check_dns: allow unsorted addresses | 14 | check_dns: allow unsorted addresses |
15 | check_dns: allow forcing complete match of all addresses | 15 | check_dns: allow forcing complete match of all addresses |
16 | check_dns: option to expect NXDOMAIN | ||
16 | check_apt: add --only-critical switch | 17 | check_apt: add --only-critical switch |
17 | check_apt: add -l/--list option to print packages | 18 | check_apt: add -l/--list option to print packages |
18 | check_file_age: add range checking | 19 | check_file_age: add range checking |
diff --git a/plugins/check_dns.c b/plugins/check_dns.c index 0f2e6541..0c10f09b 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c | |||
@@ -41,7 +41,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
41 | 41 | ||
42 | int process_arguments (int, char **); | 42 | int process_arguments (int, char **); |
43 | int validate_arguments (void); | 43 | int validate_arguments (void); |
44 | int error_scan (char *); | 44 | int error_scan (char *, int*); |
45 | int ip_match_cidr(const char *, const char *); | 45 | int ip_match_cidr(const char *, const char *); |
46 | unsigned long ip2long(const char *); | 46 | unsigned long ip2long(const char *); |
47 | void print_help (void); | 47 | void print_help (void); |
@@ -54,6 +54,7 @@ char ptr_server[ADDRESS_LENGTH] = ""; | |||
54 | int verbose = FALSE; | 54 | int verbose = FALSE; |
55 | char **expected_address = NULL; | 55 | char **expected_address = NULL; |
56 | int expected_address_cnt = 0; | 56 | int expected_address_cnt = 0; |
57 | int expect_nxdomain = FALSE; | ||
57 | 58 | ||
58 | int expect_authority = FALSE; | 59 | int expect_authority = FALSE; |
59 | int all_match = FALSE; | 60 | int all_match = FALSE; |
@@ -87,6 +88,7 @@ main (int argc, char **argv) | |||
87 | int parse_address = FALSE; /* This flag scans for Address: but only after Name: */ | 88 | int parse_address = FALSE; /* This flag scans for Address: but only after Name: */ |
88 | output chld_out, chld_err; | 89 | output chld_out, chld_err; |
89 | size_t i; | 90 | size_t i; |
91 | int is_nxdomain = FALSE; | ||
90 | 92 | ||
91 | setlocale (LC_ALL, ""); | 93 | setlocale (LC_ALL, ""); |
92 | bindtextdomain (PACKAGE, LOCALEDIR); | 94 | bindtextdomain (PACKAGE, LOCALEDIR); |
@@ -186,7 +188,7 @@ main (int argc, char **argv) | |||
186 | } | 188 | } |
187 | 189 | ||
188 | 190 | ||
189 | result = error_scan (chld_out.line[i]); | 191 | result = error_scan (chld_out.line[i], &is_nxdomain); |
190 | if (result != STATE_OK) { | 192 | if (result != STATE_OK) { |
191 | msg = strchr (chld_out.line[i], ':'); | 193 | msg = strchr (chld_out.line[i], ':'); |
192 | if(msg) msg++; | 194 | if(msg) msg++; |
@@ -199,8 +201,8 @@ main (int argc, char **argv) | |||
199 | if (verbose) | 201 | if (verbose) |
200 | puts(chld_err.line[i]); | 202 | puts(chld_err.line[i]); |
201 | 203 | ||
202 | if (error_scan (chld_err.line[i]) != STATE_OK) { | 204 | if (error_scan (chld_err.line[i], &is_nxdomain) != STATE_OK) { |
203 | result = max_state (result, error_scan (chld_err.line[i])); | 205 | result = max_state (result, error_scan (chld_err.line[i], &is_nxdomain)); |
204 | msg = strchr(input_buffer, ':'); | 206 | msg = strchr(input_buffer, ':'); |
205 | if(msg) | 207 | if(msg) |
206 | msg++; | 208 | msg++; |
@@ -209,6 +211,10 @@ main (int argc, char **argv) | |||
209 | } | 211 | } |
210 | } | 212 | } |
211 | 213 | ||
214 | if (is_nxdomain && !expect_nxdomain) { | ||
215 | die (STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), query_address); | ||
216 | } | ||
217 | |||
212 | if (addresses) { | 218 | if (addresses) { |
213 | int i,slen; | 219 | int i,slen; |
214 | char *adrp; | 220 | char *adrp; |
@@ -260,6 +266,16 @@ main (int argc, char **argv) | |||
260 | } | 266 | } |
261 | } | 267 | } |
262 | 268 | ||
269 | if (expect_nxdomain) { | ||
270 | if (!is_nxdomain) { | ||
271 | result = STATE_CRITICAL; | ||
272 | xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), query_address, address); | ||
273 | } else { | ||
274 | if (address == NULL) free(address); | ||
275 | address = "NXDOMAIN"; | ||
276 | } | ||
277 | } | ||
278 | |||
263 | /* check if authoritative */ | 279 | /* check if authoritative */ |
264 | if (result == STATE_OK && expect_authority && non_authoritative) { | 280 | if (result == STATE_OK && expect_authority && non_authoritative) { |
265 | result = STATE_CRITICAL; | 281 | result = STATE_CRITICAL; |
@@ -339,9 +355,15 @@ ip2long(const char* src) { | |||
339 | } | 355 | } |
340 | 356 | ||
341 | int | 357 | int |
342 | error_scan (char *input_buffer) | 358 | error_scan (char *input_buffer, int* is_nxdomain) |
343 | { | 359 | { |
344 | 360 | ||
361 | const int nxdomain = strstr (input_buffer, "Non-existent") || | ||
362 | strstr (input_buffer, "** server can't find") || | ||
363 | strstr (input_buffer, "** Can't find") || | ||
364 | strstr (input_buffer, "NXDOMAIN"); | ||
365 | if (nxdomain) *is_nxdomain = TRUE; | ||
366 | |||
345 | /* the DNS lookup timed out */ | 367 | /* the DNS lookup timed out */ |
346 | if (strstr (input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) || | 368 | if (strstr (input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) || |
347 | strstr (input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || | 369 | strstr (input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || |
@@ -360,7 +382,7 @@ error_scan (char *input_buffer) | |||
360 | 382 | ||
361 | /* Connection was refused */ | 383 | /* Connection was refused */ |
362 | else if (strstr (input_buffer, "Connection refused") || | 384 | else if (strstr (input_buffer, "Connection refused") || |
363 | strstr (input_buffer, "Couldn't find server") || | 385 | strstr (input_buffer, "Couldn't find server") || |
364 | strstr (input_buffer, "Refused") || | 386 | strstr (input_buffer, "Refused") || |
365 | (strstr (input_buffer, "** server can't find") && | 387 | (strstr (input_buffer, "** server can't find") && |
366 | strstr (input_buffer, ": REFUSED"))) | 388 | strstr (input_buffer, ": REFUSED"))) |
@@ -374,13 +396,6 @@ error_scan (char *input_buffer) | |||
374 | else if (strstr (input_buffer, "No information")) | 396 | else if (strstr (input_buffer, "No information")) |
375 | die (STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server); | 397 | die (STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server); |
376 | 398 | ||
377 | /* Host or domain name does not exist */ | ||
378 | else if (strstr (input_buffer, "Non-existent") || | ||
379 | strstr (input_buffer, "** server can't find") || | ||
380 | strstr (input_buffer, "** Can't find") || | ||
381 | strstr (input_buffer,"NXDOMAIN")) | ||
382 | die (STATE_CRITICAL, _("Domain %s was not found by the server\n"), query_address); | ||
383 | |||
384 | /* Network is unreachable */ | 399 | /* Network is unreachable */ |
385 | else if (strstr (input_buffer, "Network is unreachable")) | 400 | else if (strstr (input_buffer, "Network is unreachable")) |
386 | die (STATE_CRITICAL, _("Network is unreachable\n")); | 401 | die (STATE_CRITICAL, _("Network is unreachable\n")); |
@@ -417,6 +432,7 @@ process_arguments (int argc, char **argv) | |||
417 | {"server", required_argument, 0, 's'}, | 432 | {"server", required_argument, 0, 's'}, |
418 | {"reverse-server", required_argument, 0, 'r'}, | 433 | {"reverse-server", required_argument, 0, 'r'}, |
419 | {"expected-address", required_argument, 0, 'a'}, | 434 | {"expected-address", required_argument, 0, 'a'}, |
435 | {"expect-nxdomain", no_argument, 0, 'n'}, | ||
420 | {"expect-authority", no_argument, 0, 'A'}, | 436 | {"expect-authority", no_argument, 0, 'A'}, |
421 | {"all", no_argument, 0, 'L'}, | 437 | {"all", no_argument, 0, 'L'}, |
422 | {"warning", required_argument, 0, 'w'}, | 438 | {"warning", required_argument, 0, 'w'}, |
@@ -432,7 +448,7 @@ process_arguments (int argc, char **argv) | |||
432 | strcpy (argv[c], "-t"); | 448 | strcpy (argv[c], "-t"); |
433 | 449 | ||
434 | while (1) { | 450 | while (1) { |
435 | c = getopt_long (argc, argv, "hVvALt:H:s:r:a:w:c:", long_opts, &opt_index); | 451 | c = getopt_long (argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index); |
436 | 452 | ||
437 | if (c == -1 || c == EOF) | 453 | if (c == -1 || c == EOF) |
438 | break; | 454 | break; |
@@ -491,6 +507,9 @@ process_arguments (int argc, char **argv) | |||
491 | expected_address_cnt++; | 507 | expected_address_cnt++; |
492 | } | 508 | } |
493 | break; | 509 | break; |
510 | case 'n': /* expect NXDOMAIN */ | ||
511 | expect_nxdomain = TRUE; | ||
512 | break; | ||
494 | case 'A': /* expect authority */ | 513 | case 'A': /* expect authority */ |
495 | expect_authority = TRUE; | 514 | expect_authority = TRUE; |
496 | break; | 515 | break; |
@@ -532,8 +551,15 @@ process_arguments (int argc, char **argv) | |||
532 | int | 551 | int |
533 | validate_arguments () | 552 | validate_arguments () |
534 | { | 553 | { |
535 | if (query_address[0] == 0) | 554 | if (query_address[0] == 0) { |
555 | printf ("missing --host argument\n"); | ||
556 | return ERROR; | ||
557 | } | ||
558 | |||
559 | if (expected_address_cnt > 0 && expect_nxdomain) { | ||
560 | printf ("--expected-address and --expect-nxdomain cannot be combined\n"); | ||
536 | return ERROR; | 561 | return ERROR; |
562 | } | ||
537 | 563 | ||
538 | return OK; | 564 | return OK; |
539 | } | 565 | } |
@@ -566,6 +592,9 @@ print_help (void) | |||
566 | printf (" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); | 592 | printf (" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); |
567 | printf (" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); | 593 | printf (" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); |
568 | printf (" %s\n", _("value matches).")); | 594 | printf (" %s\n", _("value matches).")); |
595 | printf (" -n, --expect-nxdomain\n"); | ||
596 | printf (" %s\n", _("Expect the DNS server to return NXDOMAIN (i.e. the domain was not found)")); | ||
597 | printf (" %s\n", _("Cannot be used together with -a")); | ||
569 | printf (" -A, --expect-authority\n"); | 598 | printf (" -A, --expect-authority\n"); |
570 | printf (" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup")); | 599 | printf (" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup")); |
571 | printf (" -w, --warning=seconds\n"); | 600 | printf (" -w, --warning=seconds\n"); |
@@ -586,5 +615,5 @@ void | |||
586 | print_usage (void) | 615 | print_usage (void) |
587 | { | 616 | { |
588 | printf ("%s\n", _("Usage:")); | 617 | printf ("%s\n", _("Usage:")); |
589 | printf ("%s -H host [-s server] [-a expected-address] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname); | 618 | printf ("%s -H host [-s server] [-a expected-address] [-n] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname); |
590 | } | 619 | } |
diff --git a/plugins/t/check_dns.t b/plugins/t/check_dns.t index cdfbe60d..1e7d5340 100644 --- a/plugins/t/check_dns.t +++ b/plugins/t/check_dns.t | |||
@@ -10,7 +10,7 @@ use NPTest; | |||
10 | 10 | ||
11 | plan skip_all => "check_dns not compiled" unless (-x "check_dns"); | 11 | plan skip_all => "check_dns not compiled" unless (-x "check_dns"); |
12 | 12 | ||
13 | plan tests => 19; | 13 | plan tests => 23; |
14 | 14 | ||
15 | my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/'; | 15 | my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/'; |
16 | 16 | ||
@@ -58,7 +58,7 @@ my $dns_server = getTestParameter( | |||
58 | my $host_nonresponsive = getTestParameter( | 58 | my $host_nonresponsive = getTestParameter( |
59 | "NP_HOST_NONRESPONSIVE", | 59 | "NP_HOST_NONRESPONSIVE", |
60 | "The hostname of system not responsive to network requests", | 60 | "The hostname of system not responsive to network requests", |
61 | "10.0.0.1", | 61 | "192.0.2.0", |
62 | ); | 62 | ); |
63 | 63 | ||
64 | my $res; | 64 | my $res; |
@@ -105,3 +105,11 @@ cmp_ok( $res->return_code, '==', 0, "Got expected address"); | |||
105 | $res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_invalid_cidr -t 5"); | 105 | $res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_invalid_cidr -t 5"); |
106 | cmp_ok( $res->return_code, '==', 2, "Got wrong address"); | 106 | cmp_ok( $res->return_code, '==', 2, "Got wrong address"); |
107 | like ( $res->output, "/^DNS CRITICAL.*expected '$hostname_invalid_cidr' but got '$hostname_valid_ip'".'$/', "Output OK"); | 107 | like ( $res->output, "/^DNS CRITICAL.*expected '$hostname_invalid_cidr' but got '$hostname_valid_ip'".'$/', "Output OK"); |
108 | |||
109 | $res = NPTest->testCmd("./check_dns -H $hostname_valid -n"); | ||
110 | cmp_ok( $res->return_code, '==', 2, "Found $hostname_valid"); | ||
111 | like ( $res->output, "/^DNS CRITICAL.*Domain '$hostname_valid' was found by the server:/", "Output OK"); | ||
112 | |||
113 | $res = NPTest->testCmd("./check_dns -H $hostname_invalid -n"); | ||
114 | cmp_ok( $res->return_code, '==', 0, "Did not find $hostname_invalid"); | ||
115 | like ( $res->output, $successOutput, "Output OK" ); | ||