check_tlsa
changeset 3 10ee65f99a7d
parent 2 523934592a76
child 4 6b7f69be290a
equal deleted inserted replaced
2:523934592a76 3:10ee65f99a7d
    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