Làm thế nào để tôi hiển thị cho thuê dhcp hoạt động


27

Không có kinh nghiệm với Ubuntu. Thiết lập máy chủ dhcp khoảng một năm trước nhưng không nhớ lệnh để xem hợp đồng thuê hoạt động.

Câu trả lời:


27

Hãy thử kiểm tra hồ sơ cho thuê /var/lib/dhcp/dhcpd.leases


23

Tổ chức của chúng tôi sử dụng tập lệnh Python, như được đăng dưới đây, để kiểm tra /var/lib/dhcp/dhcpd.leasestệp:

#!/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('+------------------------------------------------------------------------------')

Tôi thích điều này, vì nó lọc ra các hợp đồng thuê đã hết hạn trước đó (không giống như xem /var/lib/dhcp/dhcpd.lease). Cám ơn vì đã chia sẻ.
Wireblue

3
Không có vấn đề gì, hãy nói với bạn bè của bạn
Luke Luke REINSTATE MONICA của Canada


Cảm ơn Luke. Tôi đã chia sẻ một liên kết đến trang này trên trang Facebook WelcomeToLinux.
LinuxGuru

7

Nếu bạn đang sử dụng Trình quản lý mạng (được mặc định trong nhiều bản phân phối), các .leasetệp sẽ nằm trong/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

Không chắc đây là do Desktop vs Server hoặc phiên bản thay đổi nhưng đây là vị trí chính xác cho Ubuntu Desktop 14.04, nó không nằm trong /var/lib/dhcp/dhcpd.lease như các câu trả lời khác đã đề xuất.
Elijah Lynn

4

Đây là một lệnh tuyệt vời bằng CLI - Bạn có thể vào thư dhcpd.logmục chứa tệp và thực hiện:

tail -f dhcpd.log

Điều đó sẽ cho bạn thấy hợp đồng thuê vì chúng đang được máy chủ cấp trong thời gian thực.

Bạn cũng có thể làm:

cat /var/lib/dhcpd/dhcpd.leases để xem các hợp đồng thuê trong hồ sơ cho thuê dhcpd.leases


4

Tôi sử dụng tập lệnh này:

#!/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;
}

Bạn có thể muốn điều chỉnh nó cho phù hợp với nhu cầu của bạn.

Ngoài ra còn có các mô-đun Perl mà bạn có thể muốn thử nếu bạn có một khái niệm mơ hồ về Perl: Net :: ISC :: DHCPd :: L thuê , POE :: Filter :: DHCPd :: Hire hoặc Text :: DHCPLease .

Cái cuối cùng có thể được cài đặt với

sudo apt-get install libtext-dhcpleases-perl

Những người khác với cpan -i.

Thật không may, tôi đã không thử bất kỳ trong số họ, bởi vì tôi đã có kịch bản của mình khi tôi nhận thấy chúng.


Tôi muốn thử tập lệnh Perl của bạn nhưng gặp lỗi. Không thể sử dụng toàn cầu $ _ trong "của tôi" tại ./bin/ShowDhcpLease.pl dòng 22, gần ", $ _"
LinuxGuru

@LinuxGuru: Đó chỉ là một cảnh báo và kịch bản vẫn hoạt động (ít nhất là đối với tôi). Nhưng dù sao, tôi đã thay đổi nó để loại bỏ cảnh báo đó.
mivk

0

Nếu bạn muốn một cái gì đó trong GUI, hãy xem Glass . Nó chạy như một ứng dụng web và cung cấp quyền truy cập vào tệp cấu hình DHCPd của bạn, cũng như cho thuê. Nó sử dụng biểu đồ và số liệu thống kê, rất hữu ích nếu bạn có nhiều mạng con hoặc nhóm.

Tôi cũng thích nó thông báo cho tôi nếu hoạt động có vẻ tắt - thiết bị không nhận được địa chỉ hoặc quá nhiều yêu cầu từ các khách hàng. Tôi đã sử dụng nó được một tháng và tôi rất thích nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.