with build
authorpesch
Thu, 26 May 2016 12:27:22 +0200
changeset 8 ebb775c59021
parent 7 a2ce47570096
child 9 2041bac74e8d
with build
Build.PL
bin/check_tlsa-record
check_tlsa
hostlist.txt
lib/Nagios/Check/DNS/check_tlsa_record.pm
t/check_tlsa_record.t
t/hostlist.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Build.PL	Thu May 26 12:27:22 2016 +0200
@@ -0,0 +1,43 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use Module::Build;
+
+my $build = Module::Build->new(
+  module_name       => 'Nagios::Check::DNS::check_tlsa_record',
+  license           => 'perl',
+  dist_name         => 'nagios-plugin-tlsa-record',
+  dist_author       => 'Heike Yvonne Pesch <pesch@schlittermann.de>',
+  dist_abstract     => 'short description',
+  dist_version_from => 'lib/Nagios/Check/DNS/check_tlsa_record.pm',
+  build_requires    => {
+    'Module::Build'       => '0.4',
+  },
+  requires    => {
+    'Test::More'          => '0.10',
+    'Monitoring::Plugin'  => '0.39',
+  },
+  checks_files    => {
+    'bin/check_tlsa-record' => 'nagios/plugins/ius/check_tlsa_record',
+  },
+  bin_scripts     => [glob 'bin/*'],
+
+
+);
+
+if (not defined $build->install_path('nagios')) {
+  my $base = do {
+    if    ($build->installdirs eq 'vendor') { '/usr/lib' }
+    elsif (defined $build->install_base)    { $build->install_base }
+    else                                    { '/usr/local/lib' }
+  };
+  $build->install_path(nagios => "$base/nagios");
+}
+
+$build->bindoc_dirs([@{ $build->bindoc_dirs }, 'blib/nagios/plugins/ius']);
+$build->add_build_element('checks');
+
+$build->create_build_script();
+
+# vim: ft=perl ts=2 sw=2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/check_tlsa-record	Thu May 26 12:27:22 2016 +0200
@@ -0,0 +1,158 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use feature qw(say);
+use Nagios::Check::DNS::check_tlsa_record;
+use File::Basename;
+use Monitoring::Plugin;
+
+my $ME      = basename $0;
+my $blurb   = 'This Plugin is intendet to check validity of TLSA Record';
+my $url     = 'http://www.schlittermann.de';
+my $author  = 'Heike Yvonne Pesch';
+my $email   = '<pesch@schlittermann.de>';
+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 $extra   = <<_;
+
+NOTICE
+If you want to use a Hostlist, you have to put entrys like this:
+
+host
+host:port
+
+
+EXAMPLES
+$ME -H ssl.schlittermann.de 
+$ME -H hh.schlittermann.de -p25
+$ME -H hh.schlittermann.de:25
+$ME -f hostlist.txt
+
+Author: $author $email
+For more information visit $url
+_
+
+
+my $nagios_tlsa  = Monitoring::Plugin->new(
+  usage   => $usage,
+  blurb   => $blurb,
+  extra   => $extra,
+  url     => $url,
+  plugin  => $ME,
+  timeout => 120,
+
+);
+$nagios_tlsa->add_arg(
+  spec     => 'host|H=s',
+  help     => q|Host/Domain to check|,
+  required => 0,
+);
+
+$nagios_tlsa->add_arg(
+  spec     => 'hostlist|f=s',
+  help     => q|Host/Domainlist in file to check|,
+  required => 0,
+);
+
+$nagios_tlsa->add_arg(
+  spec     => 'expiry|e',
+  help     => q|check expiry of Certificate|,
+  required => 0,
+);
+
+$nagios_tlsa->add_arg(
+  spec     => 'port|p=i',
+  help     => q|Port of Domain to check the TLSA (default: 443)|,
+  required => 0,
+  default  => 443,
+);
+
+$nagios_tlsa->add_arg(
+  spec     => 'queryserver|q=s',
+  required => 0,
+  help     =>
+  q|DNS Server to ask to check the TLSA (default: defined in resolve.conf)|,
+
+);
+
+$nagios_tlsa->add_arg(
+  spec     => 'protocol|P=s',
+  help     => q|Protocol to ask to check the TLSA record of domain (default: tcp)|,
+  required => 0,
+  default  => 'tcp',
+);
+
+$nagios_tlsa->getopts;
+
+my $domain     = $nagios_tlsa->opts->host;
+my $port       = $nagios_tlsa->opts->port;
+my $protocol   = $nagios_tlsa->opts->protocol;
+my $domainlist = $nagios_tlsa->opts->hostlist;
+my $expiry     = $nagios_tlsa->opts->expiry;
+my $pattern    = '^(?<domain>\S*\.[a-z]{2,4}?):{0,1}(?<port>[0-9]*$)';
+
+
+if (!$domain && !$domainlist) {
+    my $script = basename $0;
+    my $excuse = "Please set -H <domain> or -f <domainlist>\n"
+    . "For all options try $script --help";
+
+    say $excuse;
+    exit 1;
+}
+
+if ($domainlist)
+{
+  get_domains();
+  exit 0;
+}
+
+if ($domain)
+{
+
+  my $pattern    = '^(?<domain>\S*\.[a-z]{2,4}?):{1}(?<port>[0-9]+$)';
+  if ($domain =~ /$pattern/gi)
+  {
+    $domain = $+{domain};
+    $port   = $+{port};
+  }
+
+  if (!$port || $port eq '')
+  {
+    $port = 443;
+  }
+
+  if (!$protocol || $protocol ne 'tcp' || $protocol ne 'udp')
+  {
+    $protocol = 'tcp';
+  }
+
+  my $return = Nagios::Check::DNS::check_tlsa_record::main(($domain, $port, $protocol));
+  say $return;
+}
+
+sub get_domains {
+    open(my $filehandle, '<', $domainlist);
+
+    while (<$filehandle>) {
+        if (/$pattern/ig) {
+            $domain = $+{domain};
+
+            if ("$+{port}" =~ /^\s*$/) { $port = '443'; }
+            else { $port   = $+{port}; }
+
+            my $return = Nagios::Check::DNS::check_tlsa_record::main(($domain, $port));
+            say $return;
+        }
+        else {
+            die "$domainlist has wrong or malformed content\n";
+        }
+
+    }
+}
+
+# vim: ft=perl ts=2 sw=2
--- a/check_tlsa	Wed May 11 23:41:32 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-#! /usr/bin/perl
-
-use strict;
-use warnings;
-use feature qw(switch say);
-use if $^V >= v5.020 => (experimental => qw(smartmatch));
-use experimental qw(smartmatch);
-use Monitoring::Plugin;
-use File::Basename;
-
-
-my $ME      = basename $0;
-my $VERSION = '0.1';
-my $blurb   = 'This Plugin is intendet to check validity of TLSA Record';
-my $url     = 'http://www.schlittermann.de';
-my $author  = 'Heike Yvonne Pesch';
-my $email   = '<pesch@schlittermann.de>';
-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 $extra   = <<_;
-
-NOTICE
-If you want to use a Hostlist, you have to put entrys like this:
-
-host
-host:port
-
-
-EXAMPLES
-$ME -H ssl.schlittermann.de 
-$ME -H hh.schlittermann.de -p25
-$ME -H hh.schlittermann.de:25
-$ME -f hostlist.txt
-
-Author: $author $email
-For more information visit $url
-_
-
-my $check_tlsa = Monitoring::Plugin->new(
-  usage   => $usage,
-  version => $VERSION,
-  blurb   => $blurb,
-  extra   => $extra,
-  url     => $url,
-  plugin  => $ME,
-  timeout => 120,
-);
-
-$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',
-  required => 0,
-  help     =>
-  q|DNS Server to ask to check the TLSA (default: defined in resolve.conf)|,
-
-);
-
-$check_tlsa->add_arg(
-  spec     => 'protocol|P=s',
-  help     => q|Protocol to ask to check the TLSA record of domain (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";
-
-    say $excuse;
-    exit 1;
-}
-
-my $port;
-my $cert;
-my $check_date;
-my $pattern = '^(?<domain>\S*\.[a-z]{2,4}?):{0,1}(?<port>[0-9]*$)';
-
-# @TODO find better way
-# nearly the same check is defined in get_domains
-if ( defined $domain && $domain =~ /$pattern/) {
-  $domain = $+{domain};
-  $port   = $+{port};
-}
-
-if ( defined $domainlist && $domainlist ne '' && -e $domainlist) {
-    say get_domains();
-}
-else { say 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 {
-        $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 $tlsa_usage      = substr($diganswer, 0, 1);
-    my $tlsa_selector   = substr($diganswer, 2, 1);
-    my $tlsa_match_type = substr($diganswer, 4, 1);
-    my $dig_tlsa        = substr($diganswer, 6,);
-    my $valid_date      = '';
-    my $hashit;
-
-    $dig_tlsa =~ s/(\S*)\s+(\S*)$/$1$2/;
-
-    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) {
-        $valid_date = check_cert_expiry();
-    }
-
-    if ($valid_date ne '') {
-      $valid_date = "\n$valid_date";
-    }
-
-    if ("$tlsa_record" eq "$dig_tlsa") {
-
-      #this way the script exit when file is given :(
-      #$return = $check_tlsa->plugin_exit(OK, "$domain: TLSA record is valid")
-      #  . "$domain: TLSA record is valid";
-
-      #this way it's behaves like I want it to
-      $return = "OK, $domain: TLSA record is valid $valid_date";
-    }
-    else {
-      #$check_tlsa->plugin_exit(CRITICAL, "$domain: TLSA record NOT valid");
-      $return = "CRITICAL, $domain: TLSA record is NOT valid";
-    }
-    say $return;
-}
-
-sub get_domains {
-    open(my $filehandle, '<', $domainlist);
-
-    my $pattern = '^(?<domain>\S*\.[a-z]{2,4}?):{0,1}(?<port>[0-9]*$)';
-    while (<$filehandle>) {
-        if (/$pattern/ig) {
-            $domain = $+{domain};
-
-            if ("$+{port}" =~ /^\s*$/) { $port = '443'; }
-            else { $port   = $+{port}; }
-
-            check_tlsa($domain, $port);
-        }
-        else {
-            die "$domainlist has wrong or malformed content\n";
-        }
-
-    }
-}
-
-sub check_cert_expiry {
-    my $return = qx($check_date);
-    return $return;
-}
--- a/hostlist.txt	Wed May 11 23:41:32 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-ssl.schlittermann.de
-hh.schlittermann.de:25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/Nagios/Check/DNS/check_tlsa_record.pm	Thu May 26 12:27:22 2016 +0200
@@ -0,0 +1,142 @@
+use strict;
+use warnings;
+use feature qw(say switch);
+#use if $^V >= v5.0.20 => (experimental => gw(smartmatch));
+use experimental qw(smartmatch);
+package Nagios::Check::DNS::check_tlsa_record;
+
+$Nagios::Check::DNS::check_tlsa_record::VERSION = '0.1';
+
+sub main 
+{
+  my $domain   = shift;
+  my $port     = shift || 443;
+  my $protocol = shift || 'tcp';
+  my $validate = validate_tsla($domain, $port);
+  return "$validate";
+
+}
+
+sub dig_tlsa
+{
+  my $domain     = shift;
+  my $port       = shift;
+  my $protocol   = shift || 'tcp';
+  my $query      = "dig tlsa _$port._$protocol.$domain +short";
+  my $dig_return = qx($query);
+  return $dig_return;
+}
+
+sub get_cert
+{
+  my $domain = shift;
+  my $port   = shift;
+  my $same   = '< /dev/null 2>/dev/null | openssl x509';
+  my $query;
+  my $cert;
+
+  if ("$port" eq '25') {
+    $query = "openssl s_client -starttls smtp -connect $domain:$port $same";
+      
+  }   
+  else {
+    $query = "openssl s_client -connect $domain:$port $same";
+      
+  }
+  $cert = qx($query);
+  return $cert;
+}
+ 
+sub get_tlsa_from_cert
+{
+  my $cert = shift;
+  my $hashit = shift || 'sha256';
+  my $gentlsa = 'openssl x509  -pubkey | '
+    . 'openssl rsa -pubin -inform PEM -outform DER 2>/dev/null| '
+    . "openssl $hashit";
+
+  my $cert_tlsa = "echo \"$cert\" | $gentlsa";
+
+
+  my $tlsa_record = qx($cert_tlsa) or die "nothing found!\n"; 
+  $tlsa_record =~ s/^.*= (.*$)/$1/gi;
+  $tlsa_record = uc($tlsa_record);
+
+  return $tlsa_record;
+}
+
+sub check_expiry
+{
+  my $cert = shift;
+  my $check_date = 'openssl x509 -noout -startdate -enddate';
+  my $check_expiry = "echo \"$cert\"|$check_date";
+  my $expiry = qx($check_expiry);
+  
+  return "$expiry";
+}
+
+sub get_tlsa_match_type
+{
+  my $dig_return = shift;
+  
+  my $tlsa_usage      = substr($dig_return, 0, 1); 
+  my $tlsa_selector   = substr($dig_return, 2, 1); 
+  my $tlsa_match_type = substr($dig_return, 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' }
+  }   
+  return $hashit;
+
+}
+
+sub get_dig_tlsa_record
+{
+  #my $dig_return = shift;
+  my $dig_return = shift;
+  my $dig_tlsa   = substr($dig_return, 6,);
+  $dig_tlsa      =~ s/(\S*)\s+(\S*)$/$1$2/;
+
+  return "$dig_tlsa";
+}
+
+sub get_tlsa_usage
+{
+  my $dig_return      = shift;
+  my $tlsa_usage      = substr($dig_return, 0, 1); 
+
+  return "$tlsa_usage";
+}
+
+sub get_tlsa_selector
+{
+  my $dig_return      = shift;
+  my $tlsa_selector   = substr($dig_return, 2, 1); 
+
+  return "$tlsa_selector";
+}
+
+sub validate_tsla
+{
+  my $domain = shift;
+  my $port   = shift;
+  #my $dig_return = shift;
+  my $cert = get_cert($domain, $port);
+  my $dig_return = dig_tlsa($domain, $port);
+  my $dig_tlsa = get_dig_tlsa_record($dig_return);
+  my $cert_tlsa = get_tlsa_from_cert($cert);
+
+  if ("$dig_tlsa" ne "$cert_tlsa")
+  {
+    return "crtical: TLSA Record for $domain is not valid";
+  }
+   return "OK: TLSA Record for $domain is valid";
+}
+
+
+# vim: ft=perl ts=2 sw=2 foldmethod=indent
+1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/t/check_tlsa_record.t	Thu May 26 12:27:22 2016 +0200
@@ -0,0 +1,31 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More qw(no_plan);
+
+BEGIN { use_ok('Nagios::Check::DNS::check_tlsa_record') };
+
+require_ok('Nagios::Check::DNS::check_tlsa_record');
+
+#my $return = Nagios::Check::DNS::check_tlsa_record::main(($domain, $port));
+#say $return;
+
+#my $return = Nagios::Check::DNS::check_tlsa_record::main();
+#say $return;
+
+#my $return5 = Nagios::Check::DNS::check_tlsa_record::main(qw(hh.schlittermann.de 25 tcp));
+#say $return5;
+
+#my $return2 = Nagios::Check::DNS::check_tlsa_record::dig_tlsa(qw(hh.schlittermann.de 25 udp));
+#say $return2;
+#
+#my $return3 = Nagios::Check::DNS::check_tlsa_record::dig_tlsa(qw(hh.schlittermann.de 25));
+#say $return3;
+#
+#my $return4 = Nagios::Check::DNS::check_tlsa_record::dig_tlsa(qw(hh.schlittermann.de));
+#say $return4;
+
+
+
+# vim: ft=perl ts=2 sw=2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/t/hostlist.txt	Thu May 26 12:27:22 2016 +0200
@@ -0,0 +1,2 @@
+ssl.schlittermann.de
+hh.schlittermann.de:25