[monitoring-plugins] check_dns: add --expect-nxdomain

Sven Nierlein git at monitoring-plugins.org
Thu Sep 2 10:00:12 CEST 2021


    Module: monitoring-plugins
    Branch: master
    Commit: 70f55ca9db87f639856e0548a57081c886e09d14
    Author: Jonny007-MKD <nospam at jonny007-mkd.de>
 Committer: Sven Nierlein <sven at nierlein.org>
      Date: Sun Feb 23 15:02:43 2020 +0100
       URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=70f55ca

check_dns: add --expect-nxdomain

---

 NEWS                  |  1 +
 plugins/check_dns.c   | 61 +++++++++++++++++++++++++++++++++++++--------------
 plugins/t/check_dns.t | 12 ++++++++--
 3 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/NEWS b/NEWS
index 4061c03..3790e8a 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ This file documents the major additions and syntax changes between releases.
 	check_dns: Accept CIDR
 	check_dns: allow unsorted addresses
 	check_dns: allow forcing complete match of all addresses
+	check_dns: option to expect NXDOMAIN
 	check_apt: add --only-critical switch
 	check_apt: add -l/--list option to print packages
         check_file_age: add range checking
diff --git a/plugins/check_dns.c b/plugins/check_dns.c
index 0f2e654..0c10f09 100644
--- a/plugins/check_dns.c
+++ b/plugins/check_dns.c
@@ -41,7 +41,7 @@ const char *email = "devel at monitoring-plugins.org";
 
 int process_arguments (int, char **);
 int validate_arguments (void);
-int error_scan (char *);
+int error_scan (char *, int*);
 int ip_match_cidr(const char *, const char *);
 unsigned long ip2long(const char *);
 void print_help (void);
@@ -54,6 +54,7 @@ char ptr_server[ADDRESS_LENGTH] = "";
 int verbose = FALSE;
 char **expected_address = NULL;
 int expected_address_cnt = 0;
+int expect_nxdomain = FALSE;
 
 int expect_authority = FALSE;
 int all_match = FALSE;
@@ -87,6 +88,7 @@ main (int argc, char **argv)
   int parse_address = FALSE; /* This flag scans for Address: but only after Name: */
   output chld_out, chld_err;
   size_t i;
+  int is_nxdomain = FALSE;
 
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
@@ -186,7 +188,7 @@ main (int argc, char **argv)
     }
 
 
-    result = error_scan (chld_out.line[i]);
+    result = error_scan (chld_out.line[i], &is_nxdomain);
     if (result != STATE_OK) {
       msg = strchr (chld_out.line[i], ':');
       if(msg) msg++;
@@ -199,8 +201,8 @@ main (int argc, char **argv)
     if (verbose)
       puts(chld_err.line[i]);
 
-    if (error_scan (chld_err.line[i]) != STATE_OK) {
-      result = max_state (result, error_scan (chld_err.line[i]));
+    if (error_scan (chld_err.line[i], &is_nxdomain) != STATE_OK) {
+      result = max_state (result, error_scan (chld_err.line[i], &is_nxdomain));
       msg = strchr(input_buffer, ':');
       if(msg)
          msg++;
@@ -209,6 +211,10 @@ main (int argc, char **argv)
     }
   }
 
+  if (is_nxdomain && !expect_nxdomain) {
+    die (STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), query_address);
+  }
+
   if (addresses) {
     int i,slen;
     char *adrp;
@@ -260,6 +266,16 @@ main (int argc, char **argv)
     }
   }
 
+  if (expect_nxdomain) {
+    if (!is_nxdomain) {
+      result = STATE_CRITICAL;
+      xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), query_address, address);
+    } else {
+      if (address == NULL) free(address);
+      address = "NXDOMAIN";
+    }
+  }
+
   /* check if authoritative */
   if (result == STATE_OK && expect_authority && non_authoritative) {
     result = STATE_CRITICAL;
@@ -339,9 +355,15 @@ ip2long(const char* src) {
 }
 
 int
-error_scan (char *input_buffer)
+error_scan (char *input_buffer, int* is_nxdomain)
 {
 
+  const int nxdomain = strstr (input_buffer, "Non-existent") ||
+                       strstr (input_buffer, "** server can't find") ||
+                       strstr (input_buffer, "** Can't find") ||
+                       strstr (input_buffer, "NXDOMAIN");
+  if (nxdomain) *is_nxdomain = TRUE;
+
   /* the DNS lookup timed out */
   if (strstr (input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) ||
       strstr (input_buffer, _("Consider using the `dig' or `host' programs instead.  Run nslookup with")) ||
@@ -360,7 +382,7 @@ error_scan (char *input_buffer)
 
   /* Connection was refused */
   else if (strstr (input_buffer, "Connection refused") ||
-     strstr (input_buffer, "Couldn't find server") ||
+           strstr (input_buffer, "Couldn't find server") ||
            strstr (input_buffer, "Refused") ||
            (strstr (input_buffer, "** server can't find") &&
             strstr (input_buffer, ": REFUSED")))
@@ -374,13 +396,6 @@ error_scan (char *input_buffer)
   else if (strstr (input_buffer, "No information"))
     die (STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server);
 
-  /* Host or domain name does not exist */
-  else if (strstr (input_buffer, "Non-existent") ||
-           strstr (input_buffer, "** server can't find") ||
-           strstr (input_buffer, "** Can't find") ||
-     strstr (input_buffer,"NXDOMAIN"))
-    die (STATE_CRITICAL, _("Domain %s was not found by the server\n"), query_address);
-
   /* Network is unreachable */
   else if (strstr (input_buffer, "Network is unreachable"))
     die (STATE_CRITICAL, _("Network is unreachable\n"));
@@ -417,6 +432,7 @@ process_arguments (int argc, char **argv)
     {"server", required_argument, 0, 's'},
     {"reverse-server", required_argument, 0, 'r'},
     {"expected-address", required_argument, 0, 'a'},
+    {"expect-nxdomain",  no_argument, 0, 'n'},
     {"expect-authority", no_argument, 0, 'A'},
     {"all", no_argument, 0, 'L'},
     {"warning", required_argument, 0, 'w'},
@@ -432,7 +448,7 @@ process_arguments (int argc, char **argv)
       strcpy (argv[c], "-t");
 
   while (1) {
-    c = getopt_long (argc, argv, "hVvALt:H:s:r:a:w:c:", long_opts, &opt_index);
+    c = getopt_long (argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index);
 
     if (c == -1 || c == EOF)
       break;
@@ -491,6 +507,9 @@ process_arguments (int argc, char **argv)
 	expected_address_cnt++;
       }
       break;
+    case 'n': /* expect NXDOMAIN */
+      expect_nxdomain = TRUE;
+      break;
     case 'A': /* expect authority */
       expect_authority = TRUE;
       break;
@@ -532,8 +551,15 @@ process_arguments (int argc, char **argv)
 int
 validate_arguments ()
 {
-  if (query_address[0] == 0)
+  if (query_address[0] == 0) {
+    printf ("missing --host argument\n");
+    return ERROR;
+  }
+
+  if (expected_address_cnt > 0 && expect_nxdomain) {
+    printf ("--expected-address and --expect-nxdomain cannot be combined\n");
     return ERROR;
+  }
 
   return OK;
 }
@@ -566,6 +592,9 @@ print_help (void)
   printf ("    %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end"));
   printf ("    %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any"));
   printf ("    %s\n", _("value matches)."));
+  printf (" -n, --expect-nxdomain\n");
+  printf ("    %s\n", _("Expect the DNS server to return NXDOMAIN (i.e. the domain was not found)"));
+  printf ("    %s\n", _("Cannot be used together with -a"));
   printf (" -A, --expect-authority\n");
   printf ("    %s\n", _("Optionally expect the DNS server to be authoritative for the lookup"));
   printf (" -w, --warning=seconds\n");
@@ -586,5 +615,5 @@ void
 print_usage (void)
 {
   printf ("%s\n", _("Usage:"));
-  printf ("%s -H host [-s server] [-a expected-address] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname);
+  printf ("%s -H host [-s server] [-a expected-address] [-n] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname);
 }
diff --git a/plugins/t/check_dns.t b/plugins/t/check_dns.t
index cdfbe60..1e7d534 100644
--- a/plugins/t/check_dns.t
+++ b/plugins/t/check_dns.t
@@ -10,7 +10,7 @@ use NPTest;
 
 plan skip_all => "check_dns not compiled" unless (-x "check_dns");
 
-plan tests => 19;
+plan tests => 23;
 
 my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/';
 
@@ -58,7 +58,7 @@ my $dns_server       = getTestParameter(
 my $host_nonresponsive = getTestParameter(
 			"NP_HOST_NONRESPONSIVE",
 			"The hostname of system not responsive to network requests",
-			"10.0.0.1",
+			"192.0.2.0",
 			);
 
 my $res;
@@ -105,3 +105,11 @@ cmp_ok( $res->return_code, '==', 0, "Got expected address");
 $res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_invalid_cidr -t 5");
 cmp_ok( $res->return_code, '==', 2, "Got wrong address");
 like  ( $res->output, "/^DNS CRITICAL.*expected '$hostname_invalid_cidr' but got '$hostname_valid_ip'".'$/', "Output OK");
+
+$res = NPTest->testCmd("./check_dns -H $hostname_valid -n");
+cmp_ok( $res->return_code, '==', 2, "Found $hostname_valid");
+like  ( $res->output, "/^DNS CRITICAL.*Domain '$hostname_valid' was found by the server:/", "Output OK");
+
+$res = NPTest->testCmd("./check_dns -H $hostname_invalid -n");
+cmp_ok( $res->return_code, '==', 0, "Did not find $hostname_invalid");
+like  ( $res->output, $successOutput, "Output OK" );



More information about the Commits mailing list