Qpsmtpd is a Perl-based smtpd daemon that was developed by Ask Bjørn Hansen. Qpsmtpd is used for spam protection on apache.org, cpan.org and perl.org, and a number of others. It provides all the standard SMTP functionality and is supported by a series of extensible plug-ins, also written in Perl.
In this three-part tip, I will demonstrate how to use qpsmtpd. In the first part, I will show you how to install qpsmtpd. The tip assumes you are using a Linux-based distribution such as Red Hat Enterprise Linux. In the second half, I'll demonstrate how to configure qpsmtpd and in the third part, we'll put it in front of your existing MTA.
The recent upsurge in spam has inspired me to re-examine how I handle my incoming mail. Over the years, I have tackled spam with a variety of solutions that culminated in a complicated Postfix configuration with amavisd-new processing and re-injecting emails and then also using SpamAssassin, dspam, Bogofilter, Real-time Blackhole Lists (RBLs), SPF/DomainKeys/DKIM and other refinements.
This configuration was hugely complex and very hard to debug, maintain and update. It was also highly performance intensive.
So I started to look at alternatives. My requirements were simple:
- I wanted to leave Postfix as basic as possible and reduce its configuration complexity
- I wanted flexible and powerful blocking capabilities and the ability to deploy both learning and manual blocks
- I wanted to handle as much spam as possible as early in the connection as possible.
After some research, I found qpsmtpd (http://smtpd.develooper.com/)
Qpsmtpd was originally designed as a qmail-smtpd replacement daemon but it can also act as a proxy front-end or a SMTP forward email to your MTA. It includes plug-ins that can inject mail into Exim, Postfix, Qmail queues or even write directly to a Maildir spool. An API interface is available that allows for easy development of additional plug-ins.
The qpsmtpd daemon is generally designed to be interposed in front of your MTA. Email is received by qpsmtpd and then processed through a user-specified and configurable series of plug-ins that are designed to detect and block incoming spam. These plug-ins include checks against RBLs, RFC-compliant behaviour, plug-ins that call SpamAssassin and anti-virus engines like ClamAV and a number of others. Emails are either dropped or passed to your MTA.
The qpsmtpd daemon is easy to install and requires only a few simple pre-requisites. You need to install the following CPAN modules (use the cpan command to install these).
If you use a version of Perl older than 5.8.0, you will also need the following modules.
Moving on to the qpsmtpd installation, first, you need to download the qpsmtpd source code. I think using the source code gives a better picture of how qpsmtpd is put together but you can also install via RPM if you prefer. You can find instructions about how to install via RPM at the qpsmtpd Wiki.
The current release of qpsmtpd is version 0.32 and you can download it like so:
# wget http://smtpd.develooper.com/files/qpsmtpd-0.32.tar.gz
(A slightly more recent version is available in the stable branch of the qpsmtpd subversion repository; it addresses some issues that have arisen since the last release. Download it via the svn tool.
# svn co http://svn.perl.org/qpsmtpd/branches/0.3x qpsmtpd-0.3x)
Unpack the source code, change into the resulting directory, create the Makefile and make the package, like so:
# tar -zxf qpsmtpd-0.32.tar.gz # cd qpsmtpd-0.32 # perl Makefile.PL # make
Once the package is compiled, you can install it using the make install command.
# make install
This will install the Qpsmtpd.pm Perl module and its associated modules into the location of your Perl site files, for example, on a Linux-based host at /usr/lib/perl5/site_perl/5.8.8. The qpsmtpd and qpsmtpd-forkserver binaries will be installed into the /usr/bin directory.
Next, create a user to run qpsmtpd, I've chosen the user smtpd, like so:
# useradd smtpd -s /sbin/nologin
I have used the -s option to set the user's shell to /sbin/nologin, which prevents the smtpd user from logging in.
Now we want to create and configure some directories and basic configuration files. As a result of its heritage as a replacement for the qmail-smtpd daemon, the qpsmtpd daemon requires directories to be in a particular structure. The easiest way to implement this is to locate these directories off the home directory of the user qpsmtpd is running as. This allows qpsmtpd to find the required configuration files, logging directory and the plug-ins.
As a result of this non-FHS behavior, we're also going to create some symbolic links to make qpsmtpd look a bit more FHS compliant.
Create a configuration directory and populate it with the sample configuration files that are supplied with the qpsmtpd package.
# mkdir /etc/qpsmtpd # cp qpsmtpd-0.32/config.sample/* /etc/qpsmtpd # chown -R smtpd:smtpd /etc/qpsmtpd
Then link that directory to the smtpd user's home directory like so:
# ln -s /etc/qpsmtpd ~smtpd/config
Next, create a logging directory and link it in the same way.
# mkdir /var/log/qpsmtpd # chown smtpd:smtpd /var/log/qpsmtpd # chmod 0750 /var/log/qpsmtpd # ln -s /var/log/qpsmtpd ~smtpd/log
Then we need to create a temporary directory for qpsmtpd.
# mkdir ~smtpd/tmp # chown smtpd ~smtpd/tmp # chmod 0700 ~smtpd/tmp
Finally, we need to install the qpsmptd plug-ins by moving them out of the package directory. I usually choose to install the plug-ins into the /usr/share/qpsmtpd directory and link it back to the smtpd user's home directory.
# mkdir /usr/share/qpsmtpd # mv qpsmtpd-0.32/plugins /usr/share/qpsmtpd # ln -s /usr/share/qpsmtpd/plugins ~smtpd/plugins
Now you have installed qpsmtpd you can start it. The qpsmtpd daemon can be run in a number of different modes including tcpserver (using daemontools), a forkserver daemon (which forks for each new connection) and Apache::Qpsmtpd (where qpsmtpd is run via Apache 2 and mod_perl 2). There is also a pollserver daemon using Danga that is currently being developed and is not yet suitable for production use.
I'm going to examine running qpsmtpd via the forkserver daemon, which is considered the most popular mode and how perl.org and cpan.org both run their instances of qpsmtpd.
Earlier we installed the qpsmtpd-forkserver binary in the /usr/bin/ directory. Now we're going to symlink this binary into the ~smtpd directory to keep our configuration consistent.
# ln -s /usr/bin/qpsmtpd-forkserver ~smtpd
Once we've done this, we can start the qpsmtpd forkserver,
This launches the forkserver in the foreground. Without any options the forkserver will bind to all available local IP addresses on port 2525 and wait to receive email. We can override these options on the command line like so,
# ~smtpd/qpsmtpd-forkserver -l 127.0.0.1 -p 25 -u smtpd -d --pid-file /var/run/qpsmtpd-forkserver
The forkserver initiation on the previous line uses the –l option to specify the IP addresses to bind, here 127.0.0.1. The –p option specifies the port to bind to, in this case port 25. In the 0.32 release, you can only specify one IP address and port to bind to. In the 0.3x unstable release, you can specify the -l and -p options multiple times to bind to multiple IP addresses and ports.
The -u option indicates what user to run qpsmtpd as and the -d option tells the forkserver to detach and run as a daemon. If you omit the –d option, then qpsmtpd will run in the foreground. Lastly, the --pid-file option specifies the location of the daemon's PID file.
You can start qpsmtpd-forkserver from the command line as I've demonstrated or via a SysV-style init script. You can see an example of an init script at http://wiki.qpsmtpd.org/sysvinit.
You can test that qpsmtpd is working by telnet'ing to the qpsmtpd server like so:
# telnet 127.0.0.1 25 Trying 127.0.0.1... Connected to mail.domain.com (127.0.0.1). Escape character is '^]'. 220 domain.com ESMTP qpsmtpd 0.32 ready; send us your mail, but not your spam.
Type QUIT to exit the telnet session.
Now you have got qpsmtpd installed and running. From here I recommend you explore the contents of the configuration directory, in our case contained in /etc/qpsmtpd, to get an understanding of how qpsmtpd works and look at the many plug-ins available for qpsmtpd. Most of the plug-ins have inbuilt documentation you can review using the perldoc command.
In part two of this tip, I'll explain to configure qpsmtpd with a variety of plug-ins.
Did you find this tip helpful? What are your security issues? Tell us in an email!
This was first published in December 2006