ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics SMTP Proxies

by Dru Lavigne
07/24/2003

In my previous article, I demonstrated the configuration of several HTTP proxies. In this article, I'd like to finish up the proxy series by concentrating on an example SMTP proxy.

SMTP Proxies

Similar to an HTTP proxy, an SMTP proxy is used to add to the feature set already provided by your MTA, or mail server. Again, the amount of available configurable features will vary, depending upon the specific mail server software you've chosen to use in your environment.

The advantage of an SMTP proxy may lie in its ability to simplify your configuration. A web browser's configuration isn't that hard to figure out; simply play around with the available options in the Preferences menu. An SMTP server is a much more complicated piece of software. Finding and making configuration changes can involve reading reams of documentation and dealing with databases, macros, and multiple configuration files.

When dealing with email, one is usually concerned with controlling spam and viruses. Due to the prevalence of both email and the nasties associated with it, it's not surprising that there are myriad supporting applications available to a mail server administrator. This further increases the complexity. For example, one could install and configure a virus scanner, a separate application to tell the SMTP server to use the virus scanner, and yet another application to check for the possibility of spam.

A good SMTP proxy simplifies this configuration process. Remember, an application proxy scans the data portion of a packet. What better time to look for viruses and spam?

Building and Installing messagewall

I've chosen to demonstrate messagewall. I like this SMTP proxy, as it has many configurable features with a straightforward and very user-friendly configuration. Without further ado, let's become the superuser and build this port:

%cd /usr/ports/mail/messagewall
% make install clean

At the beginning of this build, the following message will go by:

You may use the following build options:
-DMESSAGEWALL_ALLOW_MULT_RCPT to allow multiple recipients. The profile 
for the first recipient will be applied to all recipients of the message

If you're ever building a port and notice a message and want to use that extra option, simply press Ctrl-D to stop the build, and start it over again with the option:

% make -DMESSAGEWALL_ALLOW_MULT_RCPT install clean

It is a better idea to check first for any possible options, like so:

$ more Makefile | grep ECHO
@${ECHO} ""
@${ECHO} "You may use the following build options:"
@${ECHO} ""
@${ECHO} "    -DMESSAGEWALL_ALLOW_MULT_RCPT to allow multiple recipients"
@${ECHO} "       The profile for the first recipient will be applied to all"
@${ECHO} "       recipients of the message."
@${ECHO} ""

Once the build is finished, another message will go by. If you missed it, you'll always find such messages in a file called pkg-message. These messages usually contain configuration information, so it's always a good idea to read a port's pkg-message.

I'll go through messagewall's pkg-message, as some of the commands work on a Linux box instead of your FreeBSD box. Also, messagewall works in a chroot. If you're unfamiliar with the term chroot and why it is a good thing, check out this introductory article.

messagewall also requires you to create two user accounts, two group accounts, and the directories to be used by the chroot. Let's take a look at pkg-message and follow the instructions:

$ more pkg-message
Messagewall has been installed, now create the chroot environment:
mkdir /home/mwall

The next instruction says to create a group using groupadd and a user using useradd. Since FreeBSD doesn't use those commands, use pw instead:

% pw groupadd mwall
% pw useradd mwall -g mwall

Next, follow along and create two directories:

% mkdir /home/mwall/pids
% chown mwall:mwall /home/mwall/pids
% mkdir /home/mwalla

Substitute the pw command for the next user and group:

% pw groupadd mwalla
% pw useradd mwalla -g mwalla

One more directory:

% mkdir /home/mwalla/pids
% chown mwalla:mwalla /home/mwalla/pids

Finally, copy the included virus patterns into your chroot environment:

% cp /usr/local/etc/messagewall/virus.patterns /home/mwall

The final instruction is:

and don't forget to edit your configfile!

One way to find out the name of that installed configfile is to search for it in the port's pkg-plist:

$ more pkg-plist | grep conf
/etc/messagewall.conf.sample

By default, all port directories start at /usr/local, so the location of this configuration file is really /usr/local/etc/messagewall.conf.sample. Since this is a sample configuration file, we'll start by copying it to the real configuration file we'll edit:

% cp /usr/local/etc/messagewall.conf.sample /usr/local/etc/messagewall.conf

Configuring messagewall

Now use your favorite editor to open up the configuration file. You'll note that everything is commented out, so the message wasn't kidding when it told you to edit the file first. The nice thing about this configuration file is the clear, readable comments. Every option is commented, and optional options are clearly labeled as OPTIONAL.

I'll walk through the configuration file with you, pointing out things to be aware of.

# This is the MessageWall sample configuration file.  All
# variables in this file must be uncommented and defined before
# MessageWall will start.

This comment is fairly clear. Since most of the defaults are reasonable, I will simply uncomment the following:

processes=1
max_clients=10
max_backends=5
max_per_ip=5
max_message_size=10485760
max_rcpt=25
max_errors=3
max_idle=60
max_parts=25
max_depth=5

As you go through your configuration file, read each comment and decide for yourself if your particular situation requires different values than the defaults. When in doubt, stick with the default value.

Now come some values that need to be customized for your installation. First, give the IP address of the machine running messagewall:

# The IP address, in dotted quad notation, that MessageWall should
# listen on.  As MessageWall will bind to port 25 on this address, it
# will need to be run as root.
#
listen_ip=1.2.3.4

Next, the IP address of the SMTP server. This may or may not be the same machine as the one running messagewall:

# The IP address, in dotted quad notation, that MessageWall should
# connect to in order to deliver messages that have passed filtering.
# MessageWall will connect to this IP address on port 25 and speak
# ESMTP or SMTP.  The server running on this IP should support ESMTP,
# PIPELINING and 8BITMIME, but does not need to.  You may chain
# MessageWall installations in order to spread filtering across
# different systems, although this is highly inefficient.
#
backend_ip=127.0.0.1

Next, the name of your company. Typically, this is the name used in the MX record of your DNS database.

# The primary domain name that MessageWall is serving.  This is used
# in several SMTP responses.
#
domain=example.com

This is followed by several other options that you may wish to leave at the default values as you uncomment them, unless you're a real SMTP guru:

path_charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_+=@"
dnsbl_timeout=5
dnsbl_domain_timeout=5
dnsdcc_timeout=5
rmx_timeout=10
rdns_timeout=10

The next value needs to be changed, as it is incorrect. It should look like this:

profile_dir=/usr/local/etc/messagewall/profiles/

We'll look at that directory and the concept of profiles once we're finished with this file. The next path is correct and can simply be uncommented:

pid_dir=/pids/

For now, uncomment the next two profiles until we've had a chance to discuss profiles.

relay_profile=Relay
default_profile=Medium

Next come the options, meaning you don't have to uncomment these if they aren't pertinent to your situation:

# OPTIONAL
#
#local_domains=local_domains
#relay_ips=relay_ips
#special_users=special_users
#relay_auth=relay_auth

Hang in there, we're almost finished. Uncomment the lines for the user accounts you created and their home directories:

root=/home/mwall
user=mwall
group=mwall
auth_root=/home/mwalla
auth_user=mwalla
auth_group=mwalla

Finally, a few more options:

# OPTIONAL
#
#certificate=/usr/local/etc/cert.pem
#backend_certificate=/usr/local/etc/cert.pem

Once you're finished uncommenting your configuration file, save your changes. Now, let's take a look at that profile directory that was mentioned in the configuration file:

% ls /usr/local/etc/messagewall/profiles/ 
./		Light		Medium Plus	Relay		Warning
../		Light Plus	None		Strong
Extreme		Medium		Reject

Profiles and Viruses

Each profile is an ASCII text file that contains a set of rules indicating what messagewall should look for when it is reading the data portion of a packet. The configuration file uses the Medium profile by default, which looks like this:

% cd /usr/local/etc/messagewall/
% more Medium
reject_score=1
dnsbl=1,list.dsbl.org
dnsbl=1,bl.spamcop.net
rmx_required=1,1
filename_reject=1,.exe
filename_reject=1,.pif
filename_reject=1,.scr
filename_reject=1,.vbs
filename_reject=1,.bat
filename_reject=1,.com
filename_reject=1,.shs
filename_reject=1,.wsc
header_rejecti=1,Precedence:junk
header_rejecti=1,X-Mailer:Microsoft CDO
header_rejecti=1,X-Mailer:eGroups Message Poster
header_rejecti=1,X-Mailer:Delphi Mailing System
header_rejecti=1,X-Mailer:diffondi
header_rejecti=1,X-Mailer:RoryMAILER
header_rejecti=1,X-Mailer:GreenRider
header_rejecti=1,X-Mailer:GoldMine
header_rejecti=1,X-Mailer:MailPro
header_rejecti=1,X-Mailer:charset(89)
header_rejecti=1,X-Mailer:MailWorkZ
header_rejecti=1,X-Mailer:bulk
virus_scan=1,virus.patterns

Note that the file is composed of variables followed by values. Explanations of each variable and examples of possible values are given in man messagewall_profiles. Most of the values are straightforward. For example, the filename_reject variable indicates which attachments should be discarded. In this profile, any attachment with an extension of exe, pif, scr, vbs, bat, com, shs, or wsc will be rejected. One could easily follow the format and add his or her own lines for extensions that should also be rejected.

If you've ever configured a spam filter such as procmail, you'll recognize the header_rejecti variable. The values indicate what to look for in an email message's header. If that value is found, the message will be rejected as spam.

Unsurprisingly, the virus_scan variable tells messagewall to scan for viruses as long as this value is turned on or set to 1. You should note that, like all SMTP proxies, messagewall relies upon a separate virus-scanning product. messagewall follows the Open AntiVirus format.

Remember copying the default virus patterns earlier? These virus definitions will get you started, but you will still want to download the latest virus definitions. If you're the curious type, the format is in ASCII text, meaning you can take a look at the virus definition file.

Simply save the downloaded file to:

/usr/local/etc/messagewall/virus.patterns

Alternately, you can use any antivirus product that supports the Open AntiVirus format. Keep in mind when choosing an antivirus product that most are free for personal use, but cost for business or commercial use.

Before we leave the default profile, you should take the time to check out the settings in the other available profiles. If you find a profile that is better suited to your network's needs, don't forget to edit messagewall.conf to reflect the desired profile.

Okay, you've chosen a profile, you've selected an antivirus product and downloaded its latest definitions. To start messagewall, simply type:

% messagewall

messagewall must be started as root in order to bind to the specified address on port 25. However, once the port is bound, it will enter the chroot and assume the identity of the mwall user. Note that you'll lose your prompt when you start messagewall and will see a series of messages:

STARTUP/STATUS: loaded profile Extreme
STARTUP/STATUS: loaded profile Medium Plus
STARTUP/STATUS: loaded profile Light
STARTUP/STATUS: loaded profile Relay
STARTUP/STATUS: loaded profile Warning
STARTUP/STATUS: loaded profile Medium
STARTUP/STATUS: loaded profile Reject
STARTUP/STATUS: loaded profile Strong
STARTUP/STATUS: loaded profile Light Plus
STARTUP/STATUS: loaded profile Strong Plus
STARTUP/STATUS: loaded profile None
{0} PROCESS/STATUS: start
{0} [0] BACKEND/STATUS: connect to 127.0.0.1 started
{0} [1] BACKEND/STATUS: connect to 127.0.0.1 started
{0} [2] BACKEND/STATUS: connect to 127.0.0.1 started
{0} [3] BACKEND/STATUS: connect to 127.0.0.1 started
{0} [4] BACKEND/STATUS: connect to 127.0.0.1 started
{0} [0] BACKEND/STATUS: connection established
{0} [1] BACKEND/STATUS: connection established
{0} [2] BACKEND/STATUS: connection established
{0} [3] BACKEND/STATUS: connection established
{0} [4] BACKEND/STATUS: connection established

You can further verify that messagewall is listening for connections by telnetting to port 25 using the IP address you specified in your configuration file:

$ telnet 1.2.3.4 25
Trying 1.2.3.4...
Connected to 1.2.3.4.
Escape character is '^]'.
220 example.com MessageWall 1.0.8 (You may not relay)

Other Utilities

Finally, there are two other utilities that were installed with messagewall. messagewallctl is used to interact with messagewall once it is running. It has its own manpage; type messagewallctl to receive its list of possible commands.

Virus definitions are usually updated on a daily basis. You'll need to make messagewall aware that the definitions have changed, but you don't want to stop the service in order to do so. Instead, simply type:

% messagewallctl reload-virus

This is the most common usage of messagewallctl. Refer to its manpage to see its other usages.

The other utility is messagewallstats. To use this handy utility, first create an empty file to hold the statistics. I've decided to create one in the chroot:

% touch ~mwall/messagewallstats

Then start messagewall, telling it to redirect its statistical output to this file:

% messagewall > ~mwall/messagewallstats

Now, whenever you want to view the statistics:

$ messagewallstats ~mwall/messagewallstats | more

As you can see, I was pretty anxious and viewed my stats before any email actually arrived and had a chance to be acted upon by messagewall:

Client Connections: 0
QUIT: 0
Disconnect: 0
Disconnect inside DATA: 0
Bare LF: 0
Idle Timeout: 0
Too many errors: 0

Client TLS Attempts: 0
Success: 0

Overflows: 0
Per-IP Overflows: 0

Backend Overflows: 0
Backend Rejection Overflows: 0

Backend connection attempts: 0
Success: 0
TLS: 0

Invalid MAIL characters: 0
Invalid RCPT characters: 0

Client Messages: 0
Bare LF inside DATA: 0
8bit inside DATA: 0
Rejected by Profile: 0
Completely Received: 0
Sent to Backend: 0
Accepted by Backend: 0

Messages Rejected by Filter: 0
Failed To/CC: 0
Failed From: 0
Matched DNSBL: 0
Matched Domain DNSBL: 0
Matched DNSDCC: 0
Reverse Path MX/A lookup timed out: 0
Reverse DNS lookup timed out: 0
Failed Reverse Path MX/A: 0
Failed Reverse DNS: 0
Failed Body check: 0
Failed Header check: 0
Illegal attachment filename: 0
Virus: 0
No accepted MIME parts: 0
Missing MIME boundary: 0
Too many parts: 0
Illegal multipart encoding: 0
Unknown MIME encoding: 0
Invalid QP encoding: 0
Invalid base64 encoding: 0

Mail Traffic
Bytes received: 0
Bytes rejected: 0
Bytes accepted: 0

This should get you started with messagewall. For further information, there is an FAQ and an archive of the mailing lists at the messagewall home page.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.


Read more FreeBSD Basics columns.

Return to the BSD DevCenter.


Copyright © 2009 O'Reilly Media, Inc.