A set of nodes are managed using ssh only (call them "deva", "devb", "devc", "devd"). Each node runs a service that supports certificates, and the certificate expiration date must be checked. Each node can have multiple certificates, and they are all returned by running the shell command "get x509 cert" on the node itself. The command outputs one cert per line, with the following format:

<CERT_NAME> hash<CERT_HASH> exp<DATE:YYYY-MM-DD> <TIME:hh:mm:ss>

Create a script that will ssh to each node and check for certificate expiration. The script should also send e-mail five days before expiration, with node name and certificate details, and another e-mail when cert expires in less than 2 days. Please notice, that it should be easy to add another node to the list. Also, another warning mail should be sent if the node is unavailable. A summary log after the work is done, would be a nice add-on.

#!/usr/bin/perl use Net::SSH::Expect; use Time::localtime; use Date::Parse; use Term::ReadKey; #Days to check validity for my $minimumExpDays = 5; my $minimumExpDays2 = 2; #Email of root my $rootEmail = "root\@localhost"; my $emailMsg = "Expiration of Certificates"; #log file location my $logfile = "/var/log/script-log.txt"; #change it to your desired lo +cation # Define servers array - List as many servers as you want, use the ful +l FQDN or IP address @servers = ("deva, “devb", “devc", “devd"); #Name of the certificates file you want to moinitor. @certfiles = ("cert.pem","cert2.pem", “cert3.pem”, “cert4.pem”); foreach (@servers) { print " $_ \n"; } print "Please enter your username for above systems? \n"; $user = <>; #A sudo user can also be hardcoded for a Cron job. chomp $user; print "\nPlease enter your password for the above systems? \n"; ReadMode 2; #Stop echoing to screen $pass = <>; chomp $pass; ReadMode 0; #Return tty to default; $to="5"; # Loop through the servers array and connect to one server (box) at a +time. foreach $box (@servers) { # Print to screen what server you are connecting to print "Connecting to $box... \n"; $ssh = Net::SSH::Expect->new ( host => "$box", password => "$pass", user => "$user", raw_pty => 1 ); undef $login_output; eval { $login_output = $ssh->login(15); }; # If login output is empty try again while ($login_output eq "") { sleep(2); $login_output = $ssh->login(15); } if ($login_output =~ m/Last login/) { print "Login Successful... \n\n"; } else { print "Login has failed! - Please check your username/password and ca +ps lock. \n\n"; next; } # RUN COMMANDS AS USER print "Running command....\n"; foreach $certfile (@certfiles) { $ssh->send("openssl x509 -in /etc/pki/tls/$certfile -noout -subject - +hash -enddate | awk \'{print \$1, \$2, \$3, \$4, \$5,\$6, \$7}\'"); while ( defined ($output = $ssh->read_line($to)) ) { # Send output of command to output array for printing when script is +complete push (@outputs, "$box: $output"); } }#while loop }#end of foreach certfile my $tmp = 3; foreach(@certfiles){ # print $_ ."\n"; my $enddate = $outputs[$tmp]; my $tmpdate; if($enddate =~ m/notAfter=(.*)/){ $tmpdate = $1; } my $end = str2time($tmpdate); my $daysleft = ($end -time())/86400; print "Days left := $daysleft .\n"; $tmp = $tmp + 4; if(($daysleft < $minimumExpDays2) || ($daysleft < $minimumExpDays)) { $emailMsg = "Your certificates will be expired in " .int($daysleft)." + days\n Please check your log file at $logfile \n"; print $emailMsg; system("echo \"$emailMsg\" | mail -s \"Certificate Expiration Warning +\" $rootEmail"); }#end if }#end offoreach print "\n ********Printing Report******** \n"; #Opening file stream, make sure you have the appropritate permission o +n the file system. open FILE, ">>$logfile" or die $!; foreach (@outputs) { #Printing a summary on console. print $_ . "\n"; #Writing into the log file. print FILE $_ . "\n"; }#end of foreach close FILE; #### END SCRIPT


In reply to RFC - PERL SCRIPT TO SSH MULTIPLE SERVER NODES, CHECKS OF SSL CERTIFICATES EXPIRY AND EMAIL TO ROOT by Zeeshan

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.