Skip to content

HTTPS证书过期检测

python
import requests
from datetime import datetime
import ssl
import socket
from contextlib import closing
from config import SITES_URLS

def extract_hostname_and_port(url):
    """Extract hostname and port from a URL."""
    hostname = url.split("//")[-1].split("/")[0].split(":")[0]
    port = url.split("//")[-1].split("/")[0].split(":")[1] if ":" in url.split("//")[-1].split("/")[0] else 443
    return hostname, int(port)

def get_ssl_cert_expiry_date(hostname, port):
    """Check the expiration date of the SSL certificate for a given hostname and port."""
    context = ssl.create_default_context()
    with closing(socket.create_connection((hostname, port))) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as ssock:
            certificate = ssock.getpeercert()
            return datetime.strptime(certificate['notAfter'], '%b %d %H:%M:%S %Y %Z')

def get_ssl_certificate_info(url):
    """Retrieve SSL certificate expiry information for a URL."""
    try:
        hostname, port = extract_hostname_and_port(url)
        expiry_date = get_ssl_cert_expiry_date(hostname, port)
        days_left = (expiry_date - datetime.utcnow()).days
        return {
            'url': url,
            'expiry_date': expiry_date,
            'days_left': days_left
        }
    except ssl.SSLCertVerificationError:
        return {
            'url': url,
            'error': 'Certificate verification failed'
        }
    except Exception as e:
        return {
            'url': url,
            'error': str(e)
        }

def sort_sites_by_expiry(urls):
    """Sort URLs by SSL certificate expiry date."""
    sites_info = []
    for url in urls:
        certificate_info = get_ssl_certificate_info(url)
        sites_info.append(certificate_info)
    
    # Sort sites by days left before certificate expires
    sorted_sites = sorted(sites_info, key=lambda x: x.get('expiry_date') if x.get('expiry_date') else datetime.max)
    return sorted_sites

def generate_report(sorted_sites):
    """Generate a report based on sorted SSL certificate information."""
    messages = []
    for site in sorted_sites:
        if 'expiry_date' in site:
            messages.append(f"Certificate expires in {site['days_left']} day(s), for {site['url']}.")
        elif 'error' in site:
            messages.append(f"Error checking certificate for {site['url']}: {site['error']}")
    
    return "\n".join(messages)

def main():
    """Main function to check SSL certificates, sort by expiry date, and send the report to Discord."""
    sorted_sites = sort_sites_by_expiry(SITES_URLS)
    report = generate_report(sorted_sites)
    print(report)

if __name__ == '__main__':
    main()

Released under the MIT License.