Atanmış dhcp adreslerini listeleme komutu


21

Dhcpd sunucusuna hangi adreslerin atandığını sormak için kullanabileceğim bir komut var mı?

Yanıtlar:


21

Hayır, bu bilgi sunucusu tarafını yalnızca DHCP sunucusundan alabilirsiniz. Bu bilgiler, ISC'nin DHCP sunucusunu kullanıyorsanız DHCP sunucusunun .lease dosyasında bulunur /var/lib/dhcpd/dhcpd.leases.

Misal

$ more /var/lib/dhcpd/dhcpd.leases
# All times in this file are in UTC (GMT), not your local timezone.   This is
# not a bug, so please don't ask about it.   There is no portable way to
# store leases in the local timezone, so please don't request this as a
# feature.   If this is inconvenient or confusing to you, we sincerely
# apologize.   Seriously, though - don't ask.
# The format of this file is documented in the dhcpd.leases(5) manual page.
# This lease file was written by isc-dhcp-V3.0.5-RedHat

lease 192.168.1.100 {
  starts 4 2011/09/22 20:27:28;
  ends 1 2011/09/26 20:27:28;
  tstp 1 2011/09/26 20:27:28;
  binding state free;
  hardware ethernet 00:1b:77:93:a1:69;
  uid "\001\000\033w\223\241i";
}
...
...

3
Ubuntu'da, yol /var/lib/dhcp/dhcpd.leases(yani dilkin sonunda hayır dhcp...)
Alexis Wilke

20

isc-dhcpdpaket sürümü 4.3.1kiraları listelemek için şu komutu içerir:

dhcp-lease-list --lease PATH_TO_LEASE_FILE

Bu, eski DHCP sürümlerini de destekleyen basit bir perl komut dosyasıdır. Debian kaynak kodunda veya resmi DHCP dağıtımında (in contrib/) bir kopyasını da görebilirsiniz .

Çıktı güzel:

$ perl contrib/dhcp-lease-list.pl --lease /var/db/dhcpd/dhcpd.leases
To get manufacturer names please download http://standards.ieee.org/regauth/oui/oui.txt to /usr/local/etc/oui.txt
MAC                IP              hostname       valid until         manufacturer
===============================================================================================
90:27:e4:f9:9d:d7  192.168.0.182   iMac-de-mac    2015-12-12 01:37:06 -NA-
d8:a2:5e:94:40:81  192.168.0.178   foo-2          2015-12-12 01:04:56 -NA-
e8:9a:8f:6e:0f:60  192.168.0.127   angela         2015-12-11 23:55:32 -NA-
ec:55:f9:c5:f2:55  192.168.0.179   angela         2015-12-11 23:54:56 -NA-
f0:4f:7c:3f:9e:dc  192.168.0.183   kindle-1234567 2015-12-11 23:54:31 -NA-
f4:ec:38:e2:f9:67  192.168.0.185   -NA-           2015-12-11 23:55:40 -NA-
f8:d1:11:b7:5a:62  192.168.0.184   -NA-           2015-12-11 23:57:34 -NA-

oui.txtDosyayı önerildiği gibi indirirseniz daha güzel , ancak aşağıdaki yamayı uygulamadığınız sürece çıktı bozulabilir:

--- dhcp-lease-list.pl.orig     2015-12-12 12:30:00.000000000 -0500
+++ dhcp-lease-list.pl  2015-12-12 12:54:31.000000000 -0500
@@ -41,7 +41,7 @@
     if (defined $oui) {
        $manu = join('-', ($_[0] =~ /^(..):(..):(..):/));
        $manu = `grep -i '$manu' $oui | cut -f3`;
-       chomp($manu);
+       $manu =~ s/^\s+|\s+$//g;
     }

     return $manu;
@@ -142,7 +142,7 @@
     }
     foreach (@leases) {
        if ($opt_format eq 'human') {
-          printf("%-19s%-16s%-15s%-20s%-20s\n",
+          printf("%-19s%-16s%-14.14s %-20s%-20s\n",
                  $_->{'mac'},       # MAC
                  $_->{'ip'},        # IP address
                  $_->{'hostname'},  # hostname

Bu düzeltme eki ISC-Bugs # 41288 olarak yukarı yönlü olarak gönderildi ve incelenmeyi bekliyor.


8

egrep komutu çıktı almak için kullanılabilir:

egrep "lease|hostname|hardware|\}" /var/lib/dhcpd/dhcpd.leases

Çıktı:

lease 192.168.11.10 {
  hardware ethernet 20:6a:8a:55:19:0a;
  client-hostname "Maryam-PC";
}
lease 192.168.11.7 {
  hardware ethernet 00:16:ea:51:d3:12;
  client-hostname "parsoon";
}
lease 192.168.11.3 {
  hardware ethernet 00:17:c4:3f:84:e3;
  client-hostname "zahra-ubuntu";
}
lease 192.168.11.5 {
  hardware ethernet 58:b0:35:f1:31:2f;
}

4

Yukarıdaki cevapların çoğu kısmi. Ve dürüst olmak gerekirse, basit bir çözüm yoktur. 1) dhcpd.leases veritabanı dosyasını ayrıştırabilir ve aktif kiralamalar hakkında bilgi alabilirsiniz, ancak herhangi bir FIXED adresi hakkında bilgi alamazsınız (aşağıdaki gibi bir satırla atanır:

host switch1      { hardware ethernet a1:b2:c3:d7:2f:bc ; fixed-address switch1.mydomain.com; }

Ve bu da bir dhcp ack'in makineye en son ne zaman gönderildiği hakkında gerçekten herhangi bir bilgi vermiyor.

2) Öte yandan, ack satırlarını aramak için dhcpd.log dosyasını ayrıştırabilirsiniz (şöyle görünürler):

2017-03-12T08:44:52.421114+01:00, Linuxx, info, dhcpd: DHCPREQUEST for 10.0.0.63 from 68:ab:35:59:9c:a1 via 10.0.0.1 
2017-03-12T08:44:52.421174+01:00, Linuxx, info, dhcpd: DHCPACK on 10.0.0.63 to 68:ab:35:59:9c:a1 via 10.0.0.1

Ama gerçekten yapman gereken, İKİ yapmak. İlk olarak günlük dosyasını ayrıştırın ve daha sonra kira başlangıç-sonu vb. Eksik bilgiler için dosyayı dhcpd.leases dosyasından veritabanıyla alınan bilgilerle güncelleyin.

Şimdi: TÜM aktif kiralamalar ile hem SABİT hem de dinamik bir HTML tablosu oluşturan bir çözüm oluşturana kadar yaklaşık 2 tam iş günü oynadım. İşte cgi-bin klasörünüze veya istediğiniz yere koyabileceğiniz kod.

#!/usr/bin/perl
#####################################################################################
# list dhcpd active leases 
#   - both "fixed" addresses which are normally not placed into leases database
#   - and dynamically given leases which are present in leases DB
# working for isc-dhcpd-server service but should also work for other compatible
# dhcpd servers. 
# produces HTML or CSV list of leases
#
# written by Marcin Gosiewski, BV Grupa s.c. Poland <marcin@gosiewski.pl>
# based on portions of code by Jason Antman <jason@jasonantman.com> 
#
# to make it work change the $logfilename and $leasedbname below and modify
# the regexp in second part of code (see below) to match your log lines format
# also you can optionally turn off reverse dns lookup (see below) which speeds up the process 
# of table creation and is useless unless you have reverse dns populated for 
# your fixed or dynamic leases
#
# CHANGELOG:
#     2017-03-13: initial version
use Socket;
use strict;
use warnings;
no warnings 'uninitialized';

# adjust this to match your files location: both log file and leases
# database. We use 2 last log files from logrotate, but you can add as many as you want
my @logfilenames = ( "/var/log/LOCALAPP.dhcpd.log.1", "/var/log/LOCALAPP.dhcpd.log" );
my $leasedbname = "/var/lib/dhcp/dhcpd.leases";
my %data = ();
# optional, can be modified to produce local time
use Time::Local;
use POSIX 'strftime';
my $now = time();
# local variables, lease information stored here
my $ip=""; 
my $status=""; 
my $interface=""; 
my $sdate="";         # beginning of lease
my $stime=""; 
my $edate="";         # end of lease
my $etime=""; 
my $adate="";         # last update (ACK) sent to requesting server
my $atime="";
my $mac=""; 
my $hostname="";
my $dnsname="";       # reverse dns lookup for host

#######################################################################
# first gather data from logfile for all ACK actions
#######################################################################

# collect all lines from log files into memory...
my @lines = (); my @loglines=(); 
foreach my $logfilename (@logfilenames)
{
  open LOGFILE, '<', $logfilename;
  chomp(@loglines = <LOGFILE>);
  #printf "LINES1: " . scalar @loglines . " in " .$logfilename . "\n";
  push(@lines, @loglines);
  close(LOGFILE);
}
@loglines=();
#printf "TOTAL LINES: " . scalar @lines . "\n";
foreach my $line (@lines)
{
  if ( $line !~ m/dhcpd: DHCPACK/) { next;}
  #printf "LINE: $line\n";

  ###############################
  # Modify the following line to make regexp capture 6 groups from log line:
  # 1 - date
  # 2 - time
  # 3 - ip 
  # 4 - mac
  # 5 - hostname if available
  # 6 - interface
  #$line =~ m/(^.{10})T(.{8}).+,\ dhcpd: DHCPACK on (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) to ((?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}.*) via (.+)/;
  $line =~m/(^.{10})T(.{8}).+,\ dhcpd: DHCPACK on (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) to ((?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}) (.*)via (.+)/;
  # process the input
  $adate="$1";
  $atime="$2";
  $ip="$3";
  $mac="$4";
  $hostname="$5";
  $interface="$6";
  #add some 'known' facts:
  $status="ACK";
  $sdate="";    #"FOREVER";
  $stime="";
  $edate="";
  $etime="";

  #create/update record for this mac_addr
  #you can add extra check here if the IP address is not duplicated within
  #ack history and choose only the newer one. 

  $data{"$mac"}->{'ip'} = "$ip";
  $data{"$mac"}->{'status'} = "$status";
  $data{"$mac"}->{'interface'} = "$interface";
  $data{"$mac"}->{'adate'} = "$adate";
  $data{"$mac"}->{'atime'} = "$atime";
  $data{"$mac"}->{'sdate'} = "$sdate";
  $data{"$mac"}->{'stime'} = "$stime";
  $data{"$mac"}->{'edate'} = "$edate";
  $data{"$mac"}->{'etime'} = "$etime";
  $data{"$mac"}->{'mac'} = "$mac";
  $data{"$mac"}->{'hostname'} = "$hostname";
}
#close(LOGFILE);

#######################################################################
# gather data from lease database for dynamic addresses
# update the records (for existing) or add new records
#######################################################################

my $isdata = 0;
my $type = "";

#this information is not present in leases database so we just set
#it to default values
$interface="dhcpd";
$status="ACTIVE";
$adate="-";
$atime="";

open LEASEDB, $leasedbname or die $!;
foreach my $line (<LEASEDB>) 
{
  chomp($line);
  $isdata = 1 if $line =~ /^lease /;
  $isdata = 0 if $line =~ /^}/;

  if ($isdata) 
  {
    if ($line =~ /^lease/) 
    {
      $ip = (split(" ", $line))[1];
    } 
    elsif ($line =~ /^  starts/) 
    {
      ($sdate, $stime) = (split(" ", $line))[2,3];
      $sdate =~ s/\//-/g;
      $stime =~ s/;//;
    } 
    elsif ($line =~ /^  ends/) 
    {
      ($type, $edate, $etime) = (split(" ", $line))[1,2,3];
      if($type eq "never;")
      {
        $edate="forever";
        $etime=" ";
      }
      else
      {
        $edate =~ s/\//-/g;
        $etime =~ s/;//;
      }
    } 
    elsif ($line =~ /^  hardware ethernet/) 
    {
            $mac = (split(" ", $line))[2];
            $mac =~ s/;//;
    } 
    elsif ($line =~ /^  client-hostname/) 
    {
            $hostname = (split(/\"/, $line))[1];
    }
    elsif($mac ne "") 
    {
        #we have parsed the whole record, no more matching entries
        #data is collected to variables. now push the record.

        #now let's decide if we are updating the record or creating
        #new record

        # check against lease date, do not add expired leases
        # convert lease end time to local time/date and compare with $now
        my $y=0; my $m=0; my $d=0; my $H=0; my $M=0; my $S=0;
        my $edatetime = $now;
        ($y, $m, $d) = split("-", $edate);
        ($H, $M, $S) = split(":", $etime);
        $edatetime = timelocal($S,$M,$H,$d,$m-1,$y);
        if($edatetime >= $now)
        {
          # now check if record exists
          if(!defined($data{"$mac"}->{'mac'}))
          {
            #record does not exist, fill up default data
            $data{"$mac"}->{'mac'} = "$mac";
            $data{"$mac"}->{'interface'} = "$interface";
            $data{"$mac"}->{'ip'} = "$ip";
            $data{"$mac"}->{'hostname'} = "$hostname";
          }
          # record exists, let's check if we should update
          $data{"$mac"}->{'status'} = "$status";
          $data{"$mac"}->{'sdate'} = "$sdate";
          $data{"$mac"}->{'stime'} = "$stime";
          $data{"$mac"}->{'edate'} = "$edate";
          $data{"$mac"}->{'etime'} = "$etime";
          $data{"$mac"}->{'hostname'} = "$hostname";
          #we do NOT update ACK time because we do not have it
          #do NOT uncomment below
          #$data{"$mac"}->{'adate'} = "$adate";
          #$data{"$mac"}->{'atime'} = "$atime";

        }
    }
  }
}
close(LEASEDB);

#######################################################################
# sort data
#######################################################################

#we sort by IP but you can sort by anything.
my @sorted = sort { ($data{$a}{'ip'}) cmp ($data{$b}{'ip'}) } %data;

#######################################################################
# Print out everything to the HTML table
#######################################################################

my $hostnamelong="";

printf "Content-type: text/html\n\n";
printf "<html><head><title>Aktywne dzierzawy DHCP</title></head>\n";
printf "<style> table, th, td { border: 1px solid lightgray; border-collapse: collapse; padding: 3px; } ";
printf "tr:nth-child(even) { background-color: #dddddd; } ";
printf "</style>\n";
printf "<body>\n";
printf "<table border='1' cellpadding='6'>\n";
printf "<tr><th>IP</th><th>Status</th><th>Interface</th><th>Lease time</th><th>ACK time</th><th>Mac</th><th>Host</th></tr>\n";
foreach my $key (@sorted) {
    if($data{$key}{'mac'} eq "") { next ; }

    # BEGIN reverse dns lookup
    # can optionally turn off reverse dns lookup (comment out below lines) which speeds up the process 
    # of table creation and is useless unless you have reverse dns populated for 
    # your fixed or dynamic leases uncomment single line below instead:
    #
    # version without reverse dns lookup:
    # $hostnamelong = $data{$key}{'hostname'};
    #
    # version with reverse dns lookup: 
    # BEGIN
    $dnsname = gethostbyaddr(inet_aton($data{$key}{'ip'}), AF_INET);
    if($data{$key}{'hostname'} ne "")
    {
      $hostnamelong = $data{$key}{'hostname'} . " | " . $dnsname;
    }
    else
    {
      $hostnamelong = $dnsname;
    }
    $dnsname = "";
    # END

    printf "<tr>";
    printf "<td>" . $data{$key}{'ip'} ."</td>";
    printf "<td>" . $data{$key}{'status'} ."</td>";
    printf "<td>" . $data{$key}{'interface'} ."</td>";
    printf "<td>" . $data{$key}{'sdate'} . " " . $data{$key}{'stime'} ." - ";
    printf $data{$key}{'edate'} . " " . $data{$key}{'etime'} ."</td>";
    printf "<td>" . $data{$key}{'adate'} . " " . $data{$key}{'atime'} . "</td>";
    printf "<td>" . $data{$key}{'mac'} ."</td>";
    printf "<td>" . $hostnamelong ."</td>";
    printf "</tr>\n";
}

printf "</table>\n";
printf "</body></html>\n";

# END of programm

Lütfen unutmayın: 1) yukarıdaki komut dosyası SİZİN ortamınızda çalıştırmadan önce küçük değişiklikler gerektirir, dosya konumlarını ve günlük dosyası biçiminize bağlı olarak bir normal ifadeyi değiştirmeniz gerekir. Komut dosyasına yorum bakın. 2) son gün içinde 2 farklı makine aynı adrese sahipse yukarıdaki komut dosyası IP'nin ACK tablosunda tekrarlanıp tekrarlanmadığını kontrol etmemektedir. Bu tasarım gereğidir (kişisel olarak son günlerde ağımda bulunan her mac adresini görmek için ihtiyacım olan şey) - kolayca değiştirebilirsiniz, kodda bunun için hazır bir bölüm var, sadece bir koşul ekleyin.

Umarım beğenirsin.


1

Kira dosyalarının formatı değişti ya da en azından kullanırken farklı dhcpcd5. Eğer var kira görüntülemek için wlan0WiFi ağı için MyNetwork, siz (böyle ya da bir şey) bu dosyaya bakmak gerekir: /var/lib/dhcpcd5/dhcpcd-wlan0-MyNetwork.lease.

Bu dosya bir ikili dosyadır. (Neden? Bilmiyorum. Ayrıştırma sırasında bazı değerli CPU döngülerini kaydetmek için? Blech.) Görüntülemek için, dhcpcd --dumpleaseikili dosyayı STDIN'den ayrıştıran ve insan tarafından okunabilir bir sürüm çıkaran:

cat /var/lib/dhcpcd5/dhcpcd-wlan0-MyNetwork.lease | dhcpcd --dumplease

Öte yandan, mevcut kira sözleşmesinin ne olduğunu görmek istiyorsanız wlan0, şunları yapabilirsiniz:

dhcpcd --dumplease wlan0

1

Aslında bunu elde etmek için bash'da bir şey yazdım. Her IP adresini aynı ad dosyasına yazar, böylece başka bir dosya tekrar görünürse, önceki dosyanın üzerine yazar, bu nedenle kopya olmaz. Ayrıca söz konusu MAC adresinin üreticisini bulmak için oui.txt dosyasını da kullanacaktır.

Kullanıp kullanamayacağınıza bakın.

#!/bin/bash

pid=$$

while read i
do
        echo $i | egrep -qi '^lease|hardware|starts|ends|hostname' || continue
        if [[ $i =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then
                ip=$(echo $i | awk '{print $2}')
                printf "IP Address: " > /root/$ip.$pid
                echo $ip >> /root/$ip.$pid
        elif [[ $i =~ starts ]]; then
                printf "\tLease start: " >> /root/$ip.$pid
                echo $i | awk '{print $3,$4}' | tr -d ';' >> /root/$ip.$pid
        elif [[ $i =~ ends ]]; then
                printf "\tLease ends: " >> /root/$ip.$pid
                echo $i | awk '{print $3,$4}' | tr -d ';' >> /root/$ip.$pid
        elif [[ $i =~ ethernet ]]; then
                mac=$(echo -n $i | awk '{print $3}' | tr -d ';')
                oui=$(echo -n $mac | tr ':' '-' | cut -c1-8)

                printf "\tMAC Address: " >> /root/$ip.$pid
                echo $mac >> /root/$ip.$pid
                printf "\tManufacturer: " >> /root/$ip.$pid
                grep -i $oui /usr/share/hwdata/oui.txt | awk '{print $3,$4,$5,$6}' >> /root/$ip.$pid
                printf "\n" >> /root/$ip.$pid
        elif [[ $i =~ hostname ]]; then
                printf "\tHostname: " >> /root/$ip.$pid
                echo $i | awk '{print $2}' | tr -d ';' >> /root/$ip.$pid
        fi

done < /var/lib/dhcpd/dhcpd.leases

cat /root/*.$pid
echo "Total leased: $(ls -l /root/*.$pid | wc -l)"
rm -rf /root/*.$pid
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.