← все скрипты

ssl-check.py

python 3.9+ ~ 62 строки обновлён 25 марта 2026

Проверяет срок действия SSL-сертификатов для списка доменов. Если до истечения менее 14 дней — отправляет уведомление в Telegram. Без внешних зависимостей, работает на стандартной библиотеке Python.

Зависимости

Использование

# Проверка одного домена
python3 ssl-check.py example.com

# Проверка списка из файла
python3 ssl-check.py -f domains.txt

# С уведомлением в Telegram
python3 ssl-check.py -f domains.txt --tg-token BOT_TOKEN --tg-chat CHAT_ID

Код

#!/usr/bin/env python3
"""ssl-check.py — проверка сроков SSL-сертификатов."""

import ssl
import socket
import argparse
import sys
from datetime import datetime, timezone
from urllib.request import urlopen, Request
from urllib.parse import urlencode

def get_cert_expiry(hostname: str, port: int = 443, timeout: int = 10) -> datetime:
    """Получает дату истечения SSL-сертификата."""
    ctx = ssl.create_default_context()
    with socket.create_connection((hostname, port), timeout=timeout) as sock:
        with ctx.wrap_socket(sock, server_hostname=hostname) as ssock:
            cert = ssock.getpeercert()
            expiry_str = cert["notAfter"]
            return datetime.strptime(expiry_str, "%b %d %H:%M:%S %Y %Z").replace(
                tzinfo=timezone.utc
            )

def send_telegram(token: str, chat_id: str, message: str) -> None:
    """Отправляет сообщение в Telegram."""
    url = f"https://api.telegram.org/bot{token}/sendMessage"
    data = urlencode({"chat_id": chat_id, "text": message, "parse_mode": "HTML"}).encode()
    req = Request(url, data=data, method="POST")
    urlopen(req, timeout=10)

def main():
    parser = argparse.ArgumentParser(description="Проверка SSL-сертификатов")
    parser.add_argument("domains", nargs="*", help="Домены для проверки")
    parser.add_argument("-f", "--file", help="Файл со списком доменов")
    parser.add_argument("--days", type=int, default=14, help="Порог в днях (по умолчанию 14)")
    parser.add_argument("--tg-token", help="Telegram bot token")
    parser.add_argument("--tg-chat", help="Telegram chat ID")
    args = parser.parse_args()

    domains = list(args.domains)
    if args.file:
        with open(args.file) as f:
            domains.extend(line.strip() for line in f if line.strip())

    if not domains:
        parser.error("Укажите хотя бы один домен")

    now = datetime.now(timezone.utc)
    alerts = []

    for domain in domains:
        try:
            expiry = get_cert_expiry(domain)
            days_left = (expiry - now).days
            status = "OK" if days_left > args.days else "ВНИМАНИЕ"
            symbol = "✓" if days_left > args.days else "⚠"
            print(f"  {symbol} {domain}: {days_left} дн. (до {expiry:%d.%m.%Y})")
            if days_left <= args.days:
                alerts.append(f"⚠ {domain}: осталось {days_left} дн.")
        except Exception as e:
            print(f"  ✗ {domain}: ошибка — {e}")
            alerts.append(f"✗ {domain}: {e}")

    if alerts and args.tg_token and args.tg_chat:
        msg = "<b>SSL Check</b>\n" + "\n".join(alerts)
        send_telegram(args.tg_token, args.tg_chat, msg)
        print(f"\nУведомление отправлено в Telegram.")

if __name__ == "__main__":
    main()