91 lines
2.3 KiB
Python
Executable File
91 lines
2.3 KiB
Python
Executable File
#!/usr/bin/python2
|
|
|
|
"""
|
|
usage:
|
|
./dhcp_failed_machines.py /var/log/dhcp.log
|
|
|
|
You can also run it directly on the gzip'd logs.
|
|
|
|
This script basically expects to run from the dhcp machine, as it looks at
|
|
/etc/dhcp/dhcpd.conf to be able to do reverse DNS lookups. It also expects the
|
|
dhcp log to be copied to some local file.
|
|
|
|
If you're lucky, there might still be a copy of this script already on the dhcp
|
|
server at /tmp/looky.py.
|
|
"""
|
|
|
|
import gzip
|
|
import itertools
|
|
import pprint
|
|
import re
|
|
import sys
|
|
|
|
lookups = {}
|
|
|
|
with open('/etc/dhcp/dhcpd.conf', 'r') as f:
|
|
for line in f:
|
|
if line.startswith('#'):
|
|
continue
|
|
if line.split() and line.split()[0] == 'host':
|
|
hostconf = list(itertools.takewhile(lambda x: x.strip() != '}', f))
|
|
d = dict([h.strip().split()[-2:] for h in hostconf])
|
|
hostname = d['ddns-hostname'].replace('"', '').replace(';', '')
|
|
lookups[d['fixed-address'].replace(';', '')] = hostname
|
|
|
|
|
|
offers = {}
|
|
offenders = set()
|
|
restarts = []
|
|
|
|
rgx = re.compile(
|
|
r'(?P<command>[A-Z]+) (?:from|on|for) (?P<host>\d+.\d+.\d+.\d+)')
|
|
server_restart_str = 'Internet Systems Consortium'
|
|
|
|
|
|
def open_file(f):
|
|
if f.endswith('.gz'):
|
|
return gzip.open(f, 'r')
|
|
else:
|
|
return open(f, 'r')
|
|
|
|
with open_file(sys.argv[1]) as f:
|
|
for line in f:
|
|
if server_restart_str in line:
|
|
restarts.append(line)
|
|
continue
|
|
m = rgx.search(line)
|
|
if m:
|
|
command = m.group('command')
|
|
host = m.group('host')
|
|
if command == 'DHCPOFFER':
|
|
offers[host] = offers.get(host, 0) + 1
|
|
if offers[host] > 2:
|
|
offenders.add(host)
|
|
if command == 'DHCPREQUEST':
|
|
offers[host] = 0
|
|
|
|
if restarts:
|
|
print 'DHCP restarts:\n %s' % ''.join(restarts)
|
|
|
|
def lookup(h):
|
|
return lookups.get(h, h)
|
|
|
|
hosts = sorted([lookup(h) for h in offenders])
|
|
if len(sys.argv) == 2:
|
|
pprint.pprint(hosts)
|
|
else:
|
|
warning = int(sys.argv[2])
|
|
critical = int(sys.argv[3])
|
|
if len(offenders) > critical:
|
|
print ('DHCP Critical, number of duts with DHCP failure is %d: %s' %
|
|
(len(hosts), ', '.join(hosts)))
|
|
sys.exit(2)
|
|
elif len(offenders) > warning:
|
|
print ('DHCP Warning, number of duts with DHCP failure is %d: %s' %
|
|
(len(hosts), ', '.join(hosts)))
|
|
sys.exit(1)
|
|
else:
|
|
print ('DHCP OK, number of duts with DHCP failure is %d: %s' %
|
|
(len(hosts), ', '.join(hosts)))
|
|
sys.exit(0)
|