1、通过openssl证书获取
openssl x509 -in <cert>.pem -noout -dates
2、通过openssl域名获取
echo | openssl s_client -servername <doman> -connect <doman>:443 2>/dev/null | openssl x509 -noout -dates
3、通过脚本获取curl
# coding: utf-8 # 查询域名证书到期情况 import re import subprocess from datetime import datetime def get_re_match_result(pattern, string): match = re.search(pattern, string) return match.group(1) def parse_time(date_str): return datetime.strptime(date_str, "%b %d %H:%M:%S %Y GMT") def format_time(date_time): return datetime.strftime(date_time, "%Y-%m-%d %H:%M:%S") def get_cert_info(domain): """获取证书信息""" cmd = f"curl -Ivs https://{domain} --connect-timeout 10" exitcode, output = subprocess.getstatusoutput(cmd) # 正则匹配 start_date = get_re_match_result('start date: (.*)', output) expire_date = get_re_match_result('expire date: (.*)', output) # 解析匹配结果 start_date = parse_time(start_date) expire_date = parse_time(expire_date) return { 'start_date': start_date, 'expire_date': expire_date } def get_cert_expire_date(domain): """获取证书剩余时间""" info = get_cert_info(domain) print(info) expire_date = info['expire_date'] # 剩余天数 return (expire_date - datetime.now()).days if __name__ == "__main__": domain = 'www.baidu.com' expire_date = get_cert_expire_date(domain) print(expire_date)
4、通过socket 获取域名ssl 证书信息
核心代码
# -*- coding: utf-8 -*- import socket import ssl def get_domain_cert(domain): """ 获取证书信息 :param domain: str :return: dict """ socket.setdefaulttimeout(5) cxt = ssl.create_default_context() skt = cxt.wrap_socket(socket.socket(), server_hostname=domain) skt.connect((domain, 443)) cert = skt.getpeercert() skt.close() return cert if __name__ == "__main__": print(get_domain_cert("www.baidu.com"))
还有一种方式也记录一下
import socket import ssl def get_domain_cert(host, port=443, timeout=3): """ 获取证书信息 存在问题:没有指定主机ip,不一定能获取到正确的证书信息 :param host: str :param port: int :param timeout: int :return: dict """ context = ssl.create_default_context() with socket.create_connection(address=(host, port), timeout=timeout) as sock: with context.wrap_socket(sock, server_hostname=host) as wrap_socket: return wrap_socket.getpeercert()
输出
{ 'subject': ((('countryName', 'CN'),), (('stateOrProvinceName', 'beijing'),), (('localityName', 'beijing'),), (('organizationalUnitName', 'service operation department'),), (('organizationName', 'Beijing Baidu Netcom Science Technology Co., Ltd'),), (('commonName', 'baidu.com'),)), 'issuer': ((('countryName', 'BE'),), (('organizationName', 'GlobalSign nv-sa'),), (('commonName', 'GlobalSign RSA OV SSL CA 2018'),)), 'version': 3, 'serialNumber': '4417CE86EF82EC6921CC6F68', 'notBefore': 'Jul 5 05:16:02 2022 GMT', 'notAfter': 'Aug 6 05:16:01 2023 GMT', 'subjectAltName': (('DNS', 'baidu.com'), ), 'OCSP': ('http://ocsp.globalsign.com/gsrsaovsslca2018',), 'caIssuers': ('http://secure.globalsign.com/cacert/gsrsaovsslca2018.crt',), 'crlDistributionPoints': ('http://crl.globalsign.com/gsrsaovsslca2018.crl',) }
结构化输出内容后的完整代码
# -*- coding: utf-8 -*- import socket import ssl from dateutil import parser # requests.packages.urllib3.disable_warnings() try: _create_unverified_https_context = ssl._create_unverified_context except AttributeError: # Legacy Python that doesn't verify HTTPS certificates by default pass else: # Handle target environment that doesn't support HTTPS verification ssl._create_default_https_context = _create_unverified_https_context DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S' socket.setdefaulttimeout(5) def get_domain_ip(domain): """ 获取ip地址 :param domain: str :return: str """ try: addrinfo = socket.getaddrinfo(domain, None) return addrinfo[0][-1][0] except Exception as e: pass return None def get_domain_cert(domain): """ 获取证书信息 :param domain: str :return: dict """ cxt = ssl.create_default_context() skt = cxt.wrap_socket(socket.socket(), server_hostname=domain) skt.connect((domain, 443)) cert = skt.getpeercert() skt.close() return cert def get_cert_info(domain): """ 获取证书信息 :param domain: str :return: dict """ cert = get_domain_cert(domain) issuer = _tuple_to_dict(cert['issuer']) subject = _tuple_to_dict(cert['subject']) return { 'domain': domain, 'ip': get_domain_ip(domain), 'subject': _name_convert(subject), 'issuer': _name_convert(issuer), # 'version': cert['version'], # 'serial_number': cert['serialNumber'], 'start_date': _parse_time(cert['notBefore']), 'expire_date': _parse_time(cert['notAfter']), } def _tuple_to_dict(cert_tuple): """ cert证书 tuple转dict :param cert_tuple: tuple :return: """ data = {} for item in cert_tuple: data[item[0][0]] = item[0][1] return data def _name_convert(data): """ 名字转换 :param data: dict :return: dict """ name_map = { 'C': 'countryName', 'CN': 'commonName', 'O': 'organizationName', 'OU': 'organizationalUnitName', 'L': 'localityName', 'ST': 'stateOrProvinceName' } dct = {} for key, value in name_map.items(): dct[key] = data.get(value, '') return dct def _parse_time(time_str): """ 解析并格式化时间 :param time_str: str :return: str """ return parser.parse(time_str).astimezone().strftime(DATETIME_FORMAT) if __name__ == "__main__": print(get_cert_info("www.baidu.com"))
输出
{ "domain": "www.baidu.com", "ip": "39.156.66.14", "subject": { "C": "CN", "CN": "baidu.com", "O": "Beijing Baidu Netcom Science Technology Co., Ltd", "OU": "service operation department", "L": "beijing", "ST": "beijing" }, "issuer": { "C": "BE", "CN": "GlobalSign RSA OV SSL CA 2018", "O": "GlobalSign nv-sa", "OU": "", "L": "", "ST": "" }, "start_date": "2022-07-05 13:16:02", "expire_date": "2023-08-06 13:16:01" }
5、通过pyOpenSSL获取证书信息
该方式,不校验证书合法性,只获取证书信息
文档:https://pyopenssl.org/en/0.15.1/index.html#
依赖
pip install pyOpenSSL
示例
# -*- coding: utf-8 -*- import ssl import OpenSSL def get_ssl_expire_date(host, port=443): cert = ssl.get_server_certificate((host, port)) x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) return x509.get_notAfter().decode() if __name__ == '__main__': print(get_ssl_expire_date('www.baidu.com')) # 20230806051601Z
6、Domain Admin可视化管理域名证书到期
项目地址:https://github.com/mouday/domain-admin
运行环境:Python 3.7.0
$ pip install domain_admin # 升级到最新版本,可选 $ pip3 install -U domain-admin -i https://pypi.org/simple # 启动运行 $ gunicorn 'domain_admin.main:app'
访问地址:http://127.0.0.1:8000
默认的管理员账号:admin 密码:123456

题外话
当下这个大数据时代不掌握一门编程语言怎么跟的上脚本呢?当下最火的编程语言Python前景一片光明!如果你也想跟上时代提升自己那么请看一下.

感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。

一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。


二、Python必备开发工具
工具都帮大家整理好了,安装就可直接上手!
三、最新Python学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

四、Python视频合集
观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

五、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

六、面试宝典


简历模板
若有侵权,请联系删除
926

被折叠的 条评论
为什么被折叠?



