Easily check SSL certificates on websites

Here is a simple script to quickly get an overview of the SSL certificates used on various websites, e.g. to check expiration or issuer. For me, this helped a lot while migrating website certificates to Let’s Encrypt.

The script is loosely based on "Zext ssl cert.sh" ( see https://www.zabbix.org/wiki/Docs/howto/ssl_certificate_check) but slightly rewritten for the purpose of bulk checking and listing more deails of certificates. The openssl command is required for the script to work properly.

After you have downloaded the script, simply edit the domains at the top of the file to match your websites. DOMAINS is an array which is to be filled with strings in the format:

domain port [protocol]

Domain and port should be self-explanatory, for simple website SSL checks use port 443 (aka https). You can also check SMTP or IMAP servers, then use smtp resp. imap as protocol and 25 resp. 143 for port. If you specify the protocol option, openssl will use STARTTLS for the connection attempt.

ssl_website_check.sh in action

Save the following code to ssl_website_check.sh or download the script:

#!/bin/bash

DOMAINS=(
'plusserver.com 443'
'amazon.com 443'
'facebook.com 443'
'twitter.com 443'
'google.de 443'
'google.com 443'
'gmail.com 443'
'gmail-smtp-in.l.google.com. 25 smtp'
)

function check_ssl_cert()
{
    host=$1
    port=$2
    proto=$3

    if [ -n "$proto" ]
    then
        starttls="-starttls $proto"
    else
        starttls=""
    fi

    cert=`openssl s_client -servername $host -host $host -port $port -showcerts $starttls -prexit </dev/null 2>/dev/null |
              sed -n '/BEGIN CERTIFICATE/,/END CERT/p' |
              openssl x509 -text 2>/dev/null`
    end_date=`echo "$cert" | sed -n 's/ *Not After : *//p'`

    end_date_seconds=`date '+%s' --date "$end_date"`
    now_seconds=`date '+%s'`
    end_date=$(echo "($end_date_seconds-$now_seconds)/24/3600" | bc)

    issue_dn=`echo "$cert" | sed -n 's/ *Issuer: *//p'`
    issuer=`echo $issue_dn | sed -n 's/.*CN=*//p'`

    serial=`echo "$cert" | openssl x509 -serial -noout`
    serial=`echo $serial | sed -n 's/.*serial=*//p'`

    printf "| %30s | %5s | %-13s | %-40s | %-50s |\n" "$host" "$port" "$end_date" "$serial" "${issuer:0:50}"
}


printf "%s\n" "/--------------------------------------------------------------------------------------------------------------------------------------------------------\\"
printf "| %30s | %5s | %-13s | %-40s | %-50s |\n" "Domain" "Port" "Expire (days)" "Serial" "Issuer"
printf "%s\n" "|--------------------------------|-------|---------------|------------------------------------------|----------------------------------------------------|"
for domain in "${DOMAINS[@]}"; do
    check_ssl_cert $domain
done
printf "%s\n" "\\--------------------------------------------------------------------------------------------------------------------------------------------------------/"

Comments

  • Gravatar for karelkarel 1 year ago

    ./ssl_website_check.sh: line x: bc: command not found
    Solved it with yum install bc.

    Is it possible to only show domains which cert expires with in a week?
    This way I get a smaller list and can keep an eye one the about to expiring ones.

    Regards Karel.

    Link / Reply
  • Gravatar for karelkarel 1 year ago

    It took some trial and error but I managed to show only expiring certs with in the next 7 days.:)

    if [ "$end_date" -le 7 ]
    then
    printf "| %30s | %5s | %-13s | %-40s | %-50s |\n" "$host" "$port" "$end_date" "$serial" "${issuer:0:50}"
    fi

    Link / Reply
Write a new Comment