We will concentrate on the sendmail SMTP mail server. It is probably the most common server, and it has been thoroughly debugged, hacked, cracked and hopefully fixed.
The sendmail daemon waits for either internal or external mail activity. When you mail something internally, the mail client attempts to get sendmail to deliver it immediately. If it can't for some reason, it is spooled to /var/spool/mqueue. Sendmail wakes up occassionally and attempts to resend anything in this queue up to some maximum number of tries or amount of time and then it sends a message back to the sender. When something is mailed to a user on your host, it contacts sendmail on (typically) port 25 and negotiates the transfer of the mail. It is spooled in /var/spool/mail/username. The mail client (pine, mush, mail, kmail, ad infinitum) looks in this file to get mail that has been sent for a given user. Some clients (e.g. kmail, evolution) move the mail from that location to a location under the users directory, others don't.
An email message has three parts:
SMTP is an ASCII-based protocol with the following command set which is described in RFC 821 and RFC 822:
HELO hostname |   | Identify the connecting host if using SMTP |
EHLO hostname |   | Identify the connecting host if using ESMTP |
MAIL From:path |   | Initiate a transaction |
RCPT To:path |   | Identifies the recipients |
VRFY address |   | Verifies if address is valid |
EXPN address |   | Expands aliases and forwards |
DATA |   | Begin message body |
QUIT |   | Ends the excahnge |
RSET |   | Resets connection state |
HELP |   | Print a summary of commands |
EMSTP is the Extended version of SMTP that handles non-text types, like audio, images and video. The characteristics of ESMTP are described in RFC 1869.
These are the required rpms, but you should also install
and there is a development rpm as well which you don't need unless you are going to make contributions to the sendmail development branch. If you want to know more about sendmail, go to sendmail.org.
Note, make sure you uninstall any previous versions of these packages if you are going to upgrade. rpm -q sendmail will tell you if you already have installations. rpm -e package-name will uninstall them. Or you can do an upgrade with rpm -Uvh package-name
If you have sendmail, put a "ps ax | grep sendmail" shows no process, try chkconfig --list sendmail to see the current status. If it isn't running, you can go to /etc/rc.d and make the appropriate changes, or try:
There are options that you can add to the script in /etc/rc.d/init.d where it runs sendmail with the -bd option. For example, you can add a number to determine how often the mail queue should be processed. Typical times are 15 to 60 minutes.
When in doubt about anything, go to sendmail.org for help.
The sendmail.cf file is typically around 1200 lines long, but a sample of the file structure is shown in the file of fragments.
Normally you wouldn't modify this file directly, but the basics of the syntax are included here.
So how do you get sendmail configured? There are a set of tools and files that are normally in /usr/share/sendmail-cf (or possibly /usr/lib/sendmail-cf on some systems). A typical directory structure is:
cf | Sample master files |
domain | Sample m4 files for Berkeley domains |
feature | Fragments to implement specific features |
hack | Special features of dubious value |
m4 | The basic config file and core files |
ostype | OS dependent file locations |
mailer | m4 files describing common mailers |
sh | Shell scripts used by m4 |
The configuration files are located in the cf directory as files with a .mc suffix. The other directories contain specific information regarding configuration which are processed with the ".mc" files to produce the sendmail.cf files. The m4 macro preprocessor is used to do the processing. The redhat.mc file specifies the configuration that you might expect on a Red Hat Linux system.
The m4 macros that are commonly used in the mc files are:
define | nbsp; | define a macro (like def in C) |
undefine | nbsp; | remove a macro definition (like undef in C) |
include | nbsp; | Includes and interprets a file |
dnl | nbsp; | discard to the next newline (a comment) |
divert | nbsp; | manage an output stream |
There are also some important macros that are used to include other files. The more important of these are:
This macro specifies a location for site-wide configuration information. For example,
DOMAIN('cs-home'))
This should be accompanied by a file usr/share/sendmail-cf/domain/cs-home which contains additional configuration information. This is often left at the default value of generic.
This macro defines the local mailers that are available and may be repeated. For example,
MAILER(smtp)
 
Here is a partial list of features and most will be discussed later.
Note that these need to be quoted as they are m4 variables and arguments with commas have to be double-quoted (``''). These seldom need to be changed, but they may need to be modified if your configuration is different from the default template.
To create your own .cf file,
It has become common on Red Hat systems to copy the .mc used to /etc/mail/sendmail.mc, apparently so that there is not doubt about which one to use. In the event that you need to create a new .cf file, it can be done in the /etc/mail directory using m4.
To have complete knowledge of the sendmail system requires a signficant amount of study and practice, more than we have time for. You can do quite a bit just with the configuration files below, and the FEATURE options.
wwwadmin: root,admin,webmaster |
root: bozo |
project3: mary,bob,candace |
To install,
newaliases
The alias file can also contain redirect information. If FEATURE(`REDIRECT') is present in the configuration file, the access file can contain records like this:
The message is returned to the sender with the new address to try. The message is not forwarded. If you want to forward, you can do that locally with the .forward file.
where the access-options are:
csnet.montana.edu | OK |
bdci-mail.com | REJECT |
campuscw.net | RELAY |
malicious.org | DISCARD |
bozo@clowns.org | 501 You can't use this mail server |
clowns.org | 550 No mail from you clowns |
To install,
makemap hash /etc/mail/access < /etc/mail/access
cs.montana.edu | us.montana.mus.msu.cs |
myisp | someisp.ispdomain.net |
To install,
makemap hash /etc/mail/domaintable < /etc/mail/domaintable
.csnet.montana.edu | cs.montana.edu |
.isp.net procmail:mailserver@relay.net |
To install,
makemap hash /etc/mail/mailertable < /etc/mail/mailertableand mailertable is enabled only if the following entry is made in the .mc file:
cs.montana.edu |
bigsky.net |
mcn.net |
194.17. |
relay-domains are enabled with one of the following entries in the .mc file:
student-clowns.org |
bozo.org |
bozo-the-clown.org |
mailbag.bozo.org |
Another use of this file to specify domains that can be accepted for delivery to other hosts. For example, a mail hub might collect mail and distribute to a number of local domains hosted on other systems,
The use of sendmail.cw is activated with the following .mc file entry:
help@origami.com | paperlady |
advice@origami.com | paperlady |
products@origami.com | ori |
mail@origami.com | error:No such user |
@clowns.com | bozo |
hawk@raptor.com | hawk@birds.com |
@raptor.com | %1@birds.com |
The use of virtusertable is activated with the following .mc file entry:
/etc/genericstable reverses this process so that local mail can be remapped to some virtual mail domain. It modifies the mail header to a new destination, but not the envelope. So the mail is\ delivered to the same mail server, but return address are changed. For example,
paperlady | help@origami.com |
ori | products@origami.com |
makemap hash /etc/mail/genericstable < /etc/mail/genericstable
and genericstable is enabled only if the following entry is made in the .mc file:
smellyfeet.com. IN MX 10 mail1.whoopee.com smellyfeet.com. IN MX 20 mail2.whoopee.comTwo mail servers provide redundancy, and the precedence values guarantee that mail1 will always to be used if it is available.
Masquerading controls outgoing mail headers. If you want to extend the address changes to the local recipients as well, use:
If you want to extend the addressing to the envelope as well as the header, add:
If you want to provide virtual mail hosting, you need to add:
Which allows you to list domains that you want to masquerade. In conjuction with this, you might want to use the limited_masquerade feature, which specifies other domain that will be masqueraded.
This feature works in conjuction with the genericstable where the domains are listed.
Normally, its not a good idea to relay mail because it allows your host to become an unwitting partner in things like email storms. sendmail-8.9 turns relaying off by default. However, if you are going to behave as a POP server, or if you have subdomains for which your server is the mail server, you will have to allow such activities. Also, if you have another host which is the mail server, then you will have to relay local mail to that server.
If you want to relay all local mail to another server, you should make the following entries in the .mc file:
If there are some users that shouldn't be forwarded, such as root, add the following:
If you want to relay all mail (local and otherwise) to a central server, use:
MAIL_HUB applies to all addresses qualified with the name of the local host, while LOCAL_RELAY applies to addresses that are unqualified. If you want both to be treated the same, set the smart_host feature.
The final step in relaying is to enter all domains that are allowed to relay in /etc/mail/relay-domains or tagged with RELAY in the access database. If you want to relay everything (not a good idea), set the promiscuous_relay feature.
If you want to forward mail to users that have changed their mail addresses to another site, you can enable redirection with:
and then put the redirection information in the access file:
Spam can be a major problem, much bigger than you think. First, you could become an unwitting spammer if you allow mail relay. Spammers find such sites and forward a single message with thousands of recipients. Your machine and network pays the price.
Also, spammers probe systems for email addresses, trying to find legitimate addresses to mail to. In some cases, they have a list of common names and they use the sendmail VRFY command to test the addresses with your sendmail server. If it responds positively, they have acquired a new address to send to. This could amount to thousands of probes if they test many names and combinations of names.
Probably the first step is to enable the access database and then reject or discard mail from the domains that seem to be a problem.
Also, sendmail supports a variety of privacy options that allow you to determine how much information another site can glean from your server. Primarily, these restrict the use of the various query commands and the access to the mail spool queue.
where the options are:
public | No privacy or security checking |
needmailhelo | Requires identification from remote host (HELO) |
noexpn | Does not allow the EXPN command (Expand Recipient List) |
novrfy | Does not allow the VRFY command (Verify user name) |
needexpnhelo | Will not execute EXPN without HELO |
needvrfyhelo | Will not execute VRFYwithout HELO |
noverb | No verbose mode for EXPN |
restrictmailq | Only mqueue group allowed to see queue |
restrictqrun | Only mqueue group allowed to run queue |
noetrn | Does not allow asynchronous queue runs as when a dial up user wants to receive mail directly. |
authwarnings | Add authentication warning (the default) |
norecipts | Turns off delivery status notification |
nobodyreturn | No message body in DSN (Delivery Status Notification), and no successful DSN returns. |
goaway | Disables all SMTP queries (VRFY, EXPN, etc.) |
For example, the following define is probably reasonable:
To limit spam, you need to identify the domains that might be responsible (unless you let the mail clients take care of it) and enter them into the /etc/mail/access file. One interesting option is to use a list called the REALTIME BLACKHOLE LIST maintained by the MAPS project. If you want to use it, add feature dnsbl to the mc file.
Mail from any site in the MAPS project database will be rejected by your machine. You can add other lists by including a URL.
You can also create your own blacklist with:
which supports 550 type of entries in the access file:
ArtFern@weasel.com | 550 Mail not allowed |
nobody@ | 550 This user not allowd |
.spammer.com | 550 Not allowed |
It is possible to perform header checking on email to further improve anti-spam filtering. This is beyond the scope this course, but would involve using the LOCAL_CONFIG AND LOCAL_RULESETS macros in the .mc file.
Set confMaxMessageSize to limit the maximum size of a message (default = 1,000,000 bytes). This is usually not a good choice as some legitimate mail is large.
Set confConnectionRateThrottle (default = 3) to limit the number of sendmail connections per second.
Set the confMaxRcptsPerMessage (default = unlimited) to limit the maximum number of recipients per message.
Reports information on the messages in the mail queue. This is useful in determining if your mailer is having difficulty delivering messages. The only option is -v, which will give the priority of the message and if delivery has already been attempted.
sendmail can be configured to collect statistics on the number and size of messages it handles. The mailstats command can then be used to view the data. In the OSTYPE file, the confSTATUS_FILE option specifies the name of the file to use (/etc/mail/statistics is the default) and enables the function.
The output of mailstats has the following format:
0 | address parsing |
1 | sender rewriting |
2 | recipient rewriting |
3 | domaintable translation |
4 | final output post-rewriting |
5 | post alias expansion rewriting |
10 | Envelope sender rewriting |
20 | Envelope recipient rewriting |
30 | Header sender rewriting |
40 | Header recipient rewriting |
50 | Add local domain |
51 | convert pseudo-domain addresses to real domain addresses |
Topic (x) | Meaning | Choices for y |
---|---|---|
0 | Shows compile flags and system identity | 1 or 10 |
8 | Shows DNS name resolution | 7 |
11 | Traces delivery | none |
12 | Shows name translation | none |
17 | Lists MX hosts | none |
21 | Traces rewriting rules | none |
27 | Shows aliasing and forwarding | 2 or 12 |
44 | Shows file open attempts during failures | 4 |
60 | Shows database map lookups | none |
  |   |
---|---|
? | this help message. |
.Dmvalue | define macro `m' to `value'. |
.Ccvalue | add `value' to class `c'. |
=Sruleset | dump the contents of the indicated ruleset. |
=M | display the known mailers. |
-ddebug-spec | equivalent to the command-line -d debug flag. |
$m | print the value of macro $m. |
$=c | print the contents of class $=c. |
/mx host | returns the MX records for `host'. |
/parse address | parse address, returning the value of crackaddr, and the parsed address (same as -bv). |
/try mailer addr | rewrite address into the form it will have when presented to the indicated mailer. |
/tryflags flags | set flags used by parsing. The flags can be `H' for Header or `E' for Envelope, and `S' for Sender or `R' for Recipient. These can be combined, `HR' sets flags for header recipients. |
/canon hostname | try to canonify hostname. |
/map mapname key | look up `key' in the indicated `mapname'. |
rules addr | run the indicated address through the named rules. Rules can be a comma separated list of rules. |
If you modify one of the /etc/mail database files, you can use the sendmail -bt command to test the configuration. In this case, you use the /map command like this:
sendmail logs through syslog using facility mail with levels "debug" through "crit". Option confLOG_LEVEL determines what level is reported. (debug means most everything, crit means only the critical stuff).
Much of what has been discussed previously relates to security in one form or another. sendmail also has features that prevent the use of .forward or aliases files that are world writable. If you want to override these features, set the confDONT_BLAME_SENDMAIL option. The name should be a reminder that this isn't particular smart.
There are three user accounts that are important to sendmail:
All sendmails mailers run as DefaultUser unless the mailer flags specify otherwise. If a "mailnull" or "sendmail" user exists, it will be the DefaultUser, otherwise it is UID=1 and GID=1 (normally bin or daemon). "mailnull" is preferred, so it should be added to the passwd file with a "star" passwd and group "nogroup". This user should own no files or directories.
TrustedUser can own maps and files and is by default root, but it can be changed.
TRUSTED_USERS is used in determining what users can process mailing lists.
RunAsUser is the UID that sendmail runs under after opening its connection. sendmail must run as root initially, and by default, continues to run as root. If it is changed to some other username, that user must:
By default, the following ownership and permission settings are necessary:
Path | Owner | Perm | Contents |
---|---|---|---|
/var/spool/mqueue | RunAsUser | 700 | Mail queue directory |
/,/var, /var/spool | root | 755 | Path to mqueue |
/etc/mail/* | TrustedUser | 644 | Map and config files |
/etc/mail/ | TrustedUser | 755 | Maps directory |
/etc | root | 755 | Path to mail directory |
If you run sendmail -v -bi, you can see if sendmail thinks that your file ownership and permissions are appropriate.
The confPRIVACY_FLAGS set to authwarnings will add an authentication-warning header if the outgoing mail appears to be forged, but many user agents hide this.
You can stop forged mail from eminating from your machine by installing and running identd. sendmail does a callback to identd to authenticate the user and get the real login name. This is then included in the message. identd (which should run by default) will return the name of the user that has a process running. On a single user machine, identd could be corrupted to return a bogus id, so don't rely on it.
Unfortunately, your .forward file must be world-readable to do this, and as we know, that can be dangerous.
If you want to invoke procmail to run over an existing file, directly or using cron, the recommended script is:
Sendmail can be configured using the M command in the .cf file, or using the MAILER option in the .mc file. This causes sendmail to use procmail to do the actual delivery of mail to the user (to the users local mailbox).
When procmail is called to do the delivery, it looks first to /etc/procmailrc for processing rules. After this, it looks for $HOME/.procmailrc for rules and the combination of the two provide the complete ruleset.
Both of these provide the essential services and many of the advanced features of sendmail in a different form. Both tend to follow the Unix-style of small components working together rather than a large monolithic system.
For example, suppose you want to use spamassassin with sendmail. You need to find a Milter plugin for spamassassin, and as it turns out, there are several at this site We will look at MIMEDefang because it has been around a while and has other uses. You can download MIMEDefang at the MIMEDefang website. MIMEDefang is written in Perl, so you can install the entire thing as Perl modules from the site or from CPAN.
After the repository is downloaded, untar it in some neutral location and then look at the README file. It mentions an excellent site for documentation at this site. Once you have MIMEDefang installed, you install spamassassin by downloading from the spamassassin site and following the installation instructions. You can also find rpm packages for spamassassin.
All of this is left as an interesting exercise, and you will note that there are other ways of getting a spam filter.
Now why use MIMEDefang instead of some other solution? Because MIMEDefang has a built in virus scanner for you email. You can configure MIMEDefang to handle mail attachments in various ways that will make it much easier to avoid viruses, and turn your Linux box into a mail filter for your Windows systems.