Skip to content
This repository has been archived by the owner on Jan 30, 2024. It is now read-only.

Commit

Permalink
Merge pull request #10144 from alphagov/move-check_puppetdb_ssh_host_…
Browse files Browse the repository at this point in the history
…keys_check

Import `check_puppetdb_ssh_host_keys` from `alphagov/nagios-plugins`
  • Loading branch information
Issy Long committed Feb 14, 2020
2 parents 798b35f + 098372f commit 4e48ca0
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 1 deletion.
@@ -1,4 +1,4 @@
define command {
command_name check_puppetdb_ssh_host_keys
command_line /usr/local/bin/check_puppetdb_ssh_host_keys
command_line /usr/lib/nagios/plugins/check_puppetdb_ssh_host_keys
}
@@ -0,0 +1,141 @@
#!/usr/bin/env python2
import json
import base64
import hashlib
import string
import urllib
import urllib2

from optparse import OptionParser

class CheckException(Exception):
def __init__(self, message, severity):
Exception.__init__(self, message)
self.severity = severity


def nagios_message(message, exitcode):
"""Format a Nagios message and exit"""
print message
sys.exit(exitcode)


def nagios_ok(message):
"""Nagios OK message"""
raise CheckException("OK: %s" % message, 0)

def nagios_critical(message):
"""Nagios CRITICAL message"""
raise CheckException("CRITICAL: %s" % message, 2)


def nagios_unknown(message):
"""Nagios UNKNOWN message"""
raise CheckException("UNKNOWN: %s" % message, 3)


FACTS = ('sshdsakey', 'sshecdsakey', 'sshrsakey')


parser = OptionParser(description='Find duplicate SSH host keys in PuppetDB')
parser.add_option(
'-H', '--host',
dest='puppetdb_host', type='str', default='puppetdb.cluster',
help='PuppetDB hostname'
)
parser.add_option(
'-s', '--ssl',
dest='puppetdb_ssl', action='store_true',
help='PuppetDB use SSL/TLS'
)
parser.add_option(
'-V', '--api-version',
dest='puppetdb_version', type='int', default=2,
help='PuppetDB API version'
)


def check(url):
"""Perform duplicate SSH host key checks"""
facts = query_puppetdb(url)
if count_hosts(facts) <= 1:
nagios_unknown('Need at least two nodes in PuppetDB')

dupes = find_dupes(facts)
if len(dupes) == 0:
nagios_ok('No duplicate SSH host keys found')

msg = ['Found hosts with duplicate SSH host keys']
for key, hosts in dupes.items():
msg.append('')
msg.append(fingerprint(key))
for host in hosts:
msg.append('- {0}'.format(host))

nagios_critical("\n".join(msg))


def query_puppetdb(base_url):
"""Query a list of certain facts from PuppetDB"""
query = '["or", {0}]'.format(', '.join([
'["=", "name", "{0}"]'.format(fact)
for fact in FACTS
]))
query_string = urllib.urlencode({'query': query})
url = '{0}/facts?{1}'.format(
base_url,
query_string,
)

res = urllib2.urlopen(url)
return json.load(res)


def count_hosts(facts):
"""Count the number of unique hosts"""
hosts = set([fact['certname'] for fact in facts])
return len(hosts)


def find_dupes(facts):
"""Find hosts with duplicate SSH host keys from PuppetDB output"""
hosts_by_key = {}
for fact in facts:
hosts_by_key.setdefault(
fact['value'],
set(),
).add(fact['certname'])

return {
k: v
for k, v in hosts_by_key.items()
if len(v) > 1
}


def fingerprint(key):
"""Convert an SSH RSA/DSA public key to a fingerprint string"""
key = base64.b64decode(key.encode('ascii'))
fp_plain = hashlib.md5(key).hexdigest()
return ':'.join(a+b for a,b in zip(fp_plain[::2], fp_plain[1::2]))


def main():
try:
opts, args = parser.parse_args()
url = '{0}://{1}/v{2}'.format(
'https' if opts.puppetdb_ssl else 'http',
opts.puppetdb_host,
opts.puppetdb_version,
)
check(url)

except CheckException as e:
nagios_message(e.message, e.severity)
except Exception as e:
# Catching all other exceptions
nagios_message("Exception: %s" % e, 3)


if __name__ == '__main__':
main()
4 changes: 4 additions & 0 deletions modules/monitoring/manifests/checks.pp
Expand Up @@ -173,6 +173,10 @@

# In AWS this is liable to happen more often as machines come and go
unless $::aws_migration {
icinga::plugin { 'check_puppetdb_ssh_host_keys':
source => 'puppet:///modules/monitoring/usr/lib/nagios/plugins/check_puppetdb_ssh_host_keys',
}

icinga::check_config { 'check_puppetdb_ssh_host_keys':
source => 'puppet:///modules/monitoring/etc/nagios3/conf.d/check_puppetdb_ssh_host_keys.cfg',
require => Class['monitoring::client'],
Expand Down

0 comments on commit 4e48ca0

Please sign in to comment.