获取socket.gaierror的处理错误:[Errno 11001] getaddrinfo在Python中使用pyopenssl失败

问题描述 投票:-1回答:1

摘要:我会在第一遍中尝试解释一下,但是如果我错过了一些相关的细节,请告诉我,我将继续进行下去。我正在从文本文件中提取服务器列表,并使用pyopenssl来解析,连接和检索SSL证书信息。根据到期日期,我正在计算证书到期之前的天数。我的结果通过数组传递,格式化,然后通过电子邮件发送。直到我的其中一台服务器无法解析并且得到socket.gaierror,它才能正常工作。

问题:如果主机无法解决,则会炸毁我的结果,并且出现以下错误。尽管它正确记录了错误,但是我尝试传递一些可以在主机,主机名,到期日期和到期日格式中记录我的结果的异常的东西,以便我可以传递给表并发送电子邮件。我希望它在主机字段中注明“无法解决”,并且可能导致到期日期和到期天数仅为“ 0”。谁能指出我实现这一目标的好方法?谢谢!

错误消息:

Checking certificate for server  server.domain.com
--- Logging error ---
Traceback (most recent call last):
  File "ssl_nag_script_test.py", line 80, in <module>
    s.connect((host, int(port)))
socket.gaierror: [Errno 11001] getaddrinfo failed.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "E:\Python36\lib\logging\__init__.py", line 992, in emit
    msg = self.format(record)
  File "E:\Python36\lib\logging\__init__.py", line 838, in format
    return fmt.format(record)
  File "E:\Python36\lib\logging\__init__.py", line 575, in format
    record.message = record.getMessage()
  File "E:\Python36\lib\logging\__init__.py", line 338, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
  File "ssl_nag_script_test.py", line 106, in <module>
    logger.warning('Error on connection to Server,', str(ip))
Message: 'Error on connection to Server,'
Arguments: ('server.domain.com:443\n',)
--- Logging error ---
Traceback (most recent call last):
  File "ssl_nag_script_test.py", line 80, in <module>
    s.connect((host, int(port)))
socket.gaierror: [Errno 11001] getaddrinfo failed.

**Then**
WARNING:root:ERROR ENCOUNTERED!
WARNING:root:Traceback (most recent call last):
  File "ssl_nag_script - Copy.py", line 114, in <module>
    key=lambda k: k[1]['days_to_expire'], reverse=False)
TypeError: '<' not supported between instances of 'str' and 'int'

Python代码

# Import the basic modules to run this script

import ssl
from datetime import datetime
import OpenSSL
import socket
from datetime import timedelta
import datetime
import traceback
import logging

# Import the needed libs for sending smtp emails

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

# Set variables for email

email_sen = '[email protected]'
email_rec = '[email protected]'
subject = 'SSL Certificate Results'

# Create message container for email

msg = MIMEMultipart('alternative')
msg['From'] = email_sen
msg['To'] = email_rec
msg['Subject'] = subject

# Setup logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.WARNING)
formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(message)s')
file_handler = logging.FileHandler('log/SSLNag.log')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)

try:
    # opening file with list of servers and set date and time
    ipfile = open('server_ip.txt')
    cur_date = datetime.datetime.utcnow()

    # Create an array to house the results.
    # Array will have sub arrays in the format of [host ip] = {host, hostname, expiration date, days to expire}

    ssl_results = {}
except Exception as e:
    logger.warning("ERROR ENCOUNTERED! \n\n")
    logger.warning(str(traceback.format_exc()))

# scan each host in the ip file and check it's ssl

for ip in ipfile:
    # Record an entry in the ssl_resutls array
    # Always default to false
    ssl_results[str(ip)] = {'host': '', 'server_name': '', 'exp_date': '', 'days_to_expire': ''}

    try:
        host = ip.strip().split(':')[0]
        port = ip.strip().split(':')[1]
        print('\nChecking certifcate for server ', host)

        # Connect to server using SSL.

        ctx = OpenSSL.SSL.Context(ssl.PROTOCOL_TLSv1)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, int(port)))
        cnx = OpenSSL.SSL.Connection(ctx, s)
        cnx.set_connect_state()
        cnx.do_handshake()

        # Connection complete get SSL certificate and close connection.

        cert = cnx.get_peer_certificate()
        s.close()

        # From SSL certificate get host name, expiration date and decode.

        server_name = cert.get_subject().commonName
        print(server_name)
        edate = cert.get_notAfter()
        edate = edate.decode()

        # Get date and format. Calculate number of days until SSL expires.

        exp_date = datetime.datetime.strptime(edate, '%Y%m%d%H%M%SZ')
        days_to_expire = int((exp_date - cur_date).days)
        print(exp_date)
        print('day to expire', days_to_expire)

        # Update the hosts entry

        ssl_results[str(ip)]['host'] = host
        ssl_results[str(ip)]['server_name'] = server_name
        ssl_results[str(ip)]['exp_date'] = exp_date
        ssl_results[str(ip)]['days_to_expire'] = days_to_expire

    # Logging for errors

    except Exception as e:
        logger.warning('Error on connection to Server,', str(ip))
        logger.warning("ERROR ENCOUNTERED", host, "\n\n")
        logger.warning(str(traceback.format_exc()))

# Loop through the ssl_results entries and generate a email + results file
try:
    # Sort the ssl_results

    sorted_results = sorted(ssl_results.items(),
                            key=lambda k: k[1]['days_to_expire'], reverse=False)

    # variable to hold html for email

    SSLCertificates = """<html>
                        <head>
                          <style>
                                table{width: 1024px;}

                                table, th, td {
                                    border: 1px solid black;
                                    border-collapse: collapse;
                                }

                                th, td {
                                    padding: 5px;
                                    text-align: left;
                                }

                                ul:before{
                                  content:attr(data-header);
                                  font-size:120%;
                                  font-weight:bold;
                                  margin-left:-15px;
                                }
                            </style>
                          </head>
                        <body>
                          <p><h2>Hello, </h2>
                          <h3>SSL Expiration Summary:</h3>
                          <span style="color:red;"><b>NOTE: If any of the below SSL certificates have less than 90 days remaining please renew.<b></span><br><br>
                          <table id=\"exp_ssls\"><tr><th>Host</th><th>Hostname</th><th>Expiration Date</th><th>Remaining Days</th></tr>
                      """
    # Write results in an html table
    # Apply this formatting if days to expire are equal to or less than 90 days

    for server, data in sorted_results:
        if float(str(data["days_to_expire"])) <= 90:
            SSLCertificates += "<tr><td bgcolor=yellow><font color=red><b>" + str(server) + "</b></td><td bgcolor=yellow><font color=red><b>" + str(data["server_name"]) + "</b></td><td bgcolor=yellow><font color=red><b>" + str(
                data["exp_date"]) + "</b></td><td bgcolor=yellow><font color=red><b>" + str(data["days_to_expire"]) + "</b></td></tr>"

        # Apply this formatting if days to expire are equal to or greater than 91 days

        if float(str(data["days_to_expire"])) >= 91:
            SSLCertificates += "<tr><td>" + str(server) + "</td><td>" + str(data["server_name"]) + "</td><td>" + str(
                data["exp_date"]) + "</td><td>" + str(data["days_to_expire"]) + "</td></tr>"
    SSLCertificates += """</body>
            </html>"""

    # Write data to a file and attach it to the email

    f = open('SSLCertificates.html', 'w')
    f.write(SSLCertificates)
    f.close()
    filename = 'SSLCertificates.html'
    attachment = open(filename, 'rb')

    # Setup email attachment

    msg.attach(MIMEText(SSLCertificates, 'html'))
    part = MIMEBase('application', 'octet-stream')
    part.set_payload(attachment.read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', "attachment; filename=" + filename)

    # Send email

    msg.attach(part)
    text = msg.as_string()
    server = smtplib.SMTP('smtp.server.com', 25)
    server.sendmail(email_sen, email_rec, text)
    server.quit()

# Logging for errors

except Exception as e:
    logging.warning("ERROR ENCOUNTERED! \n\n")
    logging.warning(str(traceback.format_exc()))
python ssl exception ssl-certificate pyopenssl
1个回答
0
投票

您有

logger.warning('Error on connection to Server,', str(ip))

但应该是:

logger.warning('Error on connection to Server "%s"', str(ip))

或同等学历。

您正在传递一个额外的参数str(ip),但是消息中没有放置它的占位符,因此,错误的以下部分:

  File "E:\Python36\lib\logging\__init__.py", line 338, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
  File "ssl_nag_script_test.py", line 106, in <module>
    logger.warning('Error on connection to Server,', str(ip))
© www.soinside.com 2019 - 2024. All rights reserved.