Quick & Dirty Guide to Sendmail

Installation and configuration

The hard way (from source code)

  1. Create directories if needed, and check ownership and access rights:
    1. mkdir -p /etc/mail /var/spool/mqueue /usr/man/man1 /usr/man/man5/ /usr/man/man8/
    2. chmod go-w / /etc /etc/mail /usr /var /var/spool /var/spool/mqueue
    3. chown root / /etc /etc/mail /usr /var /var/spool /var/spool/mqueue
  2. cd /usr/src ; tar xzvf ./sendmail.tar.gz ; cd sendmail
  3. ./Build
  4. cd cf
  5. m4 ./m4/cf.m4 ./cf/generic-linux.mc > ./cf/config.cf
  6. cd ..
  7. ./Build install
  8. cp cf/cf/config.cf /etc/mail/sendmail.cf
  9. cd sendmail
  10. ./Build install
  11. cd ..
  12. ./Build install
  13. cp sendmail/aliases /etc/mail/
  14. vi /etc/mail/local-host-names :
    mylinux.acme.com
    mylinux
    mail.acme.com
    mail
  15. /usr/sbin/sendmail -bi (or newaliases)
  16. /usr/sbin/sendmail -bd
  17. netstat -tuplan | grep sendmail (WHY IS SENDMAIL LISTENING ON TCP 587?)
  18. vi /etc/mail/sendmail.mc
    include(`/usr/src/sendmail-8.11.4/cf/m4/cf.m4')
    VERSIONID(`linux setup for Red Hat Linux')dnl
    OSTYPE(`linux')
    define(`confDEF_USER_ID',``8:12'')dnl
    undefine(`UUCP_RELAY')dnl
    undefine(`BITNET_RELAY')dnl
    define(`confAUTO_REBUILD')dnl
    define(`confTO_CONNECT', `1m')dnl
    define(`confTRY_NULL_MX_LIST',true)dnl
    define(`confDONT_PROBE_INTERFACES',true)dnl
    define(`PROCMAIL_MAILER_PATH',`/usr/bin/procmail')dnl
    define(`ALIAS_FILE',`/etc/aliases')dnl
    define(`STATUS_FILE', `/var/log/sendmail.st')dnl
    define(`UUCP_MAILER_MAX', `2000000')dnl
    define(`confUSERDB_SPEC', `/etc/mail/userdb.db')dnl
    define(`confSMTP_LOGIN_MSG', `$j SMTP mailer.')dnl
    define(`confPRIVACY_FLAGS', `noexpn,novrfy')dnl
    FEATURE(`smrsh',`/usr/sbin/smrsh')dnl
    FEATURE(`mailertable',`hash -o /etc/mail/mailertable')dnl
    FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable')dnl
    FEATURE(redirect)dnl
    FEATURE(always_add_domain)dnl
    FEATURE(use_cw_file)dnl
    FEATURE(local_procmail)dnl
    FEATURE(`access_db')dnl
    FEATURE(`blacklist_recipients')dnl
    MAILER(smtp)dnl
    MAILER(procmail)dnl
  19. m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
  20. vi access :
    127.0.0        RELAY
    192.168.0    RELAY
  21. makemap hash  access < access
  22. killall -HUP sendmail
  23.  

The easy way (using RPMs)

Note: I installed the files below on a RedHat 6.2. You might not need to install libsfio and sasl.

  1. rpm -Uvh libsfio-1999-1.i386.rpm
  2. rpm -Uvh cyrus-sasl-1.5.11-2.i386.rpm
  3. rpm -Uvh sendmail-8.9.3-20.i386.rpm
  4. rpm -Uvh sendmail-cf-8.9.3-20.i386.rpm
  5. rpm -Uvh sendmail-doc-8.9.3-20.i386.rpm
  6. In /etc/mail/local-host-names (used to be sendmail.cw), list all the names under which the mailer is known
     
    mail.acme.com
    hostrealname.acme.com
     
  7. Edit /etc/mail/access to allow local hosts to use your mailer
     
    localhost.localdomain     RELAY
    localhost    RELAY
    127.0.0.1 RELAY
    192.168.0 RELAY
    From:192.168 RELAY
    acme.com RELAY
    From:ME_TOO@aol.com REJECT
    LUSER@ REJECT
    Connect:spam-king.com ERROR:5.0.0:550 We dont accept Spam
    bad-domain.com REJECT
     
  8. (Optional) Edit /etc/mail/relay-domains (used to be sendmail.cR) to allow specific domains/networks to use your mailer as a relay

    acme.com
    192.168.0
     
  9. Launch Sendmail through /etc/rc.d/init.d/sendmail start, and check for possible errors in /var/log/maillog and /var/log/messages

Further customizing

Virtual domains

This is used to tell Sendmail to handle mail for other domains than its own. This is set in the .mc file through FEATURE(virtusertable):
	/etc/mail/virtusertable
	info@foo.com    foo-info
	info@bar.com    bar-info
	joe@bar.com     error:nouser No such user here
	jax@bar.com     error:D.S.N:unavailable Address invalid
	@baz.org        jane@example.net
	@foo.org        %1@example.com
	old+*@foo.org   new+%2@example.com
	

Domaintable

Allows for selective rewriting of domain names. For example, the entry ux4.cso.uiuc.edu students.uiuc.edu would cause all email for ux4.cso.uiuc.edu to be processed as students.uiuc.edu. The default filename for this database is /etc/mail/domaintable.

mailertable

A mailertable is a database which maps certain hosts or domains to a mailer:host pair. It is used for redirecting mail addressed to a certain host or domain to a specific destination host using a specific mailer (for example, for using phquery). The default filename for this database is /etc/mail/mailertable.
/etc/sendmail.ct -> /etc/mail/trusted-users /etc/sendmail.oE -> /etc/mail/error-header

Building a custom /etc/sendmail.cf

The only sane and safe way to build a sendmail.cf is to go through m4 macros. An m4 configuration file consists in the following structure:
	VERSIONID
	OSTYPE
	DOMAIN
	FEATURE
	local macro definitions
	MAILER
	LOCAL_RULE_*
	LOCAL_RULESETS
	
It is recommended to put the MAILER definitions last, and always put MAILER(`smtp') before MAILER(`uucp') and MAILER(`procmail'). Moreover, MAILER(`cyrus'), MAILER(`pop'), MAILER(`phquery'), and MAILER(`usenet') must be defined after MAILER(`local').

Here's a sample:

	include(`/usr/lib/sendmail-cf/m4/cf.m4')
	VERSIONID(`linux setup for Red Hat Linux')dnl
	OSTYPE(`linux')
	define(`confDEF_USER_ID',``8:12'')dnl
	undefine(`UUCP_RELAY')dnl
	undefine(`BITNET_RELAY')dnl
	define(`confAUTO_REBUILD')dnl
	define(`confTO_CONNECT', `1m')dnl
	define(`confTRY_NULL_MX_LIST',true)dnl
	define(`confDONT_PROBE_INTERFACES',true)dnl
	define(`PROCMAIL_MAILER_PATH',`/usr/bin/procmail')dnl
	define(`ALIAS_FILE',`/etc/aliases')dnl
	define(`STATUS_FILE', `/var/log/sendmail.st')dnl
	define(`UUCP_MAILER_MAX', `2000000')dnl
	define(`confUSERDB_SPEC', `/etc/mail/userdb.db')dnl
	define(`confSMTP_LOGIN_MSG', `$j SMTP mailer.')dnl
	define(`confPRIVACY_FLAGS', `noexpn,novrfy')dnl
	FEATURE(`smrsh',`/usr/sbin/smrsh')dnl
	FEATURE(`mailertable',`hash -o /etc/mail/mailertable')dnl
	FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable')dnl
	FEATURE(redirect)dnl
	FEATURE(always_add_domain)dnl
	FEATURE(use_cw_file)dnl
	FEATURE(local_procmail)dnl
	FEATURE(`access_db')dnl
	FEATURE(`blacklist_recipients')dnl
	MAILER(smtp)dnl
	MAILER(procmail)dnl
	
Once done, run m4 /etc/sendmail.mc > /etc/sendmail.cf.

Note: The dnl at the end of nearly every line stands for "delete to newline." Used after a command, it prevents the m4 macro processor from being affected by comments at the end of the line or from copying extraneous trailing whitespace into sendmail.cf. Placing "dnl " (including the space) at the beginning of a line turns the entire line into a comment.

Anatomy of /etc/sendmail.cf

Sendmail's main configuration file contains several classes of information: Built-in Sendmail rules sets:
   0 Parsing
   1 Sender rewriting
   2 Recipient rewriting
   3 Canonicalization
   4 Post cleanup
   5 Local address rewrite (after aliasing)

Masquerading

MASQUERADE_AS(`acme.com')dnl
MASQUERADE_DOMAIN(`mail.acme.com')dnl
FEATURE(allmasquerade)dnl
FEATURE(masquerade_envelope)dnl

Fighting SPAM

Good information is available from Stopping Spam and Trojan Horses with BSD available at http://www.brettglass.com/spam/paper.html.

define(`confPRIVACY_FLAGS',`goaway')dnl
FEATURE(smrsh)dnl
define(`confMAX_HEADERS_LENGTH',16384)dnl
define(`confMAX_MESSAGE_SIZE',2097152)dnl
define(`confCONNECTION_RATE_THROTTLE',3)dnl
define(`confMAX_DAEMON_CHILDREN',12)dnl
define(`confSMTP_LOGIN_MSG', `$j server ready at $b')dnl
define(`confMAX_RCPTS_PER_MESSAGE,25)dnl

FEATURE(`relay_entire_domain')
FEATURE(`relay_based_on_MX')
FEATURE(`relay_local_from')
FEATURE(`relay_mail_from')
FEATURE(`loose_relay_check')
FEATURE(`accept_unresolvable_domains')
FEATURE(`accept_unresolvable_domains')
FEATURE(`access_db')
FEATURE(`relay_hosts_only')
FEATURE(`blacklist_recipients')
FEATURE(`dnsbl')
FEATURE(`delay_checks')

Hiding the Sendmail name and version number

Besides removing all ad hoc information in the sendmail.cf (DZGreatMailer, and O SmtpGreetingMessage=$j; $b) or m4 file (define(`confSMTP_LOGIN_MSG`,'GreatMailer')dnl ), remember that you should also customize the help file whose contents is displayed when the user queries for help once he's connected to your mailer: This can be done by replacing the help file (found at /etc/mail/helpfile in recent versions) with one containing only the following two lines:
	#vers   2
	smtp    I'm sorry, Dave, I'm afraid I can't do that.
	
Note that the first area of whitespace on each line above must be a tab character, not spaces. The message may be altered to suit the administrator's taste.

Other solutions : POP connection before SMTP (http://spam.abuse.net/tools/smPbS.html) Table 3: Some popular DNS blacklists
Database Contents
MAPS Real Time Black Hole List (RBL) Hosts and networks which MAPS believes to be "friendly, or at least neutral, to spammers who use these networks either to originate or relay spam." Many mistakenly believe that the "real time" in this list's name refers to the speed with which hosts are added to the list. However, the name is intended to indicate that a mail server can block a message from the offending site in real time by querying the list. Getting a host or network added to the MAPS RBL is usually quite difficult. Entries are added only after substantial evidence has been presented that spam has been sent and complaints ignored. Queries of this database use the domain suffix rbl.maps.vix.com.
MAPS Dial-Up List (DUL) IP addresses used by ISPs' dial-up modems, as well as some pools of addresses which are dynamically assigned to DSL and cable modems. Since it is normally desirable to send mail via a server with a fixed IP address, mail sent by direct SMTP from a non-dedicated address directly to its destination is often spam. Use of the DUL to filter messages is highly effective in that it blocks much of the spam sent from "throwaway" or trial accounts with dial-up ISPs. Queries use the domain suffix dialups.mail-abuse.org.
MAPS Relay Spam Stopper (RSS) Mail servers whose bandwidth and computing power have been used to duplicate and relay spam to its final destination. In the overwhelming majority of cases, this has been done without the owner's knowledge or consent. These "open relays" are usually mail servers which run old or improperly configured mail transfer agents. Unlike ORBS (see below), the MAPS RSS only lists hosts which have been reported to have sent spam and have been confirmed to be open relays (that is, servers which will relay mail from an untrusted, outside source). It does not list "multihop relays" -- relays which consist of two or more servers working together. Queries use the domain suffix relays.mail-abuse.org.
MAPS RBL+ Master Service (RBL+) IP addresses contained in any of the MAPS databases (RBL, DUL, or RSS). The RBL+ database combines results from the three others so that a mail server can "vet" a message with a single query. A flat fee, used to support the maintenance of all of the databases, is charged for the ability to query this blacklist or mirror it via DNS zone transfers.
Open Relay Behaviour-modification System (ORBS) Mail servers which test positive for relaying, are manually entered into the ORBS database, block access when ORBS probes them, or are within the address blocks of known spammers. All servers which participate in a multihop relay are listed as open relays. The full ORBS database is queried via the domain suffix relays.orbs.org. Queries that use the suffix inputs.orbs.org instead will return a positive result only if a server has tested positive as an open relay, but not if it was blacklisted for other reasons. Some administrators see this so-called "ORBS Lite" as a good compromise between the cautious policy of the MAPS RSS and the very aggressive policy of the full ORBS database.
Adding support for blacklists:

	FEATURE(`delay_checks')dnl 
	FEATURE(dnsbl,`rbl.maps.vix.com',`Rejected - see  http://www.mail-abuse.org/rbl/')dnl
	FEATURE(dnsbl,`dul.mail-abuse.org',`Dialup - see http://www.mail-abuse.org/dul/')dnl
	FEATURE(dnsbl,`relays.mail-abuse.org',`Open relay - see http://www.mail-abuse.org/rss/')dnl
	FEATURE(dnsbl,`input.orbs.org',`Open relay - see http://www.orbs.org/')dnl
	
Make use of Procmail/formail and other filtering tools: With Procmail added in the MC file through FEATURE(local_procmail)dnl, global filters can then be added to the global procmailrc file (eg. /etc/procmailrc), and individuals can choose to invoke additional filters via ~/.procmailrc files in their home directories.

Most procmail spam filters do not use procmail alone, but combine it with other programs or subroutine packages. These include perl, formail (included with procmail), mktemp, mimencode (part of metamail), or Mime::Base64 (a CPAN module for perl).

The Spam Bouncer, developed on FreeBSD by Catherine Hampton, is among the most popular Procmail spam fighting kits. It uses Procmail and formail to detect, block, and optionally complain to the host ISP about spam. SpamDunk, by Walter Dnes, is similar, as is Greg Sutter's junkfilter. John Hardin's Procmail Filters Kit is noteworthy in that it sorts its many spam detecting rules into easily recognizable categories. (For example, if an administrator or user does not want to block messages that appear to be unwanted religious diatribes, he or she can disable the "proselytize-trap" filter.) Other Procmail-based spam filters include Bob's Spam Filter, Steve Tucker's Spamkill, and Farhad Anklesaria's Spamtrap.

Obtuse Systems' smtpd and smtpfwdd are a complementary pair of SMTP proxy daemons that can be combined to serve as a front end for sendmail. As with the sendmail access_db feature, smtpd allows the administrator to create rules that govern the acceptance or rejection of mail. Because smtpd is far more "lightweight" than sendmail, it reduces the overhead of rejecting mail that fails to satisfy the rules.

The most common way of detecting HTML-based exploits in e-mails is via procmail filter kits designed for this purpose. John Hardin's Procmail Sanitizer, perhaps the best of these, disables active content, "mangles" file extensions, optionally disables image tags, and can quarantine messages which are likely to contain malicious code. It can also scan Microsoft Office documents for macros and score them according to their potential virulence. Bjarni R. Einarsson's Anomy is similar and credits Hardin's work as inspiration.

procmail malware filter kits are installed in the same way as procmail filters for spam. Since procmail is a mail delivery agent, procmail filters normally process only mail which is bound for local users on the system where they run. However, with special changes to rules in sendmail.cf, they can work with sendmail to filter all the mail that passes through a server.

Access

The access database (normally in /etc/mail/access) allows a mail administrator to administratively allow access to the mail server by individual domains. Each database entry consists of a domain name or network number as the key and an action as the value.
cyberpromo.com  	REJECT 
sendmail.org    	RELAY 
spam@buyme.com  	550 Spammers shan't see sunlight here
192.168.212		REJECT
From:spammer@some.dom   REJECT
To:friend.domain        RELAY
Connect:friend.domain   OK
Connect:from.domain     RELAY
Connect:192.168.0	RELAY
From:good@another.dom   OK
From:another.dom        REJECT
Note: RELAY is a superset of OK and is more permissive. RELAY allows mail to be relayed or received while OK only allows it to be received. DISCARD causes the server to feign acceptance of a message and then not deliver it to some or all of the intended recipients. When a DISCARD record matches the sender (MAIL FROM:), the message will not reach any recipient. However, when it does not match the sender but does match a recipient (this will only occur if FEATURE(`blacklist_recipients') is present in the .mc file), it prevents only the specified recipient from getting the message. Others will receive it unless they too are "blacklisted."

Note that the access database is a map and just as with all maps, the database must be generated using makemap. For example: makemap hash /etc/mail/access < /etc/mail/access

Relaying

The simplest approach is to list the domains you are willing to relay in the file /etc/mail/relay-domains. Anything listed in this file will be accepted for relaying. N.B.: Sendmail must be restarted after this file is modified.

FEATURE(relay_hosts_only) Normally domains are listed in /etc/mail/relay-domains; any hosts in those domains match. With this feature, each host in a domain must be listed.
FEATURE(relay_entire_domain) Setting this feature allows relaying of all hosts within your domain. For example, on the host gateway.A.COM, this feature allows mail to or from any host in the A.COM domain. More precisely, this relays any host listed in the $=m class. This is equivalent to listing the name of the domain in /etc/mail/relay-domains.
FEATURE(access_db) This enables the hash database /etc/mail/access to enable or disable access from individual domains (or hosts, if FEATURE(relay_hosts_only) is set).
FEATURE(blacklist_recipients) If set, this feature looks up recipients as well as senders in the access database.
FEATURE(rbl) Enables rejection of mail based on the Realtime Blackhole List maintained at maps.vix.com.
FEATURE(accept_unqualified_senders) Normally, sendmail will not accept mail from a sender without a domain attached -- for example, user instead of user@B.NET. This feature allows such users.
FEATURE(accept_unresolvable_domains) Normally, sendmail will refuse to accept mail that has a return address with a domain that cannot be resolved using the regular host lookups (a technique commonly used by spammers). This feature permits acceptance of such addresses. Unresolvable domains can be selectively accepted using the access database.
FEATURE(relay_based_on_MX) Setting this feature permits relaying for any domain that is directed to your host.

Files

Macro files

Located in /usr/lib/sendmail-cf/

Configuration files

/etc/aliases
/etc/mail/Makefile
/etc/mail/access
/etc/mail/domaintable
/etc/mail/mailertable
/etc/mail/virtusertable
/etc/mail/local-host-names (used to be /etc/sendmail.cw)
/etc/mail/relay-domains (used to be /etc/sendmail.cR) 
/etc/sendmail.cf
/etc/sendmail.mc
/etc/smrsh
/etc/sysconfig/sendmail

Binaries

/usr/bin/hoststat
/usr/bin/mailq
/usr/bin/makemap
/usr/bin/newaliases
/usr/bin/purgestat
/usr/bin/rmail
/usr/lib/sendmail
/usr/lib/sendmail.hf
/usr/sbin/mailstats
/usr/sbin/makemap
/usr/sbin/praliases
/usr/sbin/sendmail
/usr/sbin/smrsh

Data files

/var/log/sendmail.st
/var/spool/mqueue

Documentation files

/usr/doc/sendmail/FAQ
/usr/doc/sendmail/KNOWNBUGS
/usr/doc/sendmail/LICENSE
/usr/doc/sendmail/README
/usr/doc/sendmail/README.cf
/usr/doc/sendmail/README.smrsh
/usr/doc/sendmail/RELEASE_NOTES
/usr/doc/sendmail/doc
/usr/doc/sendmail/doc/changes
/usr/doc/sendmail/doc/changes/Makefile
/usr/doc/sendmail/doc/changes/changes.me
/usr/doc/sendmail/doc/changes/changes.ps
/usr/doc/sendmail/doc/intro
/usr/doc/sendmail/doc/intro/Makefile
/usr/doc/sendmail/doc/intro/intro.me
/usr/doc/sendmail/doc/intro/intro.ps
/usr/doc/sendmail/doc/op
/usr/doc/sendmail/doc/op/Makefile
/usr/doc/sendmail/doc/op/op.me
/usr/doc/sendmail/doc/op/op.ps
/usr/doc/sendmail/doc/usenix
/usr/doc/sendmail/doc/usenix/Makefile
/usr/doc/sendmail/doc/usenix/usenix.me
/usr/doc/sendmail/doc/usenix/usenix.ps

Manual pages

/usr/man/man1/mailq.1.gz
/usr/man/man1/newaliases.1.gz
/usr/man/man5/aliases.5.gz
/usr/man/man8/mailstats.8.gz
/usr/man/man8/makemap.8.gz
/usr/man/man8/praliases.8.gz
/usr/man/man8/rmail.8.gz
/usr/man/man8/sendmail.8.gz

Q&A

When sending an e-mail to a local account, Sendmails queues it and complains with "MX list for acme.com. points back to mylinux.acme.com [...] DSN: Local configuration error"

You forgot to add acme.com to /etc/mail/local-host-names, so Sendmail considers that the e-mail you sent to eg. user@acme.com must be forwarded to a remote MTA instead of being delivered locally. Here's what the local-host-names file should look like:

mylinux.acme.com
acme.com
mylinux
mail.acme.com
mail

Don't forget to run either "cd /etc/mail ; makemap hash access < access" or "/etc/rc.d/init.d/sendmail restart" to tell Sendmail to re-read this file.

In /etc/mail/access, I can't enforce REJECT

If I use the following, connection from w2k.acme.com/192.168.0.1 is allowed. I tried reversing the order, to no avail. Is is by design?

192.168.0                       REJECT
acme.com                        RELAY

Resources