SUMMARY - customizing sendmail.cf for NFS mailhub clients.

From: Bill Smith (SMITH@gs.com)
Date: Tue Aug 11 1992 - 01:02:49 CDT


Last week I submitted a question regarding sendmail.cf and NFS mounted
/var/spool/mail. The following summarizes what I have learned but first, I will
restate some background for context.

GOALS
=====

Set up a mail hub which will act as an NFS server for /var/spool/mail for
our workstation clients. This is *not* the relay host to the real world. It
will allow all local Unix mail to be sent to this hub and read from this hub.
There should be (almost) no need to know individual hostnames, just the hub.

Since /var/spool/mail is NFS mounted on the clients, it is undesireable to
allow client sendmail processes to deliver mail locally (i.e. write directly to
the NFS mounted partition). Hence mail that is (incorrectly) addressed to a
client workstation, should be bounced to the mail hub for local delivery there.

Mail coming from clients should always appear as though it comes from the hub
for the purposes of replyability and name hiding.

If the mailhub is down, store and forward mechanisms must continue to work to
allow mail to be queued till the hub is back.

There are several ways to tackle this. I went through a couple of iterations
until arriving at the solution I now have. The following people were very
helpful in formulating this. This note will coalesce their input as well as
some of my own observations in one place:

Neil W. Rickert
Eckhard R"uggeberg
Frank P. Bresz
Rob Montjoy*
Rick Schultz
Dave Gagne

*Rob provided a sendmail.cf (written by "Spike" which was just about perfect
for what I needed. I am employing it (with a few small changes). Thanx Rob.

First I played around with the sendmail remote option.

The sendmail "remote" option (OR in sendmail.cf) is on by default. This causes
the mailer (when sending mail) to bypass the sendmail daemon on the client and
connect directly to the one on the hub for parsing and delivery. Since the
hub's sendmail is acting on your behalf, this is slick in that it always
appears as though the mail comes from the hub. There is a big downside to this.
If the hub is down, you cannot talk to sendmail and local queueing does not
take place, hence no store and forward till the hub is back up. (I have also
been told that there are other problems with the remote option).

Then I turned off the remote option. I played various games with rewrites then
to make the sender look like it was the server (necessary because the client
sendmail is now doing the sending). This part was not difficult, just required
a small mod to rule S11 in the ether mailer.

I now wanted users to be able to send mail to user instead of user@machine or
user@mailhub. I also wanted to prevent mail mistakenly sent to user@machine
to be delivered there (I want it bounced to the hub). I could accomplish this
with a massive alias database with a record for each user as such:
user: user@mailhub.

This would handle both problems. Alias translation would happen outbound for
mail sent to user and inbound on "machine" for mail to user@machine. In any
case, the mail would end up on mailhub. The downside is that this could be
unwieldy with hundreds of users so I wanted to build it into the rules.

I chose to rewrite the end of rule S0 so that what would normally resolve to
the local mailer would resolve to the ether mailer and fire it to the
mailhub. This worked except that I lost my personal name. I then threw it to
the internet mail list (you folks) and the responses were excellent. Basically
here is the scoop:

S0 will be applied to both sender and recipient. Sendmail will only look up the
full name and define $x for senders that resolve to the local mailer. Since I
resolved everything to the ether mailer, this lookup was bypassed inside the
sendmail daemon and the fullname was never appended.

If you route *all* mail thru the mailhub, then the mailhub (without the
rewriting rule) will successfully lookup and tack on the personal name
(provided you are in the same NIS domain). So instead of my machine sending
mail directly to user@machine.other.domain.gs.com or the internet mail gateway
machine, you send it to the mailhub (NFS server) and it will either deliver it
(for other clients of the mailhub) or forward it. It adds an extra step in some
cases but works fine:

Mail sent from smith@smg01 to jones@smg02 (both NFS clients of the mailhub)
will go from smg01 to mailhub, from mailhub to smg02. smg02 has same rewrite
which sends it back to mailhub where it is delivered. smg01 nor mailhub know
if smg02 is participating in the NFS mailhub. Only smg02 knows (via the
rewrite) so it has to get there. Note that we hope this is the exeption.
Generally, mail would be sent to jones or jones@mailhub and stop there but I
wanted to handle all cases.

(Something I don't understand yet is why the definition of $q as Dq<$g> seems
to work better that Dq$g$?x ($x)$. but it does).

Another seemingly unsolvable problem has cropped up. .forward and mail piped to
a program ceases to work with an NFS mailhub unless everything is mounted
there (not desireable). root mail causes a problem as well. With every client
mounting /var/spool/mail from the NFS mailhub, all root mail ends up jumbled
together on the mailhub. I am tackling it this way. Each client has a /.forward
file which forwards mail to the SA for that system (driven off a hostname
standard). I have an NIS map called mail.exceptions. The sendmail.cf has a
class defined for that map. All the rules will punt mail to the mailhub unless
the username is in the map. Mail destined for user@machine where user is in the
exceptions map, will be allowed to be delivered locally - the assumption is
that a .forward file visible from that machine will do something other than let
it be written into the NFS mounted /var/spool/mail. This should also allow us
to set up production accounts that will allow mail to be piped into a program.

I hope this mail was informative and not too long-winded. I was not totally
sure what an acceptable upper bound was but there is plenty to say on this
topic.

I also am not sure of the etiquette of including the sendmail.cf in here that I
got from Rob but it is of crucial importance in this case so I will include it
(with my changes) because it is almost directly usable. If this is
inappropriate you can constructively criticise me and I won't do it again.

###########################################################
#
# SENDMAIL CONFIGURATION FILE FOR NFS CLIENTS.
#
# You should install this file as /etc/sendmail.cf
# if want mail to appear to come from one central server
# and not to be delivered localy. For ease of use, you
# should then NFS mount the servers /usr/spool/mail on
# the local /usr/spool/mail.
#
# All this cf does is change any reference to the local
# hostname to the name of the server, and then send the
# mail to the server. All other address parsing is handed
# off to the server.
#
# I believe that this configuration functions correctly, however:
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# Written by Spike (spike@world.std.com). Also check out his cool
# Server cf.
#
# GOLDMAN SACHS MODIFICATIONS
#
# 08/03/92 whs Changed OT option to 30m from 3d as per Paul.
# Defined class L to be username in local passwd file. This
# is used as an exception to the rule for punting to hub.
# Define H as the mailhub. Put the que dir back to mqueue.
#
# 08/07/92 whs Add a couple more rules to S0 to handle a loop condition
# with something like exceptionuser@machine.
#

# define class L from the local passwd file. Allow these to be delivered
# locally.
#FL/etc/passwd %[^:]%*[^\n]\n
DLmail.exceptions

# my official hostname
Dj$w

# major relay mailer
DMTCP

# This is the name of the major relay so we can change our name.
# For example:
DHfi

#################################################
#
# General configuration information

# local domain name
# For example:
#Dmuc.edu

# Version number of configuration file
DVSpike-2.2

### Standard macros

# name used for error messages
DnMailer-Daemon
# UNIX header format
DlFrom $g $d
# delimiter (operator) characters
Do.:%@!^=/[]
# format of a total name
#Dq$g$?x ($x)$.
# This tends to get the Fullname added correctly
Dq<$g>
# SMTP login message
De$j Sendmail $v/$V ready at $b

### Options

# location of alias file
OA/etc/aliases
# default delivery mode (deliver in background)
Odbackground
# rebuild the alias file automagically
OD
# temporary file mode -- 0600 for secure mail, 0644 for permissive
OF0600
# default GID
Og1
# location of help file
OH/usr/lib/sendmail.hf
# log level
OL9
# default messages to old style
Oo
# Cc my postmaster on error replies I generate
OPPostmaster
# queue directory
OQ/usr/spool/mqueue
# read timeout for SMTP protocols
Or15m
# status file -- none
OS/etc/sendmail.st
# queue up everything before starting transmission, for safety
Os
# return queued mail after this long. Changed to 15m per Paul (whs 7/31/92)
OT15m
# default UID
Ou1

### Message precedences
Pfirst-class=0
Pspecial-delivery=100
Pjunk=-100

### Trusted users
T root daemon uucp

### Format of headers
H?P?Return-Path: <$g>
HReceived: $?sfrom $s $.by $j ($v/$V)
        id $i; $b
H?D?Resent-Date: $a
H?D?Date: $a
H?F?Resent-From: $q
H?F?From: $q
H?x?Full-Name: $x
HSubject:
H?M?Resent-Message-Id: <$t.$i@$j>
H?M?Message-Id: <$t.$i@$j>
HErrors-To:

###########################
### Rewriting rules ###
###########################

# Sender Field Pre-rewriting
S1
# None needed.

# Recipient Field Pre-rewriting
S2
# None needed.

# Name Canonicalization

# The magic to change the mail to make it look like it comes from the sever
# machine. If the address contains no hostname or our hostname, we change it
# to be the server hostname. $H is the name of the server machine...

S3

R$*<$+>$* $2 basic RFC822 parsing
R$!L $@$1@$H user -> user@$H
R$+@$+ $:$1@$[$2$] find real name (!CNAME)
R$!L@$=w $@$1@$H user@local -> user@$H
R$!L@$=w.$m $@$1@$H user@local.domain-> user@$H
R$=w!$!L $@$2@$H local!user -> user@$H
R$=w.$m!$!L $@$2@$H local.domain!user-> user@$H
R@$=w:$!L $@@$H:$2 @local:something
R@$=w.$m:$!L $@@$H:$2$3 @local.domain:something
R$~L%$=w $@$>3$1@$2 user%local
R$+%$=w.$m $@$>3$1@$2 user%local.domain

# We never deliver mail locally, so these are unused. How ever sendmail gets
# unhappy if we don't have them...
S4
# None needed

Mlocal, P=/bin/mail, F=rlsDFMmnP, S=10, R=20, A=mail -d $u
Mprog, P=/bin/sh, F=lsDFMeuP, S=10, R=20, A=sh -c $u

S10
# None needed.

S20
# None needed.

############################################################
#####
##### Ethernet Mailer specification
#####
##### Messages processed by this configuration are assumed to remain
##### in the same domain. This really has nothing particular to do
##### with Ethernet - the name is historical.

MTCP, P=[IPC], F=msDFMuCX, S=11, R=21, A=IPC $h
S11
# None needed.

S21
# None needed.

##### RULESET ZERO PREAMBLE

S0
# On entry, the address has been canonicalized and focused by ruleset 3.

# If the username is in the L class, then allow local deliver.
# ** NOTE: this assumes that the local username has a .forward file which
# will actually forward it somewhere else and not actually deliver
# it locally (to the SA for this machine for example).
R$%L $#local $:$1
R$%L@$=w $#local $:$1 prevent looping
R$%L@$=w.$m $#local $:$1 prevent looping

# Everthing else is punted to the mail server.
R$+ $#$M $@$H $:$1

I hope this helps

Bill Smith
Goldman, Sachs & Co.
(212)902-1920
smith@gs.com



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:06:47 CDT