Skip to content

Instantly share code, notes, and snippets.

@cgmartin
Created January 17, 2016 18:00
Show Gist options
  • Star 46 You must be signed in to star a gist
  • Fork 22 You must be signed in to fork a gist
  • Save cgmartin/49cd0aefe836932cdc96 to your computer and use it in GitHub Desktop.
Save cgmartin/49cd0aefe836932cdc96 to your computer and use it in GitHub Desktop.
Bash SSL Certificate Expiration Check
#!/bin/bash
TARGET="mysite.example.net";
RECIPIENT="hostmaster@mysite.example.net";
DAYS=7;
echo "checking if $TARGET expires in less than $DAYS days";
expirationdate=$(date -d "$(: | openssl s_client -connect $TARGET:443 -servername $TARGET 2>/dev/null \
| openssl x509 -text \
| grep 'Not After' \
|awk '{print $4,$5,$7}')" '+%s');
in7days=$(($(date +%s) + (86400*$DAYS)));
if [ $in7days -gt $expirationdate ]; then
echo "KO - Certificate for $TARGET expires in less than $DAYS days, on $(date -d @$expirationdate '+%Y-%m-%d')" \
| mail -s "Certificate expiration warning for $TARGET" $RECIPIENT ;
else
echo "OK - Certificate expires on $expirationdate";
fi;
@opthakur
Copy link

opthakur commented Jul 15, 2020

How to add multiple targets ?
@cgmartin

@Clanwarz-zz
Copy link

@opthakur

Place all your domains in a file. Run the script in a loop, giving the loop a domain each time it runs. Maybe something like this:

#!/bin/bash

DOMAINS="/path/to/list/of/domains/list.txt"
RECIPIENT="hostmaster@mysite.example.net"
DAYS="7"

while read -r TARGET; do
  echo "checking if $TARGET expires in less than $DAYS days";
  expirationdate=$(date -d "$(: | openssl s_client -connect "$TARGET":443 -servername "$TARGET" 2>/dev/null \
                                | openssl x509 -text \
                                | grep 'Not After' \
                                |awk '{print $4,$5,$7}')" '+%s');
  in7days=$(($(date +%s) + (86400*DAYS)));
  if [ "$in7days" -gt "$expirationdate" ]; then
      echo "KO - Certificate for $TARGET expires in less than $DAYS days, on $(date -d @"$expirationdate" '+%Y-%m-%d')" \
      | mail -s "Certificate expiration warning for $TARGET" $RECIPIENT ;
  else
      echo "OK - Certificate expires on $expirationdate";
  fi;
done<"${DOMAINS}"

Define your list of domains on line 3. I added some double quotes to his original script.

Cheers

@cliftonwwyeager
Copy link

How would i scan ports 443, 465, and 993, with human readable time format instead of epoch?

@vishnuv1995
Copy link

Hi,

I have getting an issue in the script once we pass the dummy url also the mail is sending with alert, how can we include that condition also in that script .

Eg:
unable to load certificate
140359043876160:error:0909006C:PEM routines:get_name:no start line:../crypto/pem/pem_lib.c:745:Expecting: TRUSTED CERTIFICATE

Once we got the above its should go to else part no need to send mail.

@dahse89
Copy link

dahse89 commented Oct 22, 2021

i recommend to also format the date for the success case

Instead of
echo "OK - Certificate expires on $expirationdate"; # OK - Certificate expires on 1658872800

do this
echo "OK - Certificate expires on $(date -d @$expirationdate '+%Y-%m-%d')"; # OK - Certificate expires on 2022-07-27

@vadirajks
Copy link

vadirajks commented Jun 1, 2022

to fix some glitch's in Ubuntu: expirationdate=$(date -d "$(echo -n | openssl s_client -servername "$TARGET" -connect "$TARGET":"443" 2>&- | openssl x509 -enddate -noout | awk -F= '{print $2}')" +%s)

@Aabhusan
Copy link

i am using this script

#!/bin/bash
TARGET="mysite.example.net";
RECIPIENT="hostmaster@mysite.example.net";
DAYS=7;
echo "checking if $TARGET expires in less than $DAYS days";
expirationdate=$(date -d "$(: | openssl s_client -connect $TARGET:443 -servername $TARGET 2>/dev/null
| openssl x509 -text
| grep 'Not After'
|awk '{print $4,$5,$7}')" '+%s');
in7days=$(($(date +%s) + (86400*$DAYS)));
if [ $in7days -gt $expirationdate ]; then
echo "KO - Certificate for $TARGET expires in less than $DAYS days, on $(date -d @$expirationdate '+%Y-%m-%d')"
| mail -s "Certificate expiration warning for $TARGET" $RECIPIENT ;
else
echo "OK - Certificate expires on $expirationdate";
fi;

i am getting this error:

checking if expires in less than 7 days
date: invalid date 'Jul 4 2023'
./checkssl2.sh: line 11: [: 1658487210: unary operator expected
OK - Certificate expires on

getting invalid date ?
can anyone help me @vadirajks @dahse89 @cgmartin

@vadirajks
Copy link

@Aabhusan : checkout below

#!/bin/bash
TARGET="example.net";
RECIPIENT="hostmaster@mysite.example.net";
DAYS=7;
echo "checking if $TARGET expires in less than $DAYS days";
expirationdate=$(date -d "$(echo -n | openssl s_client -servername "$TARGET" -connect "$TARGET":"443" 2>&- | openssl x509 -enddate -noout | awk -F= '{print $2}')" +%s)
in7days=$(($(date +%s) + (86400*$DAYS)));
if [ $in7days -gt $expirationdate ]; then
echo "KO - Certificate for (date -d @$expirationdate '+%Y-%m-%d')" | mailx -s "Certificate expiration warning for $TARGET" $RECIPIENT ;
else
echo "OK - Certificate expires on $expirationdate";
fi;

@SrikumarM
Copy link

SrikumarM commented Aug 25, 2022

@opthakur

Place all your domains in a file. Run the script in a loop, giving the loop a domain each time it runs. Maybe something like this:

#!/bin/bash

DOMAINS="/path/to/list/of/domains/list.txt"
RECIPIENT="hostmaster@mysite.example.net"
DAYS="7"

while read -r TARGET; do
  echo "checking if $TARGET expires in less than $DAYS days";
  expirationdate=$(date -d "$(: | openssl s_client -connect "$TARGET":443 -servername "$TARGET" 2>/dev/null \
                                | openssl x509 -text \
                                | grep 'Not After' \
                                |awk '{print $4,$5,$7}')" '+%s');
  in7days=$(($(date +%s) + (86400*DAYS)));
  if [ "$in7days" -gt "$expirationdate" ]; then
      echo "KO - Certificate for $TARGET expires in less than $DAYS days, on $(date -d @"$expirationdate" '+%Y-%m-%d')" \
      | mail -s "Certificate expiration warning for $TARGET" $RECIPIENT ;
  else
      echo "OK - Certificate expires on $expirationdate";
  fi;
done<"${DOMAINS}"

Define your list of domains on line 3. I added some double quotes to his original script.

Cheers

Hi,

I'm a new user of Linux can you please explain this "$(: ". the exact usage of this command,

without this line, "while read" exited after the first-line executed

thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment