Linux(Cent OS)でSSL証明書の有効期限をチェックするスクリプト


ApacheなどのWebサーバーやPostfixなどのMTA、iOSのPush Notification(Push通知)の送信などに利用するためのSSL証明書の有効期限をチェックして、期限切れが近くなったらメールを送信して有効期限を通知するためのスクリプトです。
crontabなどから定期的に実行することで証明書の有効期限WARN_DAYS以下で有効期限が残っているうちは1日に1回、有効期限が切れているならcronで実行される度にスクリプト中で指定されたメールアドレスに通知メールを送信します。

check_certificates.sh
#!/bin/bash

. ./sendmail.sh

today=`date '+%s'`
hostname=`hostname`
# SSL証明書の場所 (複数ある場合はスペースで区切って連記)
CERT_FILES="/etc/letsencrypt/live/host.example.domain/cert.pem"
# 残りの有効期限が7日間になったら警告
WARN_DAYS=7
for cert_file in ${CERT_FILES}; do
  cert_md5sum=`echo -n ${cert_file} | md5sum | cut -d' ' -f1`
  expire_date=`openssl x509 -text -in ${cert_file} -noout -dates|grep "Not After"|sed -e 's/.*Not After : //'`
  expire=`date -d "$expire_date" '+%s'`
  if [ $today -gt $expire ]; then
    # すでに証明書の期限が切れている
    from="[email protected]"
    to="[email protected]"
    cc=""
    bcc=""
    subject="SSL証明書の期限が切れています"
    contents="サーバー(${hostname})にインストールされているSSL証明書(${cert_file})の期限が$expire_dateで切れています。\n至急新しい証明書を取得してインストールしてください。"
    sendMail "$from" "$to" "$cc" "$bcc" "$subject" "$contents"
    if [ $? -eq 1 ]; then
      echo "Send E-Mail failure"
      exit 1
    fi
    echo "Send E-Mail success"
  else
    # まだ証明書の期限まで日数が残っている
    leftdays=$((($expire-$today)/86400))
    echo "leftdays:$leftdays"
    if [ -f /var/tmp/${cert_md5sum}_cert_leftdays ]; then
      # 前回警告を行なった際の有効期限の残日数を取得
      prev_leftdays=`cat /var/tmp/${cert_md5sum}_cert_leftdays`
    else
      prev_leftdays=0
    fi
    if [ $prev_leftdays -ne $leftdays ]; then
      # 前回の警告より残日数が変化していればそれを記録して再度警告
      echo $leftdays > /var/tmp/${cert_md5sum}_cert_leftdays
      if [ $leftdays -lt ${WARN_DAYS} ]; then
        from="[email protected]"
        to="[email protected]"
        cc=""
        bcc=""
        subject="SSL証明書の期限が近づいています"
        contents="サーバー(${hostname})にインストールされているSSL証明書(${cert_file})の期限があと$leftdays日です。\n期限までに新しい証明書を取得してインストールしてください。"
        sendMail "$from" "$to" "$cc" "$bcc" "$subject" "$contents"
        if [ $? -eq 1 ]; then
          echo "Send E-Mail failure"
          exit 1
        fi
        echo "Send E-Mail success"
      fi
    fi
  fi
done

上記スクリプトでは以下のメール送信用のスクリプトを呼び出します。

sendmail.sh
#!/bin/sh

sendMail() {
    from="$1"
    to="$2"
    cc="$3"
    bcc="$4"
    subject="$5"
    contents="$6"

    inputEncoding="utf-8"
    outputEncoding="iso-2022-jp"
    subjectHead="=?$outputEncoding?B?"
    subjectBody="`echo "$subject" | iconv -f $inputEncoding -t $outputEncoding | base64 | tr -d '\n'`"
    subjectTail="?="
    fullSubject="$subjectHead$subjectBody$subjectTail"
    mailContents="`echo -e \"$contents\" | iconv -f $inputEncoding -t $outputEncoding`"

cat << __MAIL_CONTENTS__ | /usr/sbin/sendmail -- $to
From: $from
To: $to
Cc: $cc
Bcc: $bcc
Subject: $fullSubject
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit

$mailContents
__MAIL_CONTENTS__

    return $?
}