Перейти к основному содержанию
 

Zabbix — срок действия SSL сертификата

Zabbix

Сегодня напишем скрипт для мониторинга срока действия SSL сертификатов наших сайтов.

Этот мониторинг пригодится многим:

  • Системным администраторам в крупных компаниях, чтобы не пропустить момент перевыпуска сертификатов. Особенно, если количество сайтов — сотни.
  • Владельцам собственных сайтов. Многие пользуются сервисом Let's Encrypt, особенностью сертификатов которого является короткий срок жизни. Если автоматика обновления сертификатов выйдет из строя, то мониторинг SSL сертификатов поможет выявить проблему до того, как она себя проявит.

Это уже вторая модификация скриптов мониторинга. Главная особенность - низкая нагрузка на заббикс.

Ссылки

IIS - SSL сертификат Let's Encrypt

Подготовка

Для работы с SSL нам потребуется утилита openssl:

apt-get install openssl

Весь мониторинг основан на команде:

echo | openssl s_client -servername internet-lab.ru -connect internet-lab.ru:443 2>/dev/null | openssl x509 -noout -dates | grep "notAfter" | cut -d'=' -f2

Команда выводит дату завершения срока действия SSL сертификата.

Скрипты

Мониторинг у меня будет находиться на самом заббикс-сервере. Создаём следующую структуру каталогов:

ssl

В директории /usr/lib/zabbix/externalscripts создадим папку ssl_expire с содержимым:

  • data — директория, пока пустая. Наполняться будет автоматически.
  • domain_list.txt — файл содержит список сайтов, для которых нужно проверять срок действия SSL сертификата. В одной строке один домен, например:
    domain1.ru
    domain2.com
    www.domain3.ru
    internet-lab.ru
    xn----7sbabo2beumogg8p.xn--p1ai
    Кириллические домены работают только в puny-коде. Конвертер в помощь.
  • ssl_check.sh — этот скрипт вызывается из заббикс-агента пользовательскими переменными. Без параметра он выводит JSON со списком доменов для автообнаружения. С доменом в качестве параметра возвращает количество дней до окончания срока действия SSL сертификата, домен должен быть в списке domain_list.txt.
  • ssl_cron.sh — этот скрипт вызывается в cron раз в шесть часов и обновляет информацию о всех SSL для доменов из списка.
  • ssl_miss.sh — этот скрипт вызывается из заббикс-агента пользовательскими переменными. С доменом в качестве параметра возвращает количество дней, прошедших с момента последнего обновления данных кроном. Помогает вызвать триггер с предупреждением, если crontab перестанет работать или по какой-то причине перестанет обрабатываться домен в скрипте.

Содержимое ssl_check.sh:

#!/bin/bash

# сколько дней осталось до истечения срока действия SSL сертификата

# получаем имя домена
DOMAIN=$1

#если домен не передан - выводим массив для автообнаружения
if [[ $DOMAIN = "" ]]; then
    # список доменов
    LISTPATH="/usr/lib/zabbix/externalscripts/ssl_expire/domain_list.txt"

    #заполняем массив из файла и выводим в JSON
    readarray DOMAINLIST < $LISTPATH
    if ((${#DOMAINLIST[*]}>0)); then
        echo "{"
        echo "  \"data\": ["
        for ((a=0; a < ${#DOMAINLIST[*]}; a++))
        do
            x=${DOMAINLIST[$a]};
            x=${x//[[:space:]]/};
            echo "    {"
            echo "      \"{#DOMAIN}\": \"${x}\""
            if ((a+1 < ${#DOMAINLIST[*]})); then
                echo "    },"
            else
                echo "    }"
            fi
        done
        echo "  ]"
        echo "}"
    fi
else
    #если домен передан - работаем

    #файл
    DATAPATH="/usr/lib/zabbix/externalscripts/ssl_expire/data/"
    FILEPATH="${DATAPATH}${DOMAIN}"

    if [ -e $FILEPATH ]; then
        CURRENTDATE=`LANG=en_EN TZ=GMT date +"%b %d %R:%S %Y %Z"`
        NOTAFTER=`cat $FILEPATH | grep "NotAfter" | cut -d'=' -f2`
        if [[ $NOTAFTER == "" ]]; then
            echo "-1"
        else
            DIFFDAYS=`echo $(( ($(date -d "$NOTAFTER" +"%s")-$(date -d "$CURRENTDATE" +"%s"))/86400 ))`
            echo "$DIFFDAYS"
        fi
    else
        echo "-1"
    fi
fi

Содержимое ssl_cron.sh:

#!/bin/bash

# Создаёт файлы доменов с текущей датой и датой истечения сертификата (для crontab)

# переменные
LISTPATH="/usr/lib/zabbix/externalscripts/ssl_expire/domain_list.txt"
DATAPATH="/usr/lib/zabbix/externalscripts/ssl_expire/data/"
CURRENTDATE=`LANG=en_EN TZ=GMT date +"%b %d %R:%S %Y %Z"`

#заполняем массив из файла
readarray DOMAINLIST < $LISTPATH
if ((${#DOMAINLIST[*]}>0)); then
    for ((a=0; a < ${#DOMAINLIST[*]}; a++))
    do
        DOMAIN=${DOMAINLIST[$a]};
        DOMAIN=${DOMAIN//[[:space:]]/};

        #получаем данные о ssl сертификате...
        NOTAFTER=`echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null | openssl x509 -noout -dates | grep "notAfter" | cut -d'=' -f2`
        VALIDNOTAFTER=`date -d "$NOTAFTER" > /dev/null 2>&1; echo $?`

        #если получили дату
        if [[ $VALIDNOTAFTER == 0 ]]; then
            FILEPATH="${DATAPATH}${DOMAIN}"
            touch $FILEPATH
            echo "CheckDate=$CURRENTDATE" > $FILEPATH
            if [[ $NOTAFTER != "" ]]; then
                echo "NotAfter=$NOTAFTER" >> $FILEPATH
            fi
        fi
    done
fi

Содержимое ssl_miss.sh:

#!/bin/bash

# выводит сколько дней назад проверялся сертификат

# получаем имя домена
DOMAIN=$1

#если домен передан - работаем
if [ $DOMAIN != "" ]; then

        #файл
        DATAPATH="/usr/lib/zabbix/externalscripts/ssl_expire/data/"
        FILEPATH="${DATAPATH}${DOMAIN}"

        if [ -f $FILEPATH ]; then
            CURRENTDATE=`LANG=en_EN TZ=GMT date +"%b %d %R:%S %Y %Z"`
            CHECKDATE=`cat $FILEPATH | grep "CheckDate" | cut -d'=' -f2`
            DIFFDAYS=`echo $(( ($(date -d "$CURRENTDATE" +"%s")-$(date -d "$CHECKDATE" +"%s"))/86400 ))`
            echo "$DIFFDAYS"
        else
            echo "-1"
        fi
else
    #ошибка
    echo "-1"
fi

Примечания к скриптам

В коде скриптов есть путь вида usr/lib/zabbix/externalscripts/, если у вас другие пути - нужно будет изменить.

CURRENTDATE=`LANG=en_EN TZ=GMT date +"%b %d %R:%S %Y %Z"`

Это получение текущей даты. На самом деле формат даты практического применения не имеет, просто привожу дату к такому же формату, как у сертификата.

  • TZ=GMT — переводит дату в формат GMT
  • LANG=en_EN — устанавливает язык
  • "%b %d %R:%S %Y %Z" — формат даты вида: Jun 14 03:59:01 2019 GMT

Crontab

В крон добавляем расписание, срабатывает раз в шесть часов:

* */6 * * * /usr/lib/zabbix/externalscripts/ssl_expire/ssl_cron.sh >/dev/null 2>&1

Перезапускаем крон:

service cron restart

По идее скрипт должен выполниться и папка data заполнится файлами с названиями доменов. Если не выполнится - запустите ssl_cron.sh сами, а потом разбирайтесь, что там с кроном.

Пример содержимого файлов на примере домена internet-lab.ru.

root@zabbix:/usr/lib/zabbix/externalscripts/ssl_expire/data# pwd
/usr/lib/zabbix/externalscripts/ssl_expire/data

root@zabbix:/usr/lib/zabbix/externalscripts/ssl_expire/data# ll | grep internet
-rw-r--r-- 1 root root   69 июн 14 06:59 internet-lab.ru

root@zabbix:/usr/lib/zabbix/externalscripts/ssl_expire/data# cat internet-lab.ru
CheckDate=Jun 14 03:59:01 2019 GMT
NotAfter=Jul 23 13:00:33 2019 GMT

Внутри файлов пишется две даты. Дата проверки в формате GMT.

CheckDate=Jun 14 03:59:01 2019 GMT

Дата истечения сертификата (если удалось определить) в формате GMT:

NotAfter=Jul 23 13:00:33 2019 GMT

Zabbix агент

Теперь нужно настроить заббикс-агент, чтобы он отдавал данные серверу. Убеждаемся, что в /etc/zabbix/zabbix_agentd.conf есть настройка:

Include=/etc/zabbix/zabbix_agentd.conf.d/

Переходим в папку /etc/zabbix/zabbix_agentd.conf.d/, создаём файл ssl_expire.conf с содержимым:

UserParameter=ssl_expire.check[*],/usr/lib/zabbix/externalscripts/ssl_expire/ssl_check.sh $1
UserParameter=ssl_expire.miss[*],/usr/lib/zabbix/externalscripts/ssl_expire/ssl_miss.sh $1
UserParameter=ssl_expire.list,/usr/lib/zabbix/externalscripts/ssl_expire/ssl_check.sh
  • ssl_expire.list — список доменов в JSON для автообнаружения.
  • ssl_expire.check[*] — дней до окончания срока действия сертификата (float, потому как может возвращать "-1").
  • ssl_expire.miss[*] — сколько дней назад была проверка. В идеале должно быть 0, иначе нужно разбираться.

Перезапускаем агент:

service zabbix-agent restart

Zabbix шаблон

Ставим на сервер шаблон и привязываем к заббикс-серверу. Шаблон я уже набросал.

Скачать шаблон: zbx_ssl_expire.xml

ssl

В шаблоне одно приложение:

ssl

Одно правило автообнаружения, срабатывает раз в час для обновления списка доменов:

ssl

Два прототипа элементов данных:

ssl

Семь прототипов триггеров:

ssl