Handling error for Getting a socket.gaierror: [Errno 11001] getaddrinfo failed using pyopenssl in Python
Handling error for Getting a socket.gaierror: [Errno 11001] getaddrinfo failed using pyopenssl in Python
总结:
我会尝试在第一次通过时进行解释,但如果我遗漏了一些相关细节,请告诉我,我会跟进。我正在从文本文件中获取服务器列表,并使用 pyopenssl 解析、连接和检索 SSL 证书信息。根据到期日期,我正在计算证书到期前的天数。我的结果通过数组传递、格式化,然后通过电子邮件发送。
它运行完美,直到我的一台服务器无法解析并且我得到 socket.gaierror。
问题: 当主机没有解决时,它会破坏我的结果,我收到以下错误。尽管它正确地记录了错误,但我正在尝试传递一些东西,这些东西会以主机、主机名、到期日期和到期天数的格式记录我的结果中的异常,我将能够传递给 table 和发送电子邮件。我希望它在主机字段 "Unable to resolve" 中注明,并且可能只是“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 = 'sen@email.com'
email_rec = 'rec@email.com'
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()))
你有
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))
总结: 我会尝试在第一次通过时进行解释,但如果我遗漏了一些相关细节,请告诉我,我会跟进。我正在从文本文件中获取服务器列表,并使用 pyopenssl 解析、连接和检索 SSL 证书信息。根据到期日期,我正在计算证书到期前的天数。我的结果通过数组传递、格式化,然后通过电子邮件发送。 它运行完美,直到我的一台服务器无法解析并且我得到 socket.gaierror。
问题: 当主机没有解决时,它会破坏我的结果,我收到以下错误。尽管它正确地记录了错误,但我正在尝试传递一些东西,这些东西会以主机、主机名、到期日期和到期天数的格式记录我的结果中的异常,我将能够传递给 table 和发送电子邮件。我希望它在主机字段 "Unable to resolve" 中注明,并且可能只是“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 = 'sen@email.com'
email_rec = 'rec@email.com'
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()))
你有
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))