Bash script to check SSL certificate expiry

This script iterates through my list of targets, checks the certificate expiry and prints the details.

Bash script to check SSL certificate expiry
Photo by Nathan Dumlao / Unsplash

I recently had to update certificates across 40 services. The rollout was handled by tools like Terraform and Ansible, but I wanted a quick script to validate that the new certificate is being used.

This openssl command allows us to fetch the certificate and print its expiry details

> openssl s_client -connect some-https-address.com:443 2>/dev/null | openssl x509 -noout -dates 2>/dev/null

notBefore=Feb 15 07:00:15 2023 GMT
notAfter=Feb 10 04:34:00 2024 GMT

The benefit of this over curl -vI is that it works against services that aren't https such as RabbitMQ, and Redis.

This script iterates through my list of hostname:port combinations, checks the certificate expiry and prints the details.

#!/bin/bash

# List the hostname and port of SSL certificates to check
targets=(
    some-https-address.com:443
    some-rabbitmq-address.com:5671
    some-redis-address.com:6379
)

# Set which year you're looking for
# In this scenario I'm checking that my new certificate has been applied
# previous cert expires 2023, new cert expired 2024
desired_year="2024"

# Colors for output
green="\e[32m"
red="\e[31m"
yellow="\e[33m"
restore_color="\e[0m"

for target in ${targets[@]}; do
    result=$(echo | openssl s_client -connect $target 2>/dev/null | openssl x509 -noout -dates 2>/dev/null)
    if [ $? -eq 0 ]; then
        not_after=$(echo $result | awk -F' ' '{print $9}')
        if [ $? -eq 0  ]; then
            (echo "$not_after" | grep "$desired_year") 1>/dev/null
            if [ $? -eq 0 ]; then
                echo -e "$green$target,$not_after$restore_color"
            else
                echo -e "$yellow$target,$not_after$restore_color"
            fi
        else
            echo -e "$red$target,notAfter string not found$restore_color"
        fi
    else
        echo -e "$red$target,failed to connect$restore_color"
    fi

done

Green for good, Yellow for 'not updated', and Red for some error such as incorrect port number.

example output