xinetd - stderr loggen

kroimon

Registered User
Hi!

Ich habe das Problem, dass bei einer Standard-Plesk-Installation (zumindest bei server4you) der qmail-smtpd ja per xinetd gestartet wird.
Nun ist qmail (und seine addons/patches) ja eigentlich darauf ausgelegt, Fehler einfach nach stderr zu schreiben und es wird davon ausgegangen, dass diese dann geloggt werden (beispielsweise per syslog).
xinetd allerdings leitet sowohl stdout als auch stderr einfach über das Socket weiter.
Gibt es eine Möglichkeit, bei xinetd die Ausgaben auf stderr nicht auf das Socket, sondern in ein Logfile oder an syslog weiterzuleiten?

Wenn es nichts fertiges gibt, gibt es eine Möglichkeit, selbiges durch ein kurzes C Programm zu erreichen?

Wäre euch für eure Hilfe sehr dankbar!
 
Du hast einen kleinen Fehler drin. Bei (x)inetd dienen stdin & stdout der Kommunikation über die TCP-Schnittstelle. Qmail (hier qmail-smtpd bzw. qmail-inject) nutzt zur Interprozess-Kommunikation Pipes. Die aufgerufenen Programm lesen wieder von stdin und schreiben weiter nach stdout. Für das Logging und (Errorreporting) liefert Qmail einen eigenen qlogger mit, der die Fehlermeldungen (i.d.R.) an Syslog weiter gibt.

Mit diesen Zusatzinformationen versuch Deine Frage bitte nochmal neu zu formulieren.

huschi.
 
Aaalso...
Die "qmail-Basis", also der folgende Prozessbaum:
Code:
qmail-send
├─qmail-clean
├─qmail-lspawn ./Maildir/
├─qmail-rspawn
└─splogger qmail
wird durch das Script /etc/init.d/qmail gestartet.
Dabei werden afaik der stderr Datenstrom auf den stdin des splogger Prozesses umgebogen, der jegliche Daten von seinem stdin wiederrum per syslog() loggt.
Status-Meldungen und eventuelle Fehler während der eigentlichen Mail-Verteilung sind also in der Log-Datei nachzuvollziehen.

Der Mail-Eingang per SMTP jedoch geschieht außerhalb dieser geschlossenen "Basis", nämlich per xinetd. Dabei wird einfach bei jeder eingehenden Verbindung auf Port 25 folgender Befehl ausgeführt (mit Plesk-Erweiterungen):
Code:
/var/qmail/bin/tcp-env -Rt0 /var/qmail/bin/relaylock /var/qmail/bin/qmail-smtpd /var/qmail/bin/smtp_auth /var/qmail/bin/true /var/qmail/bin/cmd5checkpw /var/qmail/bin/true
tcp-env besorgt ein paar Informationen über die TCP-Verbindung und speichert diese in Umgebungsvariablen. Dann nimmt es die ihm übergebenen Parameter und führt sie aus.
relaylock ist eine Plesk-Erweiterung, die in der Plesk Datenbank bei aktiviertem "POP before SMTP" nachschaut, ob der Remote-Host überhaupt Mails versenden darf, wenn ja wird die Umgebungsvariable $RELAYHOST gesetzt, qmail-smtpd nimmt dann auch Mails für Domains an, die nicht in der rcpthosts-Datei als lokale Domains angegeben sind.
Dann erst wird der eigentliche zu qmail gehörende SMTP-Dienst qmail-smtpd ausgeführt, der die Kommunikation mit dem Client übernimmt (die restlichen Parameter dienen der Authentifizierung).

Und genau hier liegt das Problem:
Die qmail-Programme gehen davon aus, dass ihre Standard-Kommunikation über die Filedeskriptoren 0 und 1 (stdin und stdout) läuft, auftretende Fehlermeldungen aber über 2 (stderr) ausgegeben werden können. Diese sollten dann laut dem eigentlichen Konzept von qmail geloggt werden (wie es oben beschrieben in der "Basis" ja auch geschieht).
Da xinetd aber sowohl stdout als auch stderr über den TCP/IP-Strom an den Client sendet, werden von qmail-Komponenten ausgegebene Fehlermeldungen an den Client, nicht aber ins Log geschrieben.

SWsoft hat das bei seiner fixen Idee, xinetd für SMTP zu nutzen, nicht bedacht. Wohl aber haben sie ihrem qmail-smtpd den qmail-spp Patch spendiert, der SMTP-Plugins erlaubt (SWsoft benutzt standardmäßig sogar eines, siehe Datei control/smtpplugins: plugins/chkrcptto).
Wie der Dokumentation von qmail-spp zu entnehmen ist, sollen Plugins ihre Fehler nach stderr schreiben, diese würden geloggt:
Code:
They:
    * should not read anything from standard input,
    * can print commands on standard output,
    * should print all errors to standard error (they are logged),
    * should not exit with error code 120.

Wenn ich jetzt also ein Plugin verwenden will (wie in meinem konkreten Fall ein angepasstes Greylisting-Plugin, weil ich nicht auf das hardgecodete Greylisting hier im Forum zurückgreifen möchte und etwas mehr Komfort bei den white/blacklists brauche), dann möchte ich mich drauf verlassen können, dass diese Konvention eingehalten wird.

Die ursprüngliche Frage war also, ob es beim xinetd eine Möglichkeit gibt, stderr nicht über den TCP-Stream, sondern in ein Log zu schreiben. Das das standardmäßig wohl nicht geht, habe ich inzwischen herausgefunden.
Nun bin ich dabei, mir in C einen kleinen Wrapper zu schreiben, der in der bei xinetd eingetragenen Commandline des Servers an erster Stelle steht, und der den stderr Strom über eine pipe selbst behandelt und Zeilenweise loggt.
Das funktioniert schonmal ganz gut, ich muss nur noch testen, ob das Zusammenspiel mit xinetd geht, da ich ja nicht nur wie tcp-env und relaylock mit exec() das Prozessimage überschreibe, sondern einen Child-Prozess fork()en muss und ich mir unsicher bin, ob xinetd dann die stdin/stdout Ströme noch bekommt, was ich aber eigentlich glaube.

Mal sehen ob ich swsoft mal anschreibe mit meinem kleinen Programm, ob die sich nicht da an die qmail Konventionen halten wollen, wenn sie es schon verwenden =)

So far...
Gruß Stefan
 
Ah, jetzt wird einiges klarer.
Aber nein, dem ist nicht so.
Deine Vorwürfe gegenüber Plesk und der non-konformität stehen und fallen mit folgender Aussage:
qmail-spp said:
* should print all errors to standard error (they are logged)
a) Die Aussage steht nur dort. Nirgendwo sonst ist von Qmail ein Logging per STDERR erwähnt.
b) Letzteres ist auch nicht umgesetzt.

Schau Dir einfach den Code von SPP an. Entweder das Diff im Download oder den Plesk Qmail-Src den Du z.B. inkl. dem Greylisting von huschi.net laden kannst.
Dort findest Du eine qmail-spp.c

Weder in der Funktion "spp()", welches die Plugins aufruft, noch sonstwo in Qmail (weder original noch in weiteren Erweiterungen) wird STDERR umgeleitet.

Ergo fragt sich, warum steht es da?
Die Antwort ist: Der Autor von qmail-spp hat seinen Qmail mit tcpserver am laufen. Das ist wohl der einzige Super-Server, der STDERR nach syslog weiter gibt. (Aber auch nicht an MAIL sondern in die messages.)

Also mußt Du Dir die Mühe machen, syslog selber anzusteuern.

huschi.
 
Nirgendwo sonst ist von Qmail ein Logging per STDERR erwähnt.

Also wenn ich mir die qmail-start.c so anschaue, sehe ich da eine Menge Aufrufe der Funktion fd_copy, mit der soweit ich das verstehe, die Ausgabe-Streams der oben genannten "Basis" auf die stdin des übergebenen loggers umgebogen werden, also völlig unabhängig vom tcpserver.

In der qsutil.c existieren mehrere log* funktionen (deren Name je nach Patch-Stand etc variieren), die aber alle nach stderr loggen.

Das Konzept ist also durchaus vorhanden, und da standardmäßig der tcpserver verwendet wurde, hat das auch mit dem smtpd geklappt.
Ich würde das Prinzip also gerne so übernehmen.

Die einzige Variante dafür ist leider ein log-wrapper... Die Source kann ich ja morgen mal hier uppen, wer weiß wer es mal gebrauchen kann...
 
Du hast doch oben bereits die Trennung von Qmail als Mail-Scheduler (qmail-send) und qmail-smtpd als Port-Listener erwähnt.
(Siehe auch Qmail: Flußdiagramm - huschi.net )
Ich dachte, wir reden hier über die selbe Sache. Daher wundert es mich, daß Du nun mit Files kommst die alle nur im Mail-Scheduler Verwendung finden.
Ich glaub Du klammerst Dich hier an eine fixe Idee. :)

Hier findest Du eine Möglichkeit auch im qmail-smtpd auf Syslog zugreifen kann (siehe ganz unten: "praktisches Beispiel"):
Plesk/Qmail: Qmail selber kompilieren - huschi.net

huschi.
 
Hm mein Problem ist eben, dass der Mail-Scheduler auf logging per stderr aufbaut, und es nun im smtpd anders sein soll. Warum sollte es?

Ich denke, ursprünglich war die Idee (des/der Programmierer), dass es dort genauso funktionieren sollte (daher wohl auch die Angaben, dass spp plugins per stderr loggen können).
Es gibt auch eine Menge spp plugins, die eben dies tun, und sich drauf verlassen.
Mit der vom Entwickler angedachten Variante mit tcpserver funktioniert das eben auch.

Deshalb denke ich, wenn man den smtpd aus seiner "vorgesehenen Umgebung" rausnimmt und stattdessen mit xinetd betreibt, der dieses "Feature" nicht hat, sollte man darauf achten, dass es irgendwie ersetzt wird, damit man nicht mit der Kompatibilität bricht.

Das genau ist aber ja wohl geschehen, sonst würde es im Sinne der Erfinder stderr wie auch immer loggen =)

Ich hoffe, du verstehst was ich meine, ohne dass du denkst, ich will deine Kompetenz anzweifeln...

Gruß Stefan
 
Ist halt die Frage welcher Programmierer hier geschlafen hat...
Das schreiben auf STDERR ist in qmail-send nicht wirklich vorgesehen und wird auch so nicht genutzt. Qmail liefert hier seine eigenen Wrapper-Funktionen mit welche ausschließlich im Einsatz ist. Hier wird lediglich der dritte Dateideskriptor als Kommunikationsweg genutzt. Von einer "grundsätzlichen Nutzung von STDERR als Logger" kann in meinen Augen nicht die Rede sein. Denn man kann jederzeit den Wrapper entsprechend austauschen und schon kann man auf die STDERR-Pipe verzichten.

Und in qmail-smtpd und alle anhängenden Programmen und Erweiterungen ist ebenfalls keine STDERR-Ausgabe zu finden. (Obwohl es hier manchmal wünschenswert wäre...)

Ergo muß wohl der Entwickler von qmail-spp hier etwas geschlafen haben.
Wahrscheinlich mit seiner Behauptung in der Doku und den entsprechenden Beispielen für Plugins. Leider hat er eben nur mit tcpserver getestet. Wer hätte auch gedacht, daß Qmail - dank Plesk - mal eine so große Verbreitung erreichen würden. Und das ausgerechnet unter xinetd...

Ein Logging-Wrapper ist ja gut und schön. Aber ich persönlich würde eine saubere Implementierung der spp-Funktionen & -Plugins vorziehen.
Es ist nun wirklich kein großer Akt die Syslog-Funktion zu nutzen.

huschi.
 
Ein Logging-Wrapper ist ja gut und schön. Aber ich persönlich würde eine saubere Implementierung der spp-Funktionen & -Plugins vorziehen.

Hm ja hast eigentlich schon recht... Wie gesagt ich wollte halt eigentlich nach dem Gedanken des spp Programmierers vorgehen, aber ich denke ich werde wirklich einfach nach syslog loggen, ist wohl einfacher...

Meinen logwrapper (stderr => syslog) häng ich einfach mal hier dran, wer weiß, wer ihn mal gebrauchen kann...

Wenn ich mein Greylisting Plugin noch angepasst hab kann ich das ja bei Gelegenheit auch mal im Mail Forum posten.

*Stefan
 

Attachments

Back
Top