Jawaban:
Coba periksa file sewa /var/lib/dhcp/dhcpd.leases
Organisasi kami menggunakan skrip Python, seperti yang diposting di bawah ini, untuk memeriksa /var/lib/dhcp/dhcpd.leases
file:
#!/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('+------------------------------------------------------------------------------')
Jika Anda menggunakan NetworkManager (yang merupakan default di banyak distribusi) .lease
file berada di/var/lib/NetworkManager
$ sudo ls -al /var/lib/NetworkManager/*.lease
-rw-r--r-- 1 root root 399 Jun 12 10:23 /var/lib/NetworkManager/dhclient-6aef9d76-0f6a-46e3-8235-a4405a695b1a-eth0.lease
-rw-r--r-- 1 root root 856 Jun 12 10:30 /var/lib/NetworkManager/dhclient-86e97e19-0a11-4606-8edf-5a179ec6f82e-eth0.lease
-rw-r--r-- 1 root root 800 Jun 12 10:30 /var/lib/NetworkManager/dhclient-d0f4b29f-3059-4f55-a8d2-34db34310384-wlan0.lease
Berikut ini perintah hebat menggunakan CLI - Anda dapat pergi ke direktori tempat dhcpd.log
file berada dan lakukan:
tail -f dhcpd.log
Itu akan menunjukkan Anda sewa karena mereka dikeluarkan oleh server secara real time.
Anda juga dapat melakukan:
cat /var/lib/dhcpd/dhcpd.leases
untuk melihat sewa yang ada di file sewa dhcpd.leases
Saya menggunakan skrip ini:
#!/usr/bin/perl
my $VERSION=0.03;
my $leases_file = "/var/lib/dhcp/dhcpd.leases";
use strict;
use Date::Parse;
my $now = time;
my %seen; # leases file has dupes (because logging failover stuff?). This hash will get rid of them.
open(L, $leases_file) or die "Cant open $leases_file : $!\n";
undef $/;
my @records = split /^lease\s+([\d\.]+)\s*\{/m, <L>;
shift @records; # remove stuff before first "lease" block
## process 2 array elements at a time: ip and data
foreach my $i (0 .. $#records) {
next if $i % 2;
my $ip;
($ip, $_) = @records[$i, $i+1];
s/^\n+//; # && warn "leading spaces removed\n";
s/[\s\}]+$//; # && warn "trailing junk removed\n";
my ($s) = /^\s* starts \s+ \d+ \s+ (.*?);/xm;
my ($e) = /^\s* ends \s+ \d+ \s+ (.*?);/xm;
my $start = str2time($s);
my $end = str2time($e);
my %h; # to hold values we want
foreach my $rx ('binding', 'hardware', 'client-hostname') {
my ($val) = /^\s*$rx.*?(\S+);/sm;
$h{$rx} = $val;
}
my $formatted_output;
if ($end && $end < $now) {
$formatted_output =
sprintf "%-15s : %-26s " . "%19s " . "%9s " . "%24s " . "%24s\n",
$ip, $h{'client-hostname'}, "" , $h{binding}, "expired" , scalar(localtime $end);
}
else {
$formatted_output =
sprintf "%-15s : %-26s " . "%19s " . "%9s " . "%24s -- " . "%24s\n",
$ip, $h{'client-hostname'}, "($h{hardware})", $h{binding}, scalar(localtime $start), scalar(localtime $end);
}
next if $seen{$formatted_output};
$seen{$formatted_output}++;
print $formatted_output;
}
Anda mungkin ingin menyesuaikannya sesuai dengan kebutuhan Anda.
Ada juga modul Perl yang mungkin ingin Anda coba jika Anda memiliki gagasan yang kabur tentang Perl: Net :: ISC :: DHCPd :: Sewa , POE :: Filter :: DHCPd :: Sewa atau Teks :: DHCPLease .
Yang terakhir dapat diinstal dengan
sudo apt-get install libtext-dhcpleases-perl
Yang lain dengan cpan -i
.
Sayangnya, saya belum mencoba salah satu dari mereka, karena saya sudah memiliki skrip ketika saya perhatikan.
Jika Anda menginginkan sesuatu dalam GUI, lihatlah Glass . Ini berjalan sebagai aplikasi web, dan menyediakan akses ke file konfigurasi DHCPd Anda, serta sewa. Ini menggunakan grafik dan statistik, yang berguna jika Anda memiliki beberapa subnet atau kumpulan.
Saya juga suka itu mengingatkan saya jika aktivitas tampak tidak aktif - perangkat tidak mendapatkan alamat secara massal, atau terlalu banyak permintaan dari klien tunggal. Saya sudah menggunakannya selama sebulan sekarang, dan saya menyukainya.