Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
centos:mail_c7:mta_13 [03.02.2015 21:25. ] – [manuelle Installation] django | centos:mail_c7:mta_13 [18.11.2024 19:00. ] (aktuell) – Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
====== Mailserver - Logfileauswertungen unter CentOS 7.x ====== | ====== Mailserver - Logfileauswertungen unter CentOS 7.x ====== | ||
Oft werden vom Management hübsche bunte Auswertungsgraphiken gewünscht, um sich so mehr oder weniger ein Bild davon zu machen, ob und wie der/die Mailserver mit der anfallenden Menge an elektronischer Post umgehen können. | Oft werden vom Management hübsche bunte Auswertungsgraphiken gewünscht, um sich so mehr oder weniger ein Bild davon zu machen, ob und wie der/die Mailserver mit der anfallenden Menge an elektronischer Post umgehen können. | ||
- | Auch als Postmaster und Admin können wir uns so einen kurzen Überblick verschaffen, | + | Auch als Postmaster und Admin können wir uns so einen kurzen Überblick verschaffen, |
Im Detail wollen wir uns nun drei der Varianten genauer ansehen. | Im Detail wollen wir uns nun drei der Varianten genauer ansehen. | ||
- **[[centos: | - **[[centos: | ||
- | - **WEB-GUIs** Graphisch sehr ansprechende | + | - **WEB-GUIs** Graphisch sehr ansprechende |
- **[[centos: | - **[[centos: | ||
- **[[centos: | - **[[centos: | ||
Zeile 34: | Zeile 34: | ||
Build Host : vml000200.dmz.nausch.org | Build Host : vml000200.dmz.nausch.org | ||
Relocations : (not relocatable) | Relocations : (not relocatable) | ||
- | Packager | + | Packager |
Vendor | Vendor | ||
URL : http:// | URL : http:// | ||
Zeile 559: | Zeile 559: | ||
===== mailgraph ===== | ===== mailgraph ===== | ||
- | Eine ansprechende graphische Übersicht kann mittels [[http:// | + | Eine ansprechende graphische Übersicht kann mittels [[http:// |
Mailgraph besteht im wesentlichen aus zwei Teilen. Das eine perl-Script ist zuständig für das Durchsuchen und Analysieren des Mailserver-Logdatei. Die gewonnenen Daten werden in **rrd**-Datendateien geschrieben. Ein zweites Perl **cgi**-Script generiert dann beim Aufrufen der zugehörigen Webseite Graphiken mit den Daten der **rrd**-Dateien. | Mailgraph besteht im wesentlichen aus zwei Teilen. Das eine perl-Script ist zuständig für das Durchsuchen und Analysieren des Mailserver-Logdatei. Die gewonnenen Daten werden in **rrd**-Datendateien geschrieben. Ein zweites Perl **cgi**-Script generiert dann beim Aufrufen der zugehörigen Webseite Graphiken mit den Daten der **rrd**-Dateien. | ||
Zeile 583: | Zeile 583: | ||
Build Host : vml000200.dmz.nausch.org | Build Host : vml000200.dmz.nausch.org | ||
Relocations : (not relocatable) | Relocations : (not relocatable) | ||
- | Packager | + | Packager |
URL : http:// | URL : http:// | ||
Summary | Summary | ||
Zeile 615: | Zeile 615: | ||
Will man die Sprache bei der Webseite, oder die Farben der Grafiken anpassen, schreibt man einfach seine Änderungen direkt in das übersichtliche CGI-Script. | Will man die Sprache bei der Webseite, oder die Farben der Grafiken anpassen, schreibt man einfach seine Änderungen direkt in das übersichtliche CGI-Script. | ||
- | # | + | # cat / |
- | <file perl cat / | + | <file perl / |
# mailgraph -- postfix mail traffic statistics | # mailgraph -- postfix mail traffic statistics | ||
Zeile 878: | Zeile 878: | ||
AddHandler cgi-script .cgi | AddHandler cgi-script .cgi | ||
- | < | + | < |
- | AllowOverride None | + | AllowOverride None |
- | Options +ExecCGI | + | Options +ExecCGI |
- | DirectoryIndex mailgraph.cgi | + | DirectoryIndex mailgraph.cgi |
- | Order deny, | + | Order deny, |
- | require IP 10.0. | + | |
</ | </ | ||
ErrorLog logs/ | ErrorLog logs/ | ||
Zeile 978: | Zeile 978: | ||
Möchte man einen graphischen Überblick über die Queues haben, so liefert uns das gerade vorgestellte und installierte **Mailgraph** leider keine grafischen werte. Hierzu greifen wir auf das Programm **[[http:// | Möchte man einen graphischen Überblick über die Queues haben, so liefert uns das gerade vorgestellte und installierte **Mailgraph** leider keine grafischen werte. Hierzu greifen wir auf das Programm **[[http:// | ||
- | Das passende Programmpaket **queuegraph** installieren am einfachsten aus dem Repository **[[centos:mailserver.guru|mailserver.guru]]**. | + | Das passende Programmpaket **queuegraph** installieren am einfachsten aus dem Repository **[[centos:nausch.org|nausch.org]]**. |
==== Installation ==== | ==== Installation ==== | ||
Zeile 999: | Zeile 999: | ||
Build Host : vml000200.dmz.nausch.org | Build Host : vml000200.dmz.nausch.org | ||
Relocations : (not relocatable) | Relocations : (not relocatable) | ||
- | Packager | + | Packager |
URL : http:// | URL : http:// | ||
Summary | Summary | ||
Zeile 1374: | Zeile 1374: | ||
=== RPM-Installation === | === RPM-Installation === | ||
- | Die wohl einfachste Art ist die der RPM-basierten Installation. Das passende Paket **mailgraph** installieren wir aus dem Repository **[[centos:mailserver.guru|mailserver.guru]]**. Aktuell wird vom Paketmaintainer die [[http:// | + | Die wohl einfachste Art ist die der RPM-basierten Installation. Das passende Paket **mailgraph** installieren wir aus dem Repository **[[centos:nausch.org|nausch.org]]**. Aktuell wird vom Paketmaintainer die [[http:// |
- | Haben wir das Repository **[[centos:mailserver.guru|mailserver.guru]]** installiert, | + | Haben wir das Repository **[[centos:nausch.org|nausch.org]]** installiert, |
# yum install mailgraph | # yum install mailgraph | ||
Zeile 1381: | Zeile 1381: | ||
Will man die beiden Pakete "nur lokal" installieren verwendet man folgenden Aufruf. | Will man die beiden Pakete "nur lokal" installieren verwendet man folgenden Aufruf. | ||
- | # yum localinstall http:// | + | # yum localinstall http:// |
- | http:// | + | http:// |
=== manuelle Installation === | === manuelle Installation === | ||
Zeile 1402: | Zeile 1402: | ||
Nun kopieren wir die Dateien aus unserem temporären Verzeichnis an die richtige Stelle im System. | Nun kopieren wir die Dateien aus unserem temporären Verzeichnis an die richtige Stelle im System. | ||
# cp / | # cp / | ||
+ | |||
+ | # cp / | ||
Das Script zur Datengenerierung kopieren wir dann noch in das Verzeichnis // | Das Script zur Datengenerierung kopieren wir dann noch in das Verzeichnis // | ||
Zeile 1408: | Zeile 1410: | ||
# cp / | # cp / | ||
+ | ==== Konfiguration ==== | ||
+ | === / | ||
+ | Die Konfiguration von mailgraph selbst gestaltet sich sehr einfach. Über die Konfigurationsdatei // | ||
+ | # vim / | ||
+ | <file hash / | ||
+ | PRIORITY=-19 | ||
+ | OPTIONS=--ignore-localhost | ||
+ | </ | ||
+ | === / | ||
+ | Will man die Sprache bei der Webseite, oder die Farben der Grafiken anpassen, schreibt man einfach seine Änderungen direkt in das übersichtliche CGI-Script. | ||
+ | # vim / | ||
+ | <file perl / | ||
+ | # mailgraph -- detailed postfix mail traffic statistics | ||
+ | # copyright (c) 2000-2007 ETH Zurich | ||
+ | # copyright (c) 2000-2007 David Schweikert < | ||
+ | # modified 2011 for queuegraph by Ralf Hildebrandt < | ||
+ | # modified 2015 for mailgraph-ng by Django < | ||
+ | # patches from Sebastian van de Meer < | ||
+ | # released under the GNU General Public License | ||
+ | use RRDs; | ||
+ | use POSIX qw(uname); | ||
+ | my $VERSION = " | ||
+ | my $host = (POSIX:: | ||
+ | my $scriptname = $ENV{" | ||
+ | my $xpoints = 800; | ||
+ | my $points_per_sample = 3; | ||
+ | my $ypoints = 160; | ||
+ | my $rrd = '/ | ||
+ | my $rrd_virus = '/ | ||
+ | my $rrd_grey = '/ | ||
+ | my $rrd_dane = '/ | ||
+ | my $rrd_dmarc = '/ | ||
+ | my $rrd_queue = '/ | ||
+ | my $rrd_post = '/ | ||
+ | my $tmp_dir = '/ | ||
+ | my @graphs = ( | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | ); | ||
+ | my %color = ( # rrggbb in hex | ||
+ | # n | ||
+ | sent => ' | ||
+ | received | ||
+ | bounced | ||
+ | virus => ' | ||
+ | spam => ' | ||
+ | rejected | ||
+ | greylisted | ||
+ | delayed | ||
+ | whitelist | ||
+ | awl => ' | ||
+ | early => ' | ||
+ | pswl => ' | ||
+ | psbl => ' | ||
+ | passold | ||
+ | veto => ' | ||
+ | pregreet | ||
+ | dnsbl => ' | ||
+ | pipelining | ||
+ | nonsmtp | ||
+ | barenewline | ||
+ | command | ||
+ | hangup | ||
+ | passnew | ||
+ | new => ' | ||
+ | reconnectok | ||
+ | active | ||
+ | deferred | ||
+ | anonymoustls | ||
+ | trustedtls | ||
+ | untrustedtls | ||
+ | verifiedtls | ||
+ | spfnone | ||
+ | spffail | ||
+ | spfpass | ||
+ | dkimnone | ||
+ | dkimfail | ||
+ | dkimpass | ||
+ | dmarcnone | ||
+ | dmarcfail | ||
+ | dmarcpass | ||
+ | ); | ||
+ | |||
+ | sub rrd_graph(@) | ||
+ | { | ||
+ | my ($range, $file, $ypoints, @rrdargs) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | my $end = time; $end -= $end % $step; | ||
+ | my $date = localtime(time); | ||
+ | $date =~ s|:|\\:|g unless $RRDs:: | ||
+ | |||
+ | my ($graphret, | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | $RRDs:: | ||
+ | |||
+ | @rrdargs, | ||
+ | |||
+ | ' | ||
+ | ); | ||
+ | |||
+ | my $ERR=RRDs:: | ||
+ | die " | ||
+ | } | ||
+ | |||
+ | sub graph($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_virus($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greylist($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greystats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreen($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreenstats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_dane($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_spf($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dkim($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dmarc($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_queue($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | sub print_html() | ||
+ | { | ||
+ | print " | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | <meta http-equiv=" | ||
+ | <link rel=" | ||
+ | </ | ||
+ | < | ||
+ | HEADER | ||
+ | |||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | for my $n (0..$# | ||
+ | print " | ||
+ | } | ||
+ | print "</ | ||
+ | |||
+ | for my $n (0..$# | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | } | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | <table border=" | ||
+ | < | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | <td> | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | </td> | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | FOOTER | ||
+ | } | ||
+ | |||
+ | sub send_image($) | ||
+ | { | ||
+ | my ($file)= @_; | ||
+ | |||
+ | -r $file or do { | ||
+ | print " | ||
+ | exit 1; | ||
+ | }; | ||
+ | |||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | open(IMG, $file) or die; | ||
+ | my $data; | ||
+ | print $data while read(IMG, $data, 16384)> | ||
+ | } | ||
+ | |||
+ | sub main() | ||
+ | { | ||
+ | my $uri = $ENV{REQUEST_URI} || ''; | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/\//,/g; | ||
+ | $uri =~ s/ | ||
+ | mkdir $tmp_dir, 0777 unless -d $tmp_dir; | ||
+ | mkdir " | ||
+ | |||
+ | my $img = $ENV{QUERY_STRING}; | ||
+ | if(defined $img and $img =~ /\S/) { | ||
+ | if($img =~ / | ||
+ | my $file = " | ||
+ | graph($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_virus($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greylist($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greystats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreen($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreenstats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_queue($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dane($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_spf($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dkim($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dmarc($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | else { | ||
+ | die " | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | print_html; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | main; | ||
+ | </ | ||
+ | |||
+ | |||
+ | === / | ||
+ | Änderungen am Aussehen im Punkto Schriften und Farben der Webseite können auch mit Hilfe der CSS-Datei vorgenommen werden. | ||
+ | # vim / | ||
+ | |||
+ | <file css / | ||
+ | body { width: 900px; background-color: | ||
+ | font-family: | ||
+ | font-size: 12pt; | ||
+ | margin: 5px } | ||
+ | h1 { margin-top: 20px; margin-bottom: | ||
+ | text-align: center } | ||
+ | h2 { background-color: | ||
+ | padding: 2px 0 2px 4px } | ||
+ | hr { height: 1px; | ||
+ | border: 0; | ||
+ | border-top: 1px solid #aaa } | ||
+ | table { border: 0px; width: 100% } | ||
+ | img { border: 0 } | ||
+ | a { text-decoration: | ||
+ | a: | ||
+ | #jump { margin: 0 0 10px 4px } | ||
+ | #jump li { list-style: none; display: inline; | ||
+ | | ||
+ | #jump li: | ||
+ | #jump li: | ||
+ | </ | ||
+ | |||
+ | === / | ||
+ | Der Vollständigkeit halber ist nachfolgend das Perl-Script zum erstellen und Befüllen der **RRD**-Datenbankfiles aufgeführt. Eine Konfiguration des scriptes ist aber __nicht__ vorgesehen und notwendig! | ||
+ | # less / | ||
+ | |||
+ | <file perl / | ||
+ | |||
+ | # mailgraph -- an rrdtool frontend for mail statistics | ||
+ | # copyright (c) 2000-2007 ETH Zurich | ||
+ | # copyright (c) 2000-2007 David Schweikert < | ||
+ | # copyright (c) 2011 Markus Neubauer < | ||
+ | # copyright (c) 2014-2015 Django < | ||
+ | # released under the GNU General Public License | ||
+ | # with spf-, dkim-, dmarc, and dane-patch Sebastian van de Meer < | ||
+ | |||
+ | ######## Parse:: | ||
+ | package Parse:: | ||
+ | use Carp; | ||
+ | use Symbol; | ||
+ | use Time:: | ||
+ | use IO::File; | ||
+ | use strict; | ||
+ | use vars qw($VERSION); | ||
+ | my %months_map = ( | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | sub is_dst_switch($$$) | ||
+ | { | ||
+ | my ($self, $t, $time) = @_; | ||
+ | # calculate the time in one hour and see if the difference is 3600 seconds. | ||
+ | # if not, we are in a dst-switch hour | ||
+ | # note that right now we only support 1-hour dst offsets | ||
+ | # cache the result | ||
+ | if(defined $self-> | ||
+ | $self-> | ||
+ | return @{$self-> | ||
+ | } | ||
+ | # calculate a number out of the day and hour to identify the hour | ||
+ | $self-> | ||
+ | # calculating hour+1 (below) is a problem if the hour is 23. as far as I | ||
+ | # know, nobody does the DST switch at this time, so just assume it isn't | ||
+ | # DST switch if the hour is 23. | ||
+ | if($t-> | ||
+ | @{$self-> | ||
+ | return @{$self-> | ||
+ | } | ||
+ | # let's see the timestamp in one hour | ||
+ | # 0: sec, 1: min, 2: h, 3: day, 4: month, 5: year | ||
+ | my $time_plus_1h = timelocal($t-> | ||
+ | if($time_plus_1h - $time > 4000) { | ||
+ | @{$self-> | ||
+ | } | ||
+ | else { | ||
+ | @{$self-> | ||
+ | } | ||
+ | return @{$self-> | ||
+ | } | ||
+ | # fast timelocal, cache minute' | ||
+ | # don't cache more than minute because of daylight saving time switch | ||
+ | # 0: sec, 1: min, 2: h, 3: day, 4: month, 5: year | ||
+ | sub str2time($$$$$$$$) | ||
+ | { | ||
+ | my $self = shift @_; | ||
+ | my $GMT = pop @_; | ||
+ | my $lastmin = $self-> | ||
+ | if(defined $lastmin and | ||
+ | $lastmin-> | ||
+ | $lastmin-> | ||
+ | $lastmin-> | ||
+ | $lastmin-> | ||
+ | $lastmin-> | ||
+ | { | ||
+ | $self-> | ||
+ | return $self-> | ||
+ | } | ||
+ | my $time; | ||
+ | if($GMT) { | ||
+ | $time = timegm(@_); | ||
+ | } | ||
+ | else { | ||
+ | $time = timelocal(@_); | ||
+ | } | ||
+ | # compensate for DST-switch | ||
+ | # - if a timewarp is detected (1:00 -> 1:30 -> 1:00): | ||
+ | # - test if we are in a DST-switch-hour | ||
+ | # - compensate if yes | ||
+ | # note that we assume that the DST-switch goes like this: | ||
+ | # time | ||
+ | # stamp | ||
+ | # comp. | ||
+ | # result | ||
+ | # old Time::Local versions behave differently (1 2 5 6 5 6 7 8) | ||
+ | if(!$GMT and !defined $self-> | ||
+ | defined $self-> | ||
+ | $self-> | ||
+ | $self-> | ||
+ | { | ||
+ | my ($off, $until) = $self-> | ||
+ | if($off) { | ||
+ | $self-> | ||
+ | $self-> | ||
+ | } | ||
+ | } | ||
+ | if(defined $self-> | ||
+ | delete $self-> | ||
+ | delete $self-> | ||
+ | } | ||
+ | $self-> | ||
+ | $self-> | ||
+ | $self-> | ||
+ | return $time+($self-> | ||
+ | } | ||
+ | sub _use_locale($) | ||
+ | { | ||
+ | use POSIX qw(locale_h strftime); | ||
+ | my $old_locale = setlocale(LC_TIME); | ||
+ | for my $locale (@_) { | ||
+ | croak " | ||
+ | for my $month (0..11) { | ||
+ | $months_map{strftime(" | ||
+ | } | ||
+ | } | ||
+ | setlocale(LC_TIME, | ||
+ | } | ||
+ | sub new($$;%) | ||
+ | { | ||
+ | my ($class, $file, %data) = @_; | ||
+ | croak "new() requires one argument: file" unless defined $file; | ||
+ | %data = () unless %data; | ||
+ | if(not defined $data{year}) { | ||
+ | $data{year} = (localtime(time))[5]+1900; | ||
+ | } | ||
+ | $data{type} = ' | ||
+ | $data{_repeat}=0; | ||
+ | if(UNIVERSAL:: | ||
+ | $data{file} = $file; | ||
+ | } | ||
+ | elsif(UNIVERSAL:: | ||
+ | $data{file} = $file; | ||
+ | $data{filetail}=1; | ||
+ | } | ||
+ | elsif(! ref $file) { | ||
+ | if($file eq ' | ||
+ | my $io = new IO::Handle; | ||
+ | $data{file} = $io-> | ||
+ | } | ||
+ | else { | ||
+ | $data{file} = new IO:: | ||
+ | defined $data{file} or croak " | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | croak " | ||
+ | } | ||
+ | if(defined $data{locale}) { | ||
+ | if(ref $data{locale} eq ' | ||
+ | _use_locale @{$data{locale}}; | ||
+ | } | ||
+ | elsif(ref $data{locale} eq '' | ||
+ | _use_locale $data{locale}; | ||
+ | } | ||
+ | else { | ||
+ | croak "' | ||
+ | } | ||
+ | } | ||
+ | return bless \%data, $class; | ||
+ | } | ||
+ | sub _year_increment($$) | ||
+ | { | ||
+ | my ($self, $mon) = @_; | ||
+ | # year change | ||
+ | if($mon==0) { | ||
+ | $self-> | ||
+ | $self-> | ||
+ | } | ||
+ | elsif($mon == 11) { | ||
+ | if($self-> | ||
+ | $self-> | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | $self-> | ||
+ | } | ||
+ | $self-> | ||
+ | } | ||
+ | sub _next_line($) | ||
+ | { | ||
+ | my $self = shift; | ||
+ | my $f = $self-> | ||
+ | if(defined $self-> | ||
+ | return $f-> | ||
+ | } | ||
+ | else { | ||
+ | return $f-> | ||
+ | } | ||
+ | } | ||
+ | sub _next_syslog($) | ||
+ | { | ||
+ | my ($self) = @_; | ||
+ | while($self-> | ||
+ | $self-> | ||
+ | return $self-> | ||
+ | } | ||
+ | my $file = $self-> | ||
+ | line: while(defined (my $str = $self-> | ||
+ | # date, time and host | ||
+ | $str =~ /^ | ||
+ | (\S{3})\s+(\d+) | ||
+ | \s | ||
+ | (\d+): | ||
+ | (?: | ||
+ | \s | ||
+ | ([-\w\.\@: | ||
+ | \s+ | ||
+ | (?: | ||
+ | (.*) # text -- 7 | ||
+ | $/x or do | ||
+ | { | ||
+ | warn " | ||
+ | next line; | ||
+ | }; | ||
+ | my $mon = $months_map{$1}; | ||
+ | defined $mon or croak " | ||
+ | $self-> | ||
+ | # convert to unix time | ||
+ | my $time = $self-> | ||
+ | if(not $self-> | ||
+ | # accept maximum one day in the present future | ||
+ | if($time - time > 86400) { | ||
+ | warn " | ||
+ | next line; | ||
+ | } | ||
+ | } | ||
+ | my ($host, $text) = ($6, $7); | ||
+ | # last message repeated ... times | ||
+ | if($text =~ /^(?:last message repeated|above message repeats) (\d+) time/) { | ||
+ | next line if defined $self-> | ||
+ | next line if not defined $self-> | ||
+ | $1 > 0 or do { | ||
+ | warn " | ||
+ | next line; | ||
+ | }; | ||
+ | $self-> | ||
+ | $self-> | ||
+ | return $self-> | ||
+ | } | ||
+ | # marks | ||
+ | next if $text eq '-- MARK --'; | ||
+ | # some systems send over the network their | ||
+ | # hostname prefixed to the text. strip that. | ||
+ | $text =~ s/ | ||
+ | # discard ':' | ||
+ | # Apr 24 19:09:40 remedy : su : + tty?? root-oracle | ||
+ | $text =~ s/^:\s+//; | ||
+ | $text =~ /^ | ||
+ | ([^: | ||
+ | (?: | ||
+ | :\s+ | ||
+ | (?:\[ID\ (\d+)\ ([a-z0-9]+)\.([a-z]+)\]\ )? # Solaris 8 " | ||
+ | (.*) # text -- 6 | ||
+ | $/x or do | ||
+ | { | ||
+ | warn " | ||
+ | next line; | ||
+ | }; | ||
+ | if($self-> | ||
+ | $self-> | ||
+ | $time, | ||
+ | $host, | ||
+ | $1, # 2: program | ||
+ | $2, # 3: pid | ||
+ | $6, # 4: text | ||
+ | ]; | ||
+ | } | ||
+ | else { | ||
+ | $self-> | ||
+ | timestamp => $time, | ||
+ | host => $host, | ||
+ | program | ||
+ | pid => $2, | ||
+ | msgid => $3, | ||
+ | facility | ||
+ | level => $5, | ||
+ | text => $6, | ||
+ | }; | ||
+ | } | ||
+ | return $self-> | ||
+ | } | ||
+ | return undef; | ||
+ | } | ||
+ | sub _next_metalog($) | ||
+ | { | ||
+ | my ($self) = @_; | ||
+ | my $file = $self-> | ||
+ | line: while(my $str = $self-> | ||
+ | # date, time and host | ||
+ | $str =~ /^ | ||
+ | (\S{3})\s+(\d+) | ||
+ | \s | ||
+ | (\d+): | ||
+ | # host is not logged | ||
+ | \s+ | ||
+ | (.*) # text -- 6 | ||
+ | $/x or do | ||
+ | { | ||
+ | warn " | ||
+ | next line; | ||
+ | }; | ||
+ | my $mon = $months_map{$1}; | ||
+ | defined $mon or croak " | ||
+ | $self-> | ||
+ | # convert to unix time | ||
+ | my $time = $self-> | ||
+ | my $text = $6; | ||
+ | $text =~ /^ | ||
+ | \[(.*? | ||
+ | # no PID | ||
+ | \s+ | ||
+ | (.*) # text -- 2 | ||
+ | $/x or do | ||
+ | { | ||
+ | warn " | ||
+ | next line; | ||
+ | }; | ||
+ | if($self-> | ||
+ | return [ | ||
+ | $time, | ||
+ | ' | ||
+ | $1, # 2: program | ||
+ | undef, | ||
+ | $2, # 4: text | ||
+ | ]; | ||
+ | } | ||
+ | else { | ||
+ | return { | ||
+ | timestamp => $time, | ||
+ | host => ' | ||
+ | program | ||
+ | text => $2, | ||
+ | }; | ||
+ | } | ||
+ | } | ||
+ | return undef; | ||
+ | } | ||
+ | sub next($) | ||
+ | { | ||
+ | my ($self) = @_; | ||
+ | if($self-> | ||
+ | return $self-> | ||
+ | } | ||
+ | elsif($self-> | ||
+ | return $self-> | ||
+ | } | ||
+ | croak " | ||
+ | } | ||
+ | |||
+ | ##################################################################### | ||
+ | ##################################################################### | ||
+ | ##################################################################### | ||
+ | |||
+ | use RRDs; | ||
+ | |||
+ | use strict; | ||
+ | use File::Tail; | ||
+ | use Getopt:: | ||
+ | use POSIX ' | ||
+ | |||
+ | my $VERSION = " | ||
+ | |||
+ | # config | ||
+ | my $rrdstep | ||
+ | my $xpoints | ||
+ | my $points_per_sample = 3; | ||
+ | |||
+ | my $daemon_logfile = '/ | ||
+ | my $daemon_pidfile = '/ | ||
+ | my $daemon_rrd_dir = '/ | ||
+ | |||
+ | # global variables | ||
+ | my $logfile; | ||
+ | my $rrd = " | ||
+ | my $rrd_virus | ||
+ | my $rrd_grey | ||
+ | my $rrd_dane | ||
+ | my $rrd_dmarc | ||
+ | my $rrd_post | ||
+ | my $year; | ||
+ | my $this_minute; | ||
+ | my %sum = ( sent => 0, received => 0, bounced => 0, rejected => 0, virus => 0, spam => 0, greylisted => 0, delayed => 0,whitelist => 0, new => 0, awl => 0, early => 0, reconnectok => 0, anonymoustls => 0, trustedtls => 0, untrustedtls => 0, verifiedtls => 0, spfnone => 0, spffail => 0, spfpass => 0, dmarcnone => 0, dmarcfail => 0, dmarcpass => 0, dkimnone => 0, dkimfail => 0, dkimpass => 0, pswl => 0, psbl => 0, passold => 0, veto => 0, pregreet => 0, dnsbl => 0, pipelining =>, nonsmtp => 0, barenewline => 0, command => 0, hangup =>, passnew => 0); | ||
+ | my $rrd_inited=0; | ||
+ | |||
+ | my %opt = (); | ||
+ | |||
+ | # prototypes | ||
+ | sub daemonize(); | ||
+ | sub process_line($); | ||
+ | #4 | ||
+ | sub event_sent($); | ||
+ | sub event_received($); | ||
+ | sub event_bounced($); | ||
+ | sub event_rejected($); | ||
+ | #2 | ||
+ | sub event_virus($); | ||
+ | sub event_spam($); | ||
+ | #7 | ||
+ | sub event_greylisted($); | ||
+ | sub event_delayed($); | ||
+ | sub event_whitelist($); | ||
+ | sub event_new($); | ||
+ | sub event_awl($); | ||
+ | sub event_early($); | ||
+ | sub event_reconnectok($); | ||
+ | #4 | ||
+ | sub event_anonymoustls($); | ||
+ | sub event_trustedtls($); | ||
+ | sub event_untrustedtls($); | ||
+ | sub event_verifiedtls($); | ||
+ | #9 | ||
+ | sub event_spfnone($); | ||
+ | sub event_spffail($); | ||
+ | sub event_spfpass($); | ||
+ | sub event_dmarcnone($); | ||
+ | sub event_dmarcfail($); | ||
+ | sub event_dmarcpass($); | ||
+ | sub event_dkimnone($); | ||
+ | sub event_dkimfail($); | ||
+ | sub event_dkimpass($); | ||
+ | #12 | ||
+ | sub event_pswl($); | ||
+ | sub event_psbl($); | ||
+ | sub event_passold($); | ||
+ | sub event_veto($); | ||
+ | sub event_pregreet($); | ||
+ | sub event_dnsbl($); | ||
+ | sub event_pipelining($); | ||
+ | sub event_nonsmtp($); | ||
+ | sub event_barenewline($); | ||
+ | sub event_command($); | ||
+ | sub event_hangup($); | ||
+ | sub event_passnew($); | ||
+ | # | ||
+ | sub init_rrd($); | ||
+ | sub update($); | ||
+ | |||
+ | sub usage | ||
+ | { | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | |||
+ | exit; | ||
+ | } | ||
+ | |||
+ | sub main | ||
+ | { | ||
+ | Getopt:: | ||
+ | GetOptions(\%opt, | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ) or exit(1); | ||
+ | usage if $opt{help}; | ||
+ | |||
+ | if($opt{version}) { | ||
+ | print " | ||
+ | exit; | ||
+ | } | ||
+ | |||
+ | $daemon_pidfile = $opt{daemon_pid} if defined $opt{daemon_pid}; | ||
+ | $daemon_logfile = $opt{daemon_log} if defined $opt{daemon_log}; | ||
+ | $daemon_rrd_dir = $opt{daemon_rrd} if defined $opt{daemon_rrd}; | ||
+ | $rrd = $opt{rrd_name}." | ||
+ | $rrd_virus | ||
+ | $rrd_grey | ||
+ | $rrd_dane | ||
+ | $rrd_dmarc | ||
+ | $rrd_post | ||
+ | |||
+ | |||
+ | # compile --ignore-host regexps | ||
+ | if(defined $opt{' | ||
+ | for my $ih (@{$opt{' | ||
+ | push @{$opt{' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if($opt{daemon} or $opt{daemon_rrd}) { | ||
+ | chdir $daemon_rrd_dir or die " | ||
+ | -w $daemon_rrd_dir or die " | ||
+ | } | ||
+ | |||
+ | daemonize if $opt{daemon}; | ||
+ | |||
+ | my $logfile = defined $opt{logfile} ? $opt{logfile} : '/ | ||
+ | my $file; | ||
+ | if($opt{cat}) { | ||
+ | $file = $logfile; | ||
+ | } | ||
+ | else { | ||
+ | $file = File:: | ||
+ | } | ||
+ | my $parser = new Parse:: | ||
+ | type => defined $opt{logtype} ? $opt{logtype} : ' | ||
+ | |||
+ | if(not defined $opt{host}) { | ||
+ | while(my $sl = $parser-> | ||
+ | process_line($sl); | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | my $host = qr/ | ||
+ | while(my $sl = $parser-> | ||
+ | process_line($sl) if $sl->[1] =~ $host; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | sub daemonize() | ||
+ | { | ||
+ | open STDIN, '/ | ||
+ | if($opt{verbose}) { | ||
+ | open STDOUT, ">> | ||
+ | or die " | ||
+ | } | ||
+ | else { | ||
+ | open STDOUT, '>/ | ||
+ | or die " | ||
+ | } | ||
+ | defined(my $pid = fork) or die " | ||
+ | if($pid) { | ||
+ | # parent | ||
+ | open PIDFILE, "> | ||
+ | or die " | ||
+ | print PIDFILE " | ||
+ | close(PIDFILE); | ||
+ | exit; | ||
+ | } | ||
+ | # child | ||
+ | setsid | ||
+ | open STDERR, '>& | ||
+ | } | ||
+ | |||
+ | sub init_rrd($) | ||
+ | { | ||
+ | my $m = shift; | ||
+ | my $rows = $xpoints/ | ||
+ | my $realrows = int($rows*1.1); | ||
+ | my $day_steps = int(3600*24 / ($rrdstep*$rows)); | ||
+ | # use multiples, otherwise rrdtool could choose the wrong RRA | ||
+ | my $week_steps = $day_steps*7; | ||
+ | my $month_steps = $week_steps*5; | ||
+ | my $year_steps = $month_steps*12; | ||
+ | |||
+ | # mail rrd | ||
+ | if(! -f $rrd and ! $opt{' | ||
+ | RRDs:: | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | $this_minute = $m; | ||
+ | } | ||
+ | elsif(-f $rrd) { | ||
+ | $this_minute = RRDs:: | ||
+ | } | ||
+ | |||
+ | # virus rrd | ||
+ | if(! -f $rrd_virus and ! $opt{' | ||
+ | RRDs:: | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | } | ||
+ | elsif(-f $rrd_virus and ! defined $rrd_virus) { | ||
+ | $this_minute = RRDs:: | ||
+ | } | ||
+ | |||
+ | # grey rrd | ||
+ | if(! -f $rrd_grey and ! $opt{' | ||
+ | RRDs:: | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | $this_minute = $m; | ||
+ | } | ||
+ | elsif(-f $rrd_grey and ! defined $rrd_grey) { | ||
+ | $this_minute = RRDs:: | ||
+ | } | ||
+ | |||
+ | # dane rrd | ||
+ | if(! -f $rrd_dane and ! $opt{' | ||
+ | RRDs:: | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | $this_minute = $m; | ||
+ | } | ||
+ | elsif(-f $rrd_dane and ! defined $rrd_dane) { | ||
+ | $this_minute = RRDs:: | ||
+ | } | ||
+ | |||
+ | # dmarc rrd | ||
+ | if(! -f $rrd_dmarc and ! $opt{' | ||
+ | RRDs:: | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | $this_minute = $m; | ||
+ | } | ||
+ | elsif(-f $rrd_dmarc and ! defined $rrd_dmarc) { | ||
+ | $this_minute = RRDs:: | ||
+ | } | ||
+ | |||
+ | # post rrd | ||
+ | if(! -f $rrd_post and ! $opt{' | ||
+ | RRDs:: | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | $this_minute = $m; | ||
+ | } | ||
+ | elsif(-f $rrd_post and ! defined $rrd_post) { | ||
+ | $this_minute = RRDs:: | ||
+ | } | ||
+ | |||
+ | $rrd_inited=1; | ||
+ | } | ||
+ | |||
+ | sub process_line($) | ||
+ | { | ||
+ | my $sl = shift; | ||
+ | my $time = $sl-> | ||
+ | my $prog = $sl-> | ||
+ | my $text = $sl-> | ||
+ | |||
+ | if($prog =~ / | ||
+ | my $prog = $1; | ||
+ | if($prog eq ' | ||
+ | if($text =~ / | ||
+ | return if $opt{' | ||
+ | $text =~ / | ||
+ | if(defined $opt{' | ||
+ | for my $ih (@{$opt{' | ||
+ | warn " | ||
+ | return if $text =~ $ih; | ||
+ | } | ||
+ | } | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /Anonymous TLS connection established to/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /Trusted TLS connection established to/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /Untrusted TLS connection established to/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /Verified TLS connection established to/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | my $client = $1; | ||
+ | return if $opt{' | ||
+ | $client =~ / | ||
+ | return if $opt{' | ||
+ | $client =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($opt{' | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($opt{' | ||
+ | event($time, | ||
+ | } | ||
+ | # | ||
+ | # | ||
+ | #} | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | if($text =~ /Blocked by SpamAssassin/ | ||
+ | event($time, | ||
+ | } | ||
+ | else { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /PASS OLD/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /WHITELIST VETO/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /WHITELIST VETO/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /PREGREET/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /PREGREET/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /DNSBL/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /DNSBL/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /COMMAND PIPELINING/ | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /COMMAND PIPELINING/ | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /NON-SMTP COMMAND/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /NON-SMTP COMMAND/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /BARE NEWLINE/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /BARE NEWLINE/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /COMMAND TIME LIMIT/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /COMMAND TIME LIMIT/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /COMMAND COUNT LIMIT/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /COMMAND COUNT LIMIT/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /COMMAND LENGTH LIMIT/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /COMMAND LENGTH LIMIT/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /HANGUP/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /HANGUP/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ /PASS NEW/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /\blost input channel\b/ ) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | if (($opt{' | ||
+ | event($time, | ||
+ | } elsif ($opt{' | ||
+ | event($time, | ||
+ | } else { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($text =~ /\bsender blocked\b/ ) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /\bsender denied\b/ ) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /\bUser unknown$/i ) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / rejected because \S+ is in a black list at \S+/) { | ||
+ | if($opt{' | ||
+ | event($time, | ||
+ | } else { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($text =~ / rejected RCPT \S+: (Sender verify failed|Unknown user)/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if( $text =~ / | ||
+ | if($text !~ /\btag2=/) { # ignore new per-recipient log entry (2.2.0) | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | if($text !~ /\btag2=/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | if($text !~ /\btag2=/) { | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | elsif($text =~ /^Virus found\b/) { | ||
+ | event($time, | ||
+ | } | ||
+ | # | ||
+ | # event($time, | ||
+ | # } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | # Vexira antivirus (old) | ||
+ | if($text =~ /^VIRUS/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | # Vexira antivirus | ||
+ | if($text =~ /^\*+ Virus\b/) { | ||
+ | event($time, | ||
+ | } | ||
+ | # Vexira antispam | ||
+ | elsif($text =~ /\bcontains spam\b/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | # AntiVir MailGate | ||
+ | if($text =~ /^Alert!/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | # avcheck | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ /^(?:spamd: )? | ||
+ | event($time, | ||
+ | } | ||
+ | # ClamAV SpamAssassin-plugin | ||
+ | elsif($text =~ /(?:result: )?CLAMAV/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ /spam detected from/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ /^\s*SPAM/ or $text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | # DrWeb | ||
+ | if($text =~ /infected/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ /Virus/) { | ||
+ | event($time, | ||
+ | } | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ /(Virus Scanning: Found)/ ) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /Bounce to/ ) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /^Spam Checks: Found ([0-9]+) spam messages/) { | ||
+ | my $cnt = $1; | ||
+ | for (my $i=0; $i<$cnt; $i++) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | # uncommment for clamassassin: | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # } | ||
+ | #} | ||
+ | elsif ($prog eq ' | ||
+ | if ($text =~ /clamd: found/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | # AntiVir Milter | ||
+ | if($text =~ /^Alert!/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ /Spam/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif($prog eq ' | ||
+ | if($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | ## Old versions (up to 1.27) | ||
+ | #if($text =~ /delayed [0-9]+ seconds: client/) { | ||
+ | # | ||
+ | #} | ||
+ | # New versions (from 1.28) | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ / | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /triplet found/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif ($prog eq ' | ||
+ | if ($text =~ /SPF pass:/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /SPF none:/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /fail:/) { | ||
+ | event($time, | ||
+ | } | ||
+ | # elsif($text =~ /SPF fail:\b/) { | ||
+ | # event($time, | ||
+ | # } | ||
+ | # elsif($text =~ /SPF softfail: | ||
+ | # event($time, | ||
+ | # } | ||
+ | } | ||
+ | elsif ($prog eq ' | ||
+ | if ($text =~ /DKIM verification successful/ | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /no signature data/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /bad signature data/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | elsif ($prog eq ' | ||
+ | if ($text =~ /pass/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /none/) { | ||
+ | event($time, | ||
+ | } | ||
+ | elsif($text =~ /fail/) { | ||
+ | event($time, | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | sub event($$) | ||
+ | { | ||
+ | my ($t, $type) = @_; | ||
+ | update($t) and $sum{$type}++; | ||
+ | } | ||
+ | |||
+ | # returns 1 if $sum should be updated | ||
+ | sub update($) | ||
+ | { | ||
+ | my $t = shift; | ||
+ | my $m = $t - $t%$rrdstep; | ||
+ | init_rrd($m) unless $rrd_inited; | ||
+ | return 1 if $m == $this_minute; | ||
+ | return 0 if $m < $this_minute; | ||
+ | |||
+ | print " | ||
+ | #4 | ||
+ | RRDs:: | ||
+ | #2 | ||
+ | RRDs:: | ||
+ | #7 | ||
+ | RRDs:: | ||
+ | #4 | ||
+ | RRDs:: | ||
+ | #9 | ||
+ | RRDs:: | ||
+ | #12 | ||
+ | RRDs:: | ||
+ | |||
+ | |||
+ | if($m > $this_minute+$rrdstep) { | ||
+ | for(my $sm=$this_minute+$rrdstep; | ||
+ | print " | ||
+ | #4 | ||
+ | RRDs:: | ||
+ | #2 | ||
+ | RRDs:: | ||
+ | #7 | ||
+ | RRDs:: | ||
+ | #4 | ||
+ | RRDs:: | ||
+ | #9 | ||
+ | RRDs:: | ||
+ | #12 | ||
+ | RRDs:: | ||
+ | } | ||
+ | } | ||
+ | $this_minute = $m; | ||
+ | #4 | ||
+ | $sum{sent}=0; | ||
+ | $sum{received}=0; | ||
+ | $sum{bounced}=0; | ||
+ | $sum{rejected}=0; | ||
+ | #2 | ||
+ | $sum{virus}=0; | ||
+ | $sum{spam}=0; | ||
+ | #7 | ||
+ | $sum{greylisted}=0; | ||
+ | $sum{delayed}=0; | ||
+ | $sum{whitelist}=0; | ||
+ | $sum{new}=0; | ||
+ | $sum{awl}=0; | ||
+ | $sum{early}=0; | ||
+ | $sum{reconnectok}=0; | ||
+ | #4 | ||
+ | $sum{anonymoustls}=0; | ||
+ | $sum{trustedtls}=0; | ||
+ | $sum{untrustedtls}=0; | ||
+ | $sum{verifiedtls}=0; | ||
+ | #9 | ||
+ | $sum{spfnone}=0; | ||
+ | $sum{spffail}=0; | ||
+ | $sum{spfpass}=0; | ||
+ | $sum{dmarcnone}=0; | ||
+ | $sum{dmarcfail}=0; | ||
+ | $sum{dmarcpass}=0; | ||
+ | $sum{dkimnone}=0; | ||
+ | $sum{dkimfail}=0; | ||
+ | $sum{dkimpass}=0; | ||
+ | # 12 | ||
+ | $sum{pswl}=0; | ||
+ | $sum{psbl}=0; | ||
+ | $sum{passold}=0; | ||
+ | $sum{veto}=0; | ||
+ | $sum{pregreet}=0; | ||
+ | $sum{dnsbl}=0; | ||
+ | $sum{pipelining}=0; | ||
+ | $sum{nonsmtp}=0; | ||
+ | $sum{barenewline}=0; | ||
+ | $sum{command}=0; | ||
+ | $sum{hangup}=0; | ||
+ | $sum{passnew}=0; | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | main; | ||
+ | |||
+ | __END__ | ||
+ | |||
+ | =head1 NAME | ||
+ | |||
+ | mailgraph.pl - rrdtool frontend for mail statistics | ||
+ | |||
+ | =head1 SYNOPSIS | ||
+ | |||
+ | B< | ||
+ | |||
+ | | ||
+ | -h, --help | ||
+ | | ||
+ | -h, --help | ||
+ | -v, --verbose | ||
+ | -V, --version | ||
+ | -c, --cat causes the logfile to be only read and not monitored | ||
+ | -l, --logfile f monitor logfile f instead of / | ||
+ | -t, --logtype t set logfile' | ||
+ | -y, --year | ||
+ | | ||
+ | -d, --daemon | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | =head1 DESCRIPTION | ||
+ | |||
+ | This script does parse syslog and updates the RRD database (mailgraph.rrd) in | ||
+ | the current directory. | ||
+ | |||
+ | =head2 Log-Types | ||
+ | |||
+ | The following types can be given to --logtype: | ||
+ | |||
+ | =over 10 | ||
+ | |||
+ | =item syslog | ||
+ | |||
+ | Traditional " | ||
+ | |||
+ | =item metalog | ||
+ | |||
+ | Metalog (see http:// | ||
+ | |||
+ | =back | ||
+ | |||
+ | =head1 COPYRIGHT | ||
+ | |||
+ | Copyright (c) 2000-2007 by ETH Zurich | ||
+ | Copyright (c) 2000-2007 by David Schweikert | ||
+ | Copyright (c) 2011 Markus Neubauer | ||
+ | Copyright (c) 2014-2015 by Django | ||
+ | |||
+ | =head1 LICENSE | ||
+ | |||
+ | This program is free software; you can redistribute it and/or modify | ||
+ | it under the terms of the GNU General Public License as published by | ||
+ | the Free Software Foundation; either version 2 of the License, or | ||
+ | (at your option) any later version. | ||
+ | |||
+ | This program is distributed in the hope that it will be useful, | ||
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
+ | GNU General Public License for more details. | ||
+ | |||
+ | You should have received a copy of the GNU General Public License | ||
+ | along with this program; if not, write to the Free Software | ||
+ | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
+ | |||
+ | =head1 AUTHOR | ||
+ | |||
+ | S<David Schweikert E< | ||
+ | |||
+ | =cut | ||
+ | |||
+ | # vi: sw=8 | ||
+ | </ | ||
+ | ==== Apache VHost anlegen ==== | ||
+ | Damit wir bequem von unserem Browser aus, die aktuellen Graphiken abfragen können, bearbeiten wir entweder die aus dem RPM stammende Konfigurationsdatei oder legen wir nun einen passenden VHost an. | ||
+ | # vim / | ||
+ | <file apache / | ||
+ | # | ||
+ | # mailgraph.nausch.org | ||
+ | # | ||
+ | < | ||
+ | ServerAdmin webmaster@nausch.org | ||
+ | ServerName mailgraph.nausch.org | ||
+ | ServerAlias www.mailgraph.nausch.org | ||
+ | ServerPath / | ||
+ | DocumentRoot "/ | ||
+ | AddHandler cgi-script .cgi | ||
+ | |||
+ | < | ||
+ | AllowOverride None | ||
+ | Options +ExecCGI | ||
+ | DirectoryIndex mailgraph.cgi | ||
+ | Order deny,allow | ||
+ | require IP 10.0. | ||
+ | </ | ||
+ | ErrorLog logs/ | ||
+ | CustomLog logs/ | ||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | Bevor wir bei unserem Webserver eine Reload der Konfiguration vornehmen, testen wir unsere neue Konfigurationsdatei auf syntaktische Fehler. | ||
+ | # apachectl -t | ||
+ | |||
+ | | ||
+ | |||
+ | Da keine Fehler aufgetreten sind, aktivieren wir die neue Konfiguration durch einen Reload des Webserver-Daemon. | ||
+ | # systemctl reload postfix | ||
+ | |||
+ | ==== NGiNX VHost anlegen ==== | ||
+ | Nutzen wir als Webserver **[[centos: | ||
+ | # vim / | ||
+ | <file http / | ||
+ | listen | ||
+ | server_name | ||
+ | access_log | ||
+ | error_log | ||
+ | |||
+ | root / | ||
+ | index queuegraph.cgi; | ||
+ | |||
+ | | ||
+ | fastcgi_split_path_info ^(.+\.cgi)(/ | ||
+ | fastcgi_index queuegraph.cgi; | ||
+ | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | ||
+ | include fastcgi_params; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Den Parameter **fastcgi_pass** setzen wir im übrigen auf den Wert aus der Konfigurationsdatei // | ||
+ | |||
+ | Haben wir die Konfigurationsdatei vervollständigt, | ||
+ | # nginx -t | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | Somit können wir unsere Konfiguration nun noch aktivieren. | ||
+ | # systemctl reload nginx | ||
+ | |||
+ | ==== Programmaufruf ==== | ||
+ | === erster manueller Start des Dämon === | ||
+ | Damit das Mail-Logfile forlaufend ausgelesen wird, starten wir nun noch den Dämon mit Hilfe des mitgelieferten systemd-Start-Scriptes // | ||
+ | # systemctl start mailgraph | ||
+ | |||
+ | Im syslog wurde der Start des Daemon entsprechend dokumentiert. | ||
+ | # tail -n2 / | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | Ebenso kann man den Status des Webservers mit Hilfe des Befehls **systemctl** abfragen. | ||
+ | # systemctl status mailgraph | ||
+ | |||
+ | < | ||
+ | | ||
+ | | ||
+ | Process: 2362 ExecStart=/ | ||
+ | Main PID: 2367 (mailgraph) | ||
+ | | ||
+ | | ||
+ | |||
+ | Feb 02 21:17:37 vml000097.dmz.nausch.org systemd[1]: Started mailgraph mail log file analyzer. | ||
+ | </ | ||
+ | |||
+ | ==== automatischer Start beim Systemstart ==== | ||
+ | Wollen wir den Daemon beim Hochfahren des Systems automatisch starten, greifen wir auf den Befehl **systemctl** zurück. | ||
+ | # systemctl enable mailgraph.service | ||
+ | |||
+ | ln -s '/ | ||
+ | |||
+ | Möchten wir uns vergewissern, | ||
+ | # systemctl is-enabled mailgraph.service | ||
+ | |||
+ | | ||
+ | |||
+ | Startet der Server nicht automatisch, | ||
+ | |||
+ | ==== Webaufruf ==== | ||
+ | Über unseren [[https:// | ||
+ | |||
+ | {{ : | ||
- | FIXME //... do geds weida ... // FIXME | ||
==== Ausgabe individualisieren ==== | ==== Ausgabe individualisieren ==== | ||
+ | Der zeitgleiche Einsatz von **Postgrey** und **Postscreen** macht i.d.R. keinen besonderen Sinn und ist auch nicht zu empfehlen. In der **CGI**-Datei, | ||
+ | <WRAP center round tip 80%> | ||
+ | Einzelne Graphen lassen sich sehr leicht und einfach ausblenden, in dem man die zugehörigen Zeilen einfach auskommentiert, | ||
+ | </ | ||
+ | |||
+ | Im folgendem Beispiel wollen wir die Greylisting-Graphen nicht mehr ausgeben lassen. Mit dem Editor unserer Wahl bearbeiten wir das **cgi**-script. | ||
+ | # vim / | ||
+ | <code perl>... | ||
+ | for my $n (0..$# | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | #print "< | ||
+ | #print "< | ||
+ | #print "< | ||
+ | #print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | } | ||
+ | ... | ||
+ | </ | ||
+ | So lassen sich z.B. auch die Reports zu **SPF**, **DKIM** und **DMARC** ausblenden, wenn man diese (aktuell noch) nicht haben möchte. Will man später die Graphen wieder sehen, reicht das Entfernen des Kommentarzeichens **#** am Anfang der betreffenden Zeilen. | ||
+ | ===== Mailgraph-NG für mehrere Mailserver ===== | ||
+ | Betreibt man mehrere Mailserver will man neben den Einzelstatistiken der einzelnen Mailserver oft auch einen Überblick über den gesamten Mail-Server-Verkehr haben. | ||
+ | Auch das lässt sich mit einem überschaubaren Aufwand realisieren. Hierzu gehen wir wie folgt vor. | ||
+ | - Von den einzelnen Mailservern holen wir die RRD-Dateien ab. | ||
+ | - Diese kopieren wir dann auf ein zentrales Verzeichnis auf unserem WEB-Server. | ||
+ | - Wir passen unser CGI-Script, welches für die dynamische Generierung der WEB-Seite benutzt wird, soweit an, dass beim Erstellen eines Graphen nicht nur eine Datenquelle herangezogen wird, sondern die Summe unserer einzelnen Mailserver verwendet werden soll. | ||
+ | Auf diese drei Schritte gehen wir nun im Detail noch ein. | ||
+ | ==== RRD-Dateien einsammeln ==== | ||
+ | Die einzelnen RRD-Dateien unserer Mailserver kopieren wir mit scp in ein temporäres Arbeitsverzeichnis unseres WEB-Servers. Hierzu legen wir uns erst einmal einen eigenen User an. | ||
+ | # groupadd -g 1100 mx-transfer && useradd -c "MX Transfer User" -d / | ||
+ | |||
+ | <WRAP center round tip 80%> | ||
+ | Das Gleiche machen wir auf jedem der MX-Hosts, von denen wir später die Dateien einsammeln möchten. | ||
+ | </ | ||
+ | |||
+ | |||
+ | Anschließend generieren wir uns einen ssh-key für diesen transfer-User. Hierzu schlüpfen wir erst in die Rolle dieses speziellen Users. | ||
+ | # su - mx-transfer | ||
+ | |||
+ | Anschließend legen wir das Unterverzeichnis für den SSH-Schlüssel an und passen dessen Verzeichnisrechte an. | ||
+ | $ mkdir ~/.ssh | ||
+ | $ chmod 700 ~/.ssh | ||
+ | |||
+ | <WRAP center round tip 80%> | ||
+ | Auch hier legen wir auf jedem der MX-Hosts, von denen wir später die Dateien einsammeln möchten, das Verzeichnis mit den nötigen Berechtigungen an. | ||
+ | </ | ||
+ | |||
+ | Nun legen wir uns einen ssh-key ohne Passphrase an, in dem wir bei der Frage nach der Passphrase einfach keine angeben. | ||
+ | $ ssh-keygen -b 4096 -t rsa -C "MX Transfer User" | ||
+ | |||
+ | < | ||
+ | Enter file in which to save the key (/ | ||
+ | Enter passphrase (empty for no passphrase): | ||
+ | Enter same passphrase again: | ||
+ | Your identification has been saved in / | ||
+ | Your public key has been saved in / | ||
+ | The key fingerprint is: | ||
+ | 30: | ||
+ | The key's randomart image is: | ||
+ | +--[ RSA 4096]----+ | ||
+ | | | | ||
+ | | . . | | ||
+ | | o o | | ||
+ | |. = o . | | ||
+ | | = + S | | ||
+ | |o + o . | | ||
+ | |o* * . | | ||
+ | |oE@ o | | ||
+ | | = .. . | | ||
+ | +-----------------+ | ||
+ | </ | ||
+ | |||
+ | Den public-key kopieren wir nun anschließend auf jeden unserer MX-Hosts. | ||
+ | $ ssh-copy-id -i ~/ | ||
+ | |||
+ | $ ssh-copy-id -i ~/ | ||
+ | |||
+ | $ ssh-copy-id -i ~/ | ||
+ | |||
+ | $ ssh-copy-id -i ~/ | ||
+ | |||
+ | Als nächstes legen wir uns die temporären Zielverzeichnisse auf unserem Webserver an, in die wir später via scp die RRD-Dateien kopieren. | ||
+ | $ mkdir -p ~/ | ||
+ | |||
+ | Somit haben wir folgende Verzeichnisstruktur auf unserem Server. | ||
+ | < | ||
+ | └── mailgraph | ||
+ | ├── mx11 | ||
+ | ├── mx12 | ||
+ | ├── mx13 | ||
+ | └── mx14 | ||
+ | </ | ||
+ | |||
+ | Für das Einsammeln der RRD-Dateien legen wir uns ein passendes Script im Verzeichnis // | ||
+ | $ mkdir ~/bin | ||
+ | |||
+ | $ vim ~/ | ||
+ | |||
+ | <file bash ~/ | ||
+ | # Django : 2015-02-26 | ||
+ | # Einsammeln der RRD-Files von den einzelnen Mailservern | ||
+ | |||
+ | cd / | ||
+ | scp 10.100.0.87:/ | ||
+ | scp 10.100.0.87:/ | ||
+ | |||
+ | cd / | ||
+ | scp 10.200.0.87:/ | ||
+ | scp 10.200.0.87:/ | ||
+ | |||
+ | cd / | ||
+ | scp 10.300.0.87:/ | ||
+ | scp 10.300.0.87:/ | ||
+ | |||
+ | cd / | ||
+ | scp 10.400.0.87:/ | ||
+ | scp 10.400.0.87:/ | ||
+ | </ | ||
+ | |||
+ | Damit das Script auch ausgeführt werden kann, geben wir ihm noch das entsprechende **x**-Recht. | ||
+ | $ chmod +x ~/ | ||
+ | |||
+ | Im 5-minütigen Abstand holen wird dann die Daten von den Mailservern ab. Hierzu nutzen wir die benutzerindividuelle **crontab** unseres Transfer-Users. | ||
+ | $ crontab -e | ||
+ | |||
+ | < | ||
+ | # alles 5 Minuten die RRD-Files von den einzelnen Mailservern einsammeln | ||
+ | 2, | ||
+ | </ | ||
+ | |||
+ | Nach kurzer Zeit haben wir nunmehr von den einzelnen Mailservern die Statistikdaten mit einer Aktualität von 5 Minuten vorliegen. | ||
+ | < | ||
+ | ├── mx11 | ||
+ | │ ├── mailgraph_dane.rrd | ||
+ | │ ├── mailgraph_dmarc.rrd | ||
+ | │ ├── mailgraph_grey.rrd | ||
+ | │ ├── mailgraph_post.rrd | ||
+ | │ ├── mailgraph.rrd | ||
+ | │ ├── mailgraph_smtpd.rrd | ||
+ | │ ├── mailgraph_virus.rrd | ||
+ | │ └── mailqueues.rrd | ||
+ | ├── mx12 | ||
+ | │ ├── mailgraph_dane.rrd | ||
+ | │ ├── mailgraph_dmarc.rrd | ||
+ | │ ├── mailgraph_grey.rrd | ||
+ | │ ├── mailgraph_post.rrd | ||
+ | │ ├── mailgraph.rrd | ||
+ | │ ├── mailgraph_smtpd.rrd | ||
+ | │ ├── mailgraph_virus.rrd | ||
+ | │ └── mailqueues.rrd | ||
+ | ├── mx13 | ||
+ | │ ├── mailgraph_dane.rrd | ||
+ | │ ├── mailgraph_dmarc.rrd | ||
+ | │ ├── mailgraph_grey.rrd | ||
+ | │ ├── mailgraph_post.rrd | ||
+ | │ ├── mailgraph.rrd | ||
+ | │ ├── mailgraph_smtpd.rrd | ||
+ | │ ├── mailgraph_virus.rrd | ||
+ | │ └── mailqueues.rrd | ||
+ | └── mx14 | ||
+ | ├── mailgraph_dane.rrd | ||
+ | ├── mailgraph_dmarc.rrd | ||
+ | ├── mailgraph_grey.rrd | ||
+ | ├── mailgraph_post.rrd | ||
+ | ├── mailgraph.rrd | ||
+ | ├── mailgraph_smtpd.rrd | ||
+ | ├── mailgraph_virus.rrd | ||
+ | └── mailqueues.rrd | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Datenbereitstellung ==== | ||
+ | Das CGI-Script, welches wir zum dynamischen Generieren der Statistikgraphen verwenden, bekommt im Verzeichnis // | ||
+ | # mkdir -p / | ||
+ | |||
+ | Die Befüllung dieser Zeilverzeichnisse nehmen wir jeweils mit Hilfe eines **rsync**-Aufrufs vor, den wir via cronjob ausführen lassen. | ||
+ | # vim / | ||
+ | |||
+ | <file bash / | ||
+ | PATH=/ | ||
+ | MAILTO=root | ||
+ | HOME=/ | ||
+ | |||
+ | # For details see man 4 crontabs | ||
+ | |||
+ | # Example of job definition: | ||
+ | # .---------------- minute (0 - 59) | ||
+ | # | .------------- hour (0 - 23) | ||
+ | # | | .---------- day of month (1 - 31) | ||
+ | # | | | .------- month (1 - 12) OR jan, | ||
+ | # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun, | ||
+ | # | | | | | | ||
+ | # * * * * * user-name command to be executed | ||
+ | |||
+ | # Django : 2015-02-26 | ||
+ | # alles 5 Minuten die RRD-Files vom Transfer-Verzeichnis abholen und in den Zielverzeichnissen ablegen | ||
+ | */5 * * * * root / | ||
+ | */5 * * * * root / | ||
+ | */5 * * * * root / | ||
+ | */5 * * * * root / | ||
+ | </ | ||
+ | |||
+ | Nach wenigen Minuten stehen die Statistikdaten, | ||
+ | |||
+ | ==== Generierung Statistikgraphen und Webseite(n) ==== | ||
+ | Zur Präsentation unserer Statistikdaten benötigen wir nun noch einen Webserver, der die aufbereiteten Daten bereitstellt. Hierzu legen wir uns folgende Verzeichnisstruktur an. | ||
+ | < | ||
+ | ├── mx | ||
+ | ├── mx11 | ||
+ | ├── mx12 | ||
+ | ├── mx13 | ||
+ | └── mx14 | ||
+ | </ | ||
+ | |||
+ | # mkdir -p / | ||
+ | |||
+ | Bei der **[[centos: | ||
+ | {{ : | ||
+ | body { width: 900px; background-color: | ||
+ | font-family: | ||
+ | font-size: 12pt; | ||
+ | margin: 5px } | ||
+ | h1 { margin-top: 20px; margin-bottom: | ||
+ | text-align: center } | ||
+ | h2 { background-color: | ||
+ | padding: 2px 0 2px 4px } | ||
+ | h3 { margin-top: 10px; margin-bottom: | ||
+ | text-align: center } | ||
+ | hr { height: 1px; | ||
+ | border: 0; | ||
+ | border-top: 1px solid #aaa } | ||
+ | table { border: 0px; width: 100% } | ||
+ | img { border: 0 } | ||
+ | a { text-decoration: | ||
+ | a: | ||
+ | #jump { margin: 0 0 10px 4px } | ||
+ | #jump li { list-style: none; display: inline; | ||
+ | | ||
+ | #jump li: | ||
+ | #jump li: | ||
+ | </ | ||
+ | |||
+ | Das Logo und die CSS-Date kopieren wir nun die die einzelnen Unterverzeichnisse. | ||
+ | # cp / | ||
+ | # cp / | ||
+ | # cp / | ||
+ | # cp / | ||
+ | # cp / | ||
+ | |||
+ | # cp / | ||
+ | # cp / | ||
+ | # cp / | ||
+ | # cp / | ||
+ | # cp / | ||
+ | |||
+ | In den Unterverzeichnissen **mx11** bis **mx14** legen wir jeweils ein CGI-Script ab. Damit wir später zwischen den Einzelanzeigen der Mailserver und der kumulierten Übersicht jeweils wechseln können, versehen wir das Originalscript aus dem RPM **[[http:// | ||
+ | |||
+ | Die wesentlichen Änderungen/ | ||
+ | * Änderungen des Verzeichnisses der Datenquellen (RRD-Dateien). \\ **Bsp. MX11:** <code perl>... | ||
+ | |||
+ | my $rrd = '/ | ||
+ | my $rrd_virus = '/ | ||
+ | my $rrd_grey | ||
+ | my $rrd_dane | ||
+ | my $rrd_dmarc = '/ | ||
+ | my $rrd_smtpd = '/ | ||
+ | my $rrd_queue = '/ | ||
+ | my $rrd_post | ||
+ | |||
+ | ... | ||
+ | </ | ||
+ | * Einfügen der Variablen **url** für die Verweise zu den jeweils anderen Statistikseiten. | ||
+ | |||
+ | my $url = " | ||
+ | my $urlg = " | ||
+ | my $url1 = " | ||
+ | my $url2 = " | ||
+ | my $url3 = " | ||
+ | my $url4 = " | ||
+ | my $url11 = " | ||
+ | my $url12 = " | ||
+ | my $url13 = " | ||
+ | my $url14 = " | ||
+ | |||
+ | |||
+ | ... | ||
+ | </ | ||
+ | * Erweiterung des Unterprogramms **print_html** um die links zu den verweisenden Statistikseiten.< | ||
+ | |||
+ | sub print_html() | ||
+ | { | ||
+ | print " | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | <meta http-equiv=" | ||
+ | <link rel=" | ||
+ | </ | ||
+ | < | ||
+ | HEADER | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | #print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | |||
+ | print "< | ||
+ | for my $n (0..$# | ||
+ | print " | ||
+ | } | ||
+ | print "</ | ||
+ | |||
+ | for my $n (0..$# | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | } | ||
+ | |||
+ | print << | ||
+ | <hr/> | ||
+ | <table border=" | ||
+ | < | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | <td> | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | </td> | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | FOOTER | ||
+ | } | ||
+ | |||
+ | ... | ||
+ | </ | ||
+ | |||
+ | ==== CGI-Scripte für die Einzelsysteme ==== | ||
+ | Für die vier Mailserver ergeben sich folgende CGI-Scripte. | ||
+ | |||
+ | === / | ||
+ | |||
+ | # vim / | ||
+ | <file perl / | ||
+ | |||
+ | # mailgraph -- detailed postfix mail traffic statistics | ||
+ | # copyright (c) 2000-2007 ETH Zurich | ||
+ | # copyright (c) 2000-2007 David Schweikert < | ||
+ | # modified 2011 for queuegraph by Ralf Hildebrandt < | ||
+ | # modified 2015 for mailgraph-ng by Django < | ||
+ | # patches from Sebastian van de Meer < | ||
+ | # released under the GNU General Public License | ||
+ | |||
+ | use RRDs; | ||
+ | use POSIX qw(uname); | ||
+ | |||
+ | my $VERSION = " | ||
+ | |||
+ | my $host = (POSIX:: | ||
+ | my $scriptname = $ENV{" | ||
+ | my $xpoints = 800; | ||
+ | my $points_per_sample = 3; | ||
+ | my $ypoints = 160; | ||
+ | my $rrd = '/ | ||
+ | my $rrd_virus = '/ | ||
+ | my $rrd_grey = '/ | ||
+ | my $rrd_dane = '/ | ||
+ | my $rrd_dmarc = '/ | ||
+ | my $rrd_smtpd = '/ | ||
+ | my $rrd_queue = '/ | ||
+ | my $rrd_post = '/ | ||
+ | |||
+ | my $tmp_dir = '/ | ||
+ | my @graphs = ( | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | ); | ||
+ | |||
+ | my %color = ( # rrggbb in hex | ||
+ | # n | ||
+ | sent => ' | ||
+ | received | ||
+ | |||
+ | bounced | ||
+ | virus => ' | ||
+ | spam => ' | ||
+ | rejected | ||
+ | |||
+ | greylisted | ||
+ | delayed | ||
+ | whitelist | ||
+ | awl => ' | ||
+ | early => ' | ||
+ | |||
+ | pswl => ' | ||
+ | psbl => ' | ||
+ | passold | ||
+ | veto => ' | ||
+ | pregreet | ||
+ | dnsbl => ' | ||
+ | pipelining | ||
+ | nonsmtp | ||
+ | barenewline | ||
+ | command | ||
+ | hangup | ||
+ | passnew | ||
+ | |||
+ | new => ' | ||
+ | reconnectok | ||
+ | |||
+ | active | ||
+ | deferred | ||
+ | |||
+ | untrustedtls | ||
+ | anonymoustls | ||
+ | trustedtls | ||
+ | verifiedtls | ||
+ | |||
+ | untrustedtlsin | ||
+ | anonymoustlsin | ||
+ | trustedtlsin | ||
+ | |||
+ | spfnone | ||
+ | spffail | ||
+ | spfpass | ||
+ | |||
+ | dkimnone | ||
+ | dkimfail | ||
+ | dkimpass | ||
+ | |||
+ | dmarcnone | ||
+ | dmarcfail | ||
+ | dmarcpass | ||
+ | ); | ||
+ | |||
+ | my $url = " | ||
+ | my $urlg = " | ||
+ | my $url1 = " | ||
+ | my $url2 = " | ||
+ | my $url3 = " | ||
+ | my $url4 = " | ||
+ | my $url11 = " | ||
+ | my $url12 = " | ||
+ | my $url13 = " | ||
+ | my $url14 = " | ||
+ | |||
+ | sub rrd_graph(@) | ||
+ | { | ||
+ | my ($range, $file, $ypoints, @rrdargs) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | my $end = time; $end -= $end % $step; | ||
+ | my $date = localtime(time); | ||
+ | $date =~ s|:|\\:|g unless $RRDs:: | ||
+ | |||
+ | my ($graphret, | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | $RRDs:: | ||
+ | |||
+ | @rrdargs, | ||
+ | |||
+ | ' | ||
+ | ); | ||
+ | |||
+ | my $ERR=RRDs:: | ||
+ | die " | ||
+ | } | ||
+ | |||
+ | sub graph($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_virus($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greylist($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greystats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreen($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreenstats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_dane($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_smtpd($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_spf($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dkim($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dmarc($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_queue($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | sub print_html() | ||
+ | { | ||
+ | print " | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | <meta http-equiv=" | ||
+ | <link rel=" | ||
+ | </ | ||
+ | < | ||
+ | HEADER | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | #print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | |||
+ | print "< | ||
+ | for my $n (0..$# | ||
+ | print " | ||
+ | } | ||
+ | print "</ | ||
+ | |||
+ | for my $n (0..$# | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | rint "<a href=' | ||
+ | print "< | ||
+ | |||
+ | } | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | <table border=" | ||
+ | < | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | < | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | FOOTER | ||
+ | } | ||
+ | |||
+ | sub send_image($) | ||
+ | { | ||
+ | my ($file)= @_; | ||
+ | |||
+ | -r $file or do { | ||
+ | print " | ||
+ | exit 1; | ||
+ | }; | ||
+ | |||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | open(IMG, $file) or die; | ||
+ | my $data; | ||
+ | print $data while read(IMG, $data, 16384)> | ||
+ | } | ||
+ | |||
+ | sub main() | ||
+ | { | ||
+ | my $uri = $ENV{REQUEST_URI} || ''; | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | mkdir $tmp_dir, 0777 unless -d $tmp_dir; | ||
+ | mkdir " | ||
+ | |||
+ | my $img = $ENV{QUERY_STRING}; | ||
+ | if(defined $img and $img =~ /\S/) { | ||
+ | if($img =~ / | ||
+ | my $file = " | ||
+ | graph($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_virus($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greylist($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greystats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreen($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreenstats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_queue($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dane($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_smtpd($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_spf($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dkim($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dmarc($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | else { | ||
+ | die " | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | print_html; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | main; | ||
+ | </ | ||
+ | |||
+ | === / | ||
+ | |||
+ | # vim / | ||
+ | <file perl / | ||
+ | |||
+ | # mailgraph -- detailed postfix mail traffic statistics | ||
+ | # copyright (c) 2000-2007 ETH Zurich | ||
+ | # copyright (c) 2000-2007 David Schweikert < | ||
+ | # modified 2011 for queuegraph by Ralf Hildebrandt < | ||
+ | # modified 2015 for mailgraph-ng by Django < | ||
+ | # patches from Sebastian van de Meer < | ||
+ | # released under the GNU General Public License | ||
+ | |||
+ | use RRDs; | ||
+ | use POSIX qw(uname); | ||
+ | |||
+ | my $VERSION = " | ||
+ | |||
+ | my $host = (POSIX:: | ||
+ | my $scriptname = $ENV{" | ||
+ | my $xpoints = 800; | ||
+ | my $points_per_sample = 3; | ||
+ | my $ypoints = 160; | ||
+ | my $rrd = '/ | ||
+ | my $rrd_virus = '/ | ||
+ | my $rrd_grey | ||
+ | my $rrd_dane | ||
+ | my $rrd_dmarc = '/ | ||
+ | my $rrd_smtpd = '/ | ||
+ | my $rrd_queue = '/ | ||
+ | my $rrd_post | ||
+ | |||
+ | my $tmp_dir = '/ | ||
+ | my @graphs = ( | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | ); | ||
+ | |||
+ | my %color = ( # rrggbb in hex | ||
+ | # n | ||
+ | sent => ' | ||
+ | received | ||
+ | |||
+ | bounced | ||
+ | virus => ' | ||
+ | spam => ' | ||
+ | rejected | ||
+ | |||
+ | greylisted | ||
+ | delayed | ||
+ | whitelist | ||
+ | awl => ' | ||
+ | early => ' | ||
+ | |||
+ | pswl => ' | ||
+ | psbl => ' | ||
+ | passold | ||
+ | veto => ' | ||
+ | pregreet | ||
+ | dnsbl => ' | ||
+ | pipelining | ||
+ | nonsmtp | ||
+ | barenewline | ||
+ | command | ||
+ | hangup | ||
+ | passnew | ||
+ | |||
+ | new => ' | ||
+ | reconnectok | ||
+ | |||
+ | active | ||
+ | deferred | ||
+ | |||
+ | untrustedtls | ||
+ | anonymoustls | ||
+ | trustedtls | ||
+ | verifiedtls | ||
+ | |||
+ | untrustedtlsin | ||
+ | anonymoustlsin | ||
+ | trustedtlsin | ||
+ | |||
+ | spfnone | ||
+ | spffail | ||
+ | spfpass | ||
+ | |||
+ | dkimnone | ||
+ | dkimfail | ||
+ | dkimpass | ||
+ | |||
+ | dmarcnone | ||
+ | dmarcfail | ||
+ | dmarcpass | ||
+ | ); | ||
+ | |||
+ | my $url = " | ||
+ | my $urlg = " | ||
+ | my $url1 = " | ||
+ | my $url2 = " | ||
+ | my $url3 = " | ||
+ | my $url4 = " | ||
+ | my $url11 = " | ||
+ | my $url12 = " | ||
+ | my $url13 = " | ||
+ | my $url14 = " | ||
+ | |||
+ | sub rrd_graph(@) | ||
+ | { | ||
+ | my ($range, $file, $ypoints, @rrdargs) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | my $end = time; $end -= $end % $step; | ||
+ | my $date = localtime(time); | ||
+ | $date =~ s|:|\\:|g unless $RRDs:: | ||
+ | |||
+ | my ($graphret, | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | $RRDs:: | ||
+ | |||
+ | @rrdargs, | ||
+ | |||
+ | ' | ||
+ | ); | ||
+ | |||
+ | my $ERR=RRDs:: | ||
+ | die " | ||
+ | } | ||
+ | |||
+ | sub graph($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_virus($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greylist($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greystats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreen($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreenstats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_dane($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_smtpd($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_spf($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dkim($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dmarc($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_queue($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | sub print_html() | ||
+ | { | ||
+ | print " | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | <meta http-equiv=" | ||
+ | <link rel=" | ||
+ | </ | ||
+ | < | ||
+ | HEADER | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | #print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | |||
+ | print "< | ||
+ | for my $n (0..$# | ||
+ | print " | ||
+ | } | ||
+ | print "</ | ||
+ | |||
+ | for my $n (0..$# | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | } | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | <table border=" | ||
+ | < | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | < | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | FOOTER | ||
+ | } | ||
+ | |||
+ | sub send_image($) | ||
+ | { | ||
+ | my ($file)= @_; | ||
+ | |||
+ | -r $file or do { | ||
+ | print " | ||
+ | exit 1; | ||
+ | }; | ||
+ | |||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | open(IMG, $file) or die; | ||
+ | my $data; | ||
+ | print $data while read(IMG, $data, 16384)> | ||
+ | } | ||
+ | |||
+ | sub main() | ||
+ | { | ||
+ | my $uri = $ENV{REQUEST_URI} || ''; | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | mkdir $tmp_dir, 0777 unless -d $tmp_dir; | ||
+ | mkdir " | ||
+ | |||
+ | my $img = $ENV{QUERY_STRING}; | ||
+ | if(defined $img and $img =~ /\S/) { | ||
+ | if($img =~ / | ||
+ | my $file = " | ||
+ | graph($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_virus($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greylist($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greystats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreen($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreenstats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_queue($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dane($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_smtpd($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_spf($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dkim($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dmarc($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | else { | ||
+ | die " | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | print_html; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | main; | ||
+ | </ | ||
+ | |||
+ | === / | ||
+ | |||
+ | # vim / | ||
+ | <file perl / | ||
+ | |||
+ | # mailgraph -- detailed postfix mail traffic statistics | ||
+ | # copyright (c) 2000-2007 ETH Zurich | ||
+ | # copyright (c) 2000-2007 David Schweikert < | ||
+ | # modified 2011 for queuegraph by Ralf Hildebrandt < | ||
+ | # modified 2015 for mailgraph-ng by Django < | ||
+ | # patches from Sebastian van de Meer < | ||
+ | # released under the GNU General Public License | ||
+ | |||
+ | use RRDs; | ||
+ | use POSIX qw(uname); | ||
+ | |||
+ | my $VERSION = " | ||
+ | |||
+ | my $host = (POSIX:: | ||
+ | my $scriptname = $ENV{" | ||
+ | my $xpoints = 800; | ||
+ | my $points_per_sample = 3; | ||
+ | my $ypoints = 160; | ||
+ | my $rrd = '/ | ||
+ | my $rrd_virus = '/ | ||
+ | my $rrd_grey | ||
+ | my $rrd_dane | ||
+ | my $rrd_dmarc = '/ | ||
+ | my $rrd_smtpd = '/ | ||
+ | my $rrd_queue = '/ | ||
+ | my $rrd_post | ||
+ | |||
+ | my $tmp_dir = '/ | ||
+ | my @graphs = ( | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | ); | ||
+ | |||
+ | my %color = ( # rrggbb in hex | ||
+ | # n | ||
+ | sent => ' | ||
+ | received | ||
+ | |||
+ | bounced | ||
+ | virus => ' | ||
+ | spam => ' | ||
+ | rejected | ||
+ | |||
+ | greylisted | ||
+ | delayed | ||
+ | whitelist | ||
+ | awl => ' | ||
+ | early => ' | ||
+ | |||
+ | pswl => ' | ||
+ | psbl => ' | ||
+ | passold | ||
+ | veto => ' | ||
+ | pregreet | ||
+ | dnsbl => ' | ||
+ | pipelining | ||
+ | nonsmtp | ||
+ | barenewline | ||
+ | command | ||
+ | hangup | ||
+ | passnew | ||
+ | |||
+ | new => ' | ||
+ | reconnectok | ||
+ | |||
+ | active | ||
+ | deferred | ||
+ | |||
+ | untrustedtls | ||
+ | anonymoustls | ||
+ | trustedtls | ||
+ | verifiedtls | ||
+ | |||
+ | untrustedtlsin | ||
+ | anonymoustlsin | ||
+ | trustedtlsin | ||
+ | |||
+ | spfnone | ||
+ | spffail | ||
+ | spfpass | ||
+ | |||
+ | dkimnone | ||
+ | dkimfail | ||
+ | dkimpass | ||
+ | |||
+ | dmarcnone | ||
+ | dmarcfail | ||
+ | dmarcpass | ||
+ | ); | ||
+ | |||
+ | my $url = " | ||
+ | my $urlg = " | ||
+ | my $url1 = " | ||
+ | my $url2 = " | ||
+ | my $url3 = " | ||
+ | my $url4 = " | ||
+ | my $url11 = " | ||
+ | my $url12 = " | ||
+ | my $url13 = " | ||
+ | my $url14 = " | ||
+ | |||
+ | sub rrd_graph(@) | ||
+ | { | ||
+ | my ($range, $file, $ypoints, @rrdargs) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | my $end = time; $end -= $end % $step; | ||
+ | my $date = localtime(time); | ||
+ | $date =~ s|:|\\:|g unless $RRDs:: | ||
+ | |||
+ | my ($graphret, | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | $RRDs:: | ||
+ | |||
+ | @rrdargs, | ||
+ | |||
+ | ' | ||
+ | ); | ||
+ | |||
+ | my $ERR=RRDs:: | ||
+ | die " | ||
+ | } | ||
+ | |||
+ | sub graph($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_virus($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greylist($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greystats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreen($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreenstats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_dane($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_smtpd($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_spf($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dkim($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dmarc($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_queue($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | sub print_html() | ||
+ | { | ||
+ | print " | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | <meta http-equiv=" | ||
+ | <link rel=" | ||
+ | </ | ||
+ | < | ||
+ | HEADER | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | #print "<a href=' | ||
+ | print "<a href=' | ||
+ | |||
+ | print "< | ||
+ | for my $n (0..$# | ||
+ | print " | ||
+ | } | ||
+ | print "</ | ||
+ | |||
+ | for my $n (0..$# | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | } | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | <table border=" | ||
+ | < | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | < | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | FOOTER | ||
+ | } | ||
+ | |||
+ | sub send_image($) | ||
+ | { | ||
+ | my ($file)= @_; | ||
+ | |||
+ | -r $file or do { | ||
+ | print " | ||
+ | exit 1; | ||
+ | }; | ||
+ | |||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | open(IMG, $file) or die; | ||
+ | my $data; | ||
+ | print $data while read(IMG, $data, 16384)> | ||
+ | } | ||
+ | |||
+ | sub main() | ||
+ | { | ||
+ | my $uri = $ENV{REQUEST_URI} || ''; | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | mkdir $tmp_dir, 0777 unless -d $tmp_dir; | ||
+ | mkdir " | ||
+ | |||
+ | my $img = $ENV{QUERY_STRING}; | ||
+ | if(defined $img and $img =~ /\S/) { | ||
+ | if($img =~ / | ||
+ | my $file = " | ||
+ | graph($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_virus($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greylist($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greystats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreen($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreenstats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_queue($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dane($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_smtpd($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_spf($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dkim($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dmarc($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | else { | ||
+ | die " | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | print_html; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | main; | ||
+ | </ | ||
+ | |||
+ | === / | ||
+ | # vim / | ||
+ | <file perl / | ||
+ | |||
+ | # mailgraph -- detailed postfix mail traffic statistics | ||
+ | # copyright (c) 2000-2007 ETH Zurich | ||
+ | # copyright (c) 2000-2007 David Schweikert < | ||
+ | # modified 2011 for queuegraph by Ralf Hildebrandt < | ||
+ | # modified 2015 for mailgraph-ng by Django < | ||
+ | # patches from Sebastian van de Meer < | ||
+ | # released under the GNU General Public License | ||
+ | |||
+ | use RRDs; | ||
+ | use POSIX qw(uname); | ||
+ | |||
+ | my $VERSION = " | ||
+ | |||
+ | my $host = (POSIX:: | ||
+ | my $scriptname = $ENV{" | ||
+ | my $xpoints = 800; | ||
+ | my $points_per_sample = 3; | ||
+ | my $ypoints = 160; | ||
+ | my $rrd = '/ | ||
+ | my $rrd_virus = '/ | ||
+ | my $rrd_grey | ||
+ | my $rrd_dane | ||
+ | my $rrd_dmarc = '/ | ||
+ | my $rrd_smtpd = '/ | ||
+ | my $rrd_queue = '/ | ||
+ | my $rrd_post | ||
+ | |||
+ | my $tmp_dir = '/ | ||
+ | my @graphs = ( | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | ); | ||
+ | |||
+ | my %color = ( # rrggbb in hex | ||
+ | # n | ||
+ | sent => ' | ||
+ | received | ||
+ | |||
+ | bounced | ||
+ | virus => ' | ||
+ | spam => ' | ||
+ | rejected | ||
+ | |||
+ | greylisted | ||
+ | delayed | ||
+ | whitelist | ||
+ | awl => ' | ||
+ | early => ' | ||
+ | |||
+ | pswl => ' | ||
+ | psbl => ' | ||
+ | passold | ||
+ | veto => ' | ||
+ | pregreet | ||
+ | dnsbl => ' | ||
+ | pipelining | ||
+ | nonsmtp | ||
+ | barenewline | ||
+ | command | ||
+ | hangup | ||
+ | passnew | ||
+ | |||
+ | new => ' | ||
+ | reconnectok | ||
+ | |||
+ | active | ||
+ | deferred | ||
+ | |||
+ | untrustedtls | ||
+ | anonymoustls | ||
+ | trustedtls | ||
+ | verifiedtls | ||
+ | |||
+ | untrustedtlsin | ||
+ | anonymoustlsin | ||
+ | trustedtlsin | ||
+ | |||
+ | spfnone | ||
+ | spffail | ||
+ | spfpass | ||
+ | |||
+ | dkimnone | ||
+ | dkimfail | ||
+ | dkimpass | ||
+ | |||
+ | dmarcnone | ||
+ | dmarcfail | ||
+ | dmarcpass | ||
+ | ); | ||
+ | |||
+ | my $url = " | ||
+ | my $urlg = " | ||
+ | my $url1 = " | ||
+ | my $url2 = " | ||
+ | my $url3 = " | ||
+ | my $url4 = " | ||
+ | my $url11 = " | ||
+ | my $url12 = " | ||
+ | my $url13 = " | ||
+ | my $url14 = " | ||
+ | |||
+ | sub rrd_graph(@) | ||
+ | { | ||
+ | my ($range, $file, $ypoints, @rrdargs) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | my $end = time; $end -= $end % $step; | ||
+ | my $date = localtime(time); | ||
+ | $date =~ s|:|\\:|g unless $RRDs:: | ||
+ | |||
+ | my ($graphret, | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | $RRDs:: | ||
+ | |||
+ | @rrdargs, | ||
+ | |||
+ | ' | ||
+ | ); | ||
+ | |||
+ | my $ERR=RRDs:: | ||
+ | die " | ||
+ | } | ||
+ | |||
+ | sub graph($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_virus($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greylist($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greystats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreen($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreenstats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_dane($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_smtpd($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_spf($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dkim($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dmarc($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_queue($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | sub print_html() | ||
+ | { | ||
+ | print " | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | <meta http-equiv=" | ||
+ | <link rel=" | ||
+ | </ | ||
+ | < | ||
+ | HEADER | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | #print "<a href=' | ||
+ | |||
+ | print "< | ||
+ | for my $n (0..$# | ||
+ | print " | ||
+ | } | ||
+ | print "</ | ||
+ | |||
+ | for my $n (0..$# | ||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | } | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | <table border=" | ||
+ | < | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | < | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | FOOTER | ||
+ | } | ||
+ | |||
+ | sub send_image($) | ||
+ | { | ||
+ | my ($file)= @_; | ||
+ | |||
+ | -r $file or do { | ||
+ | print " | ||
+ | exit 1; | ||
+ | }; | ||
+ | |||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | open(IMG, $file) or die; | ||
+ | my $data; | ||
+ | print $data while read(IMG, $data, 16384)> | ||
+ | } | ||
+ | |||
+ | sub main() | ||
+ | { | ||
+ | my $uri = $ENV{REQUEST_URI} || ''; | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | mkdir $tmp_dir, 0777 unless -d $tmp_dir; | ||
+ | mkdir " | ||
+ | |||
+ | my $img = $ENV{QUERY_STRING}; | ||
+ | if(defined $img and $img =~ /\S/) { | ||
+ | if($img =~ / | ||
+ | my $file = " | ||
+ | graph($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_virus($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greylist($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greystats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreen($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreenstats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_queue($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dane($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_smtpd($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_spf($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dkim($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dmarc($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | else { | ||
+ | die " | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | print_html; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | main; | ||
+ | </ | ||
+ | |||
+ | ==== CGI-Erweiterung für die Σ-Seite ==== | ||
+ | Wie auch schon bei den Einzelstatistiken sind bei der Σ-Seite, die die kumulierten Einzelgraphen enthält, umfangreichere Änderungen/ | ||
+ | |||
+ | === Datenquellen === | ||
+ | Da wir bei der Gesamtstatistik die Summe der einzelnen Mailserver zur Anzeige bringen wollen, benötigen wir daher auch alle Datenquellen. Die Anzahl der Variablen **$rrd_* ** erhöht sich daher entsprechend! | ||
+ | <code perl>... | ||
+ | |||
+ | my $rrd_11 | ||
+ | my $rrd_12 | ||
+ | my $rrd_13 | ||
+ | my $rrd_14 | ||
+ | my $rrd_virus_11 | ||
+ | my $rrd_virus_12 | ||
+ | my $rrd_virus_13 | ||
+ | my $rrd_virus_14 | ||
+ | my $rrd_grey_11 | ||
+ | my $rrd_grey_12 | ||
+ | my $rrd_grey_13 | ||
+ | my $rrd_grey_14 | ||
+ | my $rrd_dane_11 | ||
+ | my $rrd_dane_12 | ||
+ | my $rrd_dane_13 | ||
+ | my $rrd_dane_14 | ||
+ | my $rrd_dmarc_11 | ||
+ | my $rrd_dmarc_12 | ||
+ | my $rrd_dmarc_13 | ||
+ | my $rrd_dmarc_14 | ||
+ | my $rrd_smtpd_11 | ||
+ | my $rrd_smtpd_12 | ||
+ | my $rrd_smtpd_13 | ||
+ | my $rrd_smtpd_14 | ||
+ | my $rrd_queue_11 | ||
+ | my $rrd_queue_12 | ||
+ | my $rrd_queue_13 | ||
+ | my $rrd_queue_14 | ||
+ | my $rrd_post_11 | ||
+ | my $rrd_post_12 | ||
+ | my $rrd_post_13 | ||
+ | my $rrd_post_14 | ||
+ | |||
+ | ... | ||
+ | </ | ||
+ | |||
+ | === URL-Definitionen === | ||
+ | Damit die Seite bei Portierungen ohne große Änderungen im Code realisiert werden können, wird für die Querverweise jeweils zugehörige URL's definiert. | ||
+ | |||
+ | <code perl>... | ||
+ | |||
+ | my $url = " | ||
+ | my $urlg = " | ||
+ | my $url1 = " | ||
+ | my $url2 = " | ||
+ | my $url3 = " | ||
+ | my $url4 = " | ||
+ | my $url11 = " | ||
+ | my $url12 = " | ||
+ | my $url13 = " | ||
+ | my $url14 = " | ||
+ | |||
+ | |||
+ | ... | ||
+ | </ | ||
+ | |||
+ | === Unterprogramme graph_xxx - kumulierte Werte für die Generierung der RRD-Graphiken === | ||
+ | Bei der Generierung der kumulierten Graphiken stellt sich grundsätzlich die Frage, wie führt man den Inhalt mehrerer RRD-Dateien zusammen um einen Summengraph zu erstellen. Anstatt nun einen neue RRD-Datei mit dem Inhalt der vier einzelnen RRD-Dateien zu erstellen um daraus dann den Graphen zu generieren, wählen wir einen anderen Weg. Bei der Erstellung eines Summengraphen mit Hilfe von **RRD_GRAPH** bedienen wir uns nicht nur einer Quelle (RRD-Datei), | ||
+ | |||
+ | Dazu müssen wir im ersten Schritt **alle Datenquellen** beim RRD_GRAPH Parameter **DEF** benennen. Somit wird z.B. beim Graphen mit den nicht angenommenen Nachrichten **Rejected** statt der **beiden Zeilen** < | ||
+ | " | ||
+ | " | ||
+ | </ | ||
+ | entsprechend **acht Zeilen** | ||
+ | < | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | </ | ||
+ | |||
+ | Bei der Generierung der eigentlichen Graphen ziehen wir die **Summe der vier RRD-Dateien** heran, egal ob eine einfache Fläche, ein gestapelter Bereich oder ein Liniengraph erzeugt werden soll. Beim RRD_GRAPH Parameter **CDEF** lassen wir daher die Summe aus den Variablen // | ||
+ | |||
+ | Hierzu verwenden wir die //RRD_GRAPH eigene Berechnungssyntax// | ||
+ | |||
+ | Im Falle unseres Graphen über die Abgelehneten Nachrichten (**rejected**) berechnet sich die Gesamtsumme also wie folgt: \\ < | ||
+ | |||
+ | Daraus wird dann in der //RRD_GRAPH eigenen Berechnungssyntax//: | ||
+ | | ||
+ | |||
+ | Anstatt der ursprünglichen **CDEF**-Definitionen | ||
+ | < | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | </ | ||
+ | verwenden wir also nachfolgende **CDEF**-Definitionen: | ||
+ | |||
+ | < | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | </ | ||
+ | |||
+ | Diese Änderungen tragen wir nun bei den Unterprogrammen **graph_xxx** nach. | ||
+ | |||
+ | === Unterprogramm print_html | ||
+ | Wie auch schon bei den [[centos: | ||
+ | <code perl> | ||
+ | |||
+ | sub print_html() | ||
+ | { | ||
+ | print " | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | <meta http-equiv=" | ||
+ | <link rel=" | ||
+ | </ | ||
+ | < | ||
+ | HEADER | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | for my $n (0..$# | ||
+ | print " | ||
+ | } | ||
+ | print "</ | ||
+ | |||
+ | for my $n (0..$# | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | } | ||
+ | |||
+ | print << | ||
+ | <hr/> | ||
+ | <table border=" | ||
+ | < | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | <td> | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | </td> | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </td> | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | FOOTER | ||
+ | } | ||
+ | |||
+ | ... | ||
+ | </ | ||
+ | |||
+ | |||
+ | === CGI-Script für die ∑-Auswertung === | ||
+ | Mit allen Änderungen und Erweiterungen ergibt sich dann folgendes Gesamt-CGI-Script: | ||
+ | # vim / | ||
+ | |||
+ | <file perl / | ||
+ | |||
+ | # mailgraph -- detailed postfix mail traffic statistics | ||
+ | # copyright (c) 2000-2007 ETH Zurich | ||
+ | # copyright (c) 2000-2007 David Schweikert < | ||
+ | # modified 2011 for queuegraph by Ralf Hildebrandt < | ||
+ | # modified 2015 for mailgraph-ng by Django < | ||
+ | # patches from Sebastian van de Meer < | ||
+ | # released under the GNU General Public License | ||
+ | |||
+ | use RRDs; | ||
+ | use POSIX qw(uname); | ||
+ | |||
+ | my $VERSION = " | ||
+ | |||
+ | my $host = (POSIX:: | ||
+ | my $scriptname = $ENV{" | ||
+ | my $xpoints | ||
+ | my $points_per_sample = 3; | ||
+ | my $ypoints | ||
+ | my $rrd_11 | ||
+ | my $rrd_12 | ||
+ | my $rrd_13 | ||
+ | my $rrd_14 | ||
+ | my $rrd_virus_11 | ||
+ | my $rrd_virus_12 | ||
+ | my $rrd_virus_13 | ||
+ | my $rrd_virus_14 | ||
+ | my $rrd_grey_11 | ||
+ | my $rrd_grey_12 | ||
+ | my $rrd_grey_13 | ||
+ | my $rrd_grey_14 | ||
+ | my $rrd_dane_11 | ||
+ | my $rrd_dane_12 | ||
+ | my $rrd_dane_13 | ||
+ | my $rrd_dane_14 | ||
+ | my $rrd_dmarc_11 | ||
+ | my $rrd_dmarc_12 | ||
+ | my $rrd_dmarc_13 | ||
+ | my $rrd_dmarc_14 | ||
+ | my $rrd_smtpd_11 | ||
+ | my $rrd_smtpd_12 | ||
+ | my $rrd_smtpd_13 | ||
+ | my $rrd_smtpd_14 | ||
+ | my $rrd_queue_11 | ||
+ | my $rrd_queue_12 | ||
+ | my $rrd_queue_13 | ||
+ | my $rrd_queue_14 | ||
+ | my $rrd_post_11 | ||
+ | my $rrd_post_12 | ||
+ | my $rrd_post_13 | ||
+ | my $rrd_post_14 | ||
+ | |||
+ | my $tmp_dir = '/ | ||
+ | my @graphs = ( | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | { title => ' | ||
+ | ); | ||
+ | |||
+ | my %color = ( # rrggbb in hex | ||
+ | # n | ||
+ | sent => ' | ||
+ | received | ||
+ | |||
+ | bounced | ||
+ | virus => ' | ||
+ | spam => ' | ||
+ | rejected | ||
+ | |||
+ | greylisted | ||
+ | delayed | ||
+ | whitelist | ||
+ | awl => ' | ||
+ | early => ' | ||
+ | |||
+ | pswl => ' | ||
+ | psbl => ' | ||
+ | passold | ||
+ | veto => ' | ||
+ | pregreet | ||
+ | dnsbl => ' | ||
+ | pipelining | ||
+ | nonsmtp | ||
+ | barenewline | ||
+ | command | ||
+ | hangup | ||
+ | passnew | ||
+ | |||
+ | new => ' | ||
+ | reconnectok | ||
+ | |||
+ | active | ||
+ | deferred | ||
+ | |||
+ | untrustedtls | ||
+ | anonymoustls | ||
+ | trustedtls | ||
+ | verifiedtls | ||
+ | |||
+ | untrustedtlsin | ||
+ | anonymoustlsin | ||
+ | trustedtlsin | ||
+ | |||
+ | spfnone | ||
+ | spffail | ||
+ | spfpass | ||
+ | |||
+ | dkimnone | ||
+ | dkimfail | ||
+ | dkimpass | ||
+ | |||
+ | dmarcnone | ||
+ | dmarcfail | ||
+ | dmarcpass | ||
+ | ); | ||
+ | |||
+ | my $url = " | ||
+ | my $url1 = " | ||
+ | my $url2 = " | ||
+ | my $url3 = " | ||
+ | my $url4 = " | ||
+ | my $url11 | ||
+ | my $url12 | ||
+ | my $url13 | ||
+ | my $url14 | ||
+ | |||
+ | sub rrd_graph(@) | ||
+ | { | ||
+ | my ($range, $file, $ypoints, @rrdargs) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | my $end = time; $end -= $end % $step; | ||
+ | my $date = localtime(time); | ||
+ | $date =~ s|:|\\:|g unless $RRDs:: | ||
+ | |||
+ | my ($graphret, | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | $RRDs:: | ||
+ | |||
+ | @rrdargs, | ||
+ | |||
+ | ' | ||
+ | ); | ||
+ | |||
+ | my $ERR=RRDs:: | ||
+ | die " | ||
+ | } | ||
+ | |||
+ | sub graph($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_virus($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greylist($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | sub graph_greystats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | |||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreen($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_postscreenstats($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_dane($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_smtpd($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_spf($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dkim($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub graph_dmarc($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | sub graph_queue($$) | ||
+ | { | ||
+ | my ($range, $file) = @_; | ||
+ | my $step = $range*$points_per_sample/ | ||
+ | rrd_graph($range, | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | sub print_html() | ||
+ | { | ||
+ | print " | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | < | ||
+ | <meta http-equiv=" | ||
+ | <meta http-equiv=" | ||
+ | <link rel=" | ||
+ | </ | ||
+ | < | ||
+ | HEADER | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | for my $n (0..$# | ||
+ | print " | ||
+ | } | ||
+ | print "</ | ||
+ | |||
+ | for my $n (0..$# | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | | ||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | |||
+ | print "< | ||
+ | print "< | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "<a href=' | ||
+ | print "< | ||
+ | } | ||
+ | |||
+ | print << | ||
+ | < | ||
+ | <table border=" | ||
+ | < | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | <col width=" | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | < | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | <td class=" | ||
+ | </ | ||
+ | <td class=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | <a href=" | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | FOOTER | ||
+ | } | ||
+ | |||
+ | sub send_image($) | ||
+ | { | ||
+ | my ($file)= @_; | ||
+ | |||
+ | -r $file or do { | ||
+ | print " | ||
+ | exit 1; | ||
+ | }; | ||
+ | |||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | open(IMG, $file) or die; | ||
+ | my $data; | ||
+ | print $data while read(IMG, $data, 16384)> | ||
+ | } | ||
+ | |||
+ | sub main() | ||
+ | { | ||
+ | my $uri = $ENV{REQUEST_URI} || ''; | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | $uri =~ s/ | ||
+ | mkdir $tmp_dir, 0777 unless -d $tmp_dir; | ||
+ | mkdir " | ||
+ | |||
+ | my $img = $ENV{QUERY_STRING}; | ||
+ | if(defined $img and $img =~ /\S/) { | ||
+ | if($img =~ / | ||
+ | my $file = " | ||
+ | graph($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_virus($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greylist($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_greystats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreen($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_postscreenstats($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_queue($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dane($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_smtpd($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_spf($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dkim($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | elsif($img =~ / | ||
+ | my $file = " | ||
+ | graph_dmarc($graphs[$1]{seconds}, | ||
+ | send_image($file); | ||
+ | } | ||
+ | else { | ||
+ | die " | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | print_html; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | main; | ||
+ | </ | ||
+ | |||
+ | ==== Apache VHost anlegen ==== | ||
+ | Damit wir bequem von unserem Browser aus, die aktuellen Graphiken abfragen können, bearbeiten wir entweder die aus dem RPM stammende Konfigurationsdatei oder legen wir nun einen passenden VHost an. | ||
+ | # vim / | ||
+ | <file apache / | ||
+ | # | ||
+ | # mailgraph.nausch.org | ||
+ | # | ||
+ | < | ||
+ | ServerAdmin webmaster@nausch.org | ||
+ | ServerName mailgraph.nausch.org | ||
+ | ServerAlias www.mailgraph.nausch.org | ||
+ | ServerPath / | ||
+ | DocumentRoot "/ | ||
+ | AddHandler cgi-script .cgi | ||
+ | |||
+ | < | ||
+ | AllowOverride None | ||
+ | Options +ExecCGI | ||
+ | DirectoryIndex mailgraph.cgi | ||
+ | require IP 10.0. | ||
+ | </ | ||
+ | < | ||
+ | AllowOverride None | ||
+ | Options +ExecCGI | ||
+ | DirectoryIndex mailgraph.cgi | ||
+ | require IP 10.0. | ||
+ | </ | ||
+ | < | ||
+ | AllowOverride None | ||
+ | Options +ExecCGI | ||
+ | DirectoryIndex mailgraph.cgi | ||
+ | require IP 10.0. | ||
+ | </ | ||
+ | < | ||
+ | AllowOverride None | ||
+ | Options +ExecCGI | ||
+ | DirectoryIndex mailgraph.cgi | ||
+ | require IP 10.0. | ||
+ | </ | ||
+ | < | ||
+ | AllowOverride None | ||
+ | Options +ExecCGI | ||
+ | DirectoryIndex mailgraph.cgi | ||
+ | require IP 10.0. | ||
+ | </ | ||
+ | |||
+ | ErrorLog logs/ | ||
+ | CustomLog logs/ | ||
+ | </ | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | Bevor wir bei unserem Webserver eine Reload der Konfiguration vornehmen, testen wir unsere neue Konfigurationsdatei auf syntaktische Fehler. | ||
+ | # apachectl -t | ||
+ | |||
+ | | ||
+ | |||
+ | Da keine Fehler aufgetreten sind, aktivieren wir die neue Konfiguration durch einen Reload des Webserver-Daemon. | ||
+ | # systemctl reload postfix | ||
+ | |||
+ | ==== NGiNX vHost anlegen ==== | ||
+ | Nutzen wir als Webserver **[[centos: | ||
+ | # vim / | ||
+ | <file http / | ||
+ | listen | ||
+ | server_name | ||
+ | access_log | ||
+ | error_log | ||
+ | |||
+ | root / | ||
+ | index mailgraph.cgi; | ||
+ | |||
+ | | ||
+ | fastcgi_split_path_info ^(.+\.cgi)(/ | ||
+ | fastcgi_index mailgraph.cgi; | ||
+ | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | ||
+ | include fastcgi_params; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Den Parameter **fastcgi_pass** setzen wir im übrigen auf den Wert aus der Konfigurationsdatei // | ||
+ | |||
+ | Haben wir die Konfigurationsdatei vervollständigt, | ||
+ | # nginx -t | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | Somit können wir unsere Konfiguration nun noch aktivieren. | ||
+ | # systemctl reload nginx | ||
+ | |||
+ | ==== Webaufruf ==== | ||
+ | Rufen wir nun die definierte Webseite unserer Gesamtstatistikübersicht auf, erhalten wir nachfolgende Ansicht. | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Hier können wir nun gezielt einzelne Systeme auswählen, bzw. bei einer ausgewählten Detailstatistikseite zur Summenseite hin und her wechseln. | ||
+ | ===== AWStats ===== | ||
+ | Auch mit Hilfe des Projektes/ | ||
+ | |||
+ | ==== Installation ==== | ||
+ | Die Grundinstallation von **// | ||
+ | |||
+ | ==== Konfiguration ==== | ||
+ | Zur eigentlichen Logfileauswertung legen wir uns nun eine eigene Konfigurationdatei für // | ||
+ | # cp / | ||
+ | |||
+ | Darin passen wir nun alle Konfigurationsoptionen, | ||
+ | # vim / | ||
+ | <file bash / | ||
+ | # | ||
+ | # Copy this file into awstats.www.mydomain.conf and edit this new config file | ||
+ | # to setup AWStats (See documentation in docs/ directory). | ||
+ | # The config file must be in / | ||
+ | # Unix/Linux) or same directory than awstats.pl (Windows, Mac, Unix/ | ||
+ | # To include an environment variable in any parameter (AWStats will replace | ||
+ | # it with its value when reading it), follow the example: | ||
+ | # Parameter=" | ||
+ | # Note that environment variable AWSTATS_CURRENT_CONFIG is always defined with | ||
+ | # the config value in an AWStats running session and can be used like others. | ||
+ | # | ||
+ | # $Revision: 1.350 $ - $Author: eldy $ - $Date: 2010/09/29 19:16:21 $ | ||
+ | |||
+ | |||
+ | |||
+ | # | ||
+ | # MAIN SETUP SECTION (Required to make AWStats work) | ||
+ | # | ||
+ | |||
+ | # " | ||
+ | # Possible values: A full path, or a relative path from awstats.pl directory. | ||
+ | # Example: "/ | ||
+ | # Example: " | ||
+ | # You can also use tags in this filename if you need a dynamic file name | ||
+ | # depending on date or time (Replacement is made by AWStats at the beginning | ||
+ | # of its execution). This is available tags : | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # use n=24 if you need (1-7, 1=monday) | ||
+ | # | ||
+ | # use n=24 if you need (0-6, 0=monday) | ||
+ | # Use 0 for n if you need current year, month, day, hour... | ||
+ | # Example: "/ | ||
+ | # Example: " | ||
+ | # You can also use a pipe if log file come from a pipe : | ||
+ | # Example: "gzip -d </ | ||
+ | # If there are several log files from load balancing servers : | ||
+ | # Example: "/ | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LogFile="/ | ||
+ | LogFile=" | ||
+ | |||
+ | # Enter the log file type you want to analyze. | ||
+ | # Possible values: | ||
+ | # W - For a web log file | ||
+ | # S - For a streaming log file | ||
+ | # M - For a mail log file | ||
+ | # F - For a ftp log file | ||
+ | # Example: W | ||
+ | # Default: W | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LogType=W | ||
+ | LogType=M | ||
+ | |||
+ | # Enter here your log format (Must match your web server config. See setup | ||
+ | # instructions in documentation to know how to configure your web server to | ||
+ | # have the required log format). | ||
+ | # Possible values: 1,2,3,4 or " | ||
+ | # 1 - Apache or Lotus Notes/ | ||
+ | # 2 - IIS or ISA format (IIS W3C log format). See FAQ-COM115 For ISA. | ||
+ | # 3 - Webstar native log format. | ||
+ | # 4 - Apache or Squid native common log format (NCSA common/CLF log format) | ||
+ | # With LogFormat=4, | ||
+ | # " | ||
+ | # you must use following keys to define the log format string (See FAQ for | ||
+ | # ftp, mail or exotic web log format examples): | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # will discard records not in SiteDomain nor HostAliases | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # If your log format has some fields not included in this list, use: | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # Examples for Apache combined logs (following two examples are equivalent): | ||
+ | # LogFormat = 1 | ||
+ | # LogFormat = "%host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot" | ||
+ | # | ||
+ | # Example for IIS: | ||
+ | # LogFormat = 2 | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LogFormat=1 | ||
+ | LogFormat=" | ||
+ | |||
+ | |||
+ | # If your log field' | ||
+ | # This parameter is not used if LogFormat is a predefined value (1,2,3,4) | ||
+ | # Backslash can be used as escape character. | ||
+ | # Example: " " | ||
+ | # Example: " | ||
+ | # Example: " | ||
+ | # Example: "," | ||
+ | # Default: " " | ||
+ | # | ||
+ | LogSeparator=" | ||
+ | |||
+ | |||
+ | # " | ||
+ | # server name, used to reach the web site. | ||
+ | # If you share the same log file for several virtual web servers, this | ||
+ | # parameter is used to tell AWStats to filter record that contains records for | ||
+ | # this virtual host name only (So check that this virtual hostname can be | ||
+ | # found in your log file and use a personalized log format that include the | ||
+ | # %virtualname tag). | ||
+ | # But for multi hosting a better solution is to have one log file for each | ||
+ | # virtual web server. In this case, this parameter is only used to generate | ||
+ | # full URL's links when ShowLinksOnUrl option is set to 1. | ||
+ | # If analyzing mail log, enter here the domain name of mail server. | ||
+ | # Example: " | ||
+ | # Example: " | ||
+ | # Example: " | ||
+ | # Example: " | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: SiteDomain=" | ||
+ | SiteDomain=" | ||
+ | |||
+ | # Enter here all other possible domain names, addresses or virtual host | ||
+ | # aliases someone can use to access your site. Try to keep only the minimum | ||
+ | # number of possible names/ | ||
+ | # You can repeat the " | ||
+ | # This parameter is used to analyze referer field in log file and to help | ||
+ | # AWStats to know if a referer URL is a local URL of same site or an URL of | ||
+ | # another site. | ||
+ | # Note: Use space between each value. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Note: You can also use @/ | ||
+ | # Example: " | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: HostAliases=" | ||
+ | HostAliases=„localhost 127.0.0.1 REGEX[nausch\.org$] REGEX[www\.nausch\.org$]“ | ||
+ | |||
+ | |||
+ | # If you want to have hosts reported by name instead of ip address, AWStats | ||
+ | # need to make reverse DNS lookups (if not already done in your log file). | ||
+ | # With DNSLookup to 0, all hosts will be reported by their IP addresses and | ||
+ | # not by the full hostname of visitors (except if names are already available | ||
+ | # in log file). | ||
+ | # If you want/need to set DNSLookup to 1, don't forget that this will reduce | ||
+ | # dramatically AWStats update process speed. Do not use on large web sites. | ||
+ | # Note: Reverse DNS lookup is done on IPv4 only (Enable ipv6 plugin for IPv6). | ||
+ | # Note: Result of DNS Lookup can be used to build the Country report. However | ||
+ | # it is highly recommanded to enable the plugin ' | ||
+ | # have an accurate Country report with no need of DNS Lookup. | ||
+ | # Possible values: | ||
+ | # 0 - No DNS Lookup | ||
+ | # 1 - DNS Lookup is fully enabled | ||
+ | # 2 - DNS Lookup is made only from static DNS cache file (if it exists) | ||
+ | # Default: 2 | ||
+ | # | ||
+ | DNSLookup=2 | ||
+ | |||
+ | |||
+ | # When AWStats updates its statistics, it stores results of its analysis in | ||
+ | # files (AWStats database). All those files are written in the directory | ||
+ | # defined by the " | ||
+ | # you want AWStats to save its database and working files into. | ||
+ | # Warning: If you want to be able to use the " | ||
+ | # feature (see later), you need " | ||
+ | # directory (and " | ||
+ | # Example: "/ | ||
+ | # Example: " | ||
+ | # Example: " | ||
+ | # Default: " | ||
+ | # | ||
+ | DirData="/ | ||
+ | |||
+ | |||
+ | # Relative or absolute web URL of your awstats cgi-bin directory. | ||
+ | # This parameter is used only when AWStats is run from command line | ||
+ | # with -output option (to generate links in HTML reported page). | ||
+ | # Example: "/ | ||
+ | # Default: "/ | ||
+ | # | ||
+ | DirCgi="/ | ||
+ | |||
+ | |||
+ | # Relative or absolute web URL of your awstats icon directory. | ||
+ | # If you build static reports ("... -output > outputpath/ | ||
+ | # path of icon directory relative to the output directory ' | ||
+ | # Example: "/ | ||
+ | # Example: " | ||
+ | # Default: "/ | ||
+ | # | ||
+ | DirIcons="/ | ||
+ | |||
+ | |||
+ | # When this parameter is set to 1, AWStats adds a button on report page to | ||
+ | # allow to " | ||
+ | # made from a browser, AWStats is run as a CGI by the web server user defined | ||
+ | # in your web server (user " | ||
+ | # IIS), so the " | ||
+ | # awstatsMMYYYY[.xxx].txt must be writable by this user. Change permissions if | ||
+ | # necessary to " | ||
+ | # Warning: Update process can be long so you might experience "time out" | ||
+ | # browser errors if you don't launch AWStats frequently enough. | ||
+ | # When set to 0, update is only made when AWStats is run from the command | ||
+ | # line interface (or a task scheduler). | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: AllowToUpdateStatsFromBrowser=0 | ||
+ | AllowToUpdateStatsFromBrowser=1 | ||
+ | |||
+ | |||
+ | # AWStats saves and sorts its database on a month basis (except if using | ||
+ | # databasebreak option from command line). | ||
+ | # However, if you choose the -month=all from command line or | ||
+ | # value ' | ||
+ | # needs to reload all data for full year (each month), and sort them, | ||
+ | # requiring a large amount of time, memory and CPU. This might be a problem | ||
+ | # for web hosting providers that offer AWStats for large sites, on shared | ||
+ | # servers, to non CPU cautious customers. | ||
+ | # For this reason, the 'full year' is only enabled on Command Line by default. | ||
+ | # You can change this by setting this parameter to 0, 1, 2 or 3. | ||
+ | # Possible values: | ||
+ | # 0 - Never allowed | ||
+ | # 1 - Allowed on CLI only, -Year- value in combo is not visible | ||
+ | # 2 - Allowed on CLI only, -Year- value in combo is visible but not allowed | ||
+ | # 3 - Possible on CLI and CGI | ||
+ | # Default: 2 | ||
+ | # | ||
+ | AllowFullYearView=2 | ||
+ | |||
+ | |||
+ | |||
+ | # | ||
+ | # OPTIONAL SETUP SECTION (Not required but increase AWStats features) | ||
+ | # | ||
+ | |||
+ | # When the update process runs, AWStats can set a lock file in TEMP or TMP | ||
+ | # directory. This lock is to avoid to have 2 update processes running at the | ||
+ | # same time to prevent unknown conflicts problems and avoid DoS attacks when | ||
+ | # AllowToUpdateStatsFromBrowser is set to 1. | ||
+ | # Because, when you use lock file, you can experience sometimes problems in | ||
+ | # lock file not correctly removed (killed process for example requires that | ||
+ | # you remove the file manualy), this option is not enabled by default (Do | ||
+ | # not enable this option with no console server access). | ||
+ | # Change : Effective immediatly | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | EnableLockForUpdate=1 | ||
+ | |||
+ | |||
+ | # AWStats can do reverse DNS lookups through a static DNS cache file that was | ||
+ | # previously created manually. If no path is given in static DNS cache file | ||
+ | # name, AWStats will search DirData directory. This file is never changed. | ||
+ | # This option is not used if DNSLookup=0. | ||
+ | # Note: DNS cache file format is ' | ||
+ | # or just ' | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "/ | ||
+ | # Default: " | ||
+ | # | ||
+ | DNSStaticCacheFile=" | ||
+ | |||
+ | |||
+ | # AWStats can do reverse DNS lookups through a DNS cache file that was created | ||
+ | # by a previous run of AWStats. This file is erased and recreated after each | ||
+ | # statistics update process. You don't need to create and/or edit it. | ||
+ | # AWStats will read and save this file in DirData directory. | ||
+ | # This option is used only if DNSLookup=1. | ||
+ | # Note: If a DNSStaticCacheFile is available, AWStats will check for DNS | ||
+ | # lookup in DNSLastUpdateCacheFile after checking into DNSStaticCacheFile. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "/ | ||
+ | # Default: " | ||
+ | # | ||
+ | DNSLastUpdateCacheFile=" | ||
+ | |||
+ | |||
+ | # You can specify specific IP addresses that should NOT be looked up in DNS. | ||
+ | # This option is used only if DNSLookup=1. | ||
+ | # Note: Use space between each value. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | SkipDNSLookupFor="" | ||
+ | |||
+ | |||
+ | # The following two parameters allow you to protect a config file from being | ||
+ | # read by AWStats when called from a browser if web user has not been | ||
+ | # authenticated. Your AWStats program must be in a web protected " | ||
+ | # Apache, you can use .htaccess files to do so. With other web servers, see | ||
+ | # your server setup manual). | ||
+ | # Change : Effective immediatly | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: AllowAccessFromWebToAuthenticatedUsersOnly=0 | ||
+ | # | ||
+ | AllowAccessFromWebToAuthenticatedUsersOnly=0 | ||
+ | |||
+ | |||
+ | # This parameter gives the list of all authorized authenticated users to view | ||
+ | # statistics for this domain/ | ||
+ | # AllowAccessFromWebToAuthenticatedUsersOnly is set to 1. | ||
+ | # Change : Effective immediatly | ||
+ | # Example: "user1 user2" | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: AllowAccessFromWebToFollowingAuthenticatedUsers="" | ||
+ | # AllowAccessFromWebToFollowingAuthenticatedUsers=" | ||
+ | AllowAccessFromWebToFollowingAuthenticatedUsers="" | ||
+ | |||
+ | |||
+ | # When this parameter is defined to something, the IP address of the user that | ||
+ | # reads its statistics from a browser (when AWStats is used as a CGI) is | ||
+ | # checked and must match one of the IP address values or ranges. | ||
+ | # Change : Effective immediatly | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | AllowAccessFromWebToFollowingIPAddresses="" | ||
+ | |||
+ | |||
+ | # If the " | ||
+ | # error. However, you can ask AWStats to create it. | ||
+ | # This option can be used by some Web Hosting Providers that has defined a | ||
+ | # dynamic value for DirData (for example DirData="/ | ||
+ | # don't want to have to create a new directory each time they add a new user. | ||
+ | # Change : Effective immediatly | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | CreateDirDataIfNotExists=0 | ||
+ | |||
+ | |||
+ | # You can choose in which format the Awstats history database is saved. | ||
+ | # Note: Using " | ||
+ | # larger than using " | ||
+ | # Change : Database format is switched after next update | ||
+ | # Possible values: text or xml | ||
+ | # Default: text | ||
+ | # | ||
+ | BuildHistoryFormat=text | ||
+ | |||
+ | |||
+ | # If you prefer having the report output pages be built as XML compliant pages | ||
+ | # instead of simple HTML pages, you can set this to ' | ||
+ | # properly with old browsers). | ||
+ | # Change : Effective immediatly | ||
+ | # Possible values: html or xhtml | ||
+ | # Default: html | ||
+ | # | ||
+ | BuildReportFormat=html | ||
+ | |||
+ | |||
+ | # AWStats databases can be updated from command line of from a browser (when | ||
+ | # used as a cgi program). So AWStats database files need write permission | ||
+ | # for both command line user and default web server user (nobody for Unix, | ||
+ | # IUSR_xxx for IIS/ | ||
+ | # To avoid permission problems between update process (run by an admin user) | ||
+ | # and CGI process (ran by a low level user), AWStats can save its database | ||
+ | # files with read and write permissions for everyone. | ||
+ | # By default, AWStats keeps default user permissions on updated files. If you | ||
+ | # set AllowToUpdateStatsFromBrowser to 1, you can change this parameter to 1. | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: SaveDatabaseFilesWithPermissionsForEveryone=0 | ||
+ | SaveDatabaseFilesWithPermissionsForEveryone=1 | ||
+ | |||
+ | |||
+ | # AWStats can purge log file, after analyzing it. Note that AWStats is able | ||
+ | # to detect new lines in a log file, to process only them, so you can launch | ||
+ | # AWStats as often as you want, even with this parameter to 0. | ||
+ | # With 0, no purge is made, so you must use a scheduled task or a web server | ||
+ | # that make this purge frequently. | ||
+ | # With 1, the purge of the log file is made each time AWStats update is run. | ||
+ | # This parameter doesn' | ||
+ | # file to be purged). | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | PurgeLogFile=0 | ||
+ | |||
+ | |||
+ | # When PurgeLogFile is setup to 1, AWStats will clean your log file after | ||
+ | # processing it. You can however keep an archive file of all processed log | ||
+ | # records by setting this parameter (For example if you want to use another | ||
+ | # log analyzer). The archived log file is saved in " | ||
+ | # awstats_archive.configname[.suffix].log | ||
+ | # This parameter is not used if PurgeLogFile=0 | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: 0, 1, or tags (See LogFile parameter) for suffix | ||
+ | # Example: 1 | ||
+ | # Example: %YYYY%MM%DD | ||
+ | # Default: 0 | ||
+ | # | ||
+ | ArchiveLogRecords=0 | ||
+ | |||
+ | |||
+ | # Each time you run the update process, AWStats overwrites the ' | ||
+ | # for the month (awstatsMMYYYY[.*].txt) with the updated one. | ||
+ | # When write errors occurs (IO, disk full,...), this historic file can be | ||
+ | # corrupted and must be deleted. Because this file contains information of all | ||
+ | # past processed log files, you will loose old stats if removed. So you can | ||
+ | # ask AWStats to save last non corrupted file in a .bak file. This file is | ||
+ | # stored in " | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | KeepBackupOfHistoricFiles=1 | ||
+ | |||
+ | |||
+ | # Default index page name for your web server. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Default: " | ||
+ | # | ||
+ | DefaultFile=" | ||
+ | |||
+ | |||
+ | # Do not include access from clients that match following criteria. | ||
+ | # If your log file contains IP addresses in host field, you must enter here | ||
+ | # matching IP addresses criteria. | ||
+ | # If DNS lookup is already done in your log file, you must enter here hostname | ||
+ | # criteria, else enter ip address criteria. | ||
+ | # The opposite parameter of " | ||
+ | # Note: Use space between each value. This parameter is not case sensitive. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: SkipHosts=" | ||
+ | SkipHosts="" | ||
+ | |||
+ | # Do not include access from clients with a user agent that match following | ||
+ | # criteria. If you want to exclude a robot, you should update the robots.pm | ||
+ | # file instead of this parameter. | ||
+ | # The opposite parameter of " | ||
+ | # Note: Use space between each value. This parameter is not case sensitive. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | SkipUserAgents="" | ||
+ | |||
+ | |||
+ | # Use SkipFiles to ignore access to URLs that match one of following entries. | ||
+ | # You can enter a list of not important URLs (like framed menus, hidden pages, | ||
+ | # etc...) to exclude them from statistics. You must enter here exact relative | ||
+ | # URL as found in log file, or a matching REGEX value. Check apply on URL with | ||
+ | # all its query paramaters. | ||
+ | # For example, to ignore / | ||
+ | # pages in a particular directory, add " | ||
+ | # The opposite parameter of " | ||
+ | # Note: Use space between each value. This parameter is or not case sensitive | ||
+ | # depending on URLNotCaseSensitive parameter. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "/ | ||
+ | # Default: "" | ||
+ | # | ||
+ | SkipFiles="" | ||
+ | |||
+ | |||
+ | # Use SkipReferrersBlackList if you want to exclude records coming from a SPAM | ||
+ | # referrer. Parameter must receive a local file name containing rules applied | ||
+ | # on referrer field. If parameter is empty, no filter is applied. | ||
+ | # An example of such a file is available in lib/ | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "/ | ||
+ | # Default: "" | ||
+ | # | ||
+ | # WARNING!! Using this feature make AWStats running very slower (5 times slower | ||
+ | # with black list file provided with AWStats ! | ||
+ | # | ||
+ | SkipReferrersBlackList="" | ||
+ | |||
+ | |||
+ | # Include in stats, only accesses from hosts that match one of following | ||
+ | # entries. For example, if you want AWStats to filter access to keep only | ||
+ | # stats for visits from particular hosts, you can add those host names in | ||
+ | # this parameter. | ||
+ | # If DNS lookup is already done in your log file, you must enter here hostname | ||
+ | # criteria, else enter ip address criteria. | ||
+ | # The opposite parameter of " | ||
+ | # Note: Use space between each value. This parameter is not case sensitive. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | OnlyHosts="" | ||
+ | |||
+ | |||
+ | # Include in stats, only accesses from user agent that match one of following | ||
+ | # entries. For example, if you want AWStats to filter access to keep only | ||
+ | # stats for visits from particular browsers, you can add their user agents | ||
+ | # string in this parameter. | ||
+ | # The opposite parameter of " | ||
+ | # Note: Use space between each value. This parameter is not case sensitive. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | OnlyUserAgents="" | ||
+ | |||
+ | |||
+ | # Include in stats, only accesses from authenticated users that match one of | ||
+ | # following entries. For example, if you want AWStats to filter access to keep | ||
+ | # only stats for authenticated users, you can add those users names in | ||
+ | # this parameter. Useful for statistics for per user ftp logs. | ||
+ | # Note: Use space between each value. This parameter is not case sensitive. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "john bob REGEX[^testusers]" | ||
+ | # Default: "" | ||
+ | # | ||
+ | OnlyUsers="" | ||
+ | |||
+ | |||
+ | # Include in stats, only accesses to URLs that match one of following entries. | ||
+ | # For example, if you want AWStats to filter access to keep only stats that | ||
+ | # match a particular string, like a particular directory, you can add this | ||
+ | # directory name in this parameter. | ||
+ | # The opposite parameter of " | ||
+ | # Note: Use space between each value. This parameter is or not case sensitive | ||
+ | # depending on URLNotCaseSensitive parameter. | ||
+ | # Note: You can use regular expression values writing value with REGEX[value]. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | OnlyFiles="" | ||
+ | |||
+ | |||
+ | # Add here a list of kind of url (file extension) that must be counted as | ||
+ | # "Hit only" and not as a " | ||
+ | # image extensions as they are hit downloaded that must be counted but they | ||
+ | # are not viewed pages. URLs with such extensions are not included in the TOP | ||
+ | # Pages/URL report. | ||
+ | # Note: If you want to exclude particular URLs from stats (No Pages and no | ||
+ | # Hits reported), you must use SkipFiles parameter. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "css js class gif jpg jpeg png bmp ico rss xml swf zip arj rar gz z bz2 wav mp3 wma mpg avi" | ||
+ | # Example: "" | ||
+ | # Default: "css js class gif jpg jpeg png bmp ico rss xml swf" | ||
+ | # | ||
+ | NotPageList=" | ||
+ | |||
+ | |||
+ | # By default, AWStats considers that records found in web log file are | ||
+ | # successful hits if HTTP code returned by server is a valid HTTP code (200 | ||
+ | # and 304). Any other code are reported in HTTP status chart. | ||
+ | # Note that HTTP ' | ||
+ | # default in this list as they are not pages seen by a visitor but are | ||
+ | # protocol exchange codes to tell the browser to ask another page. Because | ||
+ | # this other page will be counted and seen with a 200 or 304 code, if you | ||
+ | # add such codes, you will have 2 pages viewed reported for only one in facts. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "200 304 302 305" | ||
+ | # Default: "200 304" | ||
+ | # | ||
+ | ValidHTTPCodes=" | ||
+ | |||
+ | |||
+ | # By default, AWStats considers that records found in mail log file are | ||
+ | # successful mail transfers if field that represent return code in analyzed | ||
+ | # log file match values defined by this parameter. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "1 250 200" | ||
+ | # Default: "1 250" | ||
+ | # | ||
+ | ValidSMTPCodes=" | ||
+ | |||
+ | |||
+ | # Some web servers on some Operating systems (IIS-Windows) consider that a | ||
+ | # login with same value but different case are the same login. To tell AWStats | ||
+ | # to also consider them as one, set this parameter to 1. | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | AuthenticatedUsersNotCaseSensitive=0 | ||
+ | |||
+ | |||
+ | # Some web servers on some Operating systems (IIS-Windows) considers that two | ||
+ | # URLs with same value but different case are the same URL. To tell AWStats to | ||
+ | # also considers them as one, set this parameter to 1. | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | URLNotCaseSensitive=0 | ||
+ | |||
+ | |||
+ | # Keep or remove the anchor string you can find in some URLs. | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | URLWithAnchor=0 | ||
+ | |||
+ | |||
+ | # In URL links, "?" | ||
+ | # / | ||
+ | # However, some servers/ | ||
+ | # their URLs. You can complete this list with all such characters. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: "?;," | ||
+ | # Default: "?;" | ||
+ | # | ||
+ | URLQuerySeparators="?;" | ||
+ | |||
+ | |||
+ | # Keep or remove the query string to the URL in the statistics for individual | ||
+ | # pages. This is primarily used to differentiate between the URLs of dynamic | ||
+ | # pages. If set to 1, mypage.html? | ||
+ | # different pages. | ||
+ | # Warning, when set to 1, memory required to run AWStats is dramatically | ||
+ | # increased if you have a lot of changing URLs (for example URLs with a random | ||
+ | # id inside). Such web sites should not set this option to 1 or use seriously | ||
+ | # the next parameter URLWithQueryWithOnlyFollowingParameters (or eventually | ||
+ | # URLWithQueryWithoutFollowingParameters). | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: | ||
+ | # 0 - URLs are cleaned from the query string (ie: "/ | ||
+ | # 1 - Full URL with query string is used (ie: "/ | ||
+ | # Default: 0 | ||
+ | # | ||
+ | URLWithQuery=0 | ||
+ | |||
+ | |||
+ | # When URLWithQuery is on, you will get the full URL with all parameters in | ||
+ | # URL reports. But among thoose parameters, sometimes you don't need a | ||
+ | # particular parameter because it does not identify the page or because it's | ||
+ | # a random ID changing for each access even if URL points to same page. In | ||
+ | # such cases, it is higly recommanded to ask AWStats to keep only parameters | ||
+ | # you need (if you know them) before counting, manipulating and storing URL. | ||
+ | # Enter here list of wanted parameters. For example, with " | ||
+ | # / | ||
+ | # will be reported as 2 hits on / | ||
+ | # This parameter is not used when URLWithQuery is 0 and can't be used with | ||
+ | # URLWithQueryWithoutFollowingParameters. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | URLWithQueryWithOnlyFollowingParameters="" | ||
+ | |||
+ | |||
+ | # When URLWithQuery is on, you will get the full URL with all parameters in | ||
+ | # URL reports. But among thoose parameters, sometimes you don't need a | ||
+ | # particular parameter because it does not identify the page or because it's | ||
+ | # a random ID changing for each access even if URL points to same page. In | ||
+ | # such cases, it is higly recommanded to ask AWStats to remove such parameters | ||
+ | # from the URL before counting, manipulating and storing URL. Enter here list | ||
+ | # of all non wanted parameters. For example if you enter " | ||
+ | # / | ||
+ | # will be reported as 2 hits on / | ||
+ | # This parameter is not used when URLWithQuery is 0 and can't be used with | ||
+ | # URLWithQueryWithOnlyFollowingParameters. | ||
+ | # Change : Effective for new updates only | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | URLWithQueryWithoutFollowingParameters="" | ||
+ | |||
+ | |||
+ | # Keep or remove the query string to the referrer URL in the statistics for | ||
+ | # external referrer pages. This is used to differentiate between the URLs of | ||
+ | # dynamic referrer pages. If set to 1, mypage.html? | ||
+ | # are counted as two different referrer pages. | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: | ||
+ | # 0 - Referrer URLs are cleaned from the query string (ie: "/ | ||
+ | # 1 - Full URL with query string is used (ie: "/ | ||
+ | # Default: 0 | ||
+ | # | ||
+ | URLReferrerWithQuery=0 | ||
+ | |||
+ | |||
+ | # AWStats can detect setup problems or show you important informations to have | ||
+ | # a better use. Keep this to 1, except if AWStats says you can change it. | ||
+ | # Change : Effective immediatly | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 1 | ||
+ | # | ||
+ | WarningMessages=1 | ||
+ | |||
+ | |||
+ | # When an error occurs, AWStats outputs a message related to errors. If you | ||
+ | # want (in most cases for security reasons) to have no error messages, you | ||
+ | # can set this parameter to your personalized generic message. | ||
+ | # Change : Effective immediatly | ||
+ | # Example: "An error occurred. Contact your Administrator" | ||
+ | # Default: "" | ||
+ | # | ||
+ | ErrorMessages="" | ||
+ | |||
+ | |||
+ | # AWStat can be run with debug=x parameter to output various informations | ||
+ | # to help in debugging or solving troubles. If you want to allow this (not | ||
+ | # enabled by default for security reasons), set this parameter to 0. | ||
+ | # Change : Effective immediatly | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | DebugMessages=0 | ||
+ | |||
+ | |||
+ | # To help you to detect if your log format is good, AWStats reports an error | ||
+ | # if all the first NbOfLinesForCorruptedLog lines have a format that does not | ||
+ | # match the LogFormat parameter. | ||
+ | # However, some worm virus attack on your web server can result in a very high | ||
+ | # number of corrupted lines in your log. So if you experience awstats stop | ||
+ | # because of bad virus records at the beginning of your log file, you can | ||
+ | # increase this parameter (very rare). | ||
+ | # Change : Effective for new updates only | ||
+ | # Default: 50 | ||
+ | # | ||
+ | NbOfLinesForCorruptedLog=50 | ||
+ | |||
+ | |||
+ | # For some particular integration needs, you may want to have CGI links to | ||
+ | # point to another script than awstats.pl. | ||
+ | # Use the name of this script in WrapperScript parameter. | ||
+ | # Change : Effective immediatly | ||
+ | # Example: " | ||
+ | # Example: " | ||
+ | # Default: "" | ||
+ | # | ||
+ | WrapperScript="" | ||
+ | |||
+ | |||
+ | # DecodeUA must be set to 1 if you use Roxen web server. This server converts | ||
+ | # all spaces in user agent field into %20. This make the AWStats robots, OS | ||
+ | # and browsers detection fail in some cases. Just change it to 1 if and only | ||
+ | # if your web server is Roxen. | ||
+ | # Change : Effective for new updates only | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | DecodeUA=0 | ||
+ | |||
+ | |||
+ | # MiscTrackerUrl can be used to make AWStats able to detect some miscellaneous | ||
+ | # things, that can not be tracked on other way, like: | ||
+ | # - Javascript disabled | ||
+ | # - Java enabled | ||
+ | # - Screen size | ||
+ | # - Color depth | ||
+ | # - Macromedia Director plugin | ||
+ | # - Macromedia Shockwave plugin | ||
+ | # - Realplayer G2 plugin | ||
+ | # - QuickTime plugin | ||
+ | # - Mediaplayer plugin | ||
+ | # - Acrobat PDF plugin | ||
+ | # To enable all these features, you must copy the awstats_misc_tracker.js file | ||
+ | # into a /js/ directory stored in your web document root and add the following | ||
+ | # HTML code at the end of your index page (but before </ | ||
+ | # | ||
+ | # <script type=" | ||
+ | # < | ||
+ | # | ||
+ | # If code is not added in index page, all those detection capabilities will be | ||
+ | # disabled. You must also check that ShowScreenSizeStats and ShowMiscStats | ||
+ | # parameters are set to 1 to make results appear in AWStats report page. | ||
+ | # If you want to use another directory than /js/, you must also change the | ||
+ | # awstatsmisctrackerurl variable into the awstats_misc_tracker.js file. | ||
+ | # Change : Effective for new updates only. | ||
+ | # Possible value: URL of javascript tracker file added in your HTML code. | ||
+ | # Default: "/ | ||
+ | # | ||
+ | MiscTrackerUrl="/ | ||
+ | |||
+ | |||
+ | |||
+ | # | ||
+ | # OPTIONAL ACCURACY SETUP SECTION (Not required but increase AWStats features) | ||
+ | # | ||
+ | |||
+ | # The following values allow you to define accuracy of AWStats entities | ||
+ | # (robots, browsers, os, referers, file types) detection. | ||
+ | # It might be a good idea for large web sites or ISP that provides AWStats to | ||
+ | # high number of customers, to set this parameter to 1 (or 0), instead of 2. | ||
+ | # Possible values: | ||
+ | # 0 = No detection, | ||
+ | # 1 = Medium/ | ||
+ | # 2 = Full detection | ||
+ | # Change : Effective for new updates only | ||
+ | # Note : LevelForBrowsersDetection can also accept value " | ||
+ | # enable detailed detection of phone/pda browsers. | ||
+ | # Default: 2 (0 for LevelForWormsDetection) | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LevelForBrowsersDetection=2 | ||
+ | LevelForBrowsersDetection=0 | ||
+ | # 2 reduces AWStats speed by 2% | ||
+ | # allphones reduces AWStats speed by 5% | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LevelForOSDetection=2 | ||
+ | LevelForOSDetection=0 | ||
+ | # 2 reduces AWStats speed by 3% | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LevelForRefererAnalyze=2 | ||
+ | LevelForRefererAnalyze=0 | ||
+ | # 2 reduces AWStats speed by 14% | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LevelForRobotsDetection=2 | ||
+ | LevelForRobotsDetection=0 | ||
+ | # 2 reduces AWStats speed by 2.5% | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LevelForSearchEnginesDetection=2 | ||
+ | LevelForSearchEnginesDetection=0 | ||
+ | # 2 reduces AWStats speed by 9% | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LevelForKeywordsDetection=2 | ||
+ | LevelForKeywordsDetection=0 | ||
+ | # 2 reduces AWStats speed by 1% | ||
+ | # Django : 2012-07-03 | ||
+ | # default: LevelForFileTypesDetection=2 | ||
+ | LevelForFileTypesDetection=0 | ||
+ | # 2 reduces AWStats speed by 1% | ||
+ | LevelForWormsDetection=0 | ||
+ | # 2 reduces AWStats speed by 15% | ||
+ | |||
+ | |||
+ | |||
+ | # | ||
+ | # OPTIONAL APPEARANCE SETUP SECTION (Not required but increase AWStats features) | ||
+ | # | ||
+ | |||
+ | # When you use AWStats as a CGI, you can have the reports shown in HTML frames. | ||
+ | # Frames are only available for report viewed dynamically. When you build | ||
+ | # pages from command line, this option is not used and no frames are built. | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 1 | ||
+ | # | ||
+ | UseFramesWhenCGI=1 | ||
+ | |||
+ | |||
+ | # This parameter asks your browser to open detailed reports into a different | ||
+ | # window than the main page. | ||
+ | # Possible values: | ||
+ | # 0 - Open all in same browser window | ||
+ | # 1 - Open detailed reports in another window except if using frames | ||
+ | # 2 - Open always in a different window even if reports are framed | ||
+ | # Default: 1 | ||
+ | # | ||
+ | DetailedReportsOnNewWindows=1 | ||
+ | |||
+ | |||
+ | # You can add, in the HTML report page, a cache lifetime (in seconds) that | ||
+ | # will be returned to the browser in HTTP header answer by server. | ||
+ | # This parameter is not used when reports are built with -staticlinks option. | ||
+ | # Example: 3600 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: Expires=3600 | ||
+ | Expires=0 | ||
+ | |||
+ | |||
+ | # To avoid too large web pages, you can ask AWStats to limit number of rows of | ||
+ | # all reported charts to this number when no other limits apply. | ||
+ | # Default: 1000 | ||
+ | # | ||
+ | MaxRowsInHTMLOutput=1000 | ||
+ | |||
+ | |||
+ | # Set your primary language (ISO-639-1 language codes). | ||
+ | # Possible values: | ||
+ | # Albanian=al, | ||
+ | # Chinese (Taiwan)=tw, | ||
+ | # Danish=dk, Dutch=nl, English=en, Estonian=et, | ||
+ | # French=fr, Galician=gl, | ||
+ | # Icelandic=is, | ||
+ | # Latvian=lv, Norwegian (Nynorsk)=nn, | ||
+ | # Portuguese=pt, | ||
+ | # Serbian=sr, Slovak=sk, Slovenian=si, | ||
+ | # Ukrainian=ua, | ||
+ | # First available language accepted by browser=auto | ||
+ | # Default: " | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: Lang=" | ||
+ | Lang=" | ||
+ | |||
+ | |||
+ | # Set the location of language files. | ||
+ | # Example: "/ | ||
+ | # Default: " | ||
+ | # | ||
+ | DirLang=" | ||
+ | |||
+ | |||
+ | # Show menu header with reports' | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 1 | ||
+ | # | ||
+ | ShowMenu=1 | ||
+ | |||
+ | |||
+ | # You choose here which reports you want to see in the main page and what you | ||
+ | # want to see in those reports. | ||
+ | # Possible values: | ||
+ | # 0 - Report is not shown at all | ||
+ | # 1 - Report is shown in main page with an entry in menu and default columns | ||
+ | # XYZ - Report shows column informations defined by code X,Y,Z... | ||
+ | # | ||
+ | # U = Unique visitors | ||
+ | # V = Visits | ||
+ | # P = Number of pages | ||
+ | # H = Number of hits (or mails) | ||
+ | # B = Bandwith (or total mail size for mail logs) | ||
+ | # L = Last access date | ||
+ | # E = Entry pages | ||
+ | # X = Exit pages | ||
+ | # C = Web compression (mod_gzip, | ||
+ | # M = Average mail size (mail logs) | ||
+ | # | ||
+ | |||
+ | # Show monthly summary | ||
+ | # Context: Web, Streaming, Mail, Ftp | ||
+ | # Default: UVPHB, Possible column codes: UVPHB | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowSummary=UVPHB | ||
+ | ShowSummary=HB | ||
+ | |||
+ | # Show monthly chart | ||
+ | # Context: Web, Streaming, Mail, Ftp | ||
+ | # Default: UVPHB, Possible column codes: UVPHB | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowMonthStats=UVPHB | ||
+ | ShowMonthStats=HB | ||
+ | |||
+ | # Show days of month chart | ||
+ | # Context: Web, Streaming, Mail, Ftp | ||
+ | # Default: VPHB, Possible column codes: VPHB | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowDaysOfMonthStats=VPHB | ||
+ | ShowDaysOfMonthStats=HB | ||
+ | |||
+ | # Show days of week chart | ||
+ | # Context: Web, Streaming, Mail, Ftp | ||
+ | # Default: PHB, Possible column codes: PHB | ||
+ | # Default: VPHB, Possible column codes: VPHB | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowDaysOfWeekStats=PHB | ||
+ | ShowDaysOfWeekStats=HB | ||
+ | |||
+ | # Show hourly chart | ||
+ | # Context: Web, Streaming, Mail, Ftp | ||
+ | # Default: PHB, Possible column codes: PHB | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowHoursStats=PHB | ||
+ | ShowHoursStats=HB | ||
+ | |||
+ | # Show domains/ | ||
+ | # Context: Web, Streaming, Mail, Ftp | ||
+ | # Default: PHB, Possible column codes: PHB | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowDomainsStats=PHB | ||
+ | ShowDomainsStats=0 | ||
+ | |||
+ | # Show hosts chart | ||
+ | # Context: Web, Streaming, Mail, Ftp | ||
+ | # Default: PHBL, Possible column codes: PHBL | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowHostsStats=PHBL | ||
+ | ShowHostsStats=HBL | ||
+ | |||
+ | # Show authenticated users chart | ||
+ | # Context: Web, Streaming, Ftp | ||
+ | # Default: 0, Possible column codes: PHBL | ||
+ | ShowAuthenticatedUsers=0 | ||
+ | |||
+ | # Show robots chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: HBL, Possible column codes: HBL | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowRobotsStats=HBL | ||
+ | ShowRobotsStats=0 | ||
+ | |||
+ | # Show worms chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: 0 (If set to other than 0, see also LevelForWormsDetection), | ||
+ | ShowWormsStats=0 | ||
+ | |||
+ | # Show email senders chart (For use when analyzing mail log files) | ||
+ | # Context: Mail | ||
+ | # Default: 0, Possible column codes: HBML | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowEMailSenders=0 | ||
+ | ShowEMailSenders=HBML | ||
+ | |||
+ | # Show email receivers chart (For use when analyzing mail log files) | ||
+ | # Context: Mail | ||
+ | # Default: 0, Possible column codes: HBML | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowEMailReceivers=0 | ||
+ | ShowEMailReceivers=HBML | ||
+ | |||
+ | # Show session chart | ||
+ | # Context: Web, Streaming, Ftp | ||
+ | # Default: 1, Possible column codes: None | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowSessionsStats=1 | ||
+ | ShowSessionsStats=0 | ||
+ | |||
+ | # Show pages-url chart. | ||
+ | # Context: Web, Streaming, Ftp | ||
+ | # Default: PBEX, Possible column codes: PBEX | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowPagesStats=PBEX | ||
+ | ShowPagesStats=0 | ||
+ | |||
+ | # Show file types chart. | ||
+ | # Context: Web, Streaming, Ftp | ||
+ | # Default: HB, Possible column codes: HBC | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowFileTypesStats=HB | ||
+ | ShowFileTypesStats=0 | ||
+ | |||
+ | # Show file size chart (Not yet available) | ||
+ | # Context: Web, Streaming, Mail, Ftp | ||
+ | # Default: 1, Possible column codes: None | ||
+ | ShowFileSizesStats=0 | ||
+ | |||
+ | # Show downloads chart. | ||
+ | # Context: Web, Streaming, Ftp | ||
+ | # Default: HB, Possible column codes: HB | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowDownloadsStats=HB | ||
+ | ShowDownloadsStats=0 | ||
+ | |||
+ | # Show operating systems chart | ||
+ | # Context: Web, Streaming, Ftp | ||
+ | # Default: 1, Possible column codes: None | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowOSStats=1 | ||
+ | ShowOSStats=0 | ||
+ | |||
+ | # Show browsers chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: 1, Possible column codes: None | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowBrowsersStats=1 | ||
+ | ShowBrowsersStats=0 | ||
+ | |||
+ | # Show screen size chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: 0 (If set to 1, see also MiscTrackerUrl), | ||
+ | ShowScreenSizeStats=0 | ||
+ | |||
+ | # Show origin chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: PH, Possible column codes: PH | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowOriginStats=PH | ||
+ | ShowOriginStats=0 | ||
+ | |||
+ | # Show keyphrases chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: 1, Possible column codes: None | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowKeyphrasesStats=1 | ||
+ | ShowKeyphrasesStats=0 | ||
+ | |||
+ | # Show keywords chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: 1, Possible column codes: None | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowKeywordsStats=1 | ||
+ | ShowKeywordsStats=0 | ||
+ | |||
+ | # Show misc chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: a (See also MiscTrackerUrl parameter), Possible column codes: anjdfrqwp | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowMiscStats=a | ||
+ | ShowMiscStats=0 | ||
+ | |||
+ | # Show http errors chart | ||
+ | # Context: Web, Streaming | ||
+ | # Default: 1, Possible column codes: None | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowHTTPErrorsStats=1 | ||
+ | ShowHTTPErrorsStats=0 | ||
+ | |||
+ | # Show smtp errors chart (For use when analyzing mail log files) | ||
+ | # Context: Mail | ||
+ | # Default: 0, Possible column codes: None | ||
+ | # Django : 2012-07-03 | ||
+ | # default: ShowSMTPErrorsStats=0 | ||
+ | ShowSMTPErrorsStats=1 | ||
+ | |||
+ | # Show the cluster report (Your LogFormat must contains the %cluster tag) | ||
+ | # Context: Web, Streaming, Ftp | ||
+ | # Default: 0, Possible column codes: PHB | ||
+ | ShowClusterStats=0 | ||
+ | |||
+ | |||
+ | # Some graphical reports are followed by the data array of values. | ||
+ | # If you don't want this array (to reduce the report size for example), you | ||
+ | # can set thoose options to 0. | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 1 | ||
+ | # | ||
+ | # Data array values for the ShowMonthStats report | ||
+ | AddDataArrayMonthStats=1 | ||
+ | # Data array values for the ShowDaysOfMonthStats report | ||
+ | AddDataArrayShowDaysOfMonthStats=1 | ||
+ | # Data array values for the ShowDaysOfWeekStats report | ||
+ | AddDataArrayShowDaysOfWeekStats=1 | ||
+ | # Data array values for the ShowHoursStats report | ||
+ | AddDataArrayShowHoursStats=1 | ||
+ | |||
+ | |||
+ | # In the Origin chart, you have stats on where your hits came from. You can | ||
+ | # include hits on pages that come from pages of same sites in this chart. | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 0 | ||
+ | # | ||
+ | IncludeInternalLinksInOriginSection=0 | ||
+ | |||
+ | |||
+ | # The following parameters can be used to choose the maximum number of lines | ||
+ | # shown for the particular following reports. | ||
+ | # | ||
+ | # Stats by countries/ | ||
+ | MaxNbOfDomain = 10 | ||
+ | MinHitDomain | ||
+ | # Stats by hosts | ||
+ | MaxNbOfHostsShown = 10 | ||
+ | MinHitHost | ||
+ | # Stats by authenticated users | ||
+ | MaxNbOfLoginShown = 10 | ||
+ | MinHitLogin | ||
+ | # Stats by robots | ||
+ | MaxNbOfRobotShown = 10 | ||
+ | MinHitRobot | ||
+ | # Stats for Downloads | ||
+ | MaxNbOfDownloadsShown = 10 | ||
+ | MinHitDownloads = 1 | ||
+ | # Stats by pages | ||
+ | MaxNbOfPageShown = 10 | ||
+ | MinHitFile | ||
+ | # Stats by OS | ||
+ | MaxNbOfOsShown = 10 | ||
+ | MinHitOs | ||
+ | # Stats by browsers | ||
+ | MaxNbOfBrowsersShown = 10 | ||
+ | MinHitBrowser = 1 | ||
+ | # Stats by screen size | ||
+ | MaxNbOfScreenSizesShown = 5 | ||
+ | MinHitScreenSize = 1 | ||
+ | # Stats by window size (following 2 parameters are not yet used) | ||
+ | MaxNbOfWindowSizesShown = 5 | ||
+ | MinHitWindowSize = 1 | ||
+ | # Stats by referers | ||
+ | MaxNbOfRefererShown = 10 | ||
+ | MinHitRefer | ||
+ | # Stats for keyphrases | ||
+ | MaxNbOfKeyphrasesShown = 10 | ||
+ | MinHitKeyphrase = 1 | ||
+ | # Stats for keywords | ||
+ | MaxNbOfKeywordsShown = 10 | ||
+ | MinHitKeyword = 1 | ||
+ | # Stats for sender or receiver emails | ||
+ | MaxNbOfEMailsShown = 20 | ||
+ | MinHitEMail | ||
+ | |||
+ | |||
+ | # Choose if you want the week report to start on sunday or monday | ||
+ | # Possible values: | ||
+ | # 0 - Week starts on sunday | ||
+ | # 1 - Week starts on monday | ||
+ | # Default: 1 | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: FirstDayOfWeek=0 | ||
+ | FirstDayOfWeek=1 | ||
+ | |||
+ | |||
+ | # List of visible flags that link to other language translations. | ||
+ | # See Lang parameter for list of allowed flag/ | ||
+ | # If you don't want any flag link, set ShowFlagLinks to "" | ||
+ | # This parameter is used only if ShowMenu parameter is set to 1. | ||
+ | # Possible values: "" | ||
+ | # Example: "en es fr nl de" | ||
+ | # Default: "" | ||
+ | # | ||
+ | ShowFlagLinks="" | ||
+ | |||
+ | |||
+ | # Each URL, shown in stats report views, are links you can click. | ||
+ | # Possible values: 0 or 1 | ||
+ | # Default: 1 | ||
+ | # | ||
+ | ShowLinksOnUrl=1 | ||
+ | |||
+ | |||
+ | # When AWStats builds HTML links in its report pages, it starts those links | ||
+ | # with " | ||
+ | # here the root of all your HTTPS links. If all your site is a SSL web site, | ||
+ | # just enter "/" | ||
+ | # This parameter is not used if ShowLinksOnUrl is 0. | ||
+ | # Example: "/ | ||
+ | # Example: "/" | ||
+ | # Default: "" | ||
+ | # | ||
+ | UseHTTPSLinkForUrl="" | ||
+ | |||
+ | |||
+ | # Maximum length of URL part shown on stats page (number of characters). | ||
+ | # This affects only URL visible text, links still work. | ||
+ | # Default: 64 | ||
+ | # | ||
+ | MaxLengthOfShownURL=64 | ||
+ | |||
+ | |||
+ | # You can enter HTML code that will be added at the top of AWStats reports. | ||
+ | # Default: "" | ||
+ | # | ||
+ | HTMLHeadSection="" | ||
+ | |||
+ | |||
+ | # You can enter HTML code that will be added at the end of AWStats reports. | ||
+ | # Great to add advert ban. | ||
+ | # Default: "" | ||
+ | # | ||
+ | HTMLEndSection="" | ||
+ | |||
+ | |||
+ | # By default AWStats page contains meta tag robots=noindex, | ||
+ | # If you want to have your statistics to be indexed, set this option to 1. | ||
+ | # Default: 0 | ||
+ | # | ||
+ | MetaRobot=0 | ||
+ | |||
+ | |||
+ | # You can set Logo and LogoLink to use your own logo. | ||
+ | # Logo must be the name of image file (must be in $DirIcons/ | ||
+ | # LogoLink is the expected URL when clicking on Logo. | ||
+ | # Default: " | ||
+ | # | ||
+ | Logo=" | ||
+ | LogoLink=" | ||
+ | |||
+ | |||
+ | # Value of maximum bar width/ | ||
+ | # Default: 260/90 | ||
+ | # | ||
+ | BarWidth | ||
+ | BarHeight | ||
+ | |||
+ | |||
+ | # You can ask AWStats to use a particular CSS (Cascading Style Sheet) to | ||
+ | # change its look. To create a style sheet, you can use samples provided with | ||
+ | # AWStats in wwwroot/css directory. | ||
+ | # Example: "/ | ||
+ | # Example: "/ | ||
+ | # Default: "" | ||
+ | # | ||
+ | StyleSheet="" | ||
+ | |||
+ | |||
+ | # Those color parameters can be used (if StyleSheet parameter is not used) | ||
+ | # to change AWStats look. | ||
+ | # Example: color_name=" | ||
+ | # | ||
+ | color_Background=" | ||
+ | color_TableBGTitle=" | ||
+ | color_TableTitle=" | ||
+ | color_TableBG=" | ||
+ | color_TableRowTitle=" | ||
+ | color_TableBGRowTitle=" | ||
+ | color_TableBorder=" | ||
+ | color_text=" | ||
+ | color_textpercent=" | ||
+ | color_titletext=" | ||
+ | color_weekend=" | ||
+ | color_link=" | ||
+ | color_hover=" | ||
+ | color_u=" | ||
+ | color_v=" | ||
+ | color_p=" | ||
+ | color_h=" | ||
+ | color_k=" | ||
+ | color_s=" | ||
+ | color_e=" | ||
+ | color_x=" | ||
+ | |||
+ | |||
+ | |||
+ | # | ||
+ | # PLUGINS | ||
+ | # | ||
+ | |||
+ | # Add here all plugin files you want to load. | ||
+ | # Plugin files must be .pm files stored in ' | ||
+ | # Uncomment LoadPlugin lines to enable a plugin after checking that perl | ||
+ | # modules required by the plugin are installed. | ||
+ | |||
+ | # PLUGIN: Tooltips | ||
+ | # REQUIRED MODULES: None | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # NOTE: This will increased HTML report pages size, thus server load and bandwidth. | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: # | ||
+ | LoadPlugin=" | ||
+ | |||
+ | # PLUGIN: DecodeUTFKeys | ||
+ | # REQUIRED MODULES: Encode and URI::Escape | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # keywords/ | ||
+ | # referer search engine. | ||
+ | # | ||
+ | # | ||
+ | |||
+ | |||
+ | # PLUGIN: IPv6 | ||
+ | # PARAMETERS: None | ||
+ | # REQUIRED MODULES: Net::IP and Net::DNS | ||
+ | # DESCRIPTION: | ||
+ | # lookup on IPv6 addresses. | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: HashFiles | ||
+ | # REQUIRED MODULES: Storable | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # This increases DNS cache files loading speed, above all for very large web sites. | ||
+ | # | ||
+ | # | ||
+ | |||
+ | |||
+ | # PLUGIN: UserInfo | ||
+ | # REQUIRED MODULES: None | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # authenticated user reports for each login value. | ||
+ | # A text file called userinfo.myconfig.txt, | ||
+ | # second is text to show, separated by a tab char) must be created in DirData | ||
+ | # directory. | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: HostInfo | ||
+ | # REQUIRED MODULES: Net::XWhois | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # info on host (like whois records). | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: # | ||
+ | LoadPlugin=" | ||
+ | |||
+ | # PLUGIN: ClusterInfo | ||
+ | # REQUIRED MODULES: None | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # number. A text file called clusterinfo.myconfig.txt, | ||
+ | # cluster number, second is text to show) separated by a tab char. must be | ||
+ | # created into DirData directory. | ||
+ | # Note this plugin is useless if ShowClusterStats is set to 0 or if you don't | ||
+ | # use a personalized log format that contains %cluster tag. | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: UrlAliases | ||
+ | # REQUIRED MODULES: None | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # A text file called urlalias.myconfig.txt, | ||
+ | # second is text to show, separated by a tab char) must be created into | ||
+ | # DirData directory. | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: TimeHiRes | ||
+ | # REQUIRED MODULES: Time::HiRes (if Perl < 5.8) | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: TimeZone | ||
+ | # REQUIRED MODULES: Time::Local | ||
+ | # PARAMETERS: [timezone offset] | ||
+ | # DESCRIPTION: | ||
+ | # This plugin reduces AWStats speed of 10% !!!!!!! | ||
+ | # LoadPlugin=" | ||
+ | # LoadPlugin=" | ||
+ | # LoadPlugin=" | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: Rawlog | ||
+ | # REQUIRED MODULES: None | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # content of current log files. A filter is also available. | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: GraphApplet | ||
+ | # REQUIRED MODULES: None | ||
+ | # PARAMETERS: [CSS classes to override] | ||
+ | # DESCRIPTION: | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: GraphGoogleChartAPI | ||
+ | # REQUIRED MODULES: None | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # in HTML reports. If country data is available and more than one country has hits, | ||
+ | # a map will be generated using Google Visualizations. | ||
+ | # Note: The machine where reports are displayed must have Internet access for the | ||
+ | # charts to be generated. The only data sent to Google includes the statistic numbers, | ||
+ | # legend names and country names. | ||
+ | # Warning: This plugin is not compatible with option BuildReportFormat=xhtml. | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: # | ||
+ | LoadPlugin=" | ||
+ | |||
+ | # PLUGIN: GeoIPfree | ||
+ | # REQUIRED MODULES: Geo::IPfree version 0.2+ (from Graciliano M.P.) | ||
+ | # PARAMETERS: None | ||
+ | # DESCRIPTION: | ||
+ | # This plugin is useless for intranet only log files. | ||
+ | # Note: You must choose between using this plugin (need Perl Geo::IPfree | ||
+ | # module, database is free but not up to date) or the GeoIP plugin (need | ||
+ | # Perl Geo::IP module from Maxmind, database is also free and up to date). | ||
+ | # Note: Activestate provide a corrupted version of Geo::IPfree 0.2 Perl | ||
+ | # module, so install it from elsewhere (from www.cpan.org for example). | ||
+ | # This plugin reduces AWStats speed by up to 10% ! | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # MAXMIND GEO IP MODULES: Please see documentation for notes on all Maxmind modules | ||
+ | |||
+ | # PLUGIN: GeoIP | ||
+ | # REQUIRED MODULES: Geo::IP or Geo:: | ||
+ | # PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/ | ||
+ | # DESCRIPTION: | ||
+ | # table with country name | ||
+ | # Replace spaces in the path of geoip data file with string " | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: # | ||
+ | LoadPlugin=" | ||
+ | |||
+ | # PLUGIN: GeoIP_City_Maxmind | ||
+ | # REQUIRED MODULES: Geo::IP or Geo:: | ||
+ | # PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/ | ||
+ | # DESCRIPTION: | ||
+ | # and hits by city including regions. | ||
+ | # Replace spaces in the path of geoip data file with string " | ||
+ | # | ||
+ | # Django : 2012-07-03 | ||
+ | # default: # | ||
+ | LoadPlugin=" | ||
+ | |||
+ | # PLUGIN: GeoIP_ASN_Maxmind | ||
+ | # REQUIRED MODULES: Geo::IP or Geo:: | ||
+ | # PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/ | ||
+ | # DESCRIPTION: | ||
+ | # This plugin can display some ISP information if included in the database. You can also provide | ||
+ | # a link that will be used to lookup additional registration data. Put the link at the end of | ||
+ | # the parameter string and the report page will include the link with the full AS number at the end. | ||
+ | # Replace spaces in the path of geoip data file with string " | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: GeoIP_Region_Maxmind | ||
+ | # REQUIRED MODULES: Geo::IP or Geo:: | ||
+ | # PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/ | ||
+ | # DESCRIPTION: | ||
+ | # Canada can be detected. | ||
+ | # Replace spaces in the path of geoip data file with string " | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: GeoIP_ISP_Maxmind | ||
+ | # REQUIRED MODULES: Geo::IP or Geo:: | ||
+ | # PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/ | ||
+ | # DESCRIPTION: | ||
+ | # Replace spaces in the path of geoip data file with string " | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # PLUGIN: GeoIP_Org_Maxmind | ||
+ | # REQUIRED MODULES: Geo::IP or Geo:: | ||
+ | # PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/ | ||
+ | # DESCRIPTION: | ||
+ | # Replace spaces in the path of geoip data file with string " | ||
+ | # | ||
+ | # | ||
+ | |||
+ | |||
+ | # | ||
+ | # EXTRA SECTIONS | ||
+ | # | ||
+ | |||
+ | # You can define your own charts, you choose here what are rows and columns | ||
+ | # keys. This feature is particularly useful for marketing purpose, tracking | ||
+ | # products orders for example. | ||
+ | # For this, edit all parameters of Extra section. Each set of parameter is a | ||
+ | # different chart. For several charts, duplicate section changing the number. | ||
+ | # Note: Each Extra section reduces AWStats speed by 8%. | ||
+ | # | ||
+ | # WARNING: A wrong setup of Extra section might result in too large arrays | ||
+ | # that will consume all your memory, making AWStats unusable after several | ||
+ | # updates, so be sure to setup it correctly. | ||
+ | # In most cases, you don't need this feature. | ||
+ | # | ||
+ | # ExtraSectionNameX is title of your personalized chart. | ||
+ | # ExtraSectionCodeFilterX is list of codes the record code field must match. | ||
+ | # Put an empty string for no test on code. | ||
+ | # ExtraSectionConditionX are conditions you can use to count or not the hit, | ||
+ | # Use one of the field condition | ||
+ | # | ||
+ | # and a regex to match, after a coma. Use " | ||
+ | # ExtraSectionFirstColumnTitleX is the first column title of the chart. | ||
+ | # ExtraSectionFirstColumnValuesX is a string to tell AWStats which field to | ||
+ | # | ||
+ | # | ||
+ | # and how to extract the value (using regex syntax). Each different value | ||
+ | # found will appear in first column of report on a different row. Be sure | ||
+ | # that list of different possible values will not grow indefinitely. | ||
+ | # ExtraSectionFirstColumnFormatX is the string used to write value. | ||
+ | # ExtraSectionStatTypesX are things you want to count. You can use standard | ||
+ | # code letters (P for pages,H for hits,B for bandwidth,L for last access). | ||
+ | # ExtraSectionAddAverageRowX add a row at bottom of chart with average values. | ||
+ | # ExtraSectionAddSumRowX add a row at bottom of chart with sum values. | ||
+ | # MaxNbOfExtraX is maximum number of rows shown in chart. | ||
+ | # MinHitExtraX is minimum number of hits required to be shown in chart. | ||
+ | # | ||
+ | |||
+ | # Example to report the 20 products the most ordered by " | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | |||
+ | |||
+ | # There is also a global parameter ExtraTrackedRowsLimit that limits the | ||
+ | # number of possible rows an ExtraSection can report. This parameter is | ||
+ | # here to protect too much memory use when you make a bad setup in your | ||
+ | # ExtraSection. It applies to all ExtraSection independently meaning that | ||
+ | # none ExtraSection can report more rows than value defined by ExtraTrackedRowsLimit. | ||
+ | # If you know an ExtraSection will report more rows than its value, you should | ||
+ | # increase this parameter or AWStats will stop with an error. | ||
+ | # Example: 2000 | ||
+ | # Default: 500 | ||
+ | # | ||
+ | ExtraTrackedRowsLimit=500 | ||
+ | |||
+ | |||
+ | # | ||
+ | # INCLUDES | ||
+ | # | ||
+ | |||
+ | # You can include other config files using the directive with the name of the | ||
+ | # config file. | ||
+ | # This is particularly useful for users who have a lot of virtual servers, so | ||
+ | # a lot of config files and want to maintain common values in only one file. | ||
+ | # Note that when a variable is defined both in a config file and in an | ||
+ | # included file, AWStats will use the last value read for parameters that | ||
+ | # contains one value and AWStats will concat all values from both files for | ||
+ | # parameters that are lists of values. | ||
+ | # | ||
+ | |||
+ | #Include "" | ||
+ | |||
+ | </ | ||
+ | |||
+ | Zusammengefasst sieht dann unsere Konfigurationdatei entsprechend wie folgt aus: | ||
+ | # egrep -v ' | ||
+ | |||
+ | <code bash> | ||
+ | LogFile=" | ||
+ | LogType=M | ||
+ | LogFormat=" | ||
+ | LogSeparator=" | ||
+ | SiteDomain=" | ||
+ | HostAliases=„localhost 127.0.0.1 REGEX[nausch\.org$] REGEX[www\.nausch\.org$]“ | ||
+ | DNSLookup=2 | ||
+ | DirData="/ | ||
+ | DirCgi="/ | ||
+ | DirIcons="/ | ||
+ | AllowToUpdateStatsFromBrowser=1 | ||
+ | AllowFullYearView=2 | ||
+ | EnableLockForUpdate=1 | ||
+ | DNSStaticCacheFile=" | ||
+ | DNSLastUpdateCacheFile=" | ||
+ | SkipDNSLookupFor="" | ||
+ | AllowAccessFromWebToAuthenticatedUsersOnly=0 | ||
+ | AllowAccessFromWebToFollowingAuthenticatedUsers="" | ||
+ | AllowAccessFromWebToFollowingIPAddresses="" | ||
+ | CreateDirDataIfNotExists=0 | ||
+ | BuildHistoryFormat=text | ||
+ | BuildReportFormat=html | ||
+ | SaveDatabaseFilesWithPermissionsForEveryone=1 | ||
+ | PurgeLogFile=0 | ||
+ | ArchiveLogRecords=0 | ||
+ | KeepBackupOfHistoricFiles=1 | ||
+ | DefaultFile=" | ||
+ | SkipHosts="" | ||
+ | SkipUserAgents="" | ||
+ | SkipFiles="" | ||
+ | SkipReferrersBlackList="" | ||
+ | OnlyHosts="" | ||
+ | OnlyUserAgents="" | ||
+ | OnlyUsers="" | ||
+ | OnlyFiles="" | ||
+ | NotPageList=" | ||
+ | ValidHTTPCodes=" | ||
+ | ValidSMTPCodes=" | ||
+ | AuthenticatedUsersNotCaseSensitive=0 | ||
+ | URLNotCaseSensitive=0 | ||
+ | URLWithAnchor=0 | ||
+ | URLQuerySeparators="?;" | ||
+ | URLWithQuery=0 | ||
+ | URLWithQueryWithOnlyFollowingParameters="" | ||
+ | URLWithQueryWithoutFollowingParameters="" | ||
+ | URLReferrerWithQuery=0 | ||
+ | WarningMessages=1 | ||
+ | ErrorMessages="" | ||
+ | DebugMessages=0 | ||
+ | NbOfLinesForCorruptedLog=50 | ||
+ | WrapperScript="" | ||
+ | DecodeUA=0 | ||
+ | MiscTrackerUrl="/ | ||
+ | LevelForBrowsersDetection=0 | ||
+ | # 2 reduces AWStats speed by 2% | ||
+ | # allphones reduces AWStats speed by 5% | ||
+ | LevelForOSDetection=0 | ||
+ | # 2 reduces AWStats speed by 3% | ||
+ | LevelForRefererAnalyze=0 | ||
+ | # 2 reduces AWStats speed by 14% | ||
+ | LevelForRobotsDetection=0 | ||
+ | # 2 reduces AWStats speed by 2.5% | ||
+ | LevelForSearchEnginesDetection=0 | ||
+ | # 2 reduces AWStats speed by 9% | ||
+ | LevelForKeywordsDetection=0 | ||
+ | # 2 reduces AWStats speed by 1% | ||
+ | LevelForFileTypesDetection=0 | ||
+ | # 2 reduces AWStats speed by 1% | ||
+ | LevelForWormsDetection=0 | ||
+ | # 2 reduces AWStats speed by 15% | ||
+ | UseFramesWhenCGI=1 | ||
+ | DetailedReportsOnNewWindows=1 | ||
+ | Expires=0 | ||
+ | MaxRowsInHTMLOutput=1000 | ||
+ | Lang=" | ||
+ | DirLang=" | ||
+ | ShowMenu=1 | ||
+ | ShowSummary=HB | ||
+ | ShowMonthStats=HB | ||
+ | ShowDaysOfMonthStats=HB | ||
+ | ShowDaysOfWeekStats=HB | ||
+ | ShowHoursStats=HB | ||
+ | ShowDomainsStats=0 | ||
+ | ShowHostsStats=HBL | ||
+ | ShowAuthenticatedUsers=0 | ||
+ | ShowRobotsStats=0 | ||
+ | ShowWormsStats=0 | ||
+ | ShowEMailSenders=HBML | ||
+ | ShowEMailReceivers=HBML | ||
+ | ShowSessionsStats=0 | ||
+ | ShowPagesStats=0 | ||
+ | ShowFileTypesStats=0 | ||
+ | ShowFileSizesStats=0 | ||
+ | ShowDownloadsStats=0 | ||
+ | ShowOSStats=0 | ||
+ | ShowBrowsersStats=0 | ||
+ | ShowScreenSizeStats=0 | ||
+ | ShowOriginStats=0 | ||
+ | ShowKeyphrasesStats=0 | ||
+ | ShowKeywordsStats=0 | ||
+ | ShowMiscStats=0 | ||
+ | ShowHTTPErrorsStats=0 | ||
+ | ShowSMTPErrorsStats=1 | ||
+ | ShowClusterStats=0 | ||
+ | AddDataArrayMonthStats=1 | ||
+ | AddDataArrayShowDaysOfMonthStats=1 | ||
+ | AddDataArrayShowDaysOfWeekStats=1 | ||
+ | AddDataArrayShowHoursStats=1 | ||
+ | IncludeInternalLinksInOriginSection=0 | ||
+ | MaxNbOfDomain = 10 | ||
+ | MinHitDomain | ||
+ | MaxNbOfHostsShown = 10 | ||
+ | MinHitHost | ||
+ | MaxNbOfLoginShown = 10 | ||
+ | MinHitLogin | ||
+ | MaxNbOfRobotShown = 10 | ||
+ | MinHitRobot | ||
+ | MaxNbOfDownloadsShown = 10 | ||
+ | MinHitDownloads = 1 | ||
+ | MaxNbOfPageShown = 10 | ||
+ | MinHitFile | ||
+ | MaxNbOfOsShown = 10 | ||
+ | MinHitOs | ||
+ | MaxNbOfBrowsersShown = 10 | ||
+ | MinHitBrowser = 1 | ||
+ | MaxNbOfScreenSizesShown = 5 | ||
+ | MinHitScreenSize = 1 | ||
+ | MaxNbOfWindowSizesShown = 5 | ||
+ | MinHitWindowSize = 1 | ||
+ | MaxNbOfRefererShown = 10 | ||
+ | MinHitRefer | ||
+ | MaxNbOfKeyphrasesShown = 10 | ||
+ | MinHitKeyphrase = 1 | ||
+ | MaxNbOfKeywordsShown = 10 | ||
+ | MinHitKeyword = 1 | ||
+ | MaxNbOfEMailsShown = 20 | ||
+ | MinHitEMail | ||
+ | FirstDayOfWeek=1 | ||
+ | ShowFlagLinks="" | ||
+ | ShowLinksOnUrl=1 | ||
+ | UseHTTPSLinkForUrl="" | ||
+ | MaxLengthOfShownURL=64 | ||
+ | HTMLHeadSection="" | ||
+ | HTMLEndSection="" | ||
+ | MetaRobot=0 | ||
+ | Logo=" | ||
+ | LogoLink=" | ||
+ | BarWidth | ||
+ | BarHeight | ||
+ | StyleSheet="" | ||
+ | color_Background=" | ||
+ | color_TableBGTitle=" | ||
+ | color_TableTitle=" | ||
+ | color_TableBG=" | ||
+ | color_TableRowTitle=" | ||
+ | color_TableBGRowTitle=" | ||
+ | color_TableBorder=" | ||
+ | color_text=" | ||
+ | color_textpercent=" | ||
+ | color_titletext=" | ||
+ | color_weekend=" | ||
+ | color_link=" | ||
+ | color_hover=" | ||
+ | color_u=" | ||
+ | color_v=" | ||
+ | color_p=" | ||
+ | color_h=" | ||
+ | color_k=" | ||
+ | color_s=" | ||
+ | color_e=" | ||
+ | color_x=" | ||
+ | LoadPlugin=" | ||
+ | LoadPlugin=" | ||
+ | LoadPlugin=" | ||
+ | LoadPlugin=" | ||
+ | LoadPlugin=" | ||
+ | ExtraTrackedRowsLimit=500 | ||
+ | </ | ||
+ | Nach erfolgreicher Konfiguration steht dem ersten Aufruf nichts mehr im Wege. Der Aufruf erfolgt über folgende URL: | ||
+ | $ firefox http:// | ||
+ | {{ : | ||
+ | ====== Links ====== | ||
+ | * **[[centos: | ||
+ | * **[[wiki: | ||
+ | * **[[http:// | ||