Anleitung: Zentraler Logserver mit Syslog NG, MySQL und Lggr Webinterface

Heute zeige ich euch wie man Lggr zusammen mit einer Datenbank, einem Webserver und Redis zu einem mächtigen Logviewer als performante alternative zu Elasticsearch oder Splunk machen kann.

Einige kennen es vielleicht. Man hat mehrere Server, etliche Applikationen oder Websites und alle schreiben brav die Meldungen in ein eigenes Logfile. Unter Umständen auch noch auf verschiedenen Servern und dann kommt der Gau.

Die einzelnen Logs auf den Servern durchzustöbern kann dann sehr Mühsam und langwierig sein aber auch die tägliche Überwachung auf Ungereimtheiten kann auf manuellem Weg sehr mühsam sein. Ein anderes Szenario, man ist irgendwo unterwegs, irgendwas fällt aus und es muss schnell gehandelt werden. Dabei hat man vielleicht nur ein Handy.

Wäre es hier nicht wunderbar ein Webinterface zu haben, was irgendwo mitlaufen kann und die Logeinträge ausgibt? Genauso das wollen wir hier nun tun. Ein Webinterface welches uns die Logs anzeigt und durchsuchen lässt.

Das Konstrukt von Backend bis Webinterface

Ziel soll es sein ein Webinterface für alle Logfiles von allen Servern zentral anzeigen zu lassen, dort suchen und Filtern zu können um Fehler schnell und effizient beheben zu können. Zum Einsatz kommt hier das Webinterface von Lggr. Zudem benötigen wir einen Apache, Redis als Caching sowie eine MySQL Datenbank als Backend. Am Ende sollte dann so ein schönes Loggr Webinterface dabei herauskommen.

lggr
Auf dem Screenshot sieht man die Statistik Seite unseres Lggr Webinterfaces mit 35,5 Millionen Einträge seit 12. Dezember 2017. Die Ladezeit beträgt ca 3-8 Sekunden. Recht ordentlich für diese Masse 😉

Auf dem Screenshot sieht man einen Teil der Statistik Seite unseres Lggr Webinterfaces mit 35,5 Millionen Einträge seit 12. Dezember 2017. Die Ladezeit beträgt ca 3-8 Sekunden. Recht ordentlich für diese Masse 😉

Dann kommen wir aber endlich zum Wesentlichen. Der Installation die wir im Folgenden Artikel genau erklären.

Die Apache Installation

Die ist relativ Simpel erledigt und war in weniger als 5 Minuten auf unserem Debian Stretch System erledigt.

apt-get install apache2

a2enmod headers expires

Damit wird Apache installiert und die benötigten Module aktiviert.

PHP installieren

Natürlich wird auch PHP benötigt. Bei Debian Stretch gibt es PHP 7 per Default

apt-get install php php-mysql

Nun noch in /etc/php/7.0/apache2/php.ini und in /etc/php/7.0/cli/php.ini eure Zeitzone setzen.

date.timezone = Europe/Berlin

Redis installieren als Caching

Damit das ganze nun auch performant ist und nicht ständig alle Anfragen direkt den Apache / PHP oder MySQL belasten, installieren wir Redis als Caching Backend

apt-get install php-redis redis-server

Solltet Ihr kein Redis benötigen oder wollen, dann könnt Ihr in der lggr_class.php von LggrCacheRedis zu LggrCacheFile ändern.

Sieht dann so aus

// $this->cache = new LggrCacheRedis();

$this->cache = LggrCacheFile

 

Lggr Webinterface

Da gibt es nun 2 Wege, entweder ihr holt euch das Original und ladet die 3rd Party Bibliotheken wie jquery und Bootstrap extra herunter oder Ihr nehmt unseren Download. Dort sind die 3rd Party Bibliotheken und ein paar Fixes im Design bereits mit enthalten. 

Variante 1: Hier Downloaden, entpacken und mit den Anpassungen weiter unten fortfahren.

Variante 2: Mehr Aufwand aber dennoch will ich diese nennen.

cd /var/www/html

apt install -y git

git clone https://github.com/kkretsch/lggr.git logger

cd /var/www

wget https://lggr.io/wp-content/uploads/2015/06/lggr_contrib.tar.gz tar xvfz lggr_contrib.tar.gz

Egal welche Variante. Ab hier geht es in jedem Fall weiter 🙂 Das Webinterface sollte unbedingt gesichert werden da hier kein Login verbaut ist. Am einfachsten mittels htaccess

 htpasswd -c /var/www/webuser logger 

Damit wird dem User “logger” ein Passwort erstellt mit dem man sich später im Webinterface einloggen kann.

In der Apache config sollte man noch .htaccess Auswertungen erlauben

$ /etc/apache2/sites-available/000-default.conf

<VirtualHost>

---SNIP---

        <Directory /var/www/html/>

        AllowOverride All

        </Directory>

</VirtualHost>

Nun noch die Rechte setzen

chown www-data:www-data /var/www/html/logger/cache/

In der inc/config_class.php muss auf den contrib Ordner verwiesen werden. In Variante 2 müssen hier die Pfade angepasst werden

/* local storage */

               $this->setUrlBootstrap('/contrib/bootstrap/');

               $this->setUrlJquery('/contrib/jquery/');

               $this->setUrlJqueryui('/contrib/jqueryui/');

               $this->setUrlJAtimepicker('/contrib/timepicker/');

               $this->setUrlChartjs('/contrib/chartjs/');

               $this->setUrlJQCloud('/contrib/jqcloud/');

MariaDB / MySQL Server und Client

Egal was Ihr einsetzen wollt, sofern Ihr nicht schon MySQL irgendwo installiert habt, müsst ihr es nun tun.

MySQL

 apt-get install -y mariadb-server mariadb-client

MariaDB

 apt-get install -y mysql-server mysql-client

 

Dann wird die Datenbank logger erstellt

mysql -u root -p

> CREATE DATABASE logger;

> quit

Die user.sql anpassen und die Passwörter entsprechend setzen. Diese liegt in /var/www/html/logger/doc

# create the following three mysql users:

# used by syslog-ng for inserting new data, referenced in /etc/syslog-ng/conf.d/08lggr.conf

GRANT INSERT,SELECT,UPDATE ON logger.* TO logger@localhost IDENTIFIED BY 'SET_PASSWORD';

# used by the web gui for normal viewing, referenced in inc/config_class.php

GRANT SELECT ON logger.* TO logviewer@localhost IDENTIFIED BY 'SET_PASSWORD';

# used by clean up cron job and for archiving, referenced in inc/adminconfig_class.php

GRANT SELECT,UPDATE,DELETE ON logger.* TO loggeradmin@localhost IDENTIFIED BY 'SET_PASSWORD';

# activate changes

FLUSH PRIVILEGES;

Das Passwort muss in dieser Datei natürlich anstelle von ‘SET_PASSWORD’ eingetragen werden.

Das SQL ausführen

mysql -u root -p < /var/www/html/logger/doc/user.sql

mysql -u root -p logger < /var/www/html/logger/doc/db.sql

Der zweite Befehl legt die initiale Datenbank an.

Als nächstes muss noch in /var/www/html/logger/inc/config_class.php und adminconfig_class.php das jeweilige Passwort eingetragen werden.

$/var/www/html/logger/inc/config_class.php

class Config extends AbstractConfig {

        function __construct() {

                $this->setDbUser('logviewer');

                $this->setDbPwd('SET_PASSWORD');

                $this->setDbName('logger');

                // Set your preferred language en_US, de_DE, or pt_BR

                $this->setLocale('de_DE');

$ /var/www/html/logger/inc/adminconfig_class.php

class AdminConfig extends AbstractConfig {

        function __construct() {

                $this->setDbUser('loggeradmin');

                $this->setDbPwd('SET_PASSWORD');

                $this->setDbName('logger');

        } // constructor

Wir haben es fast geschafft. 

Syslog NG Server installieren

apt-get install -y syslog-ng libdbd-mysql

Syslog NG rendert alle .conf Dateien in /etc/syslog-ng/conf.d/ .

Wir erstellen für Lggr also eine eigene config die so aussieht:

filter f_no_debug { not level(debug); };

options {

keep_hostname(yes);

};

source s_net {

udp( port(514) log-iw-size(2000) );                                        

};

destination d_newmysql {

sql(

flags(dont-create-tables,explicit-commits)

session-statements("SET NAMES 'utf8'")

flush_lines(10)

flush_timeout(5000)

local_time_zone("Europe/Berlin")

type(mysql)

username("logger")          <= DB user eintragen!

password("SET_PASSWORD")    <= DB password eintragen!

database("logger")          <= DB name eintragen!

host("localhost")

table("newlogs")

columns("date", "facility", "level", "host", "program", "pid", "message")

values("${R_YEAR}-${R_MONTH}-${R_DAY} ${R_HOUR}:${R_MIN}:${R_SEC}", "$FACILITY", "$LEVEL", "$HOST", "$PROGRAM", "$PID", "$MSGONLY")

indexes()

);

};

log {

source(s_net); source(s_src); filter(f_no_debug); destination(d_newmysql);

};

Achtet auf die 3 Stellen wo der User, Passwort und der Datenbankname eingetragen werden muss.

In /etc/default/syslog-ng noch eine Kleinigkeit anpassen

SYSLOGNG_OPTS="-–no-caps"

Nun Syslog NG neustarten

 service syslog-ng restart

Locale prüfen

Es sollte unbedingt noch locale mittels $locale -a geprüft werden. Der Output sollte in etwa so aussehen

locale -a

C

C.UTF-8

de_DE.utf8

POSIX

Falls hier kein de_DE.utf8 steht,  müsst Ihr noch ein dpkg-reconfigure locales durchführen und de_DE.utf8 nachinstallieren. Andernfalls wird das Webinterface nicht richtig funktionieren da die Sprachen vom System abgegriffen werden.

Cronjob einrichten

Auf jeden Fall sollte man noch den Cron installieren um die Datenbank nicht zu zu müllen. Bei uns speichern wir nur die Eintrage der letzten 40 Tage. Sehr empfehlenswert wenn man die Masse der Einträge bedenkt die da zusammenkommen können. Anders gesagt, wer braucht schon uralte Einträge. Meist sind ja doch nur die letzten Stunden / Tage interessant.

Hier der Cron den man mittels crontab -e einfügen kann

0 1 * * * /opt/scripts/lggr_clean

Mit diesem wird lediglich ein Script aufgerufen welches wie folgt aussieht

#!/bin/bash

mysql -u loggeradmin -p"SET_PASSWORD" "logger" << EOF

DELETE FROM Week WHERE date < DATE_SUB(NOW(), INTERVAL 40 DAY);

DELETE FROM newlogs WHERE date < DATE_SUB(NOW(), INTERVAL 40 DAY);

quit

EOF

Client Einrichtung

Auf den meisten Servern sollte dies relativ einfach sein, da rsyslog wohl auf ziemlich jedem System bereits läuft.

Dort muss einfach in /etc/rsyslog.conf folgende Zeile am Anfang eingefügt werden

 *.* @IP-OF-LOGGER-HOST            # UDP auf den default Port 514 

Damit wären die wichtigstens Logs bereits enthalten und Rsyslog ist ja beliebig erweiterbar.

Sollte man den Syslog NG als übermittler nutzen wollen, so kann man dies auf dem Client wie folgt.

 apt-get install syslog-ng 

Anschließend eine Datei Namens 10logger-client.conf erstellen mit diesem Inhalt

destination d_net { udp("IP-OF-LOGGER-HOST" port(514) log_fifo_size(1000)); };

log { source(s_src); destination(d_net); };

In beiden Fällen muss natürlich die IP eures Lggr Servers eingesetzt werden wo der Syslog-ng Server konfiguriert wurde.

Zudem muss natürlich der entsprechende Dienst neugestartet werden.

Also entweder oder 

service syslog-ng restart

service rsyslog restart

 

Somit haben wir den Server installiert und den ersten Client eingerichtet. Infolgedessen könnt Ihr das Webinterface aufrufen und eure ersten Einträge bewundern aber behaltet die Performance im Auge. Je nachdem wie hoch die Anzahl der Einträge ist, benötigt der Apache ein wenig mehr Ram andernfalls könnte die Ladezeit ein wenig hoch gehen. Kurzum habt Ihr anschließend einen Logviewer ohne dabei Java oder sonst etwas zu benötigen.

 

Share it!Share on FacebookEmail this to someoneShare on Google+Tweet about this on Twitter

28 Gedanken zu “Anleitung: Zentraler Logserver mit Syslog NG, MySQL und Lggr Webinterface

  1. Danke für die Anleitung. Top!
    Funktioniert auch soweit, bis auf wenn ich die Logs der pfSense auch drauf loggen möchte.
    Dann kommt folgende Fehlermeldung:
    Mar 9 12:03:26 syslog syslog-ng[521]: Error running SQL query; type=’mysql’, host=’192.168.78.111′, port=”, user=’logger’, database=’logger’, error=’1366: Incorrect integer value: \’\’ for column \’pid\’ at row 1′, query=’INSERT INTO newlogs (date, facility, level, host, program, pid, message) VALUES (\’2018-03-09 12:03:26\’, \’local0\’, \’info\’, \’192.168.78.1\’, \’filterlog\’, \’\’, \’9,,,1000000103,igb2,match,block,in,4,0×0,,2,0,0,DF,17,udp,165,192.168.1.168,239.255.255.250,34735,1900,145\’)’

    Kann mir da einer helfen?

  2. Danke für dein Feedback 🙂

    Pfsense gibt hier keine pid mit.

    Wenn du im Script diese Zeile anpasst, sollte es gehen
    values(“${R_YEAR}-${R_MONTH}-${R_DAY} ${R_HOUR}:${R_MIN}:${R_SEC}”, “$FACILITY”, “$LEVEL”, “$HOST”, “$PROGRAM”, “$PID”, “$MSGONLY”)
    in
    values(“${R_YEAR}-${R_MONTH}-${R_DAY} ${R_HOUR}:${R_MIN}:${R_SEC}”, “$FACILITY”, “$LEVEL”, “$HOST”, “$PROGRAM”, “000”, “$MSGONLY”)

  3. Super, vielen Dank, es funktioniert!

    Ein kleines Anzeige-Problem habe ich noch auf meinem iPad.
    Und zwar das Menü „Server Status und Filter…“ verschwindet hinter dem Hauptmenü und ist nicht ansteuerbar.
    Auf dem iPhone6 funktioniert es tadellos.

  4. Hi Patrick,

    sehr gern, wenns läuft passts 😉

    Das Problem auf dem iPad fiel mir so leider gar nicht auf da ich “nur” ein iPad Pro habe.
    https://www.dl-host.info/downloads/filemanager.php?file=scripte/ipad_server_info_fix.rar
    In dem File ist ein Order mit einer CSS, wenn du diese mit deiner hochgeladenen CSS überschreibst, sollte auch dieses Problem gelöst sein.
    Ich integriere das jedoch nicht in die Hauptdateien da ich vermute, dass 99% es am PC nutzen 🙂

    LG
    André

  5. #1
    Es gibt hier eine Fehlermeldung bzgl. nicht vorhandener Table:

    >>
    mysql -u root -p >
    ERROR 1146 (42S02) at line 11: Table ‘logger.servers’ doesn’t exist

    #2
    Nach Anmeldung (die .htaccess geht) beim Aufruf der Webseite bleibt diese leider komplett leer.

    #3 Es gibt offenbar Differenzen bzgl. des Datenbanknamens – “LOGGER” hier im Script und “LGGR” in den Konfigdateien.

    #4 Die Datenbankverbindung klappt nicht am Ende:
    (HY000/1045): Access denied for user ‘logviewer’@’localhost’

    🙁

  6. Hi André,

    bevor ich anfange dieses Tutorial zu befolgen, weißt du ob ich das 1 zu 1 auf einen RasPi 3+ nachstellen kann?

    LG
    Ein anderer André

  7. Hallo,

    ich habe Heute die Anwendung auf Debian 9.5 installiert. Nach mehren versuchen habe ich gemerkt das noch ein
    a2enmod rewrite && service apache2 restart notwendig ist. Jetzt werden die Logeinträge angezeigt, aber nicht mit Grafig, sondern nur als Liste. (Siehe unten)
    Muss noch etwas inApache2 aktiviert werden oder liegt der fehler ganz woanders?

    Würde mich freuen wenn jemand helfen kann.

    Gruß
    Thomas

    —SNIP—
    DL-Host

    Echtzeit
    Statistik
    Archiviert
    Sugar-Camp

    Server Status und Filter …
    Level
    96%
    2%
    1%
    0%

    Verteilung der gewählten Level.

    Server

    • Hi Thomas,
      eigentlich ist nicht mal mod rewrite notwendig aber das hängt natürlich von deinem Server und configs im Detail ab.
      Hast du mal einen Link? Du kannst den auch gern per Mail schicken.

      LG
      André

  8. Hallo André,

    bin doch noch dahinter gekommen. Der richtige Eintrag in der /var/www/html/logger/inc/config_class.php laudet “/logger/contrib/..”
    Ohne mod rewrite stand inm log : “… /var/www/html/logger/.htaccess: Invalid command ‘RewriteRule’, perhaps …”
    Server ist eine frisch aufgesetzt VM mit Debian 9.5. Ich bin mir nicht 100% sicher aber bei Debian 9.4 hatte ich dieser Probleme nicht. Allerdings habe ich das ISO gelöscht und kann es nicht mehr testen.

  9. Hallo André,

    habe die Lösung gefunden. Ich habe die Dateien nach /var/www/html/logger installiert. Danach war in der Datei inc/config_class.php
    der Eintrag ‘/contrib/bootstrap/’ falsch. Muss jetzt ‘/logger/contrib/bootstrap/’ heißen.
    Das mod rewrite deaktiviert werden muss scheint ein feater von Debian 9.5 zu sein. Dadurch bin ich nur einige Stunden im Kreis gelaufen bis ich die Lösung gefunden habe.
    Vielen Dank für dein Angebot mit der Mail, jetzt funktioniert es ja.

    Gruß,
    Thomas

  10. Hallo,

    erstmal vielen Dank für die Anleitung. Ich habe sie Schritt für Schritt abgearbeitet. Dabei sind mir ein paar Dinge aufgefallen:
    1. chown www-data:www-data /var/www/html/logger/cache/ –> das Verzeichnis …/logger/cache habe ich erstellt, da nicht vorhanden. War das ok?
    2. Was befindet sich alles unter /var/www/html/logger ? Ist da nur das Verzeichnis cache zu finden oder mehr? Das Verz. logger habe ich wie gesagt per mkdir angelegt, da nicht vorhanden.
    3. Der Aufruf der Website im Browser hat nicht geklappt. Im error-log vom Apache steht: “/var/www/html/.htaccess: Invalid command ‘RewriteRule’, perhaps misspelled or defined by a module not included in the server configuration”. Ich habe in der .htaccess nichts geändert. Was mache ich falsch?
    So sehen meine Verzeichnisse und Dateien unter /var/www/html/ aus:
    root@backup2:/var/www/html# ll
    insgesamt 124
    drwxr-xr-x 14 root root 4096 Sep 7 23:02 ./
    drwxr-xr-x 3 root root 4096 Sep 7 21:31 ../
    drwxrwxr-x 2 root root 4096 Sep 7 21:15 admin/
    -rw-rw-r– 1 root root 505 Nov 24 2017 api.php
    -rw-rw-r– 1 root root 3461 Nov 24 2017 archived.php
    drwxrwxr-x 2 root root 4096 Sep 7 21:15 cache/
    drwxrwxr-x 8 root root 4096 Sep 7 21:15 contrib/
    drwxrwxr-x 2 root root 4096 Sep 7 21:15 css/
    drwxrwxr-x 2 root root 4096 Sep 7 22:37 doc/
    -rw-rw-r– 1 root root 2371 Nov 24 2017 do.php
    -rw-rw-r– 1 root root 15086 Nov 24 2017 favicon.ico
    -rw-rw-r– 1 root root 941 Nov 24 2017 .htaccess
    drwxrwxr-x 2 root root 4096 Sep 7 21:15 icos/
    -rw-rw-r– 1 root root 789 Nov 24 2017 ids.php
    drwxrwxr-x 2 root root 4096 Sep 7 21:15 img/
    drwxrwxr-x 2 root root 4096 Sep 7 22:44 inc/
    -rw-r–r– 1 root root 10918 Sep 7 20:54 index.html.orig
    -rw-rw-r– 1 root root 11779 Nov 24 2017 index.php
    drwxrwxr-x 2 root root 4096 Sep 7 21:15 js/
    -rw-rw-r– 1 root root 2535 Nov 24 2017 live.php
    drwxrwxr-x 5 root root 4096 Sep 7 21:15 locale/
    drwxr-xr-x 3 root root 4096 Sep 7 21:45 logger/
    -rw-rw-r– 1 root root 2003 Nov 24 2017 stats.php
    drwxrwxr-x 2 root root 4096 Sep 7 23:23 tpl/

    In /var/www/html/logger/ ist nur cache/ zu finden.

    Das Lggr Webinterface habe ich von hier runtergeladen.

    Würde mich über ein bisschen Unterstützung sehr freuen.

    Servus
    Peter

    • Hi Peter,
      in dem Verzeichnis befinden sich alle Dateien die für das Webinterface benötigt werden. Die sind auch in dem Archiv enthalten 🙂
      a2enmod rewrite würde den anderen Fehler beheben.

  11. Hallo,

    meine Antwort vom 3.9. erscheint hier leider nicht.
    In der neuesten Version von Debian scheint mod_rewrite defauld deaktiviert zu sein, muss also manuell aktiviert werden. Mein Fehler war, das ich Pfade falch angepasst hatte.

    Thomas

  12. Bei mir werden unter den Filter leider keine “Server” angezeigt – somit kann ich auch nicht danach filtern.
    Jemand eine Idee? Vielen Dank

    Grüße
    Philipp

  13. Hallo zusammen,

    ich habe den Server mit der Anleitung soweit aufgesetzt und es scheint auch soweit zu funktionieren. Ich möchte gerne an den Log-Server meine interne Firewall anbinden. Verständlicherweise schickt die Firewall andere Logs als ein Server. Wie kann ich die “Auswertung” so anpassen, dass in der Webansicht eine “nette” Analyse der Firewall-Daten wie z.B. HTTP/HTTPS-Traffic angezeigt wird?
    Vielen Dank!

    Grüße
    Andre

  14. Hallo zusammen,

    wie und wo kann ich einstellen, was er aus dem Syslog von dem Device in die Tabellen einordnet?
    Ich möchte das ganze gerne für meine private Firewall einsetzten. Das empfangen und verwerten der Logs klappt soweit nur die Darstellung passt halt nicht ganz wie ich mir das vorstelle. Es soll ausgewertet werden, wer wann was wo gesurft hat und das halt in der Tabelle schön grafisch 🙂
    Ich weiß, ein Vater der sich mit IT auskennt, kann ganz schön fies sein 😉

    • Der ist wirklich schwierig. Du müsstest nicht nur das Logging in der Firewall aktivieren sondern auch die Datenbank anpassen.

      Schöner wäre hier vermutlich Grafana als Oberfläche.

  15. Hi Andre,

    danke für die tolle Anleitung. Ich habe ein kleines Problem mit der Web Gui. Wenn ich versuche nach “Server” zu filtern erscheint bei dem Dropdown-Menü nur ein kleines weißes Rechteck. Somit lässt sich der Filter nicht aktivieren. Habe ich in der Anleitung etwas übersehen, oder ist es etwas anderes?

    Vielen Dank vorab und viele Grüße
    STefan

    • Hi Stefan,

      gerne gerne und danke für die Blumen.
      Das klingt für mich nach einem Problem eines fehlenden CSS oder sowas… Kannst du mir vielleicht einen Link und Login per Mail schicken?

  16. Das mit der Datenbank anpassen ist ja erstmal kein Problem. Ich würde halt nur gerne wissen welche config Datei ich anpassen muss, damit ich die Message von der Firewall in “Häppchen” aufteile und in einzelne Spalten der Datenbank einpflegen kann.

    • Naja wenn du syslogng verwendest dann über die config Datei… genauer diese Stelle
      [code]
      columns("date", "facility", "level", "host", "program", "pid", "message")

      values("${R_YEAR}-${R_MONTH}-${R_DAY} ${R_HOUR}:${R_MIN}:${R_SEC}", "$FACILITY", "$LEVEL", "$HOST", "$PROGRAM", "$PID", "$MSGONLY")
      [/code]

Schreibe einen Kommentar