on 10-Mar-2015 11:52
Problem this snippet solves:
This script creates a text report detailing all invalid or soon to expire certificates in /config/ssl/ssl.crt/ using openssl to write out the certificate attributes.
Code :
cli script certificatereport.tcl { proc script::run {} { # Iterate through certs in files set hostname [exec {/bin/hostname}] set reportdate [exec {/bin/date}] puts "---------------------------------------------------------------------" puts "Certificate report for BIG-IP $hostname " puts "Report Date: $reportdate" puts "---------------------------------------------------------------------" puts "\n\n" set certcount 0 set certproblems 0 set certwarnings 0 foreach file [glob -directory /config/ssl/ssl.crt/ *.crt] { incr certcount # Get Certificate Subject set cn [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-subject" "|" "grep" "subject"] "=" ] end] set start [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-startdate" "|" "grep" "Before"] '='] 1] set stop [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-enddate" "|" "grep" "After"] '='] 1] # Clean up bad X509 date fields removing multiple spaces before tokenizing them regsub -all -- {[[:space:]]+} $start " " start regsub -all -- {[[:space:]]+} $stop " " stop set startparts [split $start] set stopparts [split $stop] set activatedseconds [expr {[clock scan "[lindex $startparts 0] [lindex $startparts 1], [lindex $startparts 3]"] - [clock seconds]}] set expiredseconds [expr {[clock seconds] - [clock scan "[lindex $stopparts 0] [lindex $stopparts 1], [lindex $stopparts 3]"]}] # Date Math if { $activatedseconds > 0 } { puts "File: $file" puts "\tCN: $cn certificate" puts "\tError: certificate is not valid yet. It will be valid on $start." puts "\tActivates in: [expr {$activatedseconds / 86400}] days." puts "---------------------------------------------------------------------" incr certproblems } elseif { $expiredseconds > 0 } { puts "File: $file" puts "\tCN: $cn certificate" puts "\tError: is not valid because it expired on $stop." puts "\tExpired: [expr {$expiredseconds / 86400}] days ago." puts "---------------------------------------------------------------------" incr certproblems } elseif { [expr {$expiredseconds * -1}] < 2629743 } { # All certs that will expire within this month puts "File: $file" puts "\tCN: $cn certificate" puts "\tError: is not valid because it expired on $stop." puts "\tWill Expired in: [expr {$expiredseconds / -86400}] days." puts "---------------------------------------------------------------------" incr certwarnings } } puts "\n" puts "$certcount Certificates Found" puts "$certproblems Certificate Errors Found" puts "$certwarnings Certificate Warnings Found" } }
I am getting the below error for v11.x version. The cert path had been changed to certificate_d/
certificatereport.tcl: script failed to complete:
can't eval proc: "script::run"
unable to convert date-time string "Jul , 16:06:24"
while executing
"clock scan "[lindex $startparts 0] [lindex $startparts 1], [lindex $startparts 3]""
(procedure "script::run" line 23)
invoked from within
"script::run" line:1
script did not successfully complete, status:1
I updated the script to:
1 - Enclose all 'exec' command statements in curly braces. 2 - Resolve the formatting of the regsub commands:
FROM:
regsub -all -- {[['''space''']]+} $start " " start
regsub -all -- {[['''space''']]+} $stop " " stop
TO:
regsub -all -- {[[:space:]]+} $start " " start
regsub -all -- {[[:space:]]+} $stop " " stop
I suspect this occurred during a DevCentral update at some point, so hope this is still helpful.
NOTE: There is a built-in command for this as well:
tmsh run sys crypto check-cert { log enabled stdout enabled verbose enabled }
For help on the command:
tmsh help sys crypto check-cert
Works like charm now. Thank you. I had to remove the total-signing-status not-all-signed from the script to make it work. It was throwing with errors.
Syntax Error: "total-signing-status" read-only property
But its weird it got auto added post I saved.
:Active:In Sync] tmsh list cli script certificatereport.tcl
cli script certificatereport.tcl {
proc script::run {} {
Iterate through certs in files
set hostname [exec {/bin/hostname}]
set reportdate [exec {/bin/date}]
puts "---------------------------------------------------------------------"
puts "Certificate report for BIG-IP $hostname "
puts "Report Date: $reportdate"
puts "---------------------------------------------------------------------"
puts "\n\n"
set certcount 0
set certproblems 0
set certwarnings 0
foreach file [glob -directory /config/filestore/files_d/Common_d/certificate_d/ *.crt_*] {
incr certcount
Get Certificate Subject
set cn [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-subject" "|" "grep" "subject"] "=" ] end]
set start [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-startdate" "|" "grep" "Before"] '='] 1]
set stop [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-enddate" "|" "grep" "After"] '='] 1]
Clean up bad X509 date fields removing multiple spaces before tokenizing them
regsub -all -- {[[:space:]]+} $start " " start
regsub -all -- {[[:space:]]+} $stop " " stop
set startparts [split $start]
set stopparts [split $stop]
set activatedseconds [expr {[clock scan "[lindex $startparts 0] [lindex $startparts 1], [lindex $startparts 3]"] - [clock seconds]}]
set expiredseconds [expr {[clock seconds] - [clock scan "[lindex $stopparts 0] [lindex $stopparts 1], [lindex $stopparts 3]"]}]
Date Math
if { $activatedseconds > 0 } {
puts "File: $file"
puts "\tCN: $cn certificate"
puts "\tError: certificate is not valid yet. It will be valid on $start."
puts "\tActivates in: [expr {$activatedseconds / 86400}] days."
puts "---------------------------------------------------------------------"
incr certproblems
} elseif { $expiredseconds > 0 } {
puts "File: $file"
puts "\tCN: $cn certificate"
puts "\tError: is not valid because it expired on $stop."
puts "\tExpired: [expr {$expiredseconds / 86400}] days ago."
puts "---------------------------------------------------------------------"
incr certproblems
} elseif { [expr {$expiredseconds * -1}] < 2629743 } {
All certs that will expire within this month
puts "File: $file"
puts "\tCN: $cn certificate"
puts "\tError: is not valid because it expired on $stop."
puts "\tWill Expired in: [expr {$expiredseconds / -86400}] days."
puts "---------------------------------------------------------------------"
incr certwarnings
}
}
puts "\n"
puts "$certcount Certificates Found"
puts "$certproblems Certificate Errors Found"
puts "$certwarnings Certificate Warnings Found"
}
total-signing-status not-all-signed
}
Hi Jaikumar,
I am getting an error while creating tcl file.
Error: Syntax Error: "total-signing-status" is a read-only property
Shall i too remove that line from script which you said.
can you please explain why we need to remove it
Thanks
Hi Janson,
I have create cli script tcl file and pasted the shared above scrip.
i am new in this, can you please help me in finding the output.
/var/log/ltm ? is this path where i can see the expire SSL certificates or else?
Thanks
Mohammed
Can you check the folder where
certificatereport.tcl
has created(Just guessing) Or grep the cert name in /config file
Ex: grep certa* .
No , i am not getting the output in log file.
/var/log
cat ltm | grep certa*
No Logs
Hi Mohammed,
This is a cli script, when you execute the above shared script, it will not save the output in the /var/log/ path. The output will be in console itself.
:Active:In Sync] ~ tmsh run cli script certificatereport.tcl
---------------------------------------------------------------------
Certificate report for BIG-IP hostname.company.com
Report Date: Tue Nov 6 15:16:32 GMT 2018
---------------------------------------------------------------------
File: /config/filestore/files_d/Common_d/certificate_d/:Common:application_name.crt
CN: abc.com certificate
Error: is not valid because it expired on Oct 3 13:30:09 2018 GMT.
Expired: 10 days ago.
---------------------------------------------------------------------
If you require the output to be saved in the /var/ path, it requires modification. I will explain step-by-step of this existing sript, It will look something like below,
Please follow the below steps to create the script,
1st step is to create cli script, inside the tmsh, run the create cli script command,
(Active)(/Common)(tmos) create cli script certificatereport.tcl
Once you hit enter, you'll see something like below - these are default 4 procedures,
create script certificatereport.tcl {
proc script::init {} {
}
proc script::run {} {
}
proc script::help {} {
}
proc script::tabc {} {
}
}
Since we have the script already, just delete all the lines, once you delete, it will be something like below,
create script certificatereport.tcl {
}
Now paste the code, so the final script will look something like below,
create script certificatereport.tcl {
proc script::run {} {
Iterate through certs in files
set hostname [exec {/bin/hostname}]
set reportdate [exec {/bin/date}]
puts "---------------------------------------------------------------------"
puts "Certificate report for BIG-IP $hostname "
puts "Report Date: $reportdate"
puts "---------------------------------------------------------------------"
puts "\n\n"
set certcount 0
set certproblems 0
set certwarnings 0
foreach file [glob -directory /config/filestore/files_d/Common_d/certificate_d/ *.crt_*] {
incr certcount
Get Certificate Subject
set cn [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-subject" "|" "grep" "subject"] "=" ] end]
set start [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-startdate" "|" "grep" "Before"] '='] 1]
set stop [lindex [split [exec "/usr/bin/openssl" "x509" "-in" $file "-enddate" "|" "grep" "After"] '='] 1]
Clean up bad X509 date fields removing multiple spaces before tokenizing them
regsub -all -- {[[:space:]]+} $start " " start
regsub -all -- {[[:space:]]+} $stop " " stop
set startparts [split $start]
set stopparts [split $stop]
set activatedseconds [expr {[clock scan "[lindex $startparts 0] [lindex $startparts 1], [lindex $startparts 3]"] - [clock seconds]}]
set expiredseconds [expr {[clock seconds] - [clock scan "[lindex $stopparts 0] [lindex $stopparts 1], [lindex $stopparts 3]"]}]
Date Math
if { $activatedseconds > 0 } {
puts "File: $file"
puts "\tCN: $cn certificate"
puts "\tError: certificate is not valid yet. It will be valid on $start."
puts "\tActivates in: [expr {$activatedseconds / 86400}] days."
puts "---------------------------------------------------------------------"
incr certproblems
} elseif { $expiredseconds > 0 } {
puts "File: $file"
puts "\tCN: $cn certificate"
puts "\tError: is not valid because it expired on $stop."
puts "\tExpired: [expr {$expiredseconds / 86400}] days ago."
puts "---------------------------------------------------------------------"
incr certproblems
} elseif { [expr {$expiredseconds * -1}] < 2629743 } {
All certs that will expire within this month
puts "File: $file"
puts "\tCN: $cn certificate"
puts "\tError: is not valid because it expired on $stop."
puts "\tWill Expired in: [expr {$expiredseconds / -86400}] days."
puts "---------------------------------------------------------------------"
incr certwarnings
}
}
puts "\n"
puts "$certcount Certificates Found"
puts "$certproblems Certificate Errors Found"
puts "$certwarnings Certificate Warnings Found"
}
}
Press esc, save and quit.
Finally run your script,
:Active:In Sync] ~ tmsh run cli script certificatereport.tcl
---------------------------------------------------------------------
Certificate report for BIG-IP hostname.company.com
Report Date: Tue Nov 6 15:16:32 GMT 2018
---------------------------------------------------------------------
File: /config/filestore/files_d/Common_d/certificate_d/:Common:application_name.crt
CN: abc.com certificate
Error: is not valid because it expired on Oct 3 13:30:09 2018 GMT.
Expired: 10 days ago.
---------------------------------------------------------------------
To get your output in a file, you can try this, this is easy way to do rather than modifying the script.
Active:In Sync] ~ > /var/tmp/cert-output.txt
Active:In Sync] ~ tmsh run cli script certificatereport.tcl > /var/tmp/cert-output.txt
Hi Jaikumar,
Thanks for the detail steps. I followed the step by step. i have run script but i don't found any of "will expire" or "Expired on"
(tmos) run cli script certificatereport.tcl
Certificate report for BIG-IP BIG-IP_A_v12.com
Report Date: Wed Nov 7 21:17:40 IST 2018
3 Certificates Found
0 Certificate Errors Found
0 Certificate Warnings Found
Can you please help to resolve this!
Hi Mohammed,
Can you pls run the below cmd & list the files,
ls -ltrh config/filestore/files_d/Common_d/certificate_d/*
I believe ur on v12, not sure if the cert location in v12 is different.
Hi Jaikumar,
Please find the below output.
[root@BIG-IP_A_v12:Active:Standalone] config
[root@BIG-IP_A_v12:Active:Standalone] config ls -ltrh config/filestore/files_d/Common_d/certificate_d/*
ls: cannot access config/filestore/files_d/Common_d/certificate_d/*: No such file or directory
Running 12.1.2 Virtual Edition
[root@BIG-IP_A_v12:Active:Standalone] config tmsh show sys version
Sys::Version
Main Package
Product BIG-IP
Version 12.1.2
Build 0.0.249
Edition Final
Date Wed Nov 30 16:04:00 PST 2016
Hi Jaikumar,
I have run the below command to verify the directory! and found three certificates listed below.
[root@BIG-IP_A_v12:Active:Standalone] config cd filestore/files_d/Common_d/certificate_d/
[root@BIG-IP_A_v12:Active:Standalone] certificate_d ls *.crt_*
:Common:ca-bundle.crt_19697_1 :Common:default.crt_19695_1 :Common:f5-irule.crt_19693_1
If I change the directory path as show in starting script i.e. -directory /config/ssl/ssl.crt/ *.crt, then also I don't find the output.
[root@BIG-IP_A_v12:Active:Standalone] config cd /config/ssl/ssl.crt/
[root@BIG-IP_A_v12:Active:Standalone] ssl.crt ls *.crt_*
ls: cannot access *.crt_*: No such file or directory
[root@BIG-IP_A_v12:Active:Standalone] ssl.crt
[root@BIG-IP_A_v12:Active:Standalone] ssl.crt
[root@BIG-IP_A_v12:Active:Standalone] ssl.crt
[root@BIG-IP_A_v12:Active:Standalone] ssl.crt ls
ca-bundle.crt default.crt dtca-bundle.crt dtca.crt dtdi.crt f5-irule.crt
Then the script is working totally fine,
(tmos) run cli script certificatereport.tcl
Certificate report for BIG-IP BIG-IP_A_v12.com
Report Date: Wed Nov 7 21:17:40 IST 2018
3 Certificates Found
Because there's just 3 certs only. Can you run this command as well,
tmsh show sys crypto cert all
Hi Jaikumar,
I got the results!, I have create new expire SSL cert for next 6days, 7days, 8days and 10days. and by default their 3 more ssl cert.
Thanks for support and responding!!!
root@(BIG-IP_A_v12)(cfg-sync Standalone)(Active)(/Common)(tmos) run cli script certificatereport.tcl
---------------------------------------------------------------------
Certificate report for BIG-IP BIG-IP_A_v12.com
Report Date: Fri Nov 9 23:51:57 IST 2018
---------------------------------------------------------------------
File: /config/filestore/files_d/Common_d/certificate_d/:Common:Test_10days.com.crt_39448_1
CN: Test_10days.com certificate
Error: is not valid because it expired on Nov 19 09:52:09 2018 GMT.
Will Expired in: 9 days.
---------------------------------------------------------------------
File: /config/filestore/files_d/Common_d/certificate_d/:Common:Test_8days.com.crt_39442_1
CN: Test_8days.com certificate
Error: is not valid because it expired on Nov 17 09:51:48 2018 GMT.
Will Expired in: 7 days.
---------------------------------------------------------------------
File: /config/filestore/files_d/Common_d/certificate_d/:Common:Test_6days.com.crt_39416_1
CN: Test_6days.com certificate
Error: is not valid because it expired on Nov 15 09:50:07 2018 GMT.
Will Expired in: 5 days.
---------------------------------------------------------------------
File: /config/filestore/files_d/Common_d/certificate_d/:Common:Test_7days.com.crt_39436_1
CN: Test_7days.com certificate
Error: is not valid because it expired on Nov 16 09:51:28 2018 GMT.
Will Expired in: 6 days.
---------------------------------------------------------------------
7 Certificates Found
0 Certificate Errors Found
4 Certificate Warnings Found
One question still remains same, as i was looking for SSL Cert Expire within 7days or less than.
As you can see in output, i am getting all the SSL Cert Expire i.e. 6, 7, 8, 10 Days, respectively.
My expecting result is 6 and 7 days SSL Cert should be appear.
Hi Jaikumar,
How to have this script run automatically every month and get the details through an email?
Regards, Sumit
Hi Jaikumar,
How to have this script run automatically every month and get the details through an email?
Earlier Jason Adams mentioned to convert this script to icall script to achieve this but now i am not able to find his comment here.
Could you please help.
Regards,
Sumit D
Hi Sumit,
First you'll need to have the smtp configuration set on your bigip. You can follow this below link - https://support.f5.com/csp/article/K13180
Once that is set up, try testing a mail. If you receive the test mail, your smtp is configured properly.
I personally use a remote server as a jump server and run the script in multiple bigip's. In this way I need not configure multiple machines. And the output I get is locally saved on the remote machine itself. On the remote machine, I use sendmail or mail to simply send the output as attachment. As this remote server is already configured with smtp configuration.
Hi Jaikumar,
Thanks for the update. I am able to configure smtp on BIG IP LTM and i am able to receive the email as well. Now My second requirement is to execute this script every month and that too automatically and get the output on my email. Could you please help me to achieve this.
Regards,
Sumit D
In addition to above comment-
I am able to save the output to /var/tmp/cert-output.txt
But i need to execute the script automatically every month and get the report through an email. How can we achieve this?
Hi All,
I need help to configure cron job to run below two commands on hourly basis. Could you please help me with the steps:
tmsh run cli script certificatereports.tcl > /var/tmp/cert-outputs.txt
echo "Message Body Here" | mailx -s "Subject Here" -a cert-outputs.txt name@domain.com
Hi Sumit,
Apologies on the late reply, Good to know that you already have smtp set.
The next easy step is to put a small script with any mail agent (sendmail or mail or mailx) and have that script run on cron for every month.
Goto /var/tmp/ and create a file as automatecertificatereports.sh.
Add the below code inside the automatecertificatereports.sh file.
#!/bin/sh
tmsh run cli script certificatereports.tcl > /var/tmp/cert-outputs.txt
from="abc@domain.com"
to="abc@domain.com,pqr@domain.com,xyz@domain.com"
subject="Automated SSL Certificate Report"
mail -s "$subject" -r "$from" -a "/var/tmp/cert-outputs.txt" "$to" << EOF
Hi Team,
Please find the attached SSL Certificate Report.
Thanks & Regards,
abc@domain.com
EOF
Change the permission to executable one.
chmod +x automatecertificatereports.sh
Now goto your crontab & do a list first to see the existing cron jobs running.
crontab -l
You should see some couple of disk monitors check etc etc.
Always put some good comments before you make an entry of your cronjob, Use crontab -e to edit/add your entries.
crontab -e
Goto the of the section and the below 2 lines,
## Section for Automated SSL Certificate Report - Monthly Cron - Start of month - 6 O'clk ##
0 6 1 * * /usr/bin/bash /var/tmp/automatecertificatereports.sh
You can edit this cron value according to your need. For testing, try running this for every day 1 AM report - 0 1 * * *
Hope this helps. Let us know if you have more concerns.