check_tlsa
changeset 2 523934592a76
parent 1 1ce9659ddc4f
child 3 10ee65f99a7d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/check_tlsa	Mon May 02 23:07:41 2016 +0200
@@ -0,0 +1,228 @@
+#! /usr/bin/perl
+#dig TLSA _25._tcp.ssl.schlittermann.de +dnssec +m
+#dig TLSA _25._tcp.hh.schlittermann.de
+# http://search.cpan.org/~nierlein/Monitoring-Plugin-0.39/lib/Monitoring/Plugin.pm
+# http://perldoc.perl.org/File/Basename.html
+# needs debian packet: libmonitoring-plugin-perl
+#TLSA Record generieren
+# openssl x509 -in <servername>.crt -outform DER | openssl sha256
+# neben sha256 gibt's noch sha1 sha224 sha256 sha384 sha512
+# sowie md2 md5 rmd160 (wobei ich diese nicht in betracht ziehe)
+# ssl certifikat von einem remote server anfordern
+# openssl s_client -showcerts -connect ssl.schlittermann.de:443 < /dev/null
+# https://github.com/monitoring-plugins
+# https://github.com/monitoring-plugins/monitoring-plugin-perl/blob/master/t/check_stuff.pl
+
+#openssl s_client -starttls smtp -connect ssl.schlittermann.de:25 | openssl x509  -pubkey | openssl rsa -pubin -inform PEM -outform DER | openssl sha256
+#openssl s_client -starttls smtp -connect ssl.schlittermann.de:25 | openssl x509  -outform DER | openssl sha256
+
+use strict;
+use warnings;
+use feature qw(switch);
+use if $^V >= v5.020 => (experimental => qw(smartmatch));
+use experimental qw(smartmatch);
+use Monitoring::Plugin;
+use File::Basename;
+
+#devel
+use Data::Dumper;
+
+use constant LF => "\n";
+
+my $VERSION = '0.1';
+my $blurb   = 'This Plugin is intendet to check TLSA Record';
+my $url     = 'https://schlittermann.de';
+my $author  = 'Heike Yvonne Pesch';
+my $email   = '<pesch@schlittermann.de>';
+my $extra   = LF.'Author: '.$author.' '.$email.LF
+            . 'For more information visit '.$url;
+my $license = 'GPLv3';
+my $usage   = 'Usage: %s [ -v|--verbose ] [-H <host>] [-t <timeout>] '
+            . '[ -c|--critical=<critical threshold> ] '
+            . '[ -w|--warning=<warning threshold> ] '
+            . '[ -p|--port=<portnumber> ] '
+            . '[ -q|--queryserver=<DNS-Server-IP> ] ';
+
+my $check_tlsa = Monitoring::Plugin->new(
+  usage   => $usage,
+  version => $VERSION,
+  blurb   => $blurb,
+  extra   => $extra,
+  url     => $url,
+  license => $license,
+  plugin  => basename $0,
+  timeout => 60,
+);
+
+$check_tlsa->add_arg(
+  spec => 'host|H=s',
+  help => q|Host/Domain to check|,
+  required => 0,
+);
+
+$check_tlsa->add_arg(
+  spec => 'hostlist|f=s',
+  help => q|Host/Domainlist in file to check|,
+  required => 0,
+);
+
+$check_tlsa->add_arg(
+  spec => 'expiry|e',
+  help => q|check expiry of Certificate|,
+  required => 0,
+);
+
+$check_tlsa->add_arg(
+  spec      => 'port|p=i',
+  help      => q|Port of Domain to check the TLSA (default: 443)|,
+  required  => 0,
+  default   => 443,
+);
+
+$check_tlsa->add_arg(
+  spec => 'queryserver|q=s',
+  help => q|DNS Server to ask to check the TLSA (default: defined in resolve.conf)|,
+  required => 0,
+  #default => '8.8.8.8',
+);
+
+$check_tlsa->add_arg(
+  spec => 'protocol|P=s',
+  help => q|DNS Server to ask to check the TLSA (default: tcp)|,
+  required => 0,
+  default => 'tcp',
+);
+
+$check_tlsa->getopts;
+
+my $domain     = $check_tlsa->opts->host;
+my $domainlist = $check_tlsa->opts->hostlist;
+my $expiry     = $check_tlsa->opts->expiry;
+
+if (!$domain && !$domainlist) {
+  my $script  = basename $0;
+  my $excuse  = "Please set -H <domain> or -f <domainlist>\n"
+              . "For all options try $script --help";
+
+  print $excuse,LF;
+  exit 1;
+}
+
+
+  my $port;
+  my $cert;
+  my $check_date;
+
+    if ( defined $domainlist && -e $domainlist){
+      print get_domains();
+    }
+    else { print check_tlsa(); }
+
+sub check_tlsa {
+  my $protocol    = $check_tlsa->opts->protocol;
+
+  $port = $check_tlsa->opts->port unless $port ;
+
+  if ("$port" eq '25') {
+    $cert  = "openssl s_client -starttls smtp -connect $domain:$port "
+           . '< /dev/null 2>/dev/null';
+  }
+  else {
+    #$port           = $check_tlsa->opts->port;
+    $cert   = "openssl s_client -connect $domain:$port "
+            . '< /dev/null 2>/dev/null';
+  }
+
+  my $digquery        = "dig TLSA _$port._$protocol.$domain +short";
+  my $diganswer       = qx($digquery);
+  my $dig             = substr($diganswer, 6, );
+     $dig             =~ s/(\S*)\s+(\S*)$/$1$2/;
+  my $tlsa_usage      = substr($diganswer, 0, 1);
+  my $tlsa_selector   = substr($diganswer, 2, 1);
+  my $tlsa_match_type = substr($diganswer, 4, 1);
+  my $hashit;
+
+  for ($tlsa_match_type) {
+    when('0') { die 'certs will be compared directly'}
+    when('1') {$hashit = 'sha256'}
+    when('2') {$hashit = 'sha512'}
+    default {$hashit = 'sha256'}
+  };
+
+  my $gentlsa     = 'openssl x509  -pubkey | '
+                  . 'openssl rsa -pubin -inform PEM -outform DER 2>/dev/null| '
+                  . "openssl $hashit";
+  my $certtlsa    = "$cert | $gentlsa";
+
+  $check_date  = 'openssl x509 -noout -startdate -enddate';
+  $check_date  = "$cert|$check_date";
+
+
+  my $return;
+
+  my $tlsa_record = qx($certtlsa) or die "nothing found!\n";
+  $tlsa_record =~ s/^.*= (.*$)/$1/gi;
+  $tlsa_record = uc($tlsa_record);
+
+   if (defined $expiry) {
+     print check_cert_expiry();
+   }
+
+  if ("$tlsa_record" eq "$dig") {
+    #$return = "TLSA record is $tlsa_record and valid";
+    #funktioniert nich nicht optimal mit  hostliste
+   $return = $check_tlsa->plugin_exit(OK, "$domain: TLSA record is valid")
+   . "$domain: TLSA record is valid\n";
+  }
+  else {
+    $check_tlsa->plugin_exit(CRITICAL, "$domain: TLSA record NOT valid");
+  }
+  return $return;
+  #return $cert;
+}
+
+
+
+sub get_domains {
+  open(my $filehandle, '<', $domainlist);
+
+  my $pattern = '^(?<domain>\S*\.[a-z]{2,4}?):{0,1}(?<port>[0-9]*$)';
+  my %domain2check;
+  while(<$filehandle>) {
+    if (/$pattern/ig) {
+      $domain = $+{domain};
+      $port   = $+{port};
+      #print "nunu,file ok",LF,"port: $+{port}",LF,"domain: $+{domain}",LF;
+      $domain2check{$domain} = $port;
+
+
+
+
+
+      #print check_tlsa();
+    }
+    else {
+       die "wrong content";
+     }
+
+      foreach my $key (%domain2check)
+      {
+        $domain = $key;
+        $port = $domain2check{$key};
+        print $domain, ' ', $port,"\n";
+
+
+        if ( "$port" =~ /^\s*$/) { $port = '443'; }
+        print $domain, ' ', $port,"\n";
+
+           check_tlsa($domain,$port);
+      }
+
+  }
+}
+
+sub check_cert_expiry {
+  my $return = qx($check_date);
+  return $return;
+}
+