use*_*262 19 certificate openssl ssl-certificate
我可以使用此 OpenSSL 命令找出 ssl 证书的到期日期:
openssl x509 -noout -in <filename> -enddate
Run Code Online (Sandbox Code Playgroud)
但是,如果证书分散在不同的 Web 服务器上,您如何在所有服务器上找到所有这些证书的到期日期?
似乎有一种方法可以连接到其他主机,但我不确定如何使用此方法获取到期日期:
openssl s_client -connect host:port
Run Code Online (Sandbox Code Playgroud)
Sir*_*rex 16
我遇到了同样的问题并写了这个......它快速而肮脏,但应该可以工作。它将记录(并在调试时打印到屏幕上)任何尚未有效或在接下来的 90 天内到期的证书。可能包含一些错误,但请随意整理。
#!/bin/sh
DEBUG=false
warning_days=90 # Number of days to warn about soon-to-expire certs
certs_to_check='serverA.test.co.uk:443
serverB.test.co.uk:8140
serverC.test.co.uk:443'
for CERT in $certs_to_check
do
$DEBUG && echo "Checking cert: [$CERT]"
output=$(echo | openssl s_client -connect ${CERT} 2>/dev/null |\
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' |\
openssl x509 -noout -subject -dates 2>/dev/null)
if [ "$?" -ne 0 ]; then
$DEBUG && echo "Error connecting to host for cert [$CERT]"
logger -p local6.warn "Error connecting to host for cert [$CERT]"
continue
fi
start_date=$(echo $output | sed 's/.*notBefore=\(.*\).*not.*/\1/g')
end_date=$(echo $output | sed 's/.*notAfter=\(.*\)$/\1/g')
start_epoch=$(date +%s -d "$start_date")
end_epoch=$(date +%s -d "$end_date")
epoch_now=$(date +%s)
if [ "$start_epoch" -gt "$epoch_now" ]; then
$DEBUG && echo "Certificate for [$CERT] is not yet valid"
logger -p local6.warn "Certificate for $CERT is not yet valid"
fi
seconds_to_expire=$(($end_epoch - $epoch_now))
days_to_expire=$(($seconds_to_expire / 86400))
$DEBUG && echo "Days to expiry: ($days_to_expire)"
warning_seconds=$((86400 * $warning_days))
if [ "$seconds_to_expire" -lt "$warning_seconds" ]; then
$DEBUG && echo "Cert [$CERT] is soon to expire ($seconds_to_expire seconds)"
logger -p local6.warn "cert [$CERT] is soon to expire ($seconds_to_expire seconds)"
fi
done
Run Code Online (Sandbox Code Playgroud)
如果在 OS X 上使用,您可能会发现该date命令无法正常工作。这是由于此实用程序的 Unix 和 Linux 版本存在差异。链接的帖子有使这项工作的选项。
小智 11
只需运行下面的命令,它将提供到期日期:
echo q | openssl s_client -connect google.com.br:443 | openssl x509 -noout -enddate
Run Code Online (Sandbox Code Playgroud)
您可以将此命令用于批处理文件,以便为更多远程服务器收集此信息。
下面是我的脚本,作为 nagios 中的检查。它连接到特定主机,它验证证书在 -c/-w 选项设置的阈值内是否有效。它可以检查证书的 CN 是否与您期望的名称匹配。
您需要 python openssl 库,我使用 python 2.7 进行了所有测试。
让 shell 脚本多次调用它是微不足道的。该脚本返回关键/警告/正常状态的标准 nagios 退出值。
可以像这样执行对 Google 证书的简单检查。
./check_ssl_certificate -H www.google.com -p 443 -n www.google.com
Expire OK[108d] - CN OK - cn:www.google.com
Run Code Online (Sandbox Code Playgroud)
check_ssl_certificate
#!/usr/bin/python
"""
Usage: check_ssl_certificate -H <host> -p <port> [-m <method>]
[-c <days>] [-w <days>]
-h show the help
-H <HOST> host/ip to check
-p <port> port number
-m <method> (SSLv2|SSLv3|SSLv23|TLSv1) defaults to SSLv23
-c <days> day threshold for critical
-w <days> day threshold for warning
-n name Check CN value is valid
"""
import getopt,sys
import __main__
from OpenSSL import SSL
import socket
import datetime
# On debian Based systems requires python-openssl
def get_options():
"get options"
options={'host':'',
'port':'',
'method':'SSLv23',
'critical':5,
'warning':15,
'cn':''}
try:
opts, args = getopt.getopt(sys.argv[1:], "hH:p:m:c:w:n:", ['help', "host", 'port', 'method'])
except getopt.GetoptError as err:
# print help information and exit:
print str(err) # will print something like "option -a not recognized"
usage()
sys.exit(2)
for o, a in opts:
if o in ("-h", "--help"):
print __main__.__doc__
sys.exit()
elif o in ("-H", "--host"):
options['host'] = a
pass
elif o in ("-p", "--port"):
options['port'] = a
elif o in ("-m", "--method"):
options['method'] = a
elif o == '-c':
options['critical'] = int(a)
elif o == '-w':
options['warning'] = int(a)
elif o == '-n':
options['cn'] = a
else:
assert False, "unhandled option"
if (''==options['host'] or
''==options['port']):
print __main__.__doc__
sys.exit()
if options['critical'] >= options['warning']:
print "Critical must be smaller then warning"
print __main__.__doc__
sys.exit()
return options
def main():
options = get_options()
# Initialize context
if options['method']=='SSLv3':
ctx = SSL.Context(SSL.SSLv3_METHOD)
elif options['method']=='SSLv2':
ctx = SSL.Context(SSL.SSLv2_METHOD)
elif options['method']=='SSLv23':
ctx = SSL.Context(SSL.SSLv23_METHOD)
else:
ctx = SSL.Context(SSL.TLSv1_METHOD)
# Set up client
sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.connect((options['host'], int(options['port'])))
# Send an EOF
try:
sock.send("\x04")
sock.shutdown()
peer_cert=sock.get_peer_certificate()
sock.close()
except SSL.Error,e:
print e
exit_status=0
exit_message=[]
cur_date = datetime.datetime.utcnow()
cert_nbefore = datetime.datetime.strptime(peer_cert.get_notBefore(),'%Y%m%d%H%M%SZ')
cert_nafter = datetime.datetime.strptime(peer_cert.get_notAfter(),'%Y%m%d%H%M%SZ')
expire_days = int((cert_nafter - cur_date).days)
if cert_nbefore > cur_date:
if exit_status < 2:
exit_status = 2
exit_message.append('C: cert is not valid')
elif expire_days < 0:
if exit_status < 2:
exit_status = 2
exit_message.append('Expire critical (expired)')
elif options['critical'] > expire_days:
if exit_status < 2:
exit_status = 2
exit_message.append('Expire critical')
elif options['warning'] > expire_days:
if exit_status < 1:
exit_status = 1
exit_message.append('Expire warning')
else:
exit_message.append('Expire OK')
exit_message.append('['+str(expire_days)+'d]')
for part in peer_cert.get_subject().get_components():
if part[0]=='CN':
cert_cn=part[1]
if options['cn']!='' and options['cn'].lower()!=cert_cn.lower():
if exit_status < 2:
exit_status = 2
exit_message.append(' - CN mismatch')
else:
exit_message.append(' - CN OK')
exit_message.append(' - cn:'+cert_cn)
print ''.join(exit_message)
sys.exit(exit_status)
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42329 次 |
| 最近记录: |