有时候我们会有一些需求,需要批量检查自己的域名证书的到期时间,用于提前告警续费,使用python可以轻松的完成这个任务;
这里有用到第三方库pip install -U cryptography
,这里没有考虑站点重定向等情况,低版本python或cryptography需要改一些内容,自行斟酌。
import socket
import ssl
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Sequence
from zoneinfo import ZoneInfo
from cryptography import x509
context = ssl.create_default_context()
context.load_default_certs()
def get_certificate(domain, port=443, timeout=5) -> dict:
"""https://docs.python.org/3/library/ssl.html"""
with socket.create_connection((domain, port), timeout=timeout) as _sock:
with context.wrap_socket(_sock, server_hostname=domain) as sslsock:
# cert = ssl.DER_cert_to_PEM_cert(sslsock.getpeercert(True)) # 证书加载为pem格式
cert_bytes = sslsock.getpeercert(True)
if cert_bytes is None:
return {}
certificate = x509.load_der_x509_certificate(cert_bytes)
expired = certificate.not_valid_after_utc.astimezone(ZoneInfo("Asia/Shanghai"))
created = certificate.not_valid_before_utc.astimezone(ZoneInfo("Asia/Shanghai"))
return {
"domain": domain,
"version": certificate.version.name,
"algorithm": certificate.signature_hash_algorithm.name,
"subject": certificate.subject.rfc4514_string(),
"issuer": certificate.issuer.rfc4514_string(),
"expired_at": expired.strftime("%F %T"),
"created_at": created.strftime("%F %T"),
}
def multi_get_certificate(domains: Sequence[str]) -> list[dict]:
result = []
with ThreadPoolExecutor(max_workers=3) as pool:
tasks = {pool.submit(get_certificate, domain): domain for domain in domains}
for task in as_completed(tasks):
domain = tasks[task]
try:
result.append(task.result(timeout=10)) # 10s强行断开
except Exception as exc:
print(f"{domain=}: failed to get certificate: {exc}")
return result
if __name__ == "__main__":
domains = ("baidu.com", "jd.com", "qq.com", "aliyun.com")
print(multi_get_certificate(domains))
输出以下内容
[{'domain': 'qq.com', 'version': 'v3', 'algorithm': 'sha256', 'subject': 'CN=qq.com,O=Shenzhen Tencent Computer Systems Company Limited,L=Shenzhen,ST=Guangdong Province,C=CN', 'issuer': 'CN=DigiCert Secure Site CN CA G3,O=DigiCert Inc,C=US', 'expired_at': '2024-06-10 07:59:59', 'created_at': '2023-05-10 08:00:00'},
{'domain': 'jd.com', 'version': 'v3', 'algorithm': 'sha256', 'subject': 'CN=*.jd.com,O=BEIJING JINGDONG SHANGKE INFORMATION TECHNOLOGY CO.\\, LTD.,L=Beijing,ST=Beijing,C=CN', 'issuer': 'CN=GlobalSign RSA OV SSL CA 2018,O=GlobalSign nv-sa,C=BE', 'expired_at': '2024-12-09 09:34:41', 'created_at': '2023-11-08 09:34:42'},
{'domain': 'baidu.com', 'version': 'v3', 'algorithm': 'sha256', 'subject': 'CN=www.baidu.cn,O=BeiJing Baidu Netcom Science Technology Co.\\, Ltd,ST=北京市,C=CN', 'issuer': 'CN=DigiCert Secure Site Pro CN CA G3,O=DigiCert Inc,C=US', 'expired_at': '2025-03-02 07:59:59', 'created_at': '2024-01-30 08:00:00'},
{'domain': 'aliyun.com', 'version': 'v3', 'algorithm': 'sha256', 'subject': 'CN=*.aliyun.com,O=Alibaba (China) Technology Co.\\, Ltd.,L=HangZhou,ST=ZheJiang,C=CN', 'issuer': 'CN=GlobalSign Organization Validation CA - SHA256 - G3,O=GlobalSign nv-sa,C=BE', 'expired_at': '2024-12-30 16:21:02', 'created_at': '2023-12-07 15:21:04'}]