27. August 2026 7 Min. Lesezeit

smtp-source ohne Postfix-Installation: Lasttest-Werkzeuge aus dem RPM entpacken

smtp-source und smtp-sink gehören zu Postfix, laufen aber auch ohne installierten Mailserver. Wie Sie die beiden Werkzeuge auf RHEL aus dem Paket entpacken, warum die Ausführung aus /tmp an der Mount-Option noexec scheitern kann und welche Bibliotheken mitkommen müssen.

Für SMTP-Lasttests ist smtp-source eine gute Wahl: Das Werkzeug öffnet parallele Sessions, hält sie über mehrere Nachrichten offen und bildet damit das Verbindungsverhalten eines Massenversenders deutlich realistischer ab als Testwerkzeuge, die pro Mail eine neue Verbindung aufbauen. Das Gegenstück smtp-sink nimmt Mails an und verwirft sie, ohne etwas zuzustellen. Beide gehören zum Lieferumfang von Postfix.

Genau da liegt das Problem: Auf dem System, von dem aus Sie testen wollen, ist oft kein Postfix installiert. Auf einer Mailgateway-Appliance ist eine Installation auch nicht erwünscht, denn ein zusätzlicher Postfix bringt eine eigene Konfiguration unter /etc/postfix und einen Systemdienst mit, der im ungünstigsten Fall Port 25 belegt und damit das eigentliche Mailsystem blockiert. Dazu kommt die Frage, was der Hersteller-Support von nachinstallierten Paketen auf seiner Appliance hält.

Beide Werkzeuge lassen sich aber auch ohne Installation betreiben: RPM herunterladen, Binaries samt Bibliotheken entpacken, fertig. Der Weg dorthin hat zwei Eigenheiten, die dieser Beitrag anhand eines RHEL-8-Systems zeigt. Root-Rechte brauchen Sie dafür nicht, nur Zugriff auf die Paketquellen.

Ist smtp-source schon vorhanden?

Zuerst prüfen Sie, ob das Werkzeug nicht doch schon auf dem System liegt. smtp-source befindet sich je nach Distribution ausserhalb des normalen PATH:

command -v smtp-source || \
  ls /usr/sbin/smtp-source /usr/lib/postfix/sbin/smtp-source 2>/dev/null
Optionen erklärt
OptionWirkung
command -v smtp-sourceGibt den Pfad aus, falls das Programm im PATH liegt; sonst nichts
/usr/sbin/... /usr/lib/postfix/sbin/...Die üblichen Ablageorte ausserhalb des PATH (RHEL bzw. Debian/Ubuntu)
2>/dev/nullUnterdrückt die Fehlermeldungen von ls für nicht vorhandene Pfade

Bleibt die Ausgabe leer, fehlt auch das zugehörige Paket. Auf RPM-Systemen bestätigen Sie das und prüfen zugleich, ob die Repositories Postfix anbieten:

rpm -qa | grep -i postfix
Optionen erklärt
OptionWirkung
-qAbfragemodus von rpm
-aListet alle installierten Pakete auf
grep -i postfixFiltert die Liste ohne Beachtung der Gross-/Kleinschreibung
yum list available postfix
Optionen erklärt
OptionWirkung
list availableZeigt nur Pakete, die in den Repositories vorhanden, aber nicht installiert sind
postfixBeschränkt die Ausgabe auf das gesuchte Paket

Auf dem Testsystem war kein Postfix installiert, das BaseOS-Repository bot aber postfix-3.5.8-8.el8_10 an. Damit ist der Weg frei: Das Paket lässt sich herunterladen, ohne es zu installieren.

Das RPM nur herunterladen

yum download (aus dem Plugin-Paket dnf-plugins-core, auf RHEL 8 üblicherweise vorhanden) lädt ein Paket in das aktuelle Verzeichnis, ohne es zu installieren. Das funktioniert ohne Root-Rechte, solange das Zielverzeichnis beschreibbar ist:

cd /tmp && yum download postfix
Optionen erklärt
OptionWirkung
cd /tmpWechselt in ein beschreibbares Verzeichnis; yum download legt das RPM im aktuellen Verzeichnis ab
downloadSubcommand aus dnf-plugins-core: lädt das Paket herunter, ohne es zu installieren
postfixName des herunterzuladenden Pakets

Meldet yum No such command: download, fehlt das Plugin. Mit Root-Rechten erreichen Sie dasselbe über den Installationsbefehl mit --downloadonly:

sudo yum install --downloadonly --downloaddir=/tmp postfix
Optionen erklärt
OptionWirkung
--downloadonlyBricht nach dem Herunterladen ab, es wird nichts installiert
--downloaddir=/tmpZielverzeichnis für das heruntergeladene RPM
postfixName des Pakets

Ganz ohne beides bleibt der Umweg über ein zweites System gleicher RHEL-Version: RPM dort herunterladen und per scp auf das Zielsystem kopieren.

Binaries und Bibliotheken entpacken

rpm2cpio wandelt das RPM in einen cpio-Archivstrom um, aus dem cpio gezielt einzelne Pfade extrahiert. Neben den beiden Binaries brauchen Sie auch die Postfix-Bibliotheken, denn auf RHEL sind die Werkzeuge dynamisch gegen libpostfix-*.so gelinkt:

cd /tmp && rpm2cpio postfix-*.rpm | \
  cpio -idmv ./usr/sbin/smtp-source ./usr/sbin/smtp-sink \
  './usr/lib64/postfix/*'
Optionen erklärt
OptionWirkung
rpm2cpio postfix-*.rpmWandelt das RPM in einen cpio-Archivstrom auf stdout um
-icpio-Extraktionsmodus (copy-in)
-dLegt fehlende Verzeichnisse beim Entpacken an
-mBehält die Änderungszeiten der Dateien bei
-vListet jede extrahierte Datei auf
./usr/sbin/smtp-source ./usr/sbin/smtp-sinkDie beiden Binaries, Pfade exakt wie im Archiv (mit führendem ./)
'./usr/lib64/postfix/*'Die Postfix-Bibliotheken; das Muster ist gequotet, damit cpio es auswertet und nicht die Shell

Die Dateien liegen danach unterhalb von /tmp/usr/.

Problem 1: /tmp ist mit noexec gemountet

Der naheliegende Start direkt aus /tmp schlägt auf gehärteten Systemen fehl:

bash: /tmp/usr/sbin/smtp-sink: Permission denied
[1]+  Exit 126

Exit-Code 126 trotz korrekt gesetztem Execute-Bit ist das typische Bild für ein Dateisystem mit der Mount-Option noexec. Der Kernel verweigert dann jede Programmausführung von diesem Dateisystem, unabhängig von den Dateirechten. Prüfen lässt sich das direkt:

mount | grep ' /tmp '
Optionen erklärt
OptionWirkung
mountListet ohne Argumente alle eingehängten Dateisysteme mit ihren Mount-Optionen auf
' /tmp 'Suchmuster mit Leerzeichen davor und danach, damit nur der Mountpoint /tmp trifft und nicht etwa /var/tmp

Die Lösung: Binaries und Bibliotheken in ein Verzeichnis kopieren, dessen Dateisystem Ausführung erlaubt, zum Beispiel das eigene Home:

mkdir -p ~/bin && \
  cp /tmp/usr/sbin/smtp-source /tmp/usr/sbin/smtp-sink \
     /tmp/usr/lib64/postfix/libpostfix-*.so ~/bin/ && \
  chmod +x ~/bin/smtp-source ~/bin/smtp-sink
Optionen erklärt
OptionWirkung
mkdir -p ~/binLegt das Zielverzeichnis an; ohne Fehler, falls es schon existiert
cp ... ~/bin/Kopiert die beiden Binaries und die libpostfix-*.so-Bibliotheken in das ausführbare Verzeichnis
chmod +xSetzt das Execute-Bit auf beiden Binaries

Beachten Sie, dass noexec auch das Laden von Shared Libraries betrifft. Es genügt also nicht, nur die Binaries zu verschieben und die Bibliotheken in /tmp zu lassen.

Problem 2: der Library-Pfad

Ohne weitere Angaben sucht der dynamische Linker die Postfix-Bibliotheken unter /usr/lib64/postfix, wo sie mangels Installation nicht liegen:

smtp-sink: error while loading shared libraries: libpostfix-global.so:
cannot open shared object file: No such file or directory

LD_LIBRARY_PATH ergänzt den Suchpfad des Linkers um das eigene Verzeichnis. Jeder Aufruf bekommt die Variable vorangestellt:

LD_LIBRARY_PATH=~/bin ~/bin/smtp-source ...
Optionen erklärt
OptionWirkung
LD_LIBRARY_PATH=~/binErgänzt den Suchpfad des dynamischen Linkers für diesen einen Aufruf um ~/bin
~/bin/smtp-sourceAufruf über den vollen Pfad, da ~/bin nicht im PATH liegen muss

Mit ldd ~/bin/smtp-source sehen Sie vorab, ob alle Abhängigkeiten auflösbar sind. Ausser den Postfix-Bibliotheken hängen die Werkzeuge nur an Standardbibliotheken des Systems.

Funktionstest im Loopback

Ob alles läuft, prüfen Sie ohne eine einzige echte Mail: smtp-sink lauscht als Wegwerf-Empfänger auf einem hohen Port, smtp-source liefert dagegen ein. Der ganze Verkehr bleibt auf localhost.

LD_LIBRARY_PATH=~/bin ~/bin/smtp-sink -v 127.0.0.1:2525 100 &
LD_LIBRARY_PATH=~/bin ~/bin/smtp-source -s 2 -m 10 -l 5120 \
  -f test@example.com -t test@example.com 127.0.0.1:2525
Optionen erklärt
OptionWirkung
-v (smtp-sink)Protokolliert jeden Dialogschritt der angenommenen Verbindungen
127.0.0.1:2525smtp-sink lauscht nur auf localhost, Port 2525
100Backlog: maximale Länge der Warteschlange wartender Verbindungen gemäss listen(2)
-s 2Zwei parallele SMTP-Sessions
-m 10Insgesamt zehn Nachrichten, verteilt auf die Sessions
-l 5120Nachrichtengrösse in Bytes (ohne Header), hier 5 KB
-f / -tAbsender- und Empfängeradresse

Bei Erfolg erzeugt smtp-source keine Ausgabe, während der smtp-sink für jede Nachricht den vollständigen SMTP-Dialog von HELO bis QUIT ausgibt. Danach den Hintergrundprozess beenden und die Reste aus /tmp entfernen:

kill %1
Optionen erklärt
OptionWirkung
%1Job-Angabe der Shell: beendet den ersten Hintergrundjob, hier den smtp-sink
rm -rf /tmp/usr /tmp/postfix-*.rpm
Optionen erklärt
OptionWirkung
-rEntfernt den Verzeichnisbaum rekursiv
-fKeine Rückfragen, kein Fehler bei nicht vorhandenen Pfaden
/tmp/usr /tmp/postfix-*.rpmDer entpackte Baum und das heruntergeladene RPM

Hinweise für den echten Lasttest

Für belastbare Durchsatzmessungen gehört der Lastgenerator auf eine separate Maschine im gleichen Netzsegment, nicht auf das Testobjekt selbst. Läuft smtp-source auf dem geprüften Gateway, konkurrieren Generator und Mailsystem um CPU und I/O, und die Messung zeigt diese Konkurrenz statt der tatsächlichen Kapazität. Lokal auf dem Zielsystem taugt das entpackte Werkzeug vor allem für Funktionstests des Regelwerks und für erste Plausibilitätsprüfungen.

Sobald der Test gegen den echten Port 25 geht, sind es reale Mails, die das Regelwerk des Gateways durchlaufen und je nach Konfiguration zugestellt werden. Verwenden Sie deshalb Empfängeradressen, die kontrolliert enden: ein dediziertes Testpostfach, eine Regel, die die Testabsender verwirft, oder eine vom Provider dafür vorgesehene Verwerf-Domain. Produktive Adressen gehören nicht in einen Lasttest.

Das beschriebene Vorgehen eignet sich über die beiden SMTP-Werkzeuge hinaus für jedes Kommandozeilenprogramm, das ein Paket mitbringt, dessen Installation auf dem Zielsystem nicht in Frage kommt. Die Kombination aus yum download, rpm2cpio und einem ausführbaren Verzeichnis im Home ist auf jedem RPM-System gleich.

Quellen

  1. Postfix: smtp-source(1)

    Manpage mit allen Parametern des Lastgenerators, inklusive Session- und Nachrichtensteuerung.

    https://www.postfix.org/smtp-source.1.html
  2. Postfix: smtp-sink(1)

    Manpage des Test-Empfängers, unter anderem mit Optionen für künstliche Verzögerungen und Fehlerantworten.

    https://www.postfix.org/smtp-sink.1.html
  3. Red Hat: How to download a package without installing it

    dokumentiert yum download und die Alternative --downloadonly.

    https://access.redhat.com/solutions/10154
  4. man7.org: mount(8)

    Beschreibung der Mount-Option noexec und ihrer Wirkung auf Programmausführung.

    https://man7.org/linux/man-pages/man8/mount.8.html

Kommentare

Die Kommentare werden von GitHub / Giscus geladen.