Nicht mit Ubuntu erlebt. Richten Sie vor ungefähr einem Jahr einen DHCP-Server ein, aber erinnern Sie sich nicht an den Befehl zum Anzeigen der aktiven Leases.
27
Überprüfen Sie die Lease-Datei /var/lib/dhcp/dhcpd.leases
Unsere Organisation verwendet ein Python-Skript (siehe unten), um die /var/lib/dhcp/dhcpd.leases
Datei zu untersuchen :
#!/usr/bin/python
import datetime, bisect
def parse_timestamp(raw_str):
tokens = raw_str.split()
if len(tokens) == 1:
if tokens[0].lower() == 'never':
return 'never';
else:
raise Exception('Parse error in timestamp')
elif len(tokens) == 3:
return datetime.datetime.strptime(' '.join(tokens[1:]),
'%Y/%m/%d %H:%M:%S')
else:
raise Exception('Parse error in timestamp')
def timestamp_is_ge(t1, t2):
if t1 == 'never':
return True
elif t2 == 'never':
return False
else:
return t1 >= t2
def timestamp_is_lt(t1, t2):
if t1 == 'never':
return False
elif t2 == 'never':
return t1 != 'never'
else:
return t1 < t2
def timestamp_is_between(t, tstart, tend):
return timestamp_is_ge(t, tstart) and timestamp_is_lt(t, tend)
def parse_hardware(raw_str):
tokens = raw_str.split()
if len(tokens) == 2:
return tokens[1]
else:
raise Exception('Parse error in hardware')
def strip_endquotes(raw_str):
return raw_str.strip('"')
def identity(raw_str):
return raw_str
def parse_binding_state(raw_str):
tokens = raw_str.split()
if len(tokens) == 2:
return tokens[1]
else:
raise Exception('Parse error in binding state')
def parse_next_binding_state(raw_str):
tokens = raw_str.split()
if len(tokens) == 3:
return tokens[2]
else:
raise Exception('Parse error in next binding state')
def parse_rewind_binding_state(raw_str):
tokens = raw_str.split()
if len(tokens) == 3:
return tokens[2]
else:
raise Exception('Parse error in next binding state')
def parse_leases_file(leases_file):
valid_keys = {
'starts': parse_timestamp,
'ends': parse_timestamp,
'tstp': parse_timestamp,
'tsfp': parse_timestamp,
'atsfp': parse_timestamp,
'cltt': parse_timestamp,
'hardware': parse_hardware,
'binding': parse_binding_state,
'next': parse_next_binding_state,
'rewind': parse_rewind_binding_state,
'uid': strip_endquotes,
'client-hostname': strip_endquotes,
'option': identity,
'set': identity,
'on': identity,
'abandoned': None,
'bootp': None,
'reserved': None,
}
leases_db = {}
lease_rec = {}
in_lease = False
in_failover = False
for line in leases_file:
if line.lstrip().startswith('#'):
continue
tokens = line.split()
if len(tokens) == 0:
continue
key = tokens[0].lower()
if key == 'lease':
if not in_lease:
ip_address = tokens[1]
lease_rec = {'ip_address' : ip_address}
in_lease = True
else:
raise Exception('Parse error in leases file')
elif key == 'failover':
in_failover = True
elif key == '}':
if in_lease:
for k in valid_keys:
if callable(valid_keys[k]):
lease_rec[k] = lease_rec.get(k, '')
else:
lease_rec[k] = False
ip_address = lease_rec['ip_address']
if ip_address in leases_db:
leases_db[ip_address].insert(0, lease_rec)
else:
leases_db[ip_address] = [lease_rec]
lease_rec = {}
in_lease = False
elif in_failover:
in_failover = False
continue
else:
raise Exception('Parse error in leases file')
elif key in valid_keys:
if in_lease:
value = line[(line.index(key) + len(key)):]
value = value.strip().rstrip(';').rstrip()
if callable(valid_keys[key]):
lease_rec[key] = valid_keys[key](value)
else:
lease_rec[key] = True
else:
raise Exception('Parse error in leases file')
else:
if in_lease:
raise Exception('Parse error in leases file')
if in_lease:
raise Exception('Parse error in leases file')
return leases_db
def round_timedelta(tdelta):
return datetime.timedelta(tdelta.days,
tdelta.seconds + (0 if tdelta.microseconds < 500000 else 1))
def timestamp_now():
n = datetime.datetime.utcnow()
return datetime.datetime(n.year, n.month, n.day, n.hour, n.minute,
n.second + (0 if n.microsecond < 500000 else 1))
def lease_is_active(lease_rec, as_of_ts):
return timestamp_is_between(as_of_ts, lease_rec['starts'],
lease_rec['ends'])
def ipv4_to_int(ipv4_addr):
parts = ipv4_addr.split('.')
return (int(parts[0]) << 24) + (int(parts[1]) << 16) + \
(int(parts[2]) << 8) + int(parts[3])
def select_active_leases(leases_db, as_of_ts):
retarray = []
sortedarray = []
for ip_address in leases_db:
lease_rec = leases_db[ip_address][0]
if lease_is_active(lease_rec, as_of_ts):
ip_as_int = ipv4_to_int(ip_address)
insertpos = bisect.bisect(sortedarray, ip_as_int)
sortedarray.insert(insertpos, ip_as_int)
retarray.insert(insertpos, lease_rec)
return retarray
##############################################################################
myfile = open('/var/lib/dhcp/dhcpd.leases', 'r')
leases = parse_leases_file(myfile)
myfile.close()
now = timestamp_now()
report_dataset = select_active_leases(leases, now)
print('+------------------------------------------------------------------------------')
print('| DHCPD ACTIVE LEASES REPORT')
print('+-----------------+-------------------+----------------------+-----------------')
print('| IP Address | MAC Address | Expires (days,H:M:S) | Client Hostname ')
print('+-----------------+-------------------+----------------------+-----------------')
for lease in report_dataset:
print('| ' + format(lease['ip_address'], '<15') + ' | ' + \
format(lease['hardware'], '<17') + ' | ' + \
format(str((lease['ends'] - now) if lease['ends'] != 'never' else 'never'), '>20') + ' | ' + \
lease['client-hostname'])
print('+-----------------+-------------------+----------------------+-----------------')
print('| Total Active Leases: ' + str(len(report_dataset)))
print('| Report generated (UTC): ' + str(now))
print('+------------------------------------------------------------------------------')
Wenn Sie NetworkManager verwenden (was bei vielen Distributionen standardmäßig der
.lease
Fall ist ), befinden sich die Dateien in/var/lib/NetworkManager
quelle
Hier ist ein großartiger Befehl mit CLI: Sie können in das Verzeichnis wechseln, in dem sich die
dhcpd.log
Datei befindet, und Folgendes tun:Das zeigt Ihnen, wie Leasingverträge vom Server in Echtzeit ausgestellt werden.
Sie können auch tun:
cat /var/lib/dhcpd/dhcpd.leases
um Leasingverträge anzuzeigen, die in der Leasingdatei enthalten sinddhcpd.leases
quelle
Ich benutze dieses Skript:
Sie können es an Ihre Bedürfnisse anpassen.
Es gibt auch Perl-Module, die Sie ausprobieren sollten, wenn Sie eine vage Vorstellung von Perl haben: Net :: ISC :: DHCPd :: Leases , POE :: Filter :: DHCPd :: Lease oder Text :: DHCPLeases .
Der letzte kann mit installiert werden
Die anderen mit
cpan -i
.Leider habe ich keinen von ihnen ausprobiert, weil ich mein Drehbuch schon hatte, als ich sie bemerkte.
quelle
Wenn Sie etwas in einer GUI wollen, werfen Sie einen Blick auf Glass . Es wird als Web-App ausgeführt und bietet Zugriff auf Ihre DHCPd-Konfigurationsdatei sowie auf die Leases. Es werden Diagramme und Statistiken verwendet, die hilfreich sind, wenn Sie mehrere Subnetze oder Pools haben.
Mir gefällt auch, dass es mich benachrichtigt, wenn die Aktivität ausgeschaltet zu sein scheint - Geräte, die keine Adressen in großen Mengen erhalten, oder zu viele Anfragen von einzelnen Clients. Ich benutze es jetzt seit einem Monat und ich liebe es.
quelle