{ }
menu zespół linki Logowanie
Stabilny hosting
BSDGuru zawdzięcza
firmie Datanet.pl
Hosting BSDGuru.org - DataNet.pl

Statystyki ruchu oparte o IPFW i RRDTOOL

0. Wstęp

Jeśli mamy już postawiony router na FreeBSD i wprowadziliśmy na nim kontrole
ruchu za pomocą dummynet'u to możemy się też pokusić o "zmajstrowanie"
jakichś statystyk, które pozwoliłyby łatwo, szybko i przyjemnie podglądać co
w danej chwili dzieje się na łączu internetowym i np. który z naszych użytkowników
"ciągnie" najwięcej. Więc do dzieła. Utworzenie statystyk należy podzielić
na etapy:

  1. instalacja oprogramowania
  2. przystosowanie regułek dummynet'u do pracy ze statystykami
  3. napisanie skryptów, które będą dla nas pobierały dane z dummynet'u
  4. końcowa konfiguracja
  5. wizualizacja przez strone WWW
  6. Apache
  7. Dodatek dla praktyków

1. Instalacja oprogramowania

W naszym przypadku potrzebne będą programy: mtrg oraz rrdtool. Należy je zainstalować.
Oba znajdują się w portach. MRTG w "/usr/ports/net-mgmt/mrtg" a rrdtool
w "/usr/ports/net/rrdtool". O ile MRTG możemy zainstalować w domyślnej
konfiguracji to rrdtool zalecam zainstalować z opcją "WITH_LATIN2=yes"
w celu uaktywnienia obsługi polskich znaków - kto wie, czy nie będziemy z nich
chcieli w statystykach skorzystać.

Wydajemy komendę "make install clean" w każdym z katalogów wymienionych
portów (dla rrdtool "make WITH_LATIN2=yes install clean") a następnie
komendę "rehash" aby nowo zainstalowane programy mogły być widziane
przez naszą aktualną konsole.

2. Przystosowanie regułek dummynet'u do pracy ze statystykami

Załóżmy, że mamy 3 użytkowników sieci lokalnej (192.168.0.1,2,3) i każdy z
nich ma mieć swoje statystyki. Jeśli mamy dla nich zapisane regułki dummynet'u
(np. 2 z nich ma mieć po 128Kbit/s a jeden 256Kbit/s na łączu asymetrycznym
ADSL 512/128Kbit/s) to dobrze jest je teraz ponumerować (o ile tego wcześniej
nie zrobiliśmy):

ipfw add 121 pipe 1 ip from 192.168.0.2 to any out xmit xl0
ipfw add 122 pipe 2 ip from any to 192.168.0.2 in recv xl0
ipfw pipe 1 config bw 64Kbit/s queue 4Kbytes
ipfw pipe 2 config bw 256Kbit/s queue 12Kbytes

ipfw add 131 pipe 3 ip from 192.168.0.3 to any out xmit xl0
ipfw add 132 pipe 4 ip from any to 192.168.0.3 in recv xl0
ipfw pipe 3 config bw 32Kbit/s queue 2Kbytes
ipfw pipe 4 config bw 128Kbit/s queue 8Kbytes

ipfw add 141 pipe 5 ip from 192.168.0.4 to any out xmit xl0
ipfw add 142 pipe 6 ip from any to 192.168.0.4 in recv xl0
ipfw pipe 5 config bw 32Kbit/s queue 2Kbytes
ipfw pipe 6 config bw 128Kbit/s queue 8Kbytes

U nas schemat numeracji jest taki, że np. dla 192.168.0.2 mamy rurkę numer
121 na ruch wychodzący i 122 na ruch wchodzący. Jeśli teraz wydamy komendę "ipfw
show" zobaczymy, że przy konkretnych rurkach pokazane są liczniki. Np.
dla 192.168.0.2 może to wyglądać tak:

00121 50 75000 pipe 1 ip from 192.168.0.2 to any out xmit xl0
00122 20 30000 pipe 2 ip from any to 192.168.0.2 in recv xl0

Pierwsza liczba od lewej oznacza numer regułki. Te numery przyporządkowaliśmy
"na sztywno", więc zawsze powinny być dla konkretnych rurek takie
same. Druga liczba to liczba pakietów, jakie pasowały do tej regułki i zostały
przez nią przetworzone. I wreszcie trzecia w kolejności liczba to to co nas
najbardziej interesuje - liczba bajtów, które zostały przez regułkę (rurkę)
przetworzone.

Jak łatwo się domyślić nasze statystyki będą się opierały na zbieraniu informacji
o przesłanej ilości bajtów i przedstawianiu jej w przystępny sposób.

3. Napisanie skryptów, które będą dla nas pobierały dane z dummynet'u

Jako, że nie ma sensu wyważać otwartych drzwi podam gotowe skrypty i wyjaśnię
ich działanie.

3.1. Skrypt "stat.pl"

Ten skrypt odpowiada za zbieranie ilości bajtów z liczników ipfw, zapisywanie
ich do pliku tekstowego w formacie "<bajty_odebrane>;<bajty_wysłane>"
a na koniec wyświetleniu rezultatu swojego działania.

#!/usr/bin/perl -w

$ipfw = &quot;/sbin/ipfw&quot;;<br>
  $adres_ip = $ARGV[0];<br>
  $rule_in = $ARGV[1];<br>
  $rule_out = $ARGV[2];<br>
  $zapisane = &quot;/usr/local/www/stat/$adres_ip&quot;;

$inb = 0;<br>
  $outb = 0;

if (open(plik1, &quot;&lt; $zapisane&quot;)) {<br>
  while (&lt;plik1&gt;) {<br>
  @b = split(/;/);<br>

  $inb += $b[0];<br>
  $outb += $b[1];<br>
  }<br>
  close(plik1);<br>
  }

foreach $line (`$ipfw show $rule_in`) {<br>

  chomp($line);<br>
  @cells = split(/ +/, $line);<br>
  $inb += $cells[2];<br>
  }

foreach $line (`$ipfw show $rule_out`) {<br>
  chomp($line);<br>

  @cells = split(/ +/, $line);<br>
  $outb += $cells[2];<br>
  }<br>
  printf(&quot;%.0f
%.0f
&quot;, $inb , $outb);<br>
  for $record (split &quot;

&quot;,`/usr/bin/uptime`) {<br>
  ($timestamp,$reszta) = split m[s+],$record,2;<br>
  }<br>
  $reszta=&quot;null&quot;;<br>
  printf(&quot;%s
&quot;, $timestamp);<br>

  printf(&quot;0
&quot;);

open(plik2, &quot;&gt; $zapisane&quot;);<br>
  printf(plik2 &quot;%s;%s
&quot;, $inb, $outb);<br>
  close(plik2);

system &quot;/sbin/ipfw -q zero $rule_in $rule_out&quot;;

Teraz krótkie wyjaśnienie działania. Skrypt wywołujemy z trzema argumentami:
adres ip komputera, dla którego mają być pobrane statystyki, numer regułki dla
ruchu wchodzącego, numer regułki dla ruchu wychodzącego (np. stat.pl 192.168.0.2
122 121).

Zmienna "$zapisane" definiuje nam miejsce, w którym zapisywane mają
być dane (w tym przypadku to katalog, w którym będą znajdowały się strony WWW
pokazujące statystyki). Skrypt najpierw czyta z pliku <adres_ip> (np.
pliku 192.168.0.2) poprzednio zapisaną ilość bajtów. Następnie sczytuje ilość
bajtów z liczników ipfw i dodaje do nich wcześniej pobrane z pliku dane. Mamy
więc sumę bajtów wysłanych przez dany IP przez całą swoją "kadencję".
Na koniec liczniki ipfw dla regułek, które zostały sczytane są zerowane a dane
o sumarycznym ruchu (dane przeczytane na początku z pliku plus dane sczytane
z regułek) są zapisywane do pliku tekstowego nadpisując poprzednie wartości.

Dodatkowo na potrzeby MRTG wyświetlany jest "uptime" oraz pole "0".
Zainteresowanym dlaczego są one potrzebne polecam lekturę dokumentacji MRTG.
Dla nas nie mają one znaczenia ale muszą być jednak podane, gdyż w przeciwnym
wypadku MRTG nie pracowałby poprawnie.

3.2. Skrypt "pokaz.cgi"

Ten skrypt będzie wywoływany przez stronę WWW, więc od razu nadajemy mu odpowiednie
rozszerzenie ".cgi" oraz uprawnienia (755). Skrypt wywołujemy z parametrem
<adres_ip> (np. pokaz.cgi 192.168.0.2). Plik umieszczamy w podkatalogu
"cgi-bin" naszej strony ze statystykami (np. "/usr/local/www/stat/cgi-bin").

#!/bin/sh

/usr/local/bin/rrdtool graph /usr/local/www/stat/$1.png -a PNG -w 240
  -h 80 \<br>
  -t 'Ruch 24-o godzinny' \<br>
  -c 'SHADEA#DFE2F0' -c 'SHADEB#DFE2F0' \<br>
  -x 'HOUR:1:HOUR:6:HOUR:2:0:%H' \<br>
  DEF:in=/usr/local/www/stat/$1.rrd:ds0:AVERAGE \<br>
  DEF:out=/usr/local/www/stat/$1.rrd:ds1:AVERAGE \<br>

  'CDEF:kbin=in,1024,/' \<br>
  'CDEF:kbout=out,1024,/' \<br>
  'AREA:in#00FF00:Ruch wchodzący' 'LINE1:out#0000FF:Ruch wychodzącyj' \<br>
  'GPRINT:kbin:LAST:Aktualnie: %3.2lf KB/s' 'GPRINT:kbout:LAST:Aktualnie: %3.2lf
  KB/sj' \<br>
  'GPRINT:kbin:AVERAGE:Średnio: %3.2lf KB/s' 'GPRINT:kbout:AVERAGE:Średnio:
  %3.2lf KB/sj' \<br>
  'GPRINT:kbin:MAX:Maksymalnie: %3.2lf KB/s' 'GPRINT:kbout:MAX:Maksymalnie:
  %3.2lf KB/sj'

Ten skrypt uruchamia rysowanie wykresów ruchu "na zawołanie". Pobiera
dane z pliku <adres_ip>.rrd (np. 192.168.0.2.rrd) umiejscowionego w "/usr/local/www/stat"
i rysuje na jego podstawie obrazek <adres_ip>.png (np. 192.168.0.2.png)
w szerokości 240 pikseli (-w 240) oraz wysokości 80 pikseli (-h 80). Oczywiście
do tych wielkości należy doliczyć kilka(dziesiąt) pikseli na opisy i inne rzeczy,
więc realny rozmiar będzie większy (tutaj ok. 320 x 190 pikseli). Na wykresie
dane przedstawiane są co 5 minut a cały wykres obejmuje okres 24 godzin.

3.3. Plik CSV z danymi

Nasz plik index.php będzie pobierał dane z pliku CSV, w którym mają znajdować
się dane o ilości pobranych i wysłanych bajtów dla każdego adresu IP, jaki ma
być w statystykach uwzględniony. Pliki tworzymy ręcznie w katalogu, w którym
znajdują się pliki strony i robimy to tylko raz (jeśli ktoś chce może sobie
napisać do tego automat ale skoro to operacja jednorazowa to nie za bardzo ma
to sens...). W pliku wpisujemy wartości "0;0;" i nadajemy mu odpowiednie
prawa (tak, żeby użytkownik z którego prawami działa skrypt stat.pl mógł do
tego pliku zapisywać). Przykładowo:

Plik ma nazwę 192.168.0.2 i zawartość 0;0;

4. Końcowa konfiguracja

Aby nasze statystyki działały poprawnie musimy tu wykonać parę rzeczy. Po pierwsze
musimy uruchomić MRTG tak, aby co 5 minut zapisywał do plików ".rrd".
Najpierw więc w "/usr/local/etc/mrtg" tworzymy plik konfiguracyjny
dla mrtg (np. "mrtg.cfg") o przykładowej treści:

WorkDir: /usr/local/www/stat/ # Gdzie mają być tworzone pliki .rrd<br>
  Language: Polish # Wiadomo - zawsze lepiej ustawić na Polski<br>

  NoMib2: yes<br>
  LogFormat: rrdtool # Logowanie tylko do plików .rrd<br>
  PathAdd: /usr/local/bin/<br>
  LibAdd: /usr/local/lib/perl5/<br>
  Interval: 5

Target[192.168.0.2]: `/usr/local/www/stat/cgi-bin/stat.pl 192.168.0.2
  122 121`<br>

  MaxBytes[192.168.0.2]: 36000<br>
  Title[192.168.0.2]: Ruch dla 192.168.0.2

Target[192.168.0.3]: `/usr/local/www/stat/cgi-bin/stat.pl 192.168.0.3
  132 131`<br>
  MaxBytes[192.168.0.3]: 18000<br>
  Title[192.168.0.3]: Ruch dla 192.168.0.3

Target[192.168.0.4]: `/usr/local/www/stat/cgi-bin/stat.pl 192.168.0.4
  142 141`<br>
  MaxBytes[192.168.0.4]: 18000<br>

  Title[192.168.0.4]: Ruch dla 192.168.0.4

Jak widać dla każdego komputera w sieci należy utworzyć osobny wpis uruchamiający
dla niego skrypt pobierający dane z odpowiednich numerów regułek.

Dodatkowo alby nasze statystyki były zapisywane co 5 minut dodajemy do "/etc/crontab"
wpis:

*/5 * * * * root /usr/local/bin/mrtg /usr/local/etc/mrtg/mrtg.cfg

Można teżuruchomić MRTG jako demona systemowego, co przyśpiesza jego działanie
(uruchamiany przez crona co 5 minut program zabiera na starcie pewną ilość zasobów).
W tym celu dodajemy do pliku konfiguracyjnego MRTG wpis:

RunAsDaemon: yes

lub (dla starszych wersji MRTG) uruchamiamy sam program z opcją "--daemon",
czyli:

/usr/local/bin/mrtg --daemon /usr/local/etc/mrtg/mrtg.cfg

Należy też pamiętać o zmianie uprawnień dla katalogu &quot;/usr/local/www/stat&quot;
  na takie, które umożliwią zapis (w przeciwnym razie mogą być problemy z aktualizacją
  baz rrd lub zapisem plików png):

chmod 777 /usr/local/www/stat

5. Wizualizacja przez stronę WWW

Mamy już skrypty i programy, które zbierają statystyki ruchu. Teraz należy
się postarać o pokazanie tych statystyk w jakiejś ciekawej formie. Przechodzimy
do katalogu "/usr/local/www/stat" i tworzymy w nim plik "index.php".
Jego przykładowa zawartość może wyglądać następująco:

&lt;html&gt;<br>
  &lt;head&gt;<br>
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-2&quot;&gt;<br>
  &lt;title&gt;Statystyki&lt;/title&gt;<br>

  &lt;/head&gt;

&lt;body&gt;<br>
  &lt;?<br>
  $ip = $_GET['ip'];<br>
  $sciezka=&quot;/usr/local/www/stat&quot;;<br>
  $komenda=&quot;cgi-bin/pokaz.cgi &quot; . $ip . &quot; &gt; /dev/null&quot;;<br>

  system($komenda);<br>
  $row=1;<br>
  $fp = fopen($ip,&quot;r&quot;);<br>
  while ($dane = fgetcsv($fp,1024, &quot;;&quot;))<br>
  {<br>

  $num = count($dane);<br>
  $row++;<br>
  $bajty_in = $dane[0];<br>
  $bajty_out = $dane[1];<br>
  }<br>
  fclose($fp);<br>

  ?&gt;<br>
  &lt;table border=&quot;0&quot; cellspacing=&quot;0&quot;&gt;<br>
  &lt;?<br>
  echo(&quot;&lt;tr&gt;&lt;td colspan=2 align=center&gt;&lt;h1&gt;Statystyki dla
  $ip&lt;/h1&gt;&lt;/td&gt;&lt;/tr&gt;

&quot;);<br>
  ?&gt;<br>
  &lt;tr&gt;<br>
  &lt;td align=center&gt;&lt;h1&gt;&lt;font color=green&gt;Odebrano:&lt;/font&gt;&lt;/h1&gt;&lt;/td&gt;<br>

  &lt;td align=center&gt;&lt;h1&gt;&lt;font color=blue&gt;Wysłano:&lt;/font&gt;&lt;/h1&gt;&lt;/td&gt;<br>
  &lt;/tr&gt;<br>
  &lt;tr&gt;<br>
  &lt;?<br>

  if ($bajty_in &gt; 1073741824)<br>
  {<br>
  $GB_in=number_format($bajty_in/1073741824, 3, ',', ' ');<br>
  $GB_out=number_format($bajty_out/1073741824, 3, ',', ' ');

echo(&quot;&lt;td align=center&gt;&lt;h1&gt;$GB_in GB&lt;/h1&gt;&lt;/td&gt;

&quot;);<br>
  echo(&quot;&lt;td align=center&gt;&lt;h1&gt;$GB_out GB&lt;/h1&gt;&lt;/td&gt;
&quot;);<br>
  }<br>
  else<br>

  {<br>
  $MB_in=number_format($bajty_in/1048576, 3, ',', ' ');<br>
  $MB_out=number_format($bajty_out/1048576, 3, ',', ' ');

echo(&quot;&lt;td align=center&gt;&lt;h1&gt;$MB_in MB&lt;/h1&gt;&lt;/td&gt;
&quot;);<br>

  echo(&quot;&lt;td align=center&gt;&lt;h1&gt;$MB_out MB&lt;/h1&gt;&lt;/td&gt;
&quot;);<br>
  }<br>
  ?&gt;<br>
  &lt;/tr&gt;<br>

  &lt;?<br>
  echo(&quot;&lt;tr&gt;&lt;td colspan=2&gt;&lt;img src=$ip.png&gt;&lt;/img&gt;&lt;/td&gt;&lt;/tr&gt;
&quot;);<br>
  ?&gt;<br>

  &lt;/table&gt;<br>
  &lt;/body&gt;<br>
  &lt;/html&gt;

Stronę "index.php" należy wywoływać z parametrem "ip=adres_ip"
(np. "index.php?ip=192.168.0.2") - wyświetlone wtedy będą statystyki
dla danego adresu IP. Dodatkowo na górze strony wyświetlona będzie informacja
o ilości wysłanych i odebranych przez danego użytkownika danych.

6. Apache

Mamy skrypty, mamy stronę WWW, która te skrypty może uruchamiać i wizualizować
przekazane przez nie dane, brakuje tylko serwera WWW, który mógłby to wszystko
obsłużyć. Jako, że Apache jest chyba najpopularniejszym serwerem WWW w światku
Open Source wykorzystamy go do tego zadania.

Pierwsza sprawa to instalacja Apache'a z obsługą PHP (nasz "index.php"
to po części skrypt PHP). Przechodzimy do katalogu "/usr/ports/www/apache13"
i wydajemy komendę "make install clean" aby zainstalować Apache'a.

Następnie przechodzimy do "/usr/ports/www/mod_php4" i także wydajemy
komendę "make install clean" aby zainstalować obsługę PHP dla Apache'a.
Na koniec "rehash".

Teraz kwestia konfiguracji Apache'a. Przykładowy plik konfiguracyjny może wyglądać
tak:

ServerType standalone<br>
  ServerRoot &quot;/usr/local&quot;<br>
  PidFile /var/run/httpd.pid<br>
  Timeout 300<br>
  KeepAlive On<br>

  MaxKeepAliveRequests 10<br>
  KeepAliveTimeout 30<br>
  MinSpareServers 1<br>
  MaxSpareServers 10<br>
  StartServers 1<br>
  MaxClients 10<br>

  Listen 192.168.0.1:80 # Tutaj Apache działa tylko na interfejsie LANowym; nie
  jest widoczny z Internetu.

LoadModule env_module libexec/apache/mod_env.so<br>
  LoadModule config_log_module libexec/apache/mod_log_config.so<br>
  LoadModule mime_magic_module libexec/apache/mod_mime_magic.so<br>
  LoadModule mime_module libexec/apache/mod_mime.so<br>
  LoadModule negotiation_module libexec/apache/mod_negotiation.so<br>

  LoadModule status_module libexec/apache/mod_status.so<br>
  LoadModule dir_module libexec/apache/mod_dir.so<br>
  LoadModule cgi_module libexec/apache/mod_cgi.so<br>
  LoadModule alias_module libexec/apache/mod_alias.so<br>
  LoadModule access_module libexec/apache/mod_access.so<br>
  LoadModule headers_module libexec/apache/mod_headers.so<br>

  LoadModule usertrack_module libexec/apache/mod_usertrack.so<br>
  LoadModule log_forensic_module libexec/apache/mod_log_forensic.so<br>
  LoadModule unique_id_module libexec/apache/mod_unique_id.so<br>
  LoadModule setenvif_module libexec/apache/mod_setenvif.so<br>
  LoadModule php4_module libexec/apache/libphp4.so

ClearModuleList<br>

  AddModule mod_env.c<br>
  AddModule mod_log_config.c<br>
  AddModule mod_mime_magic.c<br>
  AddModule mod_mime.c<br>
  AddModule mod_negotiation.c<br>
  AddModule mod_status.c<br>

  AddModule mod_dir.c<br>
  AddModule mod_cgi.c<br>
  AddModule mod_alias.c<br>
  AddModule mod_access.c<br>
  AddModule mod_headers.c<br>
  AddModule mod_usertrack.c<br>

  AddModule mod_log_forensic.c<br>
  AddModule mod_unique_id.c<br>
  AddModule mod_so.c<br>
  AddModule mod_setenvif.c<br>
  AddModule mod_php4.c

Port 80<br>

  User www<br>
  Group www<br>
  DocumentRoot &quot;/usr/local/www&quot;<br>
  UseCanonicalName On<br>
  DefaultType text/plain<br>
  HostnameLookups Off<br>

  ErrorLog /var/log/httpd-error.log<br>
  LogLevel warn<br>
  LogFormat &quot;%h %l %u %t &quot;%r&quot; %&gt;s %b &quot;%{Referer}i&quot;
  &quot;%{User-Agent}i&quot;&quot; combined<br>

  LogFormat &quot;%h %l %u %t &quot;%r&quot; %&gt;s %b&quot; common<br>
  LogFormat &quot;%{Referer}i -&gt; %U&quot; referer<br>

  LogFormat &quot;%{User-agent}i&quot; agent<br>
  ServerSignature Off

&lt;Directory /&gt;<br>
  Options FollowSymLinks<br>
  AllowOverride None<br>

  &lt;/Directory&gt;

&lt;Directory &quot;/usr/local/www&quot;&gt;<br>
  Options Indexes FollowSymLinks MultiViews<br>
  AllowOverride None<br>
  Order allow,deny<br>
  Allow from all<br>

  &lt;/Directory&gt;

&lt;IfModule mod_php4.c&gt;<br>
  DirectoryIndex index.php index.html index.htm<br>
  AddType application/x-httpd-php .php<br>
  AddType application/x-httpd-php-source .phps<br>
  &lt;/IfModule&gt;

&lt;IfModule mod_cgi.c&gt;<br>
  AddHandler cgi-script .cgi<br>
  &lt;/IfModule&gt;

&lt;IfModule mod_mime.c&gt;<br>
  TypesConfig /usr/local/etc/apache/mime.types<br>
  AddLanguage en .en<br>
  AddCharset ISO-8859-2 .iso-pl<br>

  &lt;IfModule mod_negotiation.c&gt;<br>
  LanguagePriority pl en<br>
  &lt;/IfModule&gt;<br>
  &lt;/IfModule&gt;

&lt;IfModule mod_mime_magic.c&gt;<br>
  MIMEMagicFile /usr/local/etc/apache/magic<br>

  &lt;/IfModule&gt;

&lt;IfModule mod_setenvif.c&gt;<br>
  BrowserMatch &quot;RealPlayer 4.0&quot; force-response-1.0<br>
  BrowserMatch &quot;Java/1.0&quot; force-response-1.0<br>

  BrowserMatch &quot;JDK/1.0&quot; force-response-1.0<br>
  &lt;/IfModule&gt;

&lt;IfModule mod_alias.c&gt;

Alias /icons/ &quot;/usr/local/www/icons/&quot;

&lt;Directory &quot;/usr/local/www/icons&quot;&gt;<br>

  Options Indexes MultiViews<br>
  AllowOverride None<br>
  Order allow,deny<br>
  Allow from all<br>
  &lt;/Directory&gt;

Alias /manual/ &quot;/usr/local/share/doc/apache/&quot;

&lt;Directory &quot;/usr/local/share/doc/apache&quot;&gt;<br>
  Options Indexes FollowSymlinks MultiViews<br>
  AllowOverride None<br>
  Order allow,deny<br>
  Allow from all<br>
  &lt;/Directory&gt;

ScriptAlias /cgi-bin/ &quot;/usr/local/www/*/cgi-bin/&quot;

&lt;Directory &quot;/usr/local/www/*/cgi-bin&quot;&gt;<br>
  AllowOverride None<br>
  Options FollowSymlinks ExecCGI<br>
  Order allow,deny<br>

  Allow from all<br>
  &lt;/Directory&gt;

&lt;/IfModule&gt;

Zapisujemy konfiguracje jako "/usr/local/etc/apache/httpd.conf" i
restartujemy serwer WWW poleceniem "apachectl restart".

Jeśli wszystko przebiegło bez problemów po wpisaniu w przeglądarce WWW adresu
"http://192.168.0.1/stat/index.php?ip=192.168.0.2" powinniśmy zobaczyć
stronę WWW ze statystykami ruchy dla adresu "192.168.0.2".

7. Dodatek dla praktyków

Nasze statystyki są stosunkowo proste i pozwalają wizualizować dane tylko na
przestrzeni 24 godzin. Jeśli chcielibyśmy mieć ładne grafy dla ruchy "tygodniowego",
"miesięcznego" i "rocznego" należy trochę zmodyfikować skrypt
"pokaz.cgi":

#!/bin/sh

/usr/local/bin/rrdtool graph /usr/local/www/stat/$1.png -a PNG -w 240
  -h 80 \<br>

  -t 'Ruch 24-o godzinny' \<br>
  -c 'SHADEA#DFE2F0' -c 'SHADEB#DFE2F0' \<br>
  -x 'HOUR:1:HOUR:6:HOUR:2:0:%H' \<br>
  DEF:in=/usr/local/www/stat/$1.rrd:ds0:AVERAGE \<br>
  DEF:out=/usr/local/www/stat/$1.rrd:ds1:AVERAGE \<br>
  'CDEF:kbin=in,1024,/' \<br>

  'CDEF:kbout=out,1024,/' \<br>
  'AREA:in#00FF00:Ruch wchodzący' 'LINE1:out#0000FF:Ruch wychodzącyj' \<br>
  'GPRINT:kbin:LAST:Aktualnie: %3.2lf KB/s' 'GPRINT:kbout:LAST:Aktualnie: %3.2lf
  KB/sj' \<br>
  'GPRINT:kbin:AVERAGE:Średnio: %3.2lf KB/s' 'GPRINT:kbout:AVERAGE:Średnio:
  %3.2lf KB/sj' \<br>
  'GPRINT:kbin:MAX:Maksymalnie: %3.2lf KB/s' 'GPRINT:kbout:MAX:Maksymalnie:
  %3.2lf KB/sj'

/usr/local/bin/rrdtool graph /usr/local/www/stat/$1-tydzien.png -a PNG
  -w 240 -h 80 \<br>

  -t 'Ruch tygodniowy' \<br>
  -c 'SHADEA#DFE2F0' -c 'SHADEB#DFE2F0' \<br>
  -x 'DAY:1:HOUR:6:DAY:1:0:%d' \<br>
  -Y -r \<br>
  -s '-1w' -e '0' \<br>
  DEF:in=/usr/local/www/stat/$1.rrd:ds0:AVERAGE \<br>

  DEF:out=/usr/local/www/stat/$1.rrd:ds1:AVERAGE \<br>
  'CDEF:kbin=in,1024,/' \<br>
  'CDEF:kbout=out,1024,/' \<br>
  'AREA:in#00FF00:Ruch wchodzący' 'LINE1:out#0000FF:Ruch wychodzącyj' \<br>
  'GPRINT:kbin:LAST:Aktualnie: %3.2lf Kbit/s' 'GPRINT:kbout:LAST:Aktualnie:
  %3.2lf Kbit/sj' \<br>
  'GPRINT:kbin:AVERAGE:Średnio: %3.2lf Kbit/s' 'GPRINT:kbout:AVERAGE:Średnio:
  %3.2lf Kbit/sj' \<br>

  'GPRINT:kbin:MAX:Maksymalnie: %3.2lf Kbit/s' 'GPRINT:kbout:MAX:Maksymalnie:
  %3.2lf Kbit/sj'

/usr/local/bin/rrdtool graph /usr/local/www/stat/$1-miesiac.png -a PNG
  -w 240 -h 80 \<br>
  -t 'Ruch miesieczny' \<br>
  -c 'SHADEA#DFE2F0' -c 'SHADEB#DFE2F0' \<br>
  -x 'DAY:7:DAY:7:DAY:7:0:%d %m' \<br>
  -Y -r \<br>

  -s '-1m' -e '0' \<br>
  DEF:in=/usr/local/www/stat/$1.rrd:ds0:AVERAGE \<br>
  DEF:out=/usr/local/www/stat/$1.rrd:ds1:AVERAGE \<br>
  'CDEF:kbin=in,1024,/' \<br>
  'CDEF:kbout=out,1024,/' \<br>
  'AREA:in#00FF00:Ruch wchodzący' 'LINE1:out#0000FF:Ruch wychodzącyj' \<br>

  'GPRINT:kbin:LAST:Aktualnie: %3.2lf Kbit/s' 'GPRINT:kbout:LAST:Aktualnie:
  %3.2lf Kbit/sj' \<br>
  'GPRINT:kbin:AVERAGE:Średnio: %3.2lf Kbit/s' 'GPRINT:kbout:AVERAGE:Średnio:
  %3.2lf Kbit/sj' \<br>
  'GPRINT:kbin:MAX:Maksymalnie: %3.2lf Kbit/s' 'GPRINT:kbout:MAX:Maksymalnie:
  %3.2lf Kbit/sj'

/usr/local/bin/rrdtool graph /usr/local/www/stat/$1-rok.png -a PNG -w
  240 -h 80 \<br>
  -t 'Ruch roczny' \<br>
  -c 'SHADEA#DFE2F0' -c 'SHADEB#DFE2F0' \<br>

  -x 'MONTH:1:MONTH:1:MONTH:1:0:%b' \<br>
  -Y -r \<br>
  -s '-1y' -e '0' \<br>
  DEF:in=/usr/local/www/stat/$1.rrd:ds0:AVERAGE \<br>
  DEF:out=/usr/local/www/stat/$1.rrd:ds1:AVERAGE \<br>
  'CDEF:kbin=in,1024,/' \<br>

  'CDEF:kbout=out,1024,/' \<br>
  'AREA:in#00FF00:Ruch wchodzący' 'LINE1:out#0000FF:Ruch wychodzącyj' \<br>
  'GPRINT:kbin:LAST:Aktualnie: %3.2lf Kbit/s' 'GPRINT:kbout:LAST:Aktualnie:
  %3.2lf Kbit/sj' \<br>
  'GPRINT:kbin:AVERAGE:Średnio: %3.2lf Kbit/s' 'GPRINT:kbout:AVERAGE:Średnio:
  %3.2lf Kbit/sj' \<br>
  'GPRINT:kbin:MAX:Maksymalnie: %3.2lf Kbit/s' 'GPRINT:kbout:MAX:Maksymalnie:
  %3.2lf Kbit/sj'

Oraz zmodyfikować plik "index.php":

&lt;html&gt;<br>
  &lt;head&gt;<br>
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-2&quot;&gt;<br>
  &lt;title&gt;Statystyki&lt;/title&gt;<br>

  &lt;/head&gt;

&lt;body topmargin=&quot;0&quot; leftmargin=&quot;0&quot;&gt;<br>
  &lt;?<br>
  $ip = $_GET['ip'];<br>
  $sciezka=&quot;/usr/local/www/stat&quot;;<br>

  $komenda=&quot;cgi-bin/pokaz.cgi &quot; . $ip . &quot; &gt; /dev/null&quot;;<br>
  system($komenda);<br>
  $row=1;<br>
  $fp = fopen($ip,&quot;r&quot;);<br>

  while ($dane = fgetcsv($fp,1024, &quot;;&quot;))<br>
  {<br>
  $num = count($dane);<br>
  $row++;<br>
  $bajty_in = $dane[0];<br>

  $bajty_out = $dane[1];<br>
  }<br>
  fclose($fp);<br>
  ?&gt;<br>
  &lt;table border=&quot;0&quot; cellspacing=&quot;0&quot;&gt;<br>

  &lt;?<br>
  echo(&quot;&lt;tr&gt;&lt;td colspan=2 align=center&gt;&lt;h1&gt;Statystyki dla
  $ip&lt;/h1&gt;&lt;/td&gt;&lt;/tr&gt;
&quot;);<br>
  ?&gt;<br>

  &lt;tr&gt;<br>
  &lt;td align=center&gt;&lt;h1&gt;&lt;font color=green&gt;Odebrano:&lt;/font&gt;&lt;/h1&gt;&lt;/td&gt;<br>
  &lt;td align=center&gt;&lt;h1&gt;&lt;font color=blue&gt;Wysłano:&lt;/font&gt;&lt;/h1&gt;&lt;/td&gt;<br>

  &lt;/tr&gt;<br>
  &lt;tr&gt;<br>
  &lt;?<br>
  if ($bajty_in &gt; 1073741824)<br>
  {<br>

  $GB_in=number_format($bajty_in/1073741824, 3, ',', ' ');<br>
  $GB_out=number_format($bajty_out/1073741824, 3, ',', ' ');

echo(&quot;&lt;td align=center&gt;&lt;h1&gt;$GB_in GB&lt;/h1&gt;&lt;/td&gt;
&quot;);<br>
  echo(&quot;&lt;td align=center&gt;&lt;h1&gt;$GB_out GB&lt;/h1&gt;&lt;/td&gt;

&quot;);<br>
  }<br>
  else<br>
  {<br>
  $MB_in=number_format($bajty_in/1048576, 3, ',', ' ');<br>
  $MB_out=number_format($bajty_out/1048576, 3, ',', ' ');

echo(&quot;&lt;td align=center&gt;&lt;h1&gt;$MB_in MB&lt;/h1&gt;&lt;/td&gt;
&quot;);<br>
  echo(&quot;&lt;td align=center&gt;&lt;h1&gt;$MB_out MB&lt;/h1&gt;&lt;/td&gt;

&quot;);<br>
  }<br>
  ?&gt;<br>
  &lt;/tr&gt;<br>
  &lt;?<br>
  echo(&quot;&lt;tr&gt;&lt;td&gt;&lt;img src=$ip.png&gt;&lt;/img&gt;&lt;/td&gt;

&quot;);<br>
  echo(&quot;&lt;td&gt;&lt;img src=$ip-tydzien.png&gt;&lt;/img&gt;&lt;/td&gt;&lt;/tr&gt;
&quot;);<br>
  echo(&quot;&lt;tr&gt;&lt;td&gt;&lt;img src=$ip-miesiac.png&gt;&lt;/img&gt;&lt;/td&gt;

&quot;);<br>
  echo(&quot;&lt;td&gt;&lt;img src=$ip-rok.png&gt;&lt;/img&gt;&lt;/td&gt;&lt;/tr&gt;
&quot;);<br>
  ?&gt;<br>
  &lt;/table&gt;<br>

  &lt;/body&gt;<br>
  &lt;/html&gt;

Dzięki tym zmianom dostaniemy nie jeden ale cztery grafy przedstawiające ruch
kolejno w ciągu 24 godzin, tygodnia, miesiąca i roku.

8. Zakończenie

Tekst ten został napisany po to aby ułatwić stworzenie prostych statystyk,
które nie obciążają mocno maszyny je generującej (grafy tworzone są tylko wtedy,
gdy ktoś wywoła stronę WWW a nie co pięć minut jak w przypadku "czystego"
MRTG). Starałem się aby tekst nie zawierał błędów lecz jak wiadomo człowiek
jest istotą omylną, więc jeśli znajdziesz jakieś błędy/niedociągnięcia proszę
o kontakt - postaram się je jak najszybciej poprawić. Oczywiście w tym tekście
zbudowaliśmy statystyki dla rurek w dummynecie ale nic nie stoi na przeszkodzie,
żeby zastosować to np. dla kolejek. Każda regułka jest liczona, więc dla każdej
można zrobić statystyki.

Miłego statystykowania.

Autor: 
Tomasz Król [ yautja(at)bsdguru.org ] -
Porozmawiaj o tym artykule na forum: 

tytus, pt., 18/04/2008 - 20:13