(Currently maintained by Ross Hamilton)
Last updated: 20th March 1998
In early 1998 the DCS mail system was upgraded from the ageing, slow and poorly featured PP mail transport agent (MTA) to the most recent version (8.8.8) of Berkeley Sendmail integrated with Procmail 3.10 as the local delivery agent (LDA), in order to provide fast, efficient, flexible mail delivery with filtering and anti-spam features.
The PP mail relay rainich (a SPARCstation 5) has been replaced with a new machine, muck (an UltraSPARC 150E). This is the most visible SMTP server (ie is most obvious from outside the department being the most prefered host specified in the departmental MX record, dcs.ed.ac.uk, and the only one listed in that record that is located in the department). The role of this machine is to accept mail from outside for delivery to local aliases (be they mailboxes, mailing lists, programs or simply redirection to other sites), or to accept mail from other departmental machines for relay outwards to remote sites. The main program that performs this task is sendmail.
The local version of sendmail on muck is the most recent release (at the time of the mail system development) - namely 8.8.8. It is run as a daemon, bound, listening to the SMTP port and processing the local (to muck) mail queue at least every minute:
/opt/mail/sbin/sendmail -bd -q1m
-C/opt/mail/etc/mail/sendmail.cf
Another sendmail process
/opt/mail/sbin/sendmail -q1m
-C/opt/mail/etc/mail/sendmail-lists.cf
looks after the lists queue making sure that any straggler traffic gets kicked at least every minute (since bulk_mailer, used to dispatch list mail, instructs sendmail to queue mail first then process it on a subsequent run).
On muck any binaries associated with mail are stored in
/opt/mail/sbin
whilst the configuration and database files are stored in
/opt/mail/etc/mail
The /opt/mail directory is mirrored to /export each night with lfu.
This version of sendmail has been enhanced beyond the standard Berkeley version. The following features should be noted:
Sendmail hands mail for local delivery to procmail which will write the mail to the users mail inbox (.mail) after acting on any global and user procmailrc/forward file.
In /opt/mail/etc/mail you will find the sendmail configuration file, database files for controlling relaying, spamming, aliases and tables for routing mail and creating virtual users. Those files are as follows:
| domain.to.mail | transport:relay.host.name |
To explicitly deliver mail to a given host, bypassing MX records, you should use the syntax:
| domain.to.mail | transport:[relay.host.name] |
Note that matching is done in order of most-to-least qualified. Also, a %1 syntax may be used to interpolate the wildcarded part of the host name. For more details and examples see cf/README.
The file is converted to a hashed file by the make process.
| dcs | dcs.ed.ac.uk |
It is advised to avoid this and discourage use of it due to conflicts which may arise in the future with the increasing pressure to deregulate and expand the top level domain namespace. Instead, fully qualified domain names should be used. The file is converted to a hashed file by the make process.
| fred@wherever.org | user1@dcs.ed.ac.uk |
or we can route mail for any user in that virtual domain to a real user:
| @wherever.org | user2@dcs.ed.ac.uk |
or we can map the username from one domain to the same in another:
| @foo.org | %1@elsewhere.com |
This is detailed further in the sendmail source tree cf/README. The file is converted to a hashed file by the make process.
| username | initial.surname@dcs.ed.ac.uk | |
| user@dcs.ed.ac.uk | a.n.other@wherever.org |
The domains for which we will perform this rewrite are specified in the generics_domainfile, one per line. This is detailed further in the sendmail source tree cf/README. The genericstable file is converted to a hashed file by the make process. generics_domainfile is a flat ASCII file. Any virtual users (virtusertable) for who you want From lines preserved should be added to this file as well.
| CheckpointInterval=3 | (to avoid resends after a crash) |
| QueueLA=5 | (stop processing the lists queue) |
| DefaultUser=31056:31000 | (majordom:local) |
| MaxRecipientPerMessage | (unlimited on lists, 500 otherwise) |
| MaxMessageSize=15000000 | (bytes; 150Mb on main queue) |
| QueueSortOrder=host | (sort on hostname) |
| StatusFile=/opt/mail/etc/mail/sendmail-lists.st |
Using a separate queue also has the advantage that a different MTA could be used in future for handling the lists (for example, exim or vmailer, drop in replacements for sendmail, which are acknowledged to have better performance).
| user@dcs.ed.ac.uk | "550 You are not permitted to send mail" |
(whilst you could also deny incoming traffic by modifying aliases).
A few words about the filtering and anti-spoofing/abuse methods that are available. These are multi-layered and outlined below:
The aliases in aliases-news define the newgroups for which the system provides a mail to news gateway (local eduni.dcs.* newsgroups). This uses the perl script /usr/local/etc/mail2news which in turn makes use of inews to dispatch the news posting vial NNTP to the news server.
Majordomo 1.94 manages all the official departmental lists. The aliases for this are in aliases-majordomo and the list files are in /opt/mail/etc/mail/majordomo/lists (the majordomo tools and config files are in /usr/local/lib/majordomo-1.94). The lists use a separate queue /var/spool/listsmqueue into which list mail is delivered using the bulk_mailer program (this pre-sorts the list mail and chops it up in order to aid sendmail in processing it more efficiently). The advantage of this scheme is that it can be migrated to a faster MTA (eg replace sendmail with exim, or perhaps vmailer) should traffic levels require this.
The lists queue can be examined by using the command:
/opt/mail/sbin/sendmail -bp
-C/opt/mail/etc/mail/sendmail-lists.cf
Users who want to run their own lists (especially small or short lived ones such as those managed by students) should be encouraged to use procmail for this (either through hand crafted recipes - refer to the procmailex man page - or using a package such as SmartList).
Outlined below are several of the most common tasks.
The main mail queue can be examined using mailq (check /opt/mail/sbin is at the front of your PATH). The output looks like:
Mail Queue (4 requests)
--Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient------------
RAA04895* 2709 Fri Jan 30 17:03 <skeletons-request@dcs.ed.ac.uk>
mmarr@lehman.com
PAA00816 325 Fri Jan 30 15:05 <hn@dcs.ed.ac.uk>
(Deferred: Connection refused by gns001.gulfnet.co.jp.)
<aba8cnla@GNS001.GULFNET.CO.JP>
OAA00084* 115 Fri Jan 30 14:47 <ewd@dcs.ed.ac.uk>
(host map: lookup (ox.ios.ac.cn): deferred)
<xw@ox.ios.ac.cn>
KAA01102 2680 Thu Jan 29 10:21 <wb@dcs.ed.ac.uk>
(host map: lookup (condor.daltek.net): deferred)
<roxxyy@condor.daltek.net>
An asterisk (*) indicates that that mail message is currently being processed. Other messages may be delayed for several reasons - most commonly remote mail server problem (error message: connection refused, or perhaps more meaningful such as an indication that the recipients is over quota or there is a lack of disk space), poor or non-existant network connectivity (connection timed out) or DNS lookup problem (map: lookup deferred). In this last case you should make sure that the local (muck) named is still running and it is not returning corrupted information. Often this problem arises due to a lack of an A or MX record for the domain/host concerned - either due to incorrect DNS configuration at the remote site or because that host/domain was never intended to receive mail (for example a user trying to mail username@host.domain.net instead of username@domain.net; this can also lead to the connection refused error). In these cases you can do one of two things. Either let the mail bounce as it will eventually do (the timeout is 5 days, as recommended by the rfc's and set in the sendmail.cf file), or you could help the mail to its destination by hard wiring a suitable mail relay/server into the mailertable. For example in the above case you might check that domain.net has suitable MX records and then add
| .domain.net | smtp:domain.net |
to mailertable and rebuild it. Alternatively judicious examination of traceroute, whois and name server records may reveal a suitable intermediate host (with better connectivity with yourself and with the target destination machine) to which you can build a route and dispatch the mail (though due to the proliferation of spamming this option is now more often than not closed to you). You should now be able to kick the mail queue and dispatch the mail.
You can kick the mail queue by message ID or by sender or recipient string. The syntax is (for recipient, sender and ID respectively):
/opt/mail/sbin/sendmail -qR<string> /opt/mail/sbin/sendmail -qS<string> /opt/mail/sbin/sendmail -qI<messageID>
add the -v flag if you wish to be voyeuristic or are trying to figure out why mail is sticking in the queue (it will print the SMTP conversation with the remote server).
Use the same approach if a local home directory server has been down - procmail will signal temporary errors to sendmail causing mail to be requeued until the server is back up.
If a host or network is down for a long period of time (eg a country or perhaps a machine we MX for such as tardis) you might want to move the queue elsewhere and process it separately, leaving the main mail queue free for other traffic (if a very large number of mail messages build up in the queue, sendmail will spend a lot of its time stating those files and sorting the queue in order to prioritise the mail correctly; by large I mean several hundred plus). You should first stop sendmail. Next copy the contents of the main queue, mqueue, to the spare queue, mqueue2. For example as root:
bash% purgestat
bash% cd /var/spool/mqueue
bash% lfu * ../mqueue2/
this will copy the current mail spool to the backup spool area. The purgestat removes the persistant host information (see below) which doesn't need to be moved. Restart sendmail on the main queue, and then start a separate sendmail to process the backup queue:
bash% /opt/mail/sbin/sendmail -q5m
-C/opt/mail/etc/mail/sendmail-backupq.cf
Keep an eye on this queue:
bash% /opt/mail/sbin/sendmail -bp
-C/opt/mail/etc/mail/sendmail-backupq.cf
to make sure that it eventually clears.
As mentioned above sendmail stores persistant hosts information in /var/spool/mqueue/.hoststat . This database contains the status of every relay that sendmail has contacted. If sendmail needs to contact one of these relays again (before it reaches the hoststat timeout value given in sendmail.cf) it checks the database to see if that relay was reachable or accepting mail. If not it queues the mail for a subsequent mail relay attempt (instead of wasting resources trying to contact that relay). The database can be viewed with the command hoststat and purged using the command purgestat. The purging is performed nightly by cron in order to avoid the database growing too large and impacting on disk I/O (it stores its data in what can become a very large directory hierarchy). If mail is stuck in the queue and attempts to kick it appear to die silently check that the mail relay concerned isn't marked as bad in the hoststat database.
The files, on disk, in the queue are labelled like
<file-type><sendmail message ID>
The sendmail message ID is like RAA26891 whilst the file types are qf, df, tf, xf and Qf. The first two are the most common. Each message consists of a queuefile (qf) containing the SMTP envelope data plus sendmail queue processing status information and a datafile (df) containing the body of the message itself. When moving or deleting messages from the queue you should always manipulate them in qf/df pairs. The tf files are temporary copies of the qf files, existing momentarily each time the queue is being processed and the staus of each message is being updated. xf files are transcripts of on going SMTP conversations, transcripts of sendmail sessions whilst mail is being received. The Qf files are bogus files; sendmail carries out a number of security checks on qf files and if such a file fails then it is renamed to a Qf file (see the bat book for further details). Hopefully few if any of these will appear.
The queue should periodically be cleaned in order to remove accumulated cruft (zero length files, convert tf to qf files, remove df files for which there is no qf file). The script /opt/mail/sbin/cleanq can be used to do this (run it with the path to the queue to clean as an argument).
See appendix B of the sendmail operations guide for more details.
The sendmail information that is sysloged is similar to this extract (wrapped for clarity):
Jan 25 12:13:53 muck.dcs.ed.ac.uk sendmail[23891]: RAA23891: from=<abc@dcs.ed.ac.uk>, size=402, class=0, pri=30402, nrcpts=1, msgid=<1544.199801278713@scaraig.dcs.ed.ac.uk>, proto=SMTP, relay=abc@scaraig.dcs.ed.ac.uk [129.215.64.71] Jan 25 12:13:54 muck.dcs.ed.ac.uk sendmail[23893]: RAA23891: to=<zaza@informatik.tu-muenchen.de>, ctladdr=<abc@dcs.ed.ac.uk> (28315/28031), delay=00:00:01, xdelay=00:00:01, mailer=esmtp, relay=tuminfo2.informatik.tu-muenchen.de. [131.159.0.81], stat=Sent (2.6.0 S.onVLG110513 message accepted)
A line is logged upon receipt of the message and then one is logged for each delivery attempt (of that message). The full details are in the sendmail operation guide (section 2.1.1) but the key items are the sendmail message ID (RAA23891, in the extract above) which allows you to cross reference the logged data with the queue information and the files on disk in the queue spool, the message ID itself (msgid) which matches that in the headers of the actual message itself, the time the message spent on our relay being processed (delay, should be low), the time taken trying to deliver the message (xdelay, usually indicates how good connectivity to the remote machine is or how responsive it is), the relays involved and the status of the message (stat). Note that for local delivery xdelay should be low unless a home directory server is down or procmail is having difficulties locking files.
On the mail relay (muck) nsu to majordom then go to the master lists directory:
cd /opt/mail/etc/mail/majordom/lists
Now create a file called <name-of-list> and an associated password file called <name-of-list>.passwd (chmod 600 this to protect it). Move back to the main mail configuration directory and become user sendmail. Now edit aliases-majordomo putting the appropriate aliases in that file (copy the aliases for another list and simply edit references to that list). Don't forget to set the list owner correctly. Now nsu to root and run make to build the final aliases file. You can create a config file for the list by mailing majordomo with
writeconfig <listname> <password>
in the body of the message.
There are several programs/scripts for collecting or processing mail related statistics. Apart from mailstats which comes with sendmail (it provides a summary of traffic), there are several scripts under ~ mailutil/various which could be used to build statistics for the web (for example).
Besides this local configuration document, you should refer to the sendmail documentation for more information. This consists of the sendmail installation operation guide
/home/sendmail/sendmail-8.8.8/doc/op/op.ps
plus READMEs in that same sendmail source tree (especially cf/README). Also consult the O'Reilly bat book - second edition in the support office. Details on spamcan are at
http://consult.ml.org/~ timb/spamcan/
on the regexp maps at
http://www.stud.uni-hannover.de/~ jk/map-regex/
and the sendmail.cf hacks from Claus Assman's web pages at
http://www.informatik.uni-kiel.de/