# -*- coding: utf-8 -*- """ @File : cert_socket_v2.py @Date : 2023-06-03 参考:python批量检查通一个集群针对同一个域名解析到不同IP地址证书的有效性 https://blog.csdn.net/reblue520/article/details/106832780 """ from __future__ import print_function, unicode_literals, absolute_import, division import socket import ssl import six from domain_admin.log import logger from domain_admin.utils import time_util def get_domain_host_list(domain, port=80): """ 获取域名映射主机地址列表,一对多关系 :param domain: str 域名 :param port: int 端口 :return: List[str] 主机地址列表 """ # fix Python2 TypeError: getaddrinfo() takes no keyword arguments # host, port, family=None, socktype=None, proto=None, flags=None if domain.startswith("https://"): domain = domain[len("https://"):] if domain.startswith("http://"): domain = domain[len("http://"):] try: # use ipv4 ret = socket.getaddrinfo( domain, port, socket.AF_INET, # 限制仅返回IPv4 0, socket.IPPROTO_TCP ) except Exception: # use ipv6 ret = socket.getaddrinfo( domain, port, socket.AF_INET6, 0, socket.IPPROTO_TCP ) lst = [] for item in ret: lst.append(item[4][0]) return lst def get_ssl_cert(domain, host=None, port=443, timeout=3): """ 获取主机证书信息 :param domain: str :param host: str :param port: int :param timeout: int :return: Dict """ logger.info({ 'domain': domain, 'host': host, 'port': port, 'timeout': timeout }) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) sock.connect((host, port)) ssl_context = ssl.create_default_context() # fix: Python2 AttributeError: __exit__ wrap_socket = ssl_context.wrap_socket(sock, server_hostname=domain) cert = wrap_socket.getpeercert() wrap_socket.close() return cert def get_ssl_cert_info(domain, host=None, port=443, timeout=3): """ 返回解析好的证书信息数据 :param domain: str :param host: str :param port: int :param timeout: int :return: """ cert = get_ssl_cert(domain, host, port, timeout) print(cert) return resolve_cert(cert) def resolve_cert(cert): """ 解析证书信息,仅解析重要信息 :param cert: Dict :return: """ data = { "start_date": time_util.parse_time(cert['notBefore']), "expire_date": time_util.parse_time(cert['notAfter']), } return data if __name__ == '__main__': print(get_domain_host_list('www.taobao.com')) # print(get_ssl_cert_info('www.taobao.com', '111.62.93.139')) # print(get_ssl_cert_info('38.60.47.102', '38.60.47.102')) # print('www.baidu.com'.encode('idna')) # b'www.baidu.com' # print('www.baidu.com'.encode('punycode')) # b'www.baidu.com-'