我正在编写一个Nagios插件,它使用sslyze的xml输出来计算基于Qualys Server Rating Guide的SSL分数。
这是我的代码:
if certificateMatchesServerHostname == 'True' and expire_in.days > 0 and validationResult == 'ok':
...
final_score = protocol_score * 0.3 + key_score * 0.3 + cipher_score * 0.4
return [nap.Metric('sslscore', final_score, min=0, max=100)]
elif certificateMatchesServerHostname != 'True':
return [nap.Metric('serverHostname', hostnameValidation[0].attrib['serverHostname'])]
elif expire_in.days <= 0:
return [nap.Metric('expireInDays', expire_in.days)]
elif validationResult != 'ok':
return [nap.Metric('validationResult', validationResult)]
@nap.guarded
def main():
check = nap.Check(
SslConfiguration(),
nap.ScalarContext('sslscore', nap.Range('@65:80'), nap.Range('@0:65')),
nap.ScalarContext('serverHostname', fmt_metric='The certificate does not match the host name {value}'),
nap.ScalarContext('expireInDays', nap.Range('@:0'), fmt_metric='The certificate expired {value} days ago'),
nap.ScalarContext('validationResult', fmt_metric='This server\'s certificate is not trusted: {value}'))
check.main(timeout=60)
我必须使用多个ScalarContext的原因是,如果SSL证书有问题,我想显示不同的fmt_metric
:不匹配,过期,不信任,......
使用上面的代码,输出看起来像这样:
SSLCONFIGURATION CRITICAL - The certificate does not match the host name a.b.c.d (outside range 0:)
critical: The certificate does not match the host name a.b.c.d (outside range 0:)
| serverHostname=a.b.c.d
我真正想要展示的是:
SSLCONFIGURATION CRITICAL - final_score is 0 (The certificate does not match the host name a.b.c.d) | sslscore=0;@65:80;@65;0;100
所以,我有一些问题:
如何在一个上下文fmt_metric
中基于sslscore值显示不同的sslscore
?
如何删除冗余线路(第二个)?
critical: The certificate does not match the host name a.b.c.d (outside range 0:)
如何将指标(第3行)移到第一行的末尾?
答案 0 :(得分:0)
在朋友的帮助下,我终于解决了这个问题。
关于第一个问题,我们可以使用nagiosplugin.summary
模块来更改状态行,如下所示:
class SslConfiguration(nap.Resource):
def __init__(self, host, port):
self.host = host
self.port = port
def check(self):
...
if hostname_validation.startswith('OK') and expire_in.days > 0 and is_trusted == 'OK':
final_score = protocol_score * 0.3 + key_score * 0.3 + cipher_score * 0.4
else:
final_score = 0
return (hostname_validation, is_trusted, expire_in.days, final_score)
def probe(self):
if self.check()[3] > 0:
return [nap.Metric('sslscore', self.check()[3])]
elif not self.check()[0].startswith('OK'):
return [nap.Metric('sslscore', 0, context='serverHostname')]
elif self.check()[1] != 'OK':
return [nap.Metric('sslscore', 0, context='validationResult')]
elif self.check()[2] <= 0:
return [nap.Metric('sslscore', 0, context='expireInDays')]
class SslSummary(nap.Summary):
def __init__(self, host, port):
self.host = host
self.port = port
def status_line(self, results):
ssl_configuration = SslConfiguration(self.host, self.port)
if results['sslscore'].context.name == 'serverHostname':
return "sslscore is 0 ({0})".format(ssl_configuration.check()[0])
elif results['sslscore'].context.name == 'validationResult':
return "sslscore is 0 ({0})".format(ssl_configuration.check()[1])
elif results['sslscore'].context.name == 'expireInDays':
return "sslscore is 0 (The certificate expired {0} days ago)".format(ssl_configuration.check()[2])
def problem(self, results):
return self.status_line(results)
可以通过将main()
的{{3}}参数设置为零来解决第二个和第三个问题:
@nap.guarded
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-H', '--host', type=str, required=True)
parser.add_argument('-p', '--port', type=int, default=443)
parser.add_argument('-v', '--verbose', action='count', default=0, help="increase output verbosity (use up to 3 times)")
parser.add_argument('-t', '--timeout', type=int, default=60)
args = parser.parse_args()
check = nap.Check(
SslConfiguration(args.host, args.port),
nap.ScalarContext('sslscore', nap.Range('@65:80'), nap.Range('@0:65')),
nap.ScalarContext('serverHostname', nap.Range('@65:80'), nap.Range('@0:65')),
nap.ScalarContext('validationResult', nap.Range('@65:80'), nap.Range('@0:65')),
nap.ScalarContext('expireInDays', nap.Range('@65:80'), nap.Range('@0:65')),
SslSummary(args.host, args.port))
check.main(args.verbose, args.timeout)
现在输出可以帮助系统管理员知道发生了什么:
check_ssl_configuration.py -H google.com
SSLCONFIGURATION OK - sslscore is 87 | sslscore=87.0;@65:80;@65
check_ssl_configuration.py -H 173.194.127.169
SSLCONFIGURATION CRITICAL - sslscore is 0 (FAILED - Certificate does NOT match 173.194.127.169) | sslscore=0;@65:80;@65