Wikis - Page

Check Certificate Expiration Perl Script

4 Likes

The script will report if a certificate is expired, if it expires today, or if it will expire within a month.
This only reports the problem certificates in your eDir tree, and if they are all good, then nothing is returned.

 

I use Net::LDAP and Date::Manip in the perl script. The corresponding packages on SLES are:

 

    • perl
    • perl-DateManip
    • perl-ldap



The options needed for the script to run are:

checkcerts.pl LDAP-IP-or-DNS-name Bind-DN Bind-password


Example:

checkcerts.pl 10.20.30.40 cn=admin,o=novell novell


The user that is used for this script only needs to have the following rights:


Entry: Browse, Inherit (for the entire tree)

Attribute: ObjectClass & ndspkinotafter - Read, Compare, Inherit


The easiest way to use this script would be to create a cron job on one server that runs once a week.

An example for the script results to be emailed to idmadmins:

/usr/local/bin/checkcerts.pl 10.20.30.40 cn=admin,o=novell password | mail -s "Certificate Expiration Report for `date -I`" -r certreport@mydomain.com idmadmins@mydomain.com


You would need to create a job for each tree you want to monitor.


The following example would run against the 10.20.30.40 tree at 1:00AM every Saturday:

0 1 * * 6  /usr/local/bin/checkcerts.pl 10.20.30.40 cn=admin,o=novell password | nail -s "Certificate Expiration Report for `date -I`" -r certreport@mydomain.com idmadmins@mydomain.com

 

#!/usr/bin/perl -w
use Net::LDAP;
use POSIX qw(strftime);
use Date::Manip;

$argc = $#ARGV + 1;
if ($argc != 3) { die "checkcerts.pl LDAPURI binduser bindpwd"; }
$ldap = Net::LDAP->new( $ARGV[0]) or die "$@";
$mesg = $ldap->bind( $ARGV[1], password => $ARGV[2] );
$mesg = $ldap->search( base => "", filter => "(objectclass=ndspkikeymaterial)" );
$mesg->code && die $mesg->error;
$currenttime = strftime("%Y%m%d", localtime());
$currtime = &ParseDate($currenttime);
$currtimeplus = &DateCalc($currtime, "1 month");

my @entries = $mesg->entries;
 my $entr;
 foreach $entr ( @entries ) {
   my $attr="ndspkinotafter";
   $certdate = substr($entr-> get_value ( $attr ), 0, 8 );
   $crtdate = &ParseDate($certdate);
   $dateresult = &Date_Cmp($currtime,$crtdate);
   $futuredateresult = &Date_Cmp($currtimeplus,$crtdate);
   if ( $dateresult < 0 ) {
         if ( $futuredateresult < 0 ) {
#             print "The certificate ", $entr->dn, " is valid.\n";
          } else {
             print "The certificate ", $entr->dn, " will expire within a month.\n"
          }
   } elsif ($dateresult==0) {
         print "The certificate ", $entr->dn, " expires today.\n";
   } else {
         print "The certificate ", $entr->dn, " has already expired.\n";
   } 
 }
$mesg = $ldap->unbind;
 

Tags:

Labels:

Collateral
Support Tips/Knowledge Docs
Support Tip
Comment List
  • Those dev channels are already available with OES 2023, just need to be enabled.

    Repository 'OES2023-SLE-Module-DevTools15-SP4-Pool' is up to date.
    Repository 'OES2023-SLE-Module-DevTools15-SP4-Updates' is up to date.

    Then pulling in perl-Date-Manip was easy once found with that extra dash in it from the older versions.

    On first testing, the script appears to work just fine.
    Of course there are no 'about to expire certs' at the moment on this system to really test, but the listcerts.pl variant does output just fine like it does on the older OES boxes.
    crontab updated to run them weekly to avoid surprises :)

    ________________________

    Andy of KonecnyConsulting.ca in Toronto
    Please use the "Like" and/or "Verified Answers" as appropriate as that helps us all.

  • There are many of us who only use eDir through OES, and don't have much if any pure SLES around.  I've successfully run it on OES 11, up to current OES 2018.3  and it has been very useful that way.   Thank you for having created this,  and directions on how to handle this particular change in this next version of SLES (among the so many others to deal with)

    ________________________

    Andy of KonecnyConsulting.ca in Toronto
    Please use the "Like" and/or "Verified Answers" as appropriate as that helps us all.

  • The script was never tested on any version of OES.  It was meant for any version of Linux as long as those perl modules were available.  If you are looking for the perl-DateManip package, with SLES 15 that has moved to the SDK/Development Tools module.  You can download the ISO or subscribe to the (sdk/development tools) channel then get that RPM.

  •   Have you gotten this running on OES2023 yet?   I can't find the perl-DateManip as an option in yast, so is this something I will have to find other than the built-in repo, or is it time to refactor this script for the newer environment?

    ________________________

    Andy of KonecnyConsulting.ca in Toronto
    Please use the "Like" and/or "Verified Answers" as appropriate as that helps us all.

  • ah ha,  I see how "Require TLS for all operations" didn't get turned on for a few key servers,  a good reason for the effort, now to start back tracking why it is off for some of those other systems.

    Not likely surprises either, I've cronned checkcerts.pl for some clients, each once a week on two different OES boxes at different ends of the network to email the results which has been a great headache saver.  that way of one box fails, I still get the other one and its warnings.

    very extendable, and worth exploring for any of us.  this is how I've grown my bash and perl scripting. doesn't make me a real dev, but helps in those day to day things.

    ________________________

    Andy of KonecnyConsulting.ca in Toronto
    Please use the "Like" and/or "Verified Answers" as appropriate as that helps us all.

  • The only additional functionality is that it supports SSL/TLS while the old (original) script does not.  Many companies do not allow clear text bind on ldap so SSL/TLS/StartTLS is required.

    I have used this script as a framework for other processes as well.  If you need to search for date values in LDAP/eDir, it is great to run a query then you can add conditions to report what you are looking for.  In one iteration I used it for reports for help desk manager to know how many password expirations were due in the next week, by day.

    Are there improvements that could be made - sure depending on your use case, but for me at least it helps me avoid unexpected certificate expiration issues (evening and weekend)

  • Hi Robert
    Thank you for updating this
      but what does this additional bit give us for the extra steps?   
    Running it on an OES 18.3 box I see no difference and the old one has been working perfectly (so far).  For now I'm not rolling this out any further than my test without any value for that additional effort and complexity of adding the ca-cert.crt (thought that script has its own value on its own)


    In my touching of many systems over the years I find various mystery scripts when troubleshooting systems others have worked on,  scripts like this with No Docs/comments!  
    So for my instances (and would be a good habit for all reading this) I added after the 1st line something like this.

    # to check|list for expiring certificates in the eDir tree,  usage in crontab
    #   0 7 * * 1 root /software/checkcerts.pl ldaps://192.168.1.10 cn=admin,ou=sa,o=system mypassword ca-cert.cer |mail -s "Certificate Expiration Report for `date -I`" adminuser@domain.com,otheradmin@domain.com
    # by Robert Ridly of NetIQ/MicroFocus, 1st posted 2009-05-12, 2019 update posted 2022-04-15 at
    community.microfocus.com/.../check-certificate-expiration-perl-script


    a one line add gets you to list all your certs so you see how far out the expires are.
     insert ~line25 before the if line
       print "Cert ", $entr->dn, " expires ", $certdate, "\n";

    ________________________

    Andy of KonecnyConsulting.ca in Toronto
    Please use the "Like" and/or "Verified Answers" as appropriate as that helps us all.

  • I am the original author.  Here is an updated version that added SSL/TLS support (I updated it in 2019):

    #!/usr/bin/perl -w
    use Net::LDAP;
    use POSIX qw(strftime);
    use Date::Manip;
    use IO::Socket::SSL;
    
    $argc = $#ARGV + 1;
    if ($argc != 4) { die "checkcerts.pl LDAPURI binduser bindpwd SSLCert"; }
    $ldap = Net::LDAP->new( $ARGV[0], verify => 'require', cafile => $ARGV[3], ) or die "$@";
    $mesg = $ldap->bind( $ARGV[1], password => $ARGV[2] );
    $mesg = $ldap->search( base => "", filter => "(objectclass=ndspkikeymaterial)" );
    $mesg->code && die $mesg->error;
    $currenttime = strftime("%Y%m%d", localtime());
    $currtime = &ParseDate($currenttime);
    $currtimeplus = &DateCalc($currtime, "1 month");
    
    my @entries = $mesg->entries;
     my $entr;
     foreach $entr ( @entries ) {
       my $attr="ndspkinotafter";
       $certdate = substr($entr-> get_value ( $attr ), 0, 8 );
       $crtdate = &ParseDate($certdate);
       $dateresult = &Date_Cmp($currtime,$crtdate);
       $futuredateresult = &Date_Cmp($currtimeplus,$crtdate);
       if ( $dateresult < 0 ) {
             if ( $futuredateresult < 0 ) {
    #             print "The certificate ", $entr->dn, " is valid.\n";
              } else {
                 print "The certificate ", $entr->dn, " will expire within a month.\n"
              }
       } elsif ($dateresult==0) {
             print "The certificate ", $entr->dn, " expires today.\n";
       } else {
             print "The certificate ", $entr->dn, " has already expired.\n";
       } 
     }
    $mesg = $ldap->unbind;
    
    

    The script now also requires perl module IO::Socket::SSL to function.  An example connection URL would be:

    ./checkcerts.pl ldaps://192.168.1.10 cn=admin,ou=sa,o=system mypassword ca-cert.cer

    The certificate needs to be the CA self signed public key/certificate.  Here is another script that uses bash/sed/awk/openssl to pull the certificate from ldap (eDirectory).

    #!/bin/sh
    while getopts h:p:f: flag
    do 
       case "${flag}" in
    	h) HOST_NAME=${OPTARG};;
    	p) PORT=${OPTARG};;
    	f) SERVER_ROOT_CERTIFICATE=${OPTARG};;
       esac
    done
    CERTS=$(echo -n | openssl s_client -connect $HOST_NAME:$PORT -showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p')
    echo "$CERTS" | awk -v RS="-----BEGIN CERTIFICATE-----" 'NR > 1 { printf RS $0 > "'$SERVER_ROOT_CERTIFICATE'"; close("'$SERVER_ROOT_CERTIFICATE'") }'
    openssl x509 -noout -in $SERVER_ROOT_CERTIFICATE -subject -dates

    The syntax for the "export-ca.sh" script is:

    sh export-ca.sh -h 192.168.1.10 -p 636 -f ca-cert.cer

  • The original attachment didn't survived the migration as did the name of the original author, but I happen to have the code and have been using it very successfully and added that code back in here 2021-07-05

    ________________________

    Andy of KonecnyConsulting.ca in Toronto
    Please use the "Like" and/or "Verified Answers" as appropriate as that helps us all.

  • The file downloads without any issues but when trying to extract it I get the following error:

    tar: This does not look like a tar archive
    tar: Skipping to next header
    tar: Exiting with failure status due to previous errors

    The file size is also 744 bytes instead of 721Bytes as stated above.
Related
Recommended