Probleme mit syslog-ng & Speichern in MySQL

C

Cupid0

UNIX-Neuling
Hallo Community,

erstmal vorweg, ich bin UNIX-Einsteiger.

Also ich habe ein OpenBSD 3.6 i386.
Habe darauf einen Apache, php4, mysql4.0.20 laufen.
Und syslogd hab ich durch syslog-ng1.6.4 ersetzt.

Nun möchte ich gerne die Syslogs in meine MySQL Datenbank speichern!

Habe mir mal sqlsyslog angeschaut(http://www.frasunek.com/sources/security/sqlsyslogd/):
dabei würde meine syslog-ng.conf so aussehen:
Code:
source src {udp();};

destination sqlsyslog-ng{
progamm("/usr/local/sbin/sqlsslogd -u sqlsyslogd --database syslog -t logs -p ");
};

log {
        source(src);
        destination(sqlsyslog-ng);
};

Das programm dass dabei ausgeführt wird ist (werden sollte) ist ein Script von sqlsyslog
Code:
/*
*
* sqlsyslogd
*
* $Log: sqlsyslogd.c,v $
* Revision 1.2  2002/01/05 16:29:36  venglin
* Bugfix
*
* Revision 1.1.1.1  2001/05/21 15:31:50  venglin
* initial import into CVS
*
* Modified 2002 by RPI, ProBIT AG (change parsing to allow for the <xx>
prefix with syslog-ng used at our site...)
*
*/

#include <mysql/mysql.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <pwd.h>
#include <sys/types.h>

#define CR                     13
#define LF                     10

MYSQL db;

static const char rcsid[] =
  "$Id: sqlsyslogd.c,v 1.2 2002/01/05 16:29:36 venglin Exp $";

void usage(av0)
char *av0;
{
             fprintf(stderr, "usage: %s [-h hostname] <-u username> [-p]"
                                                 " <-t table> [database]
\n\n", av0);
             exit(0);
}

void cleanup(x)
int x;
{
             mysql_close(&db);
             exit(0);
}

char *password(void)
{
             FILE *fp;
             static char passwd[BUFSIZ/16];
             char *p;

             if ((fp=fopen(CONF, "r")) == NULL)
                         return NULL;

             fgets(passwd, sizeof(passwd), fp);

             if ((p = index(passwd, CR)))
                         *p = '\0';
             if ((p = index(passwd, LF)))
                         *p = '\0';

             fclose(fp);

             return passwd;
}


int main(argc, argv)
int argc;
char **argv;
{
             extern char *optarg;
             extern int optind;
        int ch;
             char buf[BUFSIZ], querybuf[BUFSIZ+100];
             char *loghost, *host, *user, *passwd, *av0, *table, *logprog,
*logmesg, *logdump, *logtime, *logmont, *logdays;
             struct passwd *pw;
             gid_t nobodygid;
             uid_t nobodyuid;

             av0 = argv[0];
             loghost = host = user = passwd = table = logprog = logmesg =
logdump = logtime = logmont = logdays = NULL;

             while ((ch = getopt(argc, argv, "h:u:pt:")) != -1)
                         switch((char)ch)
                         {
                                     case 'h':
                                                 host = optarg;
                                                 break;

                                     case 'u':
                                                 user = optarg;
                                                 break;

                                     case 'p':
                                                 passwd = password();
                                                 break;

                                     case 't':
                                                 table = optarg;
                                                 break;

                                     case '?':
                                     default:

(void)usage(av0);
                         }

             argc -= optind;
             argv += optind;

             if (!user || !table)
                         (void)usage(av0);

             if (argc < 1)
                         (void)usage(av0);

             if ((pw = getpwnam("nobody")) == NULL)
             {
                         perror("getpwnam");
                         exit(1);
             }

             nobodyuid = pw->pw_uid;
             nobodygid = pw->pw_gid;

             if (setgid(nobodygid) == -1)
             {
                         perror("setgid");
                         exit(1);
        }

             if (getgid() != nobodygid)
             {
                         fprintf(stderr, "getgid() != nobodygid\n");
                         exit(1);
             }

             if (setuid(nobodyuid) == -1)
             {
                         perror("setuid");
                         exit(1);
             }

             if (getuid() != nobodyuid)
             {
                         fprintf(stderr, "getuid() != nobodyuid\n");
                         exit(1);
             }

             mysql_init(&db);

             if (!mysql_real_connect(&db, host, user, passwd, *argv, 0,
NULL, 0))
             {
                         fprintf(stderr, "failed to connect to database:
%s\n",
                                     mysql_error(&db));
                         exit(1);
             }

             signal(SIGHUP, cleanup);
             signal(SIGINT, cleanup);
             signal(SIGQUIT, cleanup);
             signal(SIGTERM, cleanup);
             signal(SIGSEGV, cleanup);
             signal(SIGBUS, cleanup);

             while(fgets(buf, sizeof(buf), stdin))
             {
                         if (strlen(buf) > 18)
                         {
                                     logdump = strtok(buf, ">");  // <xx>
                                     logmont = strtok(NULL, " "); // month
                                     logdays = strtok(NULL, " "); // day
                                     logtime = strtok(NULL, " "); // time
                                     loghost = strtok(NULL, " "); // host
                                     logprog = strtok(NULL, ":"); //program
                                     logmesg = buf + 8 + strlen(logdump) +
strlen(logmont) + strlen(logdays) + strlen(logtime) +

strlen(loghost) + strlen(logprog);

                                     if (loghost && logprog && logmesg)
                                     {
                                                 snprintf(querybuf,
sizeof(querybuf),
                                                             "INSERT INTO
%s (timestamp, host, prog, mesg) VALUES ('%s %s %s', '%s', "
                                                             "'%s', '%s')",
table, logmont, logdays, logtime, loghost, logprog, logmesg);

                                                 if (mysql_query(&db,
querybuf))

fprintf(stderr, "failed to run query: %s\n", mysql_error(&db));
                                     }
                         }
             }

             mysql_close(&db);

             exit(0);
}
(http://www.frasunek.com/sources/security/sqlsyslogd/contrib/sqlsyslogd-for-syslogng).

Also das war irgendwie die einzige Lösung sqlsyslog zum laufen zu bringen die mir einfiel. Ein Install-Skript gibt es da ja nicht wirklich und das MakeFile-Skript jammert immer nur rum dass die Befehle unbekannt sind.

Alternativ dazu habe ich auf http://vermeer.org/docs/1 noch eine ganz interessante Anleitung gefunden ähnlich wie sqlsyslog aber dort steht auch ausdrücklich dabei dass das Template() nur in v1.5 vorhanden ist und zudem kapier ich das mit dem mysql.pipe nicht.

Hoffe ihr könnt mir irgendwie helfen, ich bin nun seit drei Tagen am verzweifeln.

LG
Cupi
 
Öhm, ich kenn jetzt den syslog.nd nicht. aber das Programm hier ist kein Script sondern C-Code. Der sollte halt erstmal compiliert werden ;)

//Edit:
Hab mir grad nochmals den syslogd angeschaut. Da ist auch ein makefile dabei um den syslogd zu compilieren. Hast Du das runtergeladen und mittels "make && make install" installiert ?
 
Zuletzt bearbeitet:
Nein habe ich noch nicht gemacht. Sorry wie oben erwähnt ich bin neu in UNIX&Linux und habe noch so gut wie keine Ahnung.
Bisher war mir nur ./configure bzw ./install bekannt, soweit die Files natürlich da sind.

Welches Make-File meinst du?
Und muss vor das make && make install noch ein ./ ??
 
Danke Cybermark, hat mir sehr weitergeholfen UNIX besser kennen zu lernen


aber meine Logs sind immernoch nicht in der Datenbank *lach*

Habe wie oben schon erwähnt per program() das Script gestartet (auch mit pipe() komm ich nicht weiter).

Hab mich aber nen bisschen mit dem HowTo hier im Forum beschäftigt
(http://www.unixboard.de/vb3/showthread.php?t=9697) und nun weiß ich wenigstens was ein cronjob ist und hab das mit den pipes halbwegs verstanden.

Habe dank dem HowTo auch die Daten jetzt in der Datenbank.

Weiß jemand zufällig wie ich die $MSG in Stücke teilen kann?
Bei mir kommen Daten an, von einer Firewall. In der MSG sind daher mindestens zwei IPs, ne Regel, ne Aktion, etc vorhanden. Da ich das später in einem Webinterface ausgeben will und von Users sortieren lassen will, muss ich irgendwie die MSG teilen um diese somit einzeln in den Feldern zu haben.


LG
Cupi
 
Kannst Du mal ne kleine Ausgabe von $MSG posten und evtl. gleich mal sagen, wie es aufgeteilt werden soll?
 
Hier siehste des Log. Vor der 17162 kommt evtl. noch der Datenteil von Syslog hinzu (Host, Timestamp, etc.)
Ich brauche wenn möglich alle beschrifteten Teile in einer extra Spalte. Aber die Rot markierten (inkl "action") sind besonders wichtig

http://www.cupido-on-web.de/syslog.jpg

Also habe jetzt einige Methoden ausprobiert aber irgendwie komme ich mit keiner Methode auf nen grünen Zweig.
Ich probiere jetzt mal ein php-skript zu entwerfen.
Sollte das php laufen (inkl Variablenübergabe) wäre die Teilung von $MSG auch kein großes Problem mehr.
 
Hab jetzt mal bissl von abgesehen die $MSG aufzuteilen, das kommt später nocht, ist leider bissl schwieriger als ich dachte.
Hab stattdessen grad ein anderes Problem :(
Ich kopiert hier grad mal meinen Post ausm PHP Forum:

Hab hier ein kleines Script geschrieben das auch normal funktioniert. Habe es auf einer Windows-Oberfläche geschrieben und per SSH auf meine OpenBSD-Server-Kiste gezogen.

Ja viele würden mich dafür schlagen *grins* Aber die Rechte hab ich auf 777 gesetzt und chown=root und chgrp=wheel

Nun habe ich das Problem, dass ich dieses Script nicht ausführen lassen kann.
Das Script liest eigentlich nur einige Zeilen aus einem File aus und schreibt die Daten als String pro zeile in eine Datenbank.
Wie oben erwähnt funktioniert das Script auch wenn ich es unter Windows laufen lasse.

Habe über Konsole folgendes probiert:
wget http://localhost/phptest.php
php http://localhost/phptest.php
(jeweils mit und ohne > /dev/null)

Habe dasselbe auch in einem Cronjob (als root) stehen der jede Minute ausgeführt wird aber das klappt leider auch nicht.
Habe grad noch versucht von Win per Browser das File (Auf der BSD-Kiste) aufzurufen und musste enttäuschend feststellen dass nichtmal da das File korrekt ausgeführt wird.

Hier mal mein Script:

Code:
<?php
$dbhost="localhost";
$dbuser="root";
$dbpw="password";
$dbdatabase="bla";
$dbtable="bla";
$pipefile="/mysql.pipe"; // Pfad zur temp-Datei in der die Syslogs liegen

if (file_exists($pipefile)) {        // Prüfung ob File existiert

$fp = fopen($pipefile, "r"); // File öffnen und Zeiger an Anfang der Datei setzen
$db=mysql_connect($dbhost,$dbuser,$dbpw);
mysql_select_db($dbdatabase, $db);

while (!feof($fp)) { // Solange mach dies bis Zeiger $fp am Ende der Datei

	$data=fgets($fp);
	mysql_query("INSERT INTO $dbtable (blub) VALUES ('$data')", $db);
	
}

fclose($fp); // File schließen
$outputdb=mysql_query("SELECT * FROM $dbtable LIMIT 0 , 30", $db); //Inhalte des Table auswählen
mysql_close($db);
// START Ausgabe des Table in einer Tabelle
echo "<table>\n";
echo "Datenbankeinträge<br>";
while ($line = mysql_fetch_array($outputdb, MYSQL_ASSOC)) {
    echo "\t<tr>\n";
    foreach ($line as $col_value) {
        echo "\t\t<td>$col_value ||</td>\n";
    }
    echo "\t</tr>\n";
}
echo "</table>\n";
// ENDE Ausgabe Table
} else

// START File erstellen
tempnam('$pipefile',"FOO");
$fp = fopen($pipefile, "w");
fwrite($fp, "");
fclose($fp);
// END File erstellen

echo("<hr>ENDE");
?>
 
Andere Scripts funktionieren? Oder ist evtl. dein Environment noch nicht nicht sauber?
 
Is ne gute Frage. Werd am Montag gleich mal ausprobieren (weil ich am Wochenende nicht im Geschäft bin*g*)
 
Also hab mal ein billiges Script ausprobiert.
Diesmal funktioniert es über die Konsole. (das oben stehende Script funktionierte nichtmal in Konsole)
Aber in Cronjob funkt. das billig-script immernoch nicht :hilfe2:

Hab nen Cron als root.
und ganz normal per crontab -e aufgerufen und die Zeile wget http://localhost/crontest.php > /dev/null eingegeben.
Mal abgesehen davon dass es früher oder später von User root weg muss, sollte das doch so korrekt sein, oder?

wget nebenbei issn Browser

ich probiers kurz mal mitm php-compiler
 
Ich kenn wget ;)

So, also die vorgehensweise mit cron ist soweit korrekt, der Aufbau der crontab wie folgt:
Code:
min  hour  day  month  dow  user  command
1         *       *         *           *    root  'wget http://localhost/crontest.php > /dev/null'
Ich geh mal davon aus, dass es bei dir so passt, aber das ist ja auch mom. nicht das Problem.
PHP:
$pipefile="/mysql.pipe"; // Pfad zur temp-Datei in der die Syslogs liegen
Liegt diese Datei im root-dir? Oder sollte das eher "./mysql.pipe" sein, weils im gleichen Verzeichnis liegt ?Und wenns im root-dir liegt, hast Du da überhaupt die entsprechenden Rechte für ?
Ansonsten macht er ja weiter mit
PHP:
tempnam('$pipefile',"FOO");
welches aber je nach Version systemabhängig ist. Darin wird bei Dir wahrscheinlich auch der Hund begraben sein.
php-doku schrieb:
Erzeugt eine Datei mit einem eindeutigen Dateinamen in dem spezifizierten Verzeichnis. Wenn das Verzeichnis nicht existiert, erstellt tempnam() eine Datei im temporären Verzeichnis des Systems, und gibt den Dateinamen zurück.

Vor PHP 4.0.6 war das Verhalten von tempnam() systemabhängig. Unter Windows wird die TMP-Umgebungsvariable den dir Parameter überschreiben, unter Linux-Systemen hat die TMPDIR Umgebungsvariable Vorrang, während SVR4 immer den spezifizierten Verzeichnisnamen benutzen wird, wenn dieses existiert. Wenn Sie nicht genau wissen, wie Ihr System tempnam() behandelt, dann konsultieren Sie bitte Ihre System-Dokumentation.
Erläuterung: http://de.php.net/manual/de/function.tempnam.php

Check das mal, vielleicht wars das ja schon.
 
Zuletzt bearbeitet:
hm jo Rechte sind alle i.o. weil ich eh als root eingelogt bin.

btw. ich hab den Fehler alleine rausgefunden. Es lag ausschließlich daran, dass ich bei wget bzw später auch beim php-compiler den korrekten Pfad vergessen habe.

also /usr/local/bin/wget bzw /usr/local/bin/php http://www.blabla.de/script.php

Danke trotzdem vielmals für die Hilfe :)
 

Ähnliche Themen

Unix Webserver mit HTML Seite erstellen

dovecot und postfix Konfiguration Problem

Xubuntu - AVR32-linux crosscompile sqlite

Segmentation Fault bei strcat?

noch eine zeichenkette^^

Zurück
Oben