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