Как контролировать DHCP арендованный IP-адрес

У меня Ubuntu server 12.10 в качестве DRBL и CloneZilla. Как я могу узнать, сколько IP-адресов было назначено клиентам. Как я могу контролировать / контролировать службу DHCP-демона (остановка / запуск / состояние)?

6
задан 8 March 2013 в 18:06

5 ответов

Для мониторинга аренды Dhcp просто введите в терминале:

gedit /var/lib/dhcp/dhcpd.leases 
0
ответ дан 8 March 2013 в 18:06

Сценарий, используемый для управления демоном DHCP, зависит, на котором Вы используете. Я принимаю isc-dhcp-server. Затем это было бы:

service isc-dhcp-server stop
service isc-dhcp-server start
service isc-dhcp-server status

Если это не работает, заглядывает /etc/init для файла конфигурации, названного после dhcp, и использование это. Скажите, что Ваш файл конфигурации называют dhcpd3.conf, затем Вы заменили бы isc-dhcp-server в вышеупомянутых командах с dhcpd3.

Для наблюдения, "сколько IP-адресов было присвоено клиентам", который был исходным запросом, можно сделать это:

grep "^lease" /var/lib/isc-dhcp-server/dhcpd.leases |sort |uniq |wc -l

Это явно даст Вам количество присвоенных адресов.

Снова, если Вы получаете ошибку о /var/lib/isc-dhcp-server не быть findable, заглянуть /var/lib и замените его чем-то suggestind dhcp сервер, обычно dhcp или dhcp3

Обратите внимание, что, как упомянуто в другом ответе, это пропустит различие между присвоенным и активным (т.е. с системой с помощью них в данный момент) адреса. Кроме того, если клиент будет сильно завершением работы и не выпустит арендный договор, то Вы также сообщите о неиспользованных адресах, как присвоено.

1
ответ дан 8 March 2013 в 18:06

Для просмотра списка всех активных IP-адресов клиентов вы можете использовать namp. Он может содержать список как DHCP, так и статических клиентов.

вы можете установить namp на свой ПК с помощью

sudo apt-get install nmap

. Затем, чтобы перечислить все активные клиенты, которые вы можете сделать,

 nmap -v -sP 192.168.0.0/255

здесь IP-адреса от 0 до 255 Отсканированные и активные IP будут отображаться.

Лучший сетевой монитор, который я могу найти, это nethogs. Вы можете получить его, установив с помощью

sudo apt-get install nethogs

Затем просто

sudo nethogs <connection_name>

Можно показать монитор трафика в вашем терминале.

Надеюсь, это поможет вам.

0
ответ дан 8 March 2013 в 18:06

Если вы используете isc-dhcp-server на безголовом сервере UBUNTU 14.04

Для управления isc-dhcp-server

service isc-dhcp-server stop
service isc-dhcp-server start
service isc-dhcp-server status

Для мониторинга isc-dhcp-server

Этот метод будет работать на автономном сервере (без графического интерфейса пользователя) для «только назначенные DHCP-аренды» , войдите в систему, введите следующую команду из терминал

cat /var/lib/dhcp/dhcpd.leases

Если установлен NMAP , введите эту команду с терминала

nmap -v -sP 192.168.0.0/24

This Метод будет работать в этой подсети и сканировать 256 адресов, а также выводить IP и MAC-адреса. Он ответит, если HOST не работает с IP-адресом, который не имеет назначения, и ответит MAC-адресом и IP-адресом, если HOST работает.

В зависимости от того, находится ли коммутатор или маршрутизатор между ПК и сетью, и в зависимости от того, на чем работает маршрутизатор или коммутатор «сетевого уровня 2/3/4».

tail -f /var/log/syslog будет выводить адреса DHCP, которые активно назначаются.

tcpdump -i eth0 port 67 or port 68 -e -n будет захватывать пакеты DHCP на порту 67 и порту 68 на сетевом интерфейсе eth0

Если установлен DHCPDUMP , введите эту команду с терминала

[ 118] DUMP «как это подразумевает» информацию DHCP от сервера к клиенту.

0
ответ дан 8 March 2013 в 18:06

Все ответы выше неравнодушны. И быть честным нет никакого простого решения. 1) можно проанализировать dhcpd.leases файл базы данных и получить информацию об активных арендных договорах, но

  • Вы не получите информацию ни о каких ФИКСИРОВАННЫХ адресах (присвоенный строкой как:

    host switch1      { hardware ethernet a1:b2:c3:d7:2f:bc ; fixed-address switch1.mydomain.com; }
    
  • и это также действительно не дает информации о том, когда был прошлый раз, когда dhcp ack был отправлен на машину.

2) с другой стороны, можно проанализировать файл dhcpd.log для поиска ack строк (они похожи на это):

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

Который дает Вам информацию о запросах DHCPD и ответах, но нет никакой информации о фактических арендных договорах (время, состояние).

То, что необходимо действительно сделать, должно сделать ОБОИХ. Сначала проанализируйте файл журнала и затем обновите файл с информацией, полученной из dhcpd.leases файла с базой данных для недостающей информации как начинать-конец арендного договора и т.д.

Теперь: Я играл приблизительно 2 полных рабочих дня, пока я не создал решение, которое создает HTML-таблицу со ВСЕМИ активными арендными договорами, оба ЗАФИКСИРОВАННЫЕ и динамичные. Вот код, который можно поместить в папку cgi-мусорного-ведра или везде, где.

#!/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
# in shell can pipe to lynx:
#   ./dhcp-leases.pl | lynx -stdin
#
# written by Marcin Gosiewski, BV Grupa s.c. Poland <marcin.gosiewski@bvsystemy.pl> http://www.bvsystemy.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
#     2019-08-15: extended for @logprog by Jim Klimov
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" );
# Alternately, on systems without explicit log (e.g. with systemd journals), use empty array of files:
### my @logfilenames = ( ); # if empty, use output from logprog below
my @logprog = qw ( sudo journalctl --no-pager -lu dhcpd );
# Delegate rights for logprog as root, e.g.
#   echo 'www-data  ALL=(root)  NOPASSWD:/usr/bin/journalctl --no-pager -lu dhcpd' > /etc/sudoers.d/www-journalctl
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=(); 
if (scalar @logfilenames > 0) {
 foreach my $logfilename (@logfilenames)
 {
  open LOGFILE, '<', $logfilename;
  chomp(@loglines = <LOGFILE>);
  #printf "LINES1: " . scalar @loglines . " in " .$logfilename . "\n";
  push(@lines, @loglines);
  close(LOGFILE);
 }
} else {
  open LOGPROG, '-|', join (' ', @logprog) or die "Could not pipe from logprog";
  chomp(@loglines = <LOGPROG>);
  #printf "LINES1: " . scalar @loglines . " in " .$logfilename . "\n";
  push(@lines, @loglines);
  close(LOGPROG);
}
@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 (.+)/;
  #$line =~ m/^(.{6}) (.{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";
  if (length($hostname) > 0) {
    $hostname =~ s/^\ *\(*//;
    $hostname =~ s/\)*\ *$//;
  }
  $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

Обратите внимание на то, что:

1) для вышеупомянутого сценария нужна небольшая модификация прежде, чем работать в ВАШЕЙ среде, необходимо изменить местоположения файлов и один regex в зависимости от формата файла журнала. См. комментарий в сценарии.

2) вышеупомянутый сценарий не проверяет, не повторяется ли IP в таблице ACK, если 2 различных машины получили тот же адрес в течение прошлых дней. Это дизайном (что я лично должен был видеть каждый MAC-адрес, который присутствовал в моей сети в течение прошлых дней) - можно легко изменить его, существует готовый раздел для этого в коде, просто добавьте одно условие.

Надеюсь, что Вам нравится он.

4
ответ дан 8 March 2013 в 18:06

Другие вопросы по тегам:

Похожие вопросы: