Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

check_dig.c: Fix string matching of -a parameter so that partial matches will not #652

Merged
merged 2 commits into from Jan 13, 2023

Conversation

kraken-jim
Copy link
Contributor

produce false "OK" status reports, such as when the -a string is
10.4.5.2 and the DNS result is 210.4.5.247.

Fixes #641

produce false "OK" status reports, such as when the -a string is
10.4.5.2 and the DNS result is 210.4.5.247.
@kraken-jim kraken-jim changed the title Fix string matching of -a parameter so that partial matches will not check_dig.c: Fix string matching of -a parameter so that partial matches will not Apr 22, 2022
@sawolf
Copy link
Member

sawolf commented May 4, 2022

Hi @kraken-jim, thanks for the patch!

I agree that this is a bug, and the change in approach looks correct to me - will do more testing and merge closer to the next release.

@kraken-jim
Copy link
Contributor Author

kraken-jim commented Oct 24, 2022

Hi, @sawolf. I'm honored to see that one of my patches is being considered for the 2.4.1 release. I'm writing in the hope that some documentation on this patch to check_dig.c might either help in testing, or be a basis for a revision to the documentation.

TL/DR:

  • -a string still defaults to the -l string
  • success is returned if any line of the answer section:
    • begins with -a string followed by .<tab>
    • ends with <tab> followed by -a string followed by newline

In a nutshell:

  • The -a parameter still defaults to the -l parameter, so no change in how default values are assigned
  • The -a string still has to appear in the ;; ANSWER SECTION: of the dig output, in its entirety, with specific delimiters, depending on whether it is at the beginning of a line (left-match) or the end of a line (right-match).
  • Either a left-match or a right-match will cause an OK result with no further parsing of the answer section.
  • If the end of the answer section is reached (a blank line), parsing stops and a failure result is returned.

In a "left-match," the -a string must appear at the beginning of a line, followed by a . and a tab. This is the nominal case when -l is a DNS name and -a defaults to the same as -l. The plugin returns OK so long as at least one of the DNS records returned has a name (not a value) that matches -a in its entirety. Note that check_dig -vl example.com. fails. Don't pass a trailing dot in the -l argument to check_dig! If the user insists on doing something like checking the presence of NS records for the root zone ., then passing -a set to a null string will do it:

$ check_dig -T ns -vl . -a ""
/usr/bin/drill   . ns
Looking for: '' length 0
;; ANSWER SECTION:
.       499014  IN      NS      e.root-servers.net.
DNS OK - 0.010 seconds response time (. 499014 IN NS e.root-servers.net.)|time=0.010472s;;;0.000000

In a "right-match," the -a string must appear at the end of the line, preceded by a tab, and the match must continue to end-of-line. One use case for this type of match is when -l is a DNS name, and -a is an expected IP number. Unlike the -l parameter, a trailing dot can sometimes be meaningful in the -a parameter. Consider the case when example.com is a CNAME record with value www.example.com and www.example.com is an A record with value 10.20.30.40:

$ dig example.com
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 24278
;; flags: qr rd ra ; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 
;; QUESTION SECTION:
;; example.com. IN      A

;; ANSWER SECTION:
example.com.          3364    IN      CNAME   www.example.com.
www.example.com.       900    IN      A       10.20.30.40

;; AUTHORITY SECTION:
<snip>

Here is a "left-match" case. We'll let -a default to -l. The match found is shown by using the -v switch:

$ check_dig -vl example.com 
/usr/bin/drill   example.com A
Looking for: 'example.com' length 23
;; ANSWER SECTION:
example.com.        1491    IN      CNAME   www.example.com.
DNS OK - 0.010 seconds response time (example.com. 1491 IN CNAME www.example.com.)|time=0.009741s;;;0.000000

This example succeeds because the -a string example.com appears at the beginning of a line, followed by .<tab>.
Here is another left-match case, using a non-default -a string:

$ check_dig -vl example.com -a www.example.com
/usr/bin/drill   example.com A
Looking for: 'www.example.com' length 20
;; ANSWER SECTION:
example.com.        2756    IN      CNAME   www.example.com.
www.example.com.    900     IN      A       10.20.30.40
DNS OK - 0.010 seconds response time (www.example.com. 900 IN A 10.20.30.40)|time=0.009604s;;;0.000000

Notice that parsing of the ANSWER SECTION continues beyond the first line to the second line. This second line is where the left-match is found: the line begins with www.example.com followed by a dot and a tab. Notice that both times the record that matches is reflected in the DNS OK response string.

A typical right-hand match example would be check_dig -vl example.com -a 10.20.30.40. Any line in the answer section that ends with <tab>10.20.30.40 would indicate an OK result:

DNS OK - 0.018 seconds response time (www.example.com. 900 IN A 10.20.30.40)|time=0.017602s;;;0.000000

Finally, the user can also use a right-match to check that a DNS name appears in the rightmost value, such as testing the value of a CNAME or MX record:

$ check_dig -vl example.com -a www.example.com.
/usr/bin/drill   example.com A
Looking for: 'www.example.com.' length 21
;; ANSWER SECTION:
example.com.    2008    IN      CNAME   www.example.com.
DNS OK - 0.010 seconds response time (example.com. 2008 IN CNAME www.example.com.)|time=0.010053s;;;0.000000

Because of the formatting that dig/drill uses, when testing MX records, the priority is considered part of the right-hand match string, in the form <priority><space><hostname>. This gives the user the ability to not only verify that the proper DNS name is present, but that the priority values are correct.

This fails:

$ check_dig -T mx -vl example.com -a .
/usr/bin/drill   example.com mx
Looking for: '.' length 1
;; ANSWER SECTION:
example.com.    86222   IN      MX      0 .

DNS WARNING - 0.010 seconds response time (Server not found in ANSWER SECTION)|time=0.009600s;;;0.000000

This works:

$ check_dig -T mx -vl example.com -a '0 .'
/usr/bin/drill   example.com mx
Looking for: '0 .' length 3
;; ANSWER SECTION:
example.com.    86204   IN      MX      0 .
DNS OK - 0.010 seconds response time (example.com. 86204 IN MX 0 .)|time=0.009624s;;;0.000000

TXT records, too!

Left-match, just to make sure a TXT record is found:

$ check_dig -vl example.com -T txt
/usr/bin/drill   example.com txt
Looking for: 'example.com' length 11
;; ANSWER SECTION:
example.com.    86284   IN      TXT     "wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn"
DNS OK - 0.010 seconds response time (example.com. 86284 IN TXT "wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn")|time=0.009516s;;;0.000000

Right-match, to make sure the TXT is what it ought to be:

$ check_dig -vl example.com -T txt -a '"wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn"'
/usr/bin/drill   example.com txt
Looking for: '"wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn"' length 34
;; ANSWER SECTION:
example.com.    86202   IN      TXT     "wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn"
DNS OK - 0.010 seconds response time (example.com. 86202 IN TXT "wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn")|time=0.010284s;;;0.000000

Notice that because drill returns the TXT value including quotes, we must include the quotes in the -a string. Backslash-escaping would work as well.

Even PTR records:

No reverse DNS == failure:

$ check_dig -vT PTR -l 2.2.2.4.in-addr.arpa
/usr/bin/drill   2.2.2.4.in-addr.arpa PTR
Looking for: '2.2.2.4.in-addr.arpa' length 20
;; ANSWER SECTION:

DNS WARNING - 0.036 seconds response time (Server not found in ANSWER SECTION)|time=0.035758s;;;0.000000

Checking for a right-hand match on a PTR record again requires a trailing . in the -a string:

$ check_dig -vT PTR -l 4.4.8.8.in-addr.arpa -a dns.google.
/usr/bin/drill   4.4.8.8.in-addr.arpa PTR
Looking for: 'dns.google.' length 11
;; ANSWER SECTION:
4.4.8.8.in-addr.arpa.   59981   IN      PTR     dns.google.
DNS OK - 0.015 seconds response time (4.4.8.8.in-addr.arpa. 59981 IN PTR dns.google.)|time=0.014725s;;;0.000000

sawolf added a commit that referenced this pull request Jan 13, 2023
@sawolf sawolf merged commit 06ace73 into nagios-plugins:master Jan 13, 2023
@sawolf
Copy link
Member

sawolf commented Jan 13, 2023

This is definitely good for the next release. Thanks again for the patch as well as for the clear explanation!

@sawolf sawolf added this to the 2.4.3 milestone Jan 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

check_dig: string matching of -a argument is too loose
2 participants