Summary
In the first installment of her series on sendmail, Carole covered the new features of sendmail 8.9.3 and discussed details of the binary. In this second installment, 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)
| WIZARD'S GUIDE TO SECURITY | ||
| By Carole Fennelly |
| Setting up sendmail on a firewall: Read the whole series! | |
|---|---|
|
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 subdomain 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.
cf 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.
mc) template files to create a sendmail
cf file.
These files are in /usr/local/src/sendmail-8.9.3/cf/cf and have the
suffix mc. 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 sendmailcf file with it
and comparing it to your production sendmailcf file. This will let
you know if someone has edited the production sendmailcf file
without updating the mc template file. I have to confess that I
have been guilty of editing the sendmailcf 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're
running Solaris 2x, the file is generic-solaris2mc. 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 firebox.mc. You'll 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 book about sendmail (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 the description of their purpose follows.
You could probably use this with modifications for your particular
domain (represented here as company.com).
VERSIONID(`@(#)cbf.mc 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.OSTYPE(solaris2)dnl
The next line should be your operating system type. If you're running Linux, replacesolaris2withlinux. I've configured for both. Thednl(delete through new line) ending on each line keepsm4from inserting blank lines. It isn't necessary, just aesthetic.DOMAIN(generic)dnl
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 theendmail-8.9.3/cf/domaindirectory. This file isn't 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 Costales's Sendmail and the Sendmail.org site). I'll
just go over the ones I typically use.
FEATURE(nouucp)dnl
I don't have anyuucp-type addresses, so I don't see any point in processinguucprules that I don't need; however, there's no harm in leaving in theuucpsupport.FEATURE(always_add_domain)dnl
It is recommended that this feature be used to force the local or program mailer to fully qualify mail.FEATURE(allmasquerade
I use this feature on the firewall to force all mail to appear to originate from the site's official domain name. However, I don't use it on the internal mail gateway. You need to use this feature in conjunction withASQUERADE_AS.FEATURE(masquerade_entire_domain)
This feature forces any host within my domain to appear to come from the same domain. I don't use this feature internally because I want to make decisions based on subdomains. To the public Internet, I want everything to appear to come from my top-level domain.FEATURE(masquerade_envelope)
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 achrootcell, 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/smrshis used instead of/bin/shby the program mailer. To havesmrshexecute a program, it must be placed in the directory/usr/adm/sm.bin(or by settingCMDDIRto something else in your site-config file).smrshwill search this directory to validate a requested program or script and will then use/bin/shto execute that program or script. If the program or script isn't in the directory, the request is rejected.FEATURE(relay_entire_domain)
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.FEATURE(blacklist_recipients)
I'm tired of getting mail directed towwwwhen I don't yet have a Web server. (I've been a bit busy.) I use this feature to block mail sent towww, nobody,andguest. As I mentioned last month, you have to set up the access database to use this feature.MASQUERADE_AS(company.com)
Obviously, this is the value I want used for the masquerading features I defined above.MASQUERADE_DOMAIN(company.com othername.com)
Use this feature if you're known as many internal domains, but want to appear to be from the domain you listed inMASQUERADE_AS.define
You can define your own macros for sendmail or use the one that are built in. If you define your own, be careful not to pick a macro name (or letter) that is already in use! It can cause some unexpected behavior. All lowercase letters are reserved for sendmail as well as some uppercase letters. (See Table 31-7 in Costales's Sendmail and also visit the Sendmail.org site; both are listed in Resources.)MAILER(local)dnl
You definitely need this feature to deliver mail locally. Although no users are on the firewall, you still have to be able to havecronjobs send mail to root.MAILER(smtp)dnl
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.
LOCAL_RULE_0
R$+ < @ $* $={MyNames} . > $#smtp $@
mailgate.company.com $: $1 < @ $m >
LOCAL_CONFIG
C{MyNames}company.com othername.com
firewall.mc file for your system in the directory
/usr/local/src/sendmail-8.9.3/cf/cf. To turn this into a
sendmailcf file, you have to use the m4 macro compiler:
m4 ../m4/cf.m4 firewallmc> firewallcf
If everything goes well, your new configuration file will be
firewall.cf. Copy this file to /etc/mail/firewall.cf.
After testing, you can copy or link it to /etc/mail/sendmail.cf (or
wherever your
system keeps its sendmail.cf file) with mode 600, owned by root.
R$+ < @ $* $={MyNames} . > $#smtp $@
mailgate.company.com $: $ 1< @ $m >
I was really trying to avoid explaining rulesets, as it has been covered done at length in Sendmail and other places. To summarize, here are some important things to remember:
R$+ < @ $* $={MyNames} .
>) is evaluated and, if it matches, performs the action or rewrites on
the right side (in this case, $#smtp $@ mailgate.company.com $: $1
< @ $m >).
C{MyNames} isn't defined in
your config file, this rule will make no sense. While this may
seem obvious, I've seen administrators ask their ISP for a line they
can add to their sendmail.cf file to route mail from the firewall.
As in
any program, it's meaningless to use a variable that has not been
defined.
$* 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 $@
mailgate.company.com $: $1 < @ $m >
In this example, if the rule gets "carole.fennelly@morrigan.othername.com" 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} othername.com (this would also match company.com).
Because it's a match, the RHS takes effect. The SMTP mailer is called and delivers to the system: mailgate mail for user "carole.fennelly" that is qualified for my domain ($m).
/usr/lib/sendmail.8.9.3) with your new configuration file
(/etc/mail/firewall.cf).
This offline test ensures the basic functionality of your configuration.
/usr/lib/sendmail.8.9.3 -C/etc/mail/firewallcf -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 email address (in bold below).
(output deleted) define(M as company.com) redefine(n as MAILER-DAEMON) define(D as company.com.) 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 user@company.com (Test your domain) rewrite: ruleset 3 input: user @ company.com 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 $@ mailgate.company.com $: user < @ company . com > rewrite: ruleset 0 returns: $# smtp $@ mailgate.company.com $: user < @ company . com > > > 3,0 user@internet.com (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 < @ internet . com . > rewrite: ruleset 0 returns: $# esmtp $@ internet . com . $: user < @ internet . com . > >< control-D > to exit
Note that for testing, it isn't necessary to use a valid user in
the email address as long 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 user@company.com really
exists -- I'm just testing to see if I'm routing company.com and
internet.com properly. No mail is generated from the test.
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
present some testing techniques and "stupid sendmail tricks."
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.