Click on our Sponsors to help Support SunWorld
Wizard's Guide to Security by Carole Fennelly

Setting up sendmail on a firewall, Part 2

How to create and build the configuration file

May  1999
[Next story]
[Table of Contents]
Subscribe to SunWorld, it's free!

In part one of her series on sendmail, Carole covered the new features of sendmail 8.9.3 and discussed details of the binary. In this second part, she gets into the intricacies of the configuration file and shows you how to generate, build, and test a config file for your firewall. (3,000 words)

Mail this
article to
a friend

Last month, I started this series on sendmail 8.9 with the intention of pointing out the advantages of upgrading to this more secure version that includes anti-spam and anti-relaying features. Little did I know at the time that the release of the Melissa virus would demonstrate the value of using an open source mail system such as sendmail. Accompanying the release of the CERT advisory regarding the virus was a method for filtering out the affected mail with sendmail -- even though sendmail was not the target in this case.

Aside from the Melissa virus, some of the systems I support were subjected to a "surprise" audit. The firewall that was running sendmail 8.9 thwarted every mail attack, in many cases because the source address was not valid. The auditors made quite an issue over the fact that systems not yet upgraded to sendmail 8.9 permitted mail relaying and were subject to spamming. The upgrade is in progress.

To continue where I left off last month, I'll describe the sendmail configuration file and explain the template file that works for me on my firewall. I use a variation of this template in most places with a few changes, depending on how I want to route mail. Generally, I do not recommend that the firewall handle routing to multiple mail gateways; if one of the mail gateways goes down, it can cause a denial of service problem on the firewall. I recommend that the firewall just send all mail for the company to one master mail gateway on the internal DMZ. This system can handle sub-domain routing. This way, if the mail system gets flooded, other firewall services can still function. To keep things simple, I'll just describe the configuration file for the firewall.

The configuration file
Now comes the fun part -- creating the configuration file. I generate a new one every time I update sendmail to verify that I can create one from scratch, if required. This is not as complicated as it sounds, providing I have a template file that reflects my local configuration. Too often, I have seen sites with a legacy file that was originally written by an administrator who left the company years ago. This configuration file usually becomes a hopelessly confusing set of redundant and conflicting rules that the current staff is afraid to clean up. I have found it much easier, in the long run, to start from scratch and create a new file. You will have to do this anyway if you are running a much older version of sendmail. While there is effort required in doing this the first time, subsequent releases are much easier because you can use the same template file.

m4 configuration
The open source version of sendmail comes with m4 macro configuration (mc) template files to create a file. These files are in /usr/local/src/sendmail-8.9.3/cf/cf and have an .mc suffix. Using the template file (and keeping it up to date!) makes upgrading to new releases relatively painless. I keep my template files in a special directory and then copy them when I need them. If you are starting with an existing template file, make sure you test its validity by generating a file with it and comparing it to your production file. This will let you know if someone has edited the production file without updating the .mc template file. I have to confess that I have been guilty of editing the file live, but I usually go back and make sure the .mc file is updated.

Copy the generic template file for your operating system. If you are running Solaris 2.x, the file is If there isn't a generic template file for your OS, pick one and edit it to change the OSTYPE() to match your OS (an "ls" of the directory /usr/local/src/sendmail-8.9.3/cf/ostype shows the available operating systems). For example, there is no Linux template file, but there is a linux.m4 file in the ostype directory. Just change "solaris2" to "linux" for OSTYPE. I usually copy this file to the system's name, as in "". You will need to edit this file for your site's configuration. The example I am giving works on most firewalls I've configured that have to route mail to an internal mail gateway. There are, no doubt, other ways to do the same thing. Chapter 19 in Bryan Costales's Sendmail book (see Resources) has a very useful description of the sendmail m4 macros. It is very important to remember that sendmail expects tabs, not spaces between the fields in the rulesets. If you do a cut and paste, you will have to go back and change the spaces between the fields to tabs.

The remainder of this section describes the .mc file that I would typically use for a firewall. The actual lines from my .mc file are in bold face and code font, and the description of their purpose follows. You could probably use this with modifications for your particular domain (represented here as "").

VERSIONID(`@(#) 8.9.3 (Wizard's Keys) 2/19/1999')
Edit the VERSIONID line to something meaningful for your site. This is not necessary to make anything work, but it's good housekeeping.

The next line should be your operating system type. If you're running Linux, replace "solaris2" with "linux". I've configured for both. The dnl (delete through new line) ending on each line keeps m4 from inserting blank lines. It's not necessary, just aesthetic.

You can have your own domain file for site-specific configuration options. A generic file, as well as examples of other domain files, are provided in the sendmail-8.9.3/cf/domain directory. This file is not required, but if you support multiple sendmail configurations at your site (for example, an external firewall, an internal firewall, an internal mail gateway, etc.), it can be very useful.

FEATURE in the .mc file
This portion of the .mc file is where you can get creative and make sendmail do all sorts of things without you having to write a special rule. Make sure you read up on these features (I recommend you review both the Sendmail book and the site). I'll just go over the ones I typically use.

I don't have any uucp type addresses, so I don't see any point in processing uucp rules that I don't need; however, there's is no harm in leaving in the uucp support.

It is recommended that this feature be used to force the local or program mailer to fully qualify mail.

I use this feature on the firewall to force all mail to appear to originate from the site's official domain name. However, I do not use it on the internal mail gateway. You need to use this feature in conjunction with MASQUERADE_AS.

This feature forces any host within my domain to appear to come from the same domain. I do not use this feature internally because I want to make decisions based on sub-domains. To the public Internet, I want everything to appear to come from my top-level domain.

This feature causes the envelope to be masqueraded to and is useful for centralizing error messages on one host. I use this feature on both the internal mail gateway and the firewall.

FEATURE(`smrsh', `/usr/local/etc/smrsh')dnl
I run sendmail in a chroot cell, but a little extra paranoia on the firewall doesn't hurt. The source for smrsh (sendmail restricted shell) comes with the release, but needs to be compiled and installed separately. /usr/local/etc/smrsh is used instead of /bin/sh by the program mailer. To have smrsh execute a program, it must be placed in the directory /usr/adm/sm.bin (or by setting CMDDIR to something else in your site configuration file). Smrsh will search this directory to validate a requested program or script and will then use /bin/sh to execute that program or script. If the program or script is not in the directory, the request is rejected.

As I described last month, this feature allows any host within my domain to relay mail through my system. For a private, small company this approach is fine; for some larger clients with multiple organizations, I won't use this feature.

I am tired of getting mail directed to "www" when I don't (yet) have a Web server. (I've been a bit busy.) I use this feature to block mail for "www," "nobody," and "guest." As I mentioned last month, you have to set up the access database to use this feature.

Obviously, this is the value I want used for the masquerading features I defined above.

Use this feature if you are known as many internal domains, but want to appear to be from the domain you listed in MASQUERADE_AS.

You can define your own macros for sendmail or use the built-in ones. If you define your own, be careful not to pick a macro name (or letter) that is already used! It can cause some unexpected behavior. All lowercase letters are reserved for sendmail as well as some uppercase letters. (See Table 31-7 in the Sendmail book and also visit the site; both are listed in Resources.)

You definitely need this feature to deliver mail locally. Although no users are on the firewall, you still have to be able to have cron jobs send mail to root.

You need this feature to be able to process smtp mail. You can add other mailers if you use them.

LOCAL RULES in the .mc file
This portion of the .mc file is where the (black) magic of sendmail comes in. You can make sendmail do almost anything, if you know how. A word of caution: If there is already a built-in FEATURE to do what you want, use it. Try to avoid the temptation of adding complexity. Don't forget the period (.) after {MyNames}. MyNames is a variable -- you can call it anything that's not reserved. Also, as I stated before, there must be a tab between "{MyNames} . > " and "$#smtp" to distinguish between the left side and the right side.

R$+  <  @  $*  $={MyNames}  .  >  	$#smtp   $@   $:   $1   < @  $m  >


Building the configuration file
If you've been following along, you should know have a template "" file for your system in the directory /usr/local/src/sendmail-8.9.3/cf/cf. To turn this into a file, you have to use the m4 macro compiler:

	m4  ../m4/cf.m4  >

If everything goes well, your new configuration file will be Copy this file to /etc/mail/ After testing, you can copy or link it to /etc/mail/ (or wherever your system keeps its file) with mode 600, owned by root.

What the heck is this?
It may look like line noise to you, but the following line is actually very important and warrants explanation:

R$+  <  @  $*  $={MyNames}  .  >  	 $#smtp   $@   $:  $  1<  @  $m  >

I was really trying to avoid explaining rulesets, as it has been covered done at length in theSendmail book and other places. To summarize, here are some important things to remember:

$*	match zero or more tokens 
$+	match one or more tokens
$-	match exactly one token
$={MyNames}	match a member of class {myNames}  (defined 
with C{MyNames)

R$+  <  @  $*  $={MyNames}  .  >  	$#smtp   $@   $:  $1  <  @  $m  >
In this example, if the rule gets "" it will match:

	$+	carole.fennelly (this becomes the positional variable $1)
	$*	morrigan (this could be null and in fact gets dropped but is $2)
	$={MyNames} (this would also match

Because it is a match, the RHS takes effect. The SMTP mailer is called and delivers to the system "mailgate mail for the user "carole.fennelly" that is qualified for my domain ($m).

Testing the configuration file
To test the configuration file, invoke the new sendmail binary you created (/usr/lib/sendmail.8.9.3) with your new configuration file (/etc/mail/

This offline test ensures the basic functionality of your configuration.

	/usr/lib/sendmail.8.9.3  -C/etc/mail/   -bt -d35.9

This test will produce a lot of output because I specified a fairly detailed debug level and placed us in the test mode. You will enter the rulesets you want to test along with a sample e-mail address (in bold below).

	(output deleted)
	define(M as
redefine(n as MAILER-DAEMON)
define(D as
define(Z as 8.9.3)
define(deliveryMode as b)
define(_ as fennelly@localhost)
redefine(deliveryMode as i)
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> 3,0 			(Test your domain)
rewrite: ruleset   3   input: user @
rewrite: ruleset  96   input: user < @ company . com >
rewrite: ruleset  96 returns: user < @ firebox . company . com . >
rewrite: ruleset   3 returns: user < @ firebox . company . com . >
rewrite: ruleset   0   input: user < @ firebox . company . com . >
rewrite: ruleset 199   input: user < @ firebox . company . com . >
rewrite: ruleset 199 returns: user < @ firebox . company . com . >
rewrite: ruleset  98   input: user < @ firebox . company . com . >
rewrite: ruleset  98 returns: $# smtp $@ $: user < 
@ company . com >
rewrite: ruleset   0 returns: $# smtp $@ $: user <
@ company . com >
> >  3,0 			(now test an internet site)
rewrite: ruleset   3   input: user @ internet . com
rewrite: ruleset  96   input: user < @ internet . com >
rewrite: ruleset  96 returns: user < @ internet . com . >
rewrite: ruleset   3 returns: user < @ internet . com . >
rewrite: ruleset   0   input: user < @ internet . com . >
rewrite: ruleset 199   input: user < @ internet . com . >
rewrite: ruleset 199 returns: user < @ internet . com . >
rewrite: ruleset  98   input: user < @ internet . com . >
rewrite: ruleset  98 returns: user < @ internet . com . >
rewrite: ruleset 198   input: user < @ internet . com . >
rewrite: ruleset  95   input: < > user < @ internet . com . >
rewrite: ruleset  95 returns: user < @ internet . com . >
rewrite: ruleset 198 returns: $# esmtp $@ internet . com . $: user < @ 
. com . >
rewrite: ruleset   0 returns: $# esmtp $@ internet . com . $: user < @ 
. com . >
>< control-D > to exit

Note that for testing, it is not necessary to use a valid user in the e-mail address as log as the format is legal. What you want to determine is that mail for your domain is routed to your mailgate system, and mail for an outside domain is delivered to the destination domain. It doesn't matter if "" really exists -- I'm just testing to see if I'm routing "" and "" properly. No mail is generated from the test.

Final thoughts
I really appreciate receiving feedback from readers. While most of it is very positive and constructive, occasionally there will be a comment that is neither. I'd like to take this opportunity to clarify my objectives with this column. I write about technical issues that I have worked on. It does not mean that the method is necessarily the best or only solution. It's what I happen to have done. Hopefully, it will be something you can learn something from. I do not want to get into "religious wars" over software choices.

There has been enough interest based on part one of this series to justify adding a third column on sendmail. Next month's column will show some testing techniques and "stupid Sendmail tricks." Please feel free to send me mail ( with anything you'd like to see covered. Just don't make the subject "Important message from:..!"

Disclaimer: The information and software in this article are provided as-is and should be used with caution. Each environment is unique and the reader is cautioned to investigate with his or her company as to the feasibility of using the information and software in the article. No warranties, implied or actual, are granted for any use of the information and software in this article and neither author nor publisher is responsible for any damages, either consequential or incidental, with respect to use of the information and software contained herein.

Click on our Sponsors to help Support SunWorld


Related SunWorld articles Additional sendmail resources Favorite links for the month Additional SunWorld resources

About the author
Carole Fennelly is a partner in Wizard's Keys Corporation, a company specializing in computer security consulting. She has been a Unix system administrator for more than 15 years on various platforms and has particularly focused on sendmail configurations of late. Carole provides security consultation to several financial institutions in the New York City area.

What did you think of this article?
-Very worth reading
-Worth reading
-Not worth reading
-Too long
-Just right
-Too short
-Too technical
-Just right
-Not technical enough

[Table of Contents]
Subscribe to SunWorld, it's free!
[Next story]
Sun's Site

[(c) Copyright  Web Publishing Inc., and IDG Communication company]

If you have technical problems with this magazine, contact

Last modified: