#!/usr/bin/env python2
# --------------------------------------------
# check_SSLexpiration_zabbix.py
# fork from : https://gist.github.com/ytyng/c844c985e4c0d96990e9
# thanks: http://qiita.com/uemura/items/a3a0937f77494e62213c
# --------------------------------------------
import sys
import re
import subprocess
import datetime
def parse_result_date_string(date_string):
"""
:convert date string to datetime
>>> date_string = "Feb 2 05:47:50 2015 GMT"
>>> d = parse_result_date_string(date_string)
>>> d
datetime.datetime(2015, 2, 2, 5, 47, 50)
"""
d = datetime.datetime.strptime(date_string, '%b %d %H:%M:%S %Y %Z')
return d
re_start = re.compile(r'Not Before: (.+)')
re_end = re.compile(r'Not After : (.+)')
def get_date_strings_from_result(result):
"""
:return: cert start date, cert expire date
>>> text = "Not Before: Feb 2 05:47:47 2015 GMT\\n" \\
... "Not After : Feb 4 16:03:29 2016 GMT"
>>> get_date_strings_from_result(text)
('Feb 2 05:47:47 2015 GMT', 'Feb 4 16:03:29 2016 GMT')
"""
rr_start = re_start.search(result)
rr_end = re_end.search(result)
return rr_start.group(1) if rr_start else None, \
rr_end.group(1) if rr_end else None
def get_cert_start_expire_date(domain, port):
"""
:return: cert start date, cert expire date
"""
command = "openssl s_client -connect {}:{} -servername {} < /dev/null 2>/dev/null | openssl x509 -text 2>/dev/null | grep Not"
command = command.format(domain,port,domain)
out = subprocess.check_output(command, shell=True)
ss, es = get_date_strings_from_result(out)
return parse_result_date_string(ss), parse_result_date_string(es)
def get_cert_expire_delta(domain,port):
"""
time delta cert expire date and now
"""
start_date, expire_date = get_cert_start_expire_date(domain,port)
return expire_date - datetime.datetime.now()
def main():
try:
domain = sys.argv[1]
port = sys.argv[2]
delta = get_cert_expire_delta(domain,port)
result_days = delta.days
except:
result_days = -1000
print(result_days)
if __name__ == '__main__':
main()
#!/bin/bash
# ----------------------------------------------
# configの中身をDisovery用のjsonぽく返すだけ
# thanks : https://qiita.com/usiusi360/items/51e8478cb080412958a4
# ----------------------------------------------
SCRIPTDIR="$(dirname $0)"
SCRIPTNAME="$(basename $0)"
CONFNAME="${SCRIPTDIR}/${SCRIPTNAME%\.*}.conf"
if [ ! -f "${CONFNAME}" ]; then
echo "${CONFNAME}が存在しません"
exit 1
fi
echo "{"
echo " \"data\":["
FIRST=1
while read SERVERNAME PORT ; do
if [ ${FIRST} -eq 1 ] ; then
echo -n ""
FIRST=0
else
echo ","
fi
echo -e -n "\t\t{ \"{#CRTCHK_TARGET_SERVERNAME}\": \"${SERVERNAME}\" , \"{#CRTCHK_TARGET_PORT}\": \"${PORT}\"}"
done < ${CONFNAME}
echo ""
echo " ]"
echo "}"
UserParameter=crtchk.daystoexpire[*],/etc/zabbix/check_SSLexpiration_zabbix.py $1 $2
UserParameter=crtchk.discovery,/etc/zabbix/crtchk.discovery.sh
servername1 443
servername2 443
servername3 443
servername4 8443
servername5 443
servername6 8443
servername7 443
名前 |
SSL期限監視 |
タイプ |
Zabbixエージェント |
キー |
crtchk.discovery |
監視間隔 |
30m |
存在しなくなったリソースの保持期間 |
3600 |
名前 |
crtchk-daystoexpire – {#CRTCHK_TARGET_SERVERNAME}:{#CRTCHK_TARGET_PORT} |
タイプ |
Zabbixエージェント |
キー |
crtchk.daystoexpire[{#CRTCHK_TARGET_SERVERNAME},{#CRTCHK_TARGET_PORT}] |
データ型 |
数値(浮動小数) |
単位 |
days |
名前 |
SSL証明書の期限取得に失敗しました – {#CRTCHK_TARGET_SERVERNAME}:{#CRTCHK_TARGET_PORT} |
条件式 |
crtchk.daystoexpire[{#CRTCHK_TARGET_SERVERNAME},{#CRTCHK_TARGET_PORT}].last()}=-1000 |
正常イベントの生成 |
条件式 |
障害イベント生成モード |
単一 |
名前 |
SSL証明書の期限が近づいています – {#CRTCHK_TARGET_SERVERNAME}:{#CRTCHK_TARGET_PORT} |
条件式 |
{Zabbix server:crtchk.daystoexpire[{#CRTCHK_TARGET_SERVERNAME},{#CRTCHK_TARGET_PORT}].last()}<10 |
正常イベントの生成 |
条件式 |
障害イベント生成モード |
単一 |
依存関係 |
SSL証明書の期限取得に失敗しました – {#CRTCHK_TARGET_SERVERNAME}:{#CRTCHK_TARGET_PORT} |
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>5.0</version>
<date>2022-08-09T08:50:14Z</date>
<groups>
<group>
<name>Templates</name>
</group>
</groups>
<templates>
<template>
<template>Template Check SSL Certificate</template>
<name>Template Check SSL Certificate</name>
<groups>
<group>
<name>Templates</name>
</group>
</groups>
<applications>
<application>
<name>SSL</name>
</application>
</applications>
<discovery_rules>
<discovery_rule>
<name>crtchk.discovery</name>
<key>crtchk.discovery</key>
<delay>30m</delay>
<lifetime>3600</lifetime>
<item_prototypes>
<item_prototype>
<name>crtchk-daystoexpire - {#CRTCHK_TARGET_SERVERNAME}:{#CRTCHK_TARGET_PORT}</name>
<key>crtchk.daystoexpire[{#CRTCHK_TARGET_SERVERNAME},{#CRTCHK_TARGET_PORT}]</key>
<delay>60m</delay>
<history>14d</history>
<trends>0</trends>
<units>days</units>
<applications>
<application>
<name>SSL</name>
</application>
</applications>
<trigger_prototypes>
<trigger_prototype>
<expression>{last()}=-1000</expression>
<name>Failed to get SSL certificate's expiration date - {#CRTCHK_TARGET_SERVERNAME}:{#CRTCHK_TARGET_PORT}</name>
<priority>HIGH</priority>
</trigger_prototype>
<trigger_prototype>
<expression>{last()}<14</expression>
<name>The SSL certificate's expiration date is is approaching. - {#CRTCHK_TARGET_SERVERNAME}:{#CRTCHK_TARGET_PORT}</name>
<priority>HIGH</priority>
<dependencies>
<dependency>
<name>Failed to get SSL certificate's expiration date - {#CRTCHK_TARGET_SERVERNAME}:{#CRTCHK_TARGET_PORT}</name>
<expression>{Template Check SSL Certificate:crtchk.daystoexpire[{#CRTCHK_TARGET_SERVERNAME},{#CRTCHK_TARGET_PORT}].last()}=-1000</expression>
</dependency>
</dependencies>
</trigger_prototype>
</trigger_prototypes>
</item_prototype>
</item_prototypes>
</discovery_rule>
</discovery_rules>
</template>
</templates>
</zabbix_export>