32 my $VERSION = '0.1'; |
32 my $VERSION = '0.1'; |
33 my $blurb = 'This Plugin is intendet to check TLSA Record'; |
33 my $blurb = 'This Plugin is intendet to check TLSA Record'; |
34 my $url = 'https://schlittermann.de'; |
34 my $url = 'https://schlittermann.de'; |
35 my $author = 'Heike Yvonne Pesch'; |
35 my $author = 'Heike Yvonne Pesch'; |
36 my $email = '<pesch@schlittermann.de>'; |
36 my $email = '<pesch@schlittermann.de>'; |
37 my $extra = LF.'Author: '.$author.' '.$email.LF |
37 my $extra = |
38 . 'For more information visit '.$url; |
38 LF |
|
39 . 'Author: ' |
|
40 . $author . ' ' |
|
41 . $email |
|
42 . LF |
|
43 . 'For more information visit ' |
|
44 . $url; |
39 my $license = 'GPLv3'; |
45 my $license = 'GPLv3'; |
40 my $usage = 'Usage: %s [ -v|--verbose ] [-H <host>] [-t <timeout>] ' |
46 my $usage = |
41 . '[ -c|--critical=<critical threshold> ] ' |
47 'Usage: %s [ -v|--verbose ] [-H <host>] [-t <timeout>] ' |
42 . '[ -w|--warning=<warning threshold> ] ' |
48 . '[ -c|--critical=<critical threshold> ] ' |
43 . '[ -p|--port=<portnumber> ] ' |
49 . '[ -w|--warning=<warning threshold> ] ' |
44 . '[ -q|--queryserver=<DNS-Server-IP> ] '; |
50 . '[ -p|--port=<portnumber> ] ' |
|
51 . '[ -q|--queryserver=<DNS-Server-IP> ] '; |
45 |
52 |
46 my $check_tlsa = Monitoring::Plugin->new( |
53 my $check_tlsa = Monitoring::Plugin->new( |
47 usage => $usage, |
54 usage => $usage, |
48 version => $VERSION, |
55 version => $VERSION, |
49 blurb => $blurb, |
56 blurb => $blurb, |
50 extra => $extra, |
57 extra => $extra, |
51 url => $url, |
58 url => $url, |
52 license => $license, |
59 license => $license, |
53 plugin => basename $0, |
60 plugin => basename $0, |
54 timeout => 60, |
61 timeout => 60, |
55 ); |
62 ); |
56 |
63 |
57 $check_tlsa->add_arg( |
64 $check_tlsa->add_arg( |
58 spec => 'host|H=s', |
65 spec => 'host|H=s', |
59 help => q|Host/Domain to check|, |
66 help => q|Host/Domain to check|, |
60 required => 0, |
67 required => 0, |
61 ); |
68 ); |
62 |
69 |
63 $check_tlsa->add_arg( |
70 $check_tlsa->add_arg( |
64 spec => 'hostlist|f=s', |
71 spec => 'hostlist|f=s', |
65 help => q|Host/Domainlist in file to check|, |
72 help => q|Host/Domainlist in file to check|, |
66 required => 0, |
73 required => 0, |
67 ); |
74 ); |
68 |
75 |
69 $check_tlsa->add_arg( |
76 $check_tlsa->add_arg( |
70 spec => 'expiry|e', |
77 spec => 'expiry|e', |
71 help => q|check expiry of Certificate|, |
78 help => q|check expiry of Certificate|, |
72 required => 0, |
79 required => 0, |
73 ); |
80 ); |
74 |
81 |
75 $check_tlsa->add_arg( |
82 $check_tlsa->add_arg( |
76 spec => 'port|p=i', |
83 spec => 'port|p=i', |
77 help => q|Port of Domain to check the TLSA (default: 443)|, |
84 help => q|Port of Domain to check the TLSA (default: 443)|, |
78 required => 0, |
85 required => 0, |
79 default => 443, |
86 default => 443, |
80 ); |
87 ); |
81 |
88 |
82 $check_tlsa->add_arg( |
89 $check_tlsa->add_arg( |
83 spec => 'queryserver|q=s', |
90 spec => 'queryserver|q=s', |
84 help => q|DNS Server to ask to check the TLSA (default: defined in resolve.conf)|, |
91 help => |
85 required => 0, |
92 q|DNS Server to ask to check the TLSA (default: defined in resolve.conf)|, |
86 #default => '8.8.8.8', |
93 required => 0, |
87 ); |
94 |
88 |
95 #default => '8.8.8.8', |
89 $check_tlsa->add_arg( |
96 ); |
90 spec => 'protocol|P=s', |
97 |
91 help => q|DNS Server to ask to check the TLSA (default: tcp)|, |
98 $check_tlsa->add_arg( |
92 required => 0, |
99 spec => 'protocol|P=s', |
93 default => 'tcp', |
100 help => q|DNS Server to ask to check the TLSA (default: tcp)|, |
|
101 required => 0, |
|
102 default => 'tcp', |
94 ); |
103 ); |
95 |
104 |
96 $check_tlsa->getopts; |
105 $check_tlsa->getopts; |
97 |
106 |
98 my $domain = $check_tlsa->opts->host; |
107 my $domain = $check_tlsa->opts->host; |
99 my $domainlist = $check_tlsa->opts->hostlist; |
108 my $domainlist = $check_tlsa->opts->hostlist; |
100 my $expiry = $check_tlsa->opts->expiry; |
109 my $expiry = $check_tlsa->opts->expiry; |
101 |
110 |
102 if (!$domain && !$domainlist) { |
111 if (!$domain && !$domainlist) { |
103 my $script = basename $0; |
112 my $script = basename $0; |
104 my $excuse = "Please set -H <domain> or -f <domainlist>\n" |
113 my $excuse = "Please set -H <domain> or -f <domainlist>\n" |
105 . "For all options try $script --help"; |
114 . "For all options try $script --help"; |
106 |
115 |
107 print $excuse,LF; |
116 print $excuse, LF; |
108 exit 1; |
117 exit 1; |
109 } |
118 } |
110 |
119 |
111 |
120 my $port; |
112 my $port; |
121 my $cert; |
113 my $cert; |
122 my $check_date; |
114 my $check_date; |
123 |
115 |
124 if (defined $domainlist && -e $domainlist) { |
116 if ( defined $domainlist && -e $domainlist){ |
125 print get_domains(); |
117 print get_domains(); |
126 } |
118 } |
127 else { print check_tlsa(); } |
119 else { print check_tlsa(); } |
|
120 |
128 |
121 sub check_tlsa { |
129 sub check_tlsa { |
122 my $protocol = $check_tlsa->opts->protocol; |
130 my $protocol = $check_tlsa->opts->protocol; |
123 |
131 |
124 $port = $check_tlsa->opts->port unless $port ; |
132 $port = $check_tlsa->opts->port unless $port; |
125 |
133 |
126 if ("$port" eq '25') { |
134 if ("$port" eq '25') { |
127 $cert = "openssl s_client -starttls smtp -connect $domain:$port " |
135 $cert = "openssl s_client -starttls smtp -connect $domain:$port " |
128 . '< /dev/null 2>/dev/null'; |
136 . '< /dev/null 2>/dev/null'; |
129 } |
137 } |
130 else { |
138 else { |
131 #$port = $check_tlsa->opts->port; |
139 #$port = $check_tlsa->opts->port; |
132 $cert = "openssl s_client -connect $domain:$port " |
140 $cert = "openssl s_client -connect $domain:$port " |
133 . '< /dev/null 2>/dev/null'; |
141 . '< /dev/null 2>/dev/null'; |
134 } |
142 } |
135 |
143 |
136 my $digquery = "dig TLSA _$port._$protocol.$domain +short"; |
144 my $digquery = "dig TLSA _$port._$protocol.$domain +short"; |
137 my $diganswer = qx($digquery); |
145 my $diganswer = qx($digquery); |
138 my $dig = substr($diganswer, 6, ); |
146 my $dig = substr($diganswer, 6,); |
139 $dig =~ s/(\S*)\s+(\S*)$/$1$2/; |
147 $dig =~ s/(\S*)\s+(\S*)$/$1$2/; |
140 my $tlsa_usage = substr($diganswer, 0, 1); |
148 my $tlsa_usage = substr($diganswer, 0, 1); |
141 my $tlsa_selector = substr($diganswer, 2, 1); |
149 my $tlsa_selector = substr($diganswer, 2, 1); |
142 my $tlsa_match_type = substr($diganswer, 4, 1); |
150 my $tlsa_match_type = substr($diganswer, 4, 1); |
143 my $hashit; |
151 my $hashit; |
144 |
152 |
145 for ($tlsa_match_type) { |
153 for ($tlsa_match_type) { |
146 when('0') { die 'certs will be compared directly'} |
154 when ('0') { die 'certs will be compared directly' } |
147 when('1') {$hashit = 'sha256'} |
155 when ('1') { $hashit = 'sha256' } |
148 when('2') {$hashit = 'sha512'} |
156 when ('2') { $hashit = 'sha512' } |
149 default {$hashit = 'sha256'} |
157 default { $hashit = 'sha256' } |
150 }; |
158 } |
151 |
159 |
152 my $gentlsa = 'openssl x509 -pubkey | ' |
160 my $gentlsa = |
153 . 'openssl rsa -pubin -inform PEM -outform DER 2>/dev/null| ' |
161 'openssl x509 -pubkey | ' |
154 . "openssl $hashit"; |
162 . 'openssl rsa -pubin -inform PEM -outform DER 2>/dev/null| ' |
155 my $certtlsa = "$cert | $gentlsa"; |
163 . "openssl $hashit"; |
156 |
164 my $certtlsa = "$cert | $gentlsa"; |
157 $check_date = 'openssl x509 -noout -startdate -enddate'; |
165 |
158 $check_date = "$cert|$check_date"; |
166 $check_date = 'openssl x509 -noout -startdate -enddate'; |
159 |
167 $check_date = "$cert|$check_date"; |
160 |
168 |
161 my $return; |
169 my $return; |
162 |
170 |
163 my $tlsa_record = qx($certtlsa) or die "nothing found!\n"; |
171 my $tlsa_record = qx($certtlsa) or die "nothing found!\n"; |
164 $tlsa_record =~ s/^.*= (.*$)/$1/gi; |
172 $tlsa_record =~ s/^.*= (.*$)/$1/gi; |
165 $tlsa_record = uc($tlsa_record); |
173 $tlsa_record = uc($tlsa_record); |
166 |
174 |
167 if (defined $expiry) { |
175 if (defined $expiry) { |
168 print check_cert_expiry(); |
176 print check_cert_expiry(); |
169 } |
177 } |
170 |
178 |
171 if ("$tlsa_record" eq "$dig") { |
179 if ("$tlsa_record" eq "$dig") { |
172 #$return = "TLSA record is $tlsa_record and valid"; |
180 |
173 #funktioniert nich nicht optimal mit hostliste |
181 #$return = "TLSA record is $tlsa_record and valid"; |
174 $return = $check_tlsa->plugin_exit(OK, "$domain: TLSA record is valid") |
182 #funktioniert nich nicht optimal mit hostliste |
175 . "$domain: TLSA record is valid\n"; |
183 $return = $check_tlsa->plugin_exit(OK, "$domain: TLSA record is valid") |
176 } |
184 . "$domain: TLSA record is valid\n"; |
177 else { |
185 } |
178 $check_tlsa->plugin_exit(CRITICAL, "$domain: TLSA record NOT valid"); |
186 else { |
179 } |
187 $check_tlsa->plugin_exit(CRITICAL, "$domain: TLSA record NOT valid"); |
180 return $return; |
188 } |
181 #return $cert; |
189 return $return; |
182 } |
190 |
183 |
191 #return $cert; |
184 |
192 } |
185 |
193 |
186 sub get_domains { |
194 sub get_domains { |
187 open(my $filehandle, '<', $domainlist); |
195 open(my $filehandle, '<', $domainlist); |
188 |
196 |
189 my $pattern = '^(?<domain>\S*\.[a-z]{2,4}?):{0,1}(?<port>[0-9]*$)'; |
197 my $pattern = '^(?<domain>\S*\.[a-z]{2,4}?):{0,1}(?<port>[0-9]*$)'; |
190 my %domain2check; |
198 my %domain2check; |
191 while(<$filehandle>) { |
199 while (<$filehandle>) { |
192 if (/$pattern/ig) { |
200 if (/$pattern/ig) { |
193 $domain = $+{domain}; |
201 $domain = $+{domain}; |
194 $port = $+{port}; |
202 $port = $+{port}; |
195 #print "nunu,file ok",LF,"port: $+{port}",LF,"domain: $+{domain}",LF; |
203 |
196 $domain2check{$domain} = $port; |
204 #print "nunu,file ok",LF,"port: $+{port}",LF,"domain: $+{domain}",LF; |
197 |
205 $domain2check{$domain} = $port; |
198 |
206 |
199 |
207 #print check_tlsa(); |
200 |
208 } |
201 |
209 else { |
202 #print check_tlsa(); |
210 die "wrong content"; |
203 } |
211 } |
204 else { |
212 |
205 die "wrong content"; |
213 foreach my $key (%domain2check) { |
206 } |
214 $domain = $key; |
207 |
215 $port = $domain2check{$key}; |
208 foreach my $key (%domain2check) |
216 print $domain, ' ', $port, "\n"; |
209 { |
217 |
210 $domain = $key; |
218 if ("$port" =~ /^\s*$/) { $port = '443'; } |
211 $port = $domain2check{$key}; |
219 print $domain, ' ', $port, "\n"; |
212 print $domain, ' ', $port,"\n"; |
220 |
213 |
221 check_tlsa($domain, $port); |
214 |
222 } |
215 if ( "$port" =~ /^\s*$/) { $port = '443'; } |
223 |
216 print $domain, ' ', $port,"\n"; |
224 } |
217 |
|
218 check_tlsa($domain,$port); |
|
219 } |
|
220 |
|
221 } |
|
222 } |
225 } |
223 |
226 |
224 sub check_cert_expiry { |
227 sub check_cert_expiry { |
225 my $return = qx($check_date); |
228 my $return = qx($check_date); |
226 return $return; |
229 return $return; |
227 } |
230 } |
228 |
231 |