smtp-source without a Postfix installation: extracting load-testing tools from the RPM
smtp-source and smtp-sink are part of Postfix, but also run without an installed mail server. Learn how to extract the two tools from the package on RHEL, why running them from /tmp can fail because of the noexec mount option, and which libraries must be included.
For SMTP load tests, smtp-source is a good choice: the tool opens parallel sessions, keeps them open across multiple messages and thus models the connection behaviour of a bulk sender far more realistically than test tools that establish a new connection for each email. Its counterpart, smtp-sink, accepts emails and discards them without delivering anything. Both are included with Postfix.
That is precisely where the problem lies: Postfix is often not installed on the system from which you want to test. Installation is also undesirable on a mail gateway appliance, because an additional Postfix installation brings its own configuration under /etc/postfix and a system service which, in the worst case, occupies port 25 and blocks the actual mail system. There is also the question of what vendor support thinks of subsequently installed packages on its appliance.
However, both tools can also be used without installation: download the RPM, extract the binaries along with the libraries, done. This approach has two specifics, which this article demonstrates on an RHEL 8 system. You do not need root privileges, only access to the package repositories.
Is smtp-source already available?
First, check whether the tool might already be present on the system. Depending on the distribution, smtp-source is located outside the normal PATH:
command -v smtp-source || \
ls /usr/sbin/smtp-source /usr/lib/postfix/sbin/smtp-source 2>/dev/null
If the output remains empty, the associated package is also missing. On RPM systems, confirm this and check at the same time whether the repositories offer Postfix:
rpm -qa | grep -i postfix
yum list available postfix
No Postfix was installed on the test system, but the BaseOS repository offered postfix-3.5.8-8.el8_10. This clears the way: the package can be downloaded without installing it.
Download only the RPM
yum download (from the plugin package dnf-plugins-core, usually available on RHEL 8) downloads a package to the current directory without installing it. This works without root privileges as long as the target directory is writable:
cd /tmp && yum download postfix
If yum reports No such command: download, the plugin is missing. With root privileges, you can achieve the same using the installation command with --downloadonly:
sudo yum install --downloadonly --downloaddir=/tmp postfix
If neither is available, the remaining workaround is to use a second system with the same RHEL version: download the RPM there and copy it to the target system using scp.
Extract binaries and libraries
rpm2cpio converts the RPM into a cpio archive stream, from which cpio selectively extracts individual paths. Besides the two binaries, you also need the Postfix libraries, because on RHEL the tools are dynamically linked against libpostfix-*.so:
cd /tmp && rpm2cpio postfix-*.rpm | \
cpio -idmv ./usr/sbin/smtp-source ./usr/sbin/smtp-sink \
'./usr/lib64/postfix/*'
The files are then located under /tmp/usr/.
Problem 1: /tmp is mounted with noexec
The obvious attempt to run them directly from /tmp fails on hardened systems:
bash: /tmp/usr/sbin/smtp-sink: Permission denied
[1]+ Exit 126
Exit code 126 despite a correctly set execute bit is typical for a file system with the noexec mount option. The kernel then denies all program execution from that file system, regardless of file permissions. You can check this directly:
mount | grep ' /tmp '
The solution is to copy the binaries and libraries to a directory whose file system permits execution, such as your own home directory:
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
Note that noexec also affects the loading of shared libraries. It is therefore not enough to move only the binaries and leave the libraries in /tmp.
Problem 2: the library path
Without further instructions, the dynamic linker searches for the Postfix libraries under /usr/lib64/postfix, where they are absent because there is no installation:
smtp-sink: error while loading shared libraries: libpostfix-global.so:
cannot open shared object file: No such file or directory
LD_LIBRARY_PATH adds your own directory to the linker’s search path. Prefix the variable to every invocation:
LD_LIBRARY_PATH=~/bin ~/bin/smtp-source ...
With ldd ~/bin/smtp-source, you can check in advance whether all dependencies can be resolved. Apart from the Postfix libraries, the tools depend only on standard system libraries.
Functional test via loopback
You can verify that everything works without sending a single real email: smtp-sink listens as a disposable receiver on a high port, while smtp-source delivers to it. All traffic remains on 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
On success, smtp-source produces no output, while smtp-sink outputs the complete SMTP dialog from HELO through to QUIT for every message. Then stop the background process and remove the remnants from /tmp:
kill %1
rm -rf /tmp/usr /tmp/postfix-*.rpm
Notes for the real load test
For reliable throughput measurements, the load generator belongs on a separate machine in the same network segment, not on the test target itself. If smtp-source runs on the gateway being examined, the generator and the mail system compete for CPU and I/O, and the measurement reflects that competition rather than actual capacity. On the target system locally, the extracted tool is primarily suitable for functional tests of the ruleset and initial plausibility checks.
As soon as the test targets the real port 25, these are real emails that pass through the gateway’s ruleset and may be delivered depending on the configuration. Therefore, use recipient addresses with controlled endpoints: a dedicated test mailbox, a rule that discards the test senders, or a discard domain provided by the provider for this purpose. Production addresses do not belong in a load test.
The procedure described is suitable beyond the two SMTP tools for any command-line program supplied by a package whose installation on the target system is not an option. The combination of yum download, rpm2cpio and an executable directory in the home directory is the same on every RPM system.
Kommentarer
Kommentarerna hämtas från GitHub / Giscus.