Skip to content

Commit f0917e5

Browse files
author
wafuwafu13
committed
improve match process
1 parent 5ef74ae commit f0917e5

File tree

4 files changed

+262
-50
lines changed

4 files changed

+262
-50
lines changed

check-dns/README.md

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,33 @@
44

55
Monitor DNS response.
66

7-
## Synopsis
7+
## Usage
8+
9+
### Options
810

9-
Check DNS server status
10-
If DNS server returns
1111
```
12-
NOERROR -> OK
13-
otherwise -> CRITICAL
12+
-H, --host= The name or address you want to query
13+
-s, --server= DNS server you want to use for the lookup
14+
-p, --port= Port number you want to use (default: 53)
15+
-q, --querytype= DNS record query type where TYPE =(A, AAAA, TXT, MX, CNAME) (default: A)
16+
-c, --queryclass= DNS record class type where TYPE =(IN, CS, CH, HS, NONE, ANY) (default: IN)
17+
--norec Set not recursive mode
18+
-e, --expected-string= The string you expect the DNS server to return. If multiple responses are returned at once, you have to specify whole string
1419
```
20+
21+
- The currently supported query types are A, AAAA, TXT, MX, CNAME.
22+
- Punycode is not supported.
23+
24+
### Check DNS server status
25+
26+
If DNS server returns `NOERROR` in status of HEADER, then the checker result becomes `OK`, if not `NOERROR`, then `CRITICAL`
27+
1528
```
1629
check-dns -H example.com -s 8.8.8.8
1730
```
1831

19-
Check IP-ADDRESS DNS server returns
32+
### Check string DNS server returns
33+
2034
If DNS server returns 1.1.1.1 and 2.2.2.2
2135
```
2236
-a 1.1.1.1 -a 2.2.2.2 -> OK
@@ -55,23 +69,46 @@ check-dns -H example.com -s 8.8.8.8
5569
If there are no problems in the execution result, add a setting in mackerel-agent.conf .
5670

5771
```
58-
[plugin.checks.fileage-sample]
72+
[plugin.checks.dns-sample]
5973
command = ["check-dns", "-H", "example.com", "-s", "8.8.8.8"]
6074
```
6175

62-
## Usage
63-
### Options
76+
## NOTICES AND INFORMATION
77+
78+
This plugin incorporates material from third parties.
79+
80+
### miekg/dns
81+
82+
**source**: https://github.com/miekg/dns
6483

6584
```
66-
-H, --host= The name or address you want to query
67-
-s, --server= DNS server you want to use for the lookup
68-
-p, --port= Port number you want to use (default: 53)
69-
-q, --querytype= DNS record query type where TYPE =(A, AAAA, SRV, TXT, MX, ANY) (default: A)
70-
-c, --queryclass= DNS record class type where TYPE =(IN, CS, CH, HS, NONE, ANY) (default: IN)
71-
--norec Set not recursive mode
72-
-a, --expected-address= IP-ADDRESS you expect the DNS server to return. If multiple addresses are returned at once, you have to specify whole string of addresses
73-
```
85+
BSD 3-Clause License
86+
87+
Copyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben.
88+
All rights reserved.
7489
75-
## For more information
90+
Redistribution and use in source and binary forms, with or without
91+
modification, are permitted provided that the following conditions are met:
7692
77-
Please execute `check-dns -h` and you can get command line options.
93+
1. Redistributions of source code must retain the above copyright notice, this
94+
list of conditions and the following disclaimer.
95+
96+
2. Redistributions in binary form must reproduce the above copyright notice,
97+
this list of conditions and the following disclaimer in the documentation
98+
and/or other materials provided with the distribution.
99+
100+
3. Neither the name of the copyright holder nor the names of its
101+
contributors may be used to endorse or promote products derived from
102+
this software without specific prior written permission.
103+
104+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
105+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
106+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
107+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
108+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
109+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
110+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
111+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
112+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
113+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
114+
```

check-dns/lib/check_dns.go

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ import (
1313
)
1414

1515
type dnsOpts struct {
16-
Host string `short:"H" long:"host" required:"true" description:"The name or address you want to query"`
17-
Server string `short:"s" long:"server" description:"DNS server you want to use for the lookup"`
18-
Port int `short:"p" long:"port" default:"53" description:"Port number you want to use"`
19-
QueryType string `short:"q" long:"querytype" default:"A" description:"DNS record query type where TYPE =(A, AAAA, SRV, TXT, MX, ANY)"`
20-
QueryClass string `short:"c" long:"queryclass" default:"IN" description:"DNS record class type where TYPE =(IN, CS, CH, HS, NONE, ANY)"`
21-
Norec bool `long:"norec" description:"Set not recursive mode"`
22-
ExpectedAddress []string `short:"a" long:"expected-address" description:"IP-ADDRESS you expect the DNS server to return. If multiple addresses are returned at once, you have to specify whole string of addresses"`
16+
Host string `short:"H" long:"host" required:"true" description:"The name or address you want to query"`
17+
Server string `short:"s" long:"server" description:"DNS server you want to use for the lookup"`
18+
Port int `short:"p" long:"port" default:"53" description:"Port number you want to use"`
19+
QueryType string `short:"q" long:"querytype" default:"A" description:"DNS record query type where TYPE =(A, AAAA, TXT, MX, CNAME)"`
20+
QueryClass string `short:"c" long:"queryclass" default:"IN" description:"DNS record class type where TYPE =(IN, CS, CH, HS, NONE, ANY)"`
21+
Norec bool `long:"norec" description:"Set not recursive mode"`
22+
ExpectedString []string `short:"e" long:"expected-string" description:"The string you expect the DNS server to return. If multiple responses are returned at once, you have to specify whole string"`
2323
}
2424

25+
var supportedQueryType = map[string]int{"A": 1, "AAAA": 1, "TXT": 1, "MX": 1, "CNAME": 1}
26+
2527
// Do the plugin
2628
func Do() {
2729
opts, err := parseArgs(os.Args[1:])
@@ -52,13 +54,14 @@ func (opts *dnsOpts) run() *checkers.Checker {
5254
}
5355
nameserver = net.JoinHostPort(nameserver, strconv.Itoa(opts.Port))
5456

55-
queryType, ok := dns.StringToType[strings.ToUpper(opts.QueryType)]
57+
_, ok := supportedQueryType[strings.ToUpper(opts.QueryType)]
5658
if !ok {
57-
return checkers.Critical(fmt.Sprintf("%s is invalid queryType", opts.QueryType))
59+
return checkers.Critical(fmt.Sprintf("%s is not supported query type", opts.QueryType))
5860
}
61+
queryType := dns.StringToType[strings.ToUpper(opts.QueryType)]
5962
queryClass, ok := dns.StringToClass[strings.ToUpper(opts.QueryClass)]
6063
if !ok {
61-
return checkers.Critical(fmt.Sprintf("%s is invalid queryClass", opts.QueryClass))
64+
return checkers.Critical(fmt.Sprintf("%s is invalid query class", opts.QueryClass))
6265
}
6366

6467
c := new(dns.Client)
@@ -78,26 +81,43 @@ func (opts *dnsOpts) run() *checkers.Checker {
7881

7982
checkSt := checkers.OK
8083
/**
81-
if DNS server return 1.1.1.1, 2.2.2.2
82-
1: --expected-address 1.1.1.1, 2.2.2.2 -> OK
83-
2: --expected-address 1.1.1.1, 2.2.2.2, 3.3.3.3 -> WARNING
84-
3: --expected-address 1.1.1.1 -> WARNING
85-
4: --expected-address 1.1.1.1, 3.3.3.3 -> WARNING
86-
5: --expected-address 3.3.3.3 -> CRITICAL
87-
6: --expected-address 3.3.3.3, 4.4.4.4, 5.5.5.5 -> CRITICAL
84+
if DNS server return 1.1.1.1, 2.2.2.2
85+
1: -e 1.1.1.1 -e 2.2.2.2 -> OK
86+
2: -e 1.1.1.1 -e 2.2.2.2 -e 3.3.3.3 -> WARNING
87+
3: -e 1.1.1.1 -e -> WARNING
88+
4: -e 1.1.1.1 -e 3.3.3.3 -> WARNING
89+
5: -e 3.3.3.3 -e -> CRITICAL
90+
6: -e 3.3.3.3 -e 4.4.4.4 -e 5.5.5.5 -> CRITICAL
8891
**/
89-
if len(opts.ExpectedAddress) != 0 {
92+
if len(opts.ExpectedString) != 0 {
9093
match := 0
91-
for _, v := range opts.ExpectedAddress {
94+
for _, expectedString := range opts.ExpectedString {
9295
for _, answer := range r.Answer {
93-
// strings.Split(answer.String(), "\t") is formatted as [a.root-servers.net. 328177 IN A 198.41.0.4]
94-
if strings.Split(answer.String(), "\t")[4] == strings.TrimSpace(v) {
96+
var anserWithoutHeader string
97+
expectMatch := expectedString
98+
switch t := answer.(type) {
99+
case *dns.A:
100+
anserWithoutHeader = t.A.String()
101+
case *dns.AAAA:
102+
anserWithoutHeader = t.AAAA.String()
103+
case *dns.TXT:
104+
anserWithoutHeader = sprintTxt(t.Txt)
105+
// " is added by sprintTxt
106+
expectMatch = "\"" + expectedString + "\""
107+
case *dns.MX:
108+
anserWithoutHeader = strconv.Itoa(int(t.Preference)) + " " + sprintName(t.Mx)
109+
case *dns.CNAME:
110+
anserWithoutHeader = sprintName(t.Target)
111+
default:
112+
return checkers.Critical(fmt.Sprintf("%s is not supported query type", opts.QueryType))
113+
}
114+
if anserWithoutHeader == expectMatch {
95115
match += 1
96116
}
97117
}
98118
}
99119
if match == len(r.Answer) {
100-
if len(opts.ExpectedAddress) == len(r.Answer) { // case 1
120+
if len(opts.ExpectedString) == len(r.Answer) { // case 1
101121
checkSt = checkers.OK
102122
} else { // case 2
103123
checkSt = checkers.WARNING

check-dns/lib/check_dns_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func TestCheckDns(t *testing.T) {
6666
{
6767
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-q", "AAA"},
6868
checkers.CRITICAL,
69-
[]string{"AAA is invalid queryType"},
69+
[]string{"AAA is not supported query type"},
7070
},
7171
{
7272
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-c", "IN"},
@@ -76,36 +76,36 @@ func TestCheckDns(t *testing.T) {
7676
{
7777
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-c", "INN"},
7878
checkers.CRITICAL,
79-
[]string{"INN is invalid queryClass"},
79+
[]string{"INN is invalid query class"},
8080
},
8181
{
82-
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-a", "198.41.0.4"},
82+
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-e", "198.41.0.4"},
8383
checkers.OK,
8484
[]string{"status: NOERROR", "198.41.0.4"},
8585
},
8686
{
87-
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-q", "AAAA", "--expected-address", "2001:503:ba3e::2:30"},
87+
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-q", "AAAA", "--expected-string", "2001:503:ba3e::2:30"},
8888
checkers.OK,
8989
[]string{"status: NOERROR", "2001:503:ba3e::2:30"},
9090
},
9191
{
92-
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-a", "198.41.0.3"},
92+
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-e", "198.41.0.3"},
9393
checkers.CRITICAL,
9494
[]string{"status: NOERROR", "198.41.0.4"},
9595
},
9696
{
97-
[]string{"-H", "a.root-servers.invalid", "-s", "8.8.8.8", "-a", "198.41.0.4"},
97+
[]string{"-H", "a.root-servers.invalid", "-s", "8.8.8.8", "-e", "198.41.0.4"},
9898
checkers.CRITICAL,
9999
[]string{"status: NXDOMAIN"},
100100
},
101101
{
102-
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-a", "198.41.0.3", "-a", "198.41.0.4"},
102+
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-e", "198.41.0.3", "-e", "198.41.0.4"},
103103
checkers.WARNING,
104104
[]string{"status: NOERROR", "198.41.0.4"},
105105
},
106106
{
107-
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-a", "198.41.0.3", "-a", " 198.41.0.4 "},
108-
checkers.WARNING,
107+
[]string{"-H", "a.root-servers.net", "-s", "8.8.8.8", "-e", "198.41.0.3", "-e", " 198.41.0.4 "},
108+
checkers.CRITICAL,
109109
[]string{"status: NOERROR", "198.41.0.4"},
110110
},
111111
}

0 commit comments

Comments
 (0)