Passing All Mail to a Relay

Create a minimal sendmail configuration containing only an OSTYPE statement to specify the correct operating system and a FEATURE command to select the nullclient feature:

# cd /usr/local/src/sendmail-8.12.9/cf/cf 

# cat > sendmail.mc 

VERSIONID(`nullclient master configuration file.')

dnl Select the correct operating system  OSTYPE(`linux')

dnl Select the nullclient feature and specify the relay server

FEATURE(`nullclient', `smtp.wrotethebook.com')

Ctrl-D 

Build the new sendmail.cf file, copy it to the correct path, and restart sendmail.

Any Unix system running sendmail, even when the system is used as a single-user workstation, is fully capable of handling its own mail. Some workstations configure sendmail to handle both inbound and outbound mail—just like a mail server. Many Unix workstations, even those that depend on a mail server to collect their inbound mail, have a full sendmail configuration for handling outbound mail. Yet, it is also possible to create a very simple sendmail configuration on a workstation that relies on a mail server for both inbound and outbound mail service. When the nullclient feature is used, a system sends all of its mail through a mail relay host.

The nullclient configuration contains only two essential lines: the OSTYPE macro that identifies the client’s operating system and the FEATURE macro that configures the nullclient feature. The nullclient feature has two fields. The first is the feature name: nullclient. The second is the name of the relay host to which outbound mail is sent. The format of the second field is mailer:host., where mailer is the name of a mailer defined in the configuration and host is the domain name of the relay host. The basic nullclient configuration contains only the local and prog mailers, and the five SMTP mailers: smtp, esmtp, smtp8, dsmtp, and relay. mailer defaults to relay if no other mailer name is provided. This default is correct and should only be changed if you add other mailers to the configuration and have a specific reason for using another mailer. We allow mailer to default to relay in the sample configuration, and we recommend that you do the same.

The server value is assigned to the $S, $H, and $M macros in the sendmail.cf configuration file. These macros are, respectively, the smart host, mail hub, and masquerade macros. sendmail:

  • Sends all outbound mail to the server identified by the $S macro; sends all mail that would normally be delivered by the local mailer to the server identified by the $H macro.
  • Changes the hostname in the sender address of outbound mail to the hostname defined in macro $M.

A few sendmail -bv tests show the impact of the nullclient configuration on mail delivery:

# sendmail -bv tyler@example.com

tyler@example.com... deliverable: mailer relay, host smtp.wrotethebook.com, user

tyler@example.com  # sendmail -bv sara@crab  sara@crab... deliverable: mailer relay,

host smtp.wrotethebook.com, user

sara@crab.wrotethebook.com

# sendmail -bv craig

craig... deliverable: mailer relay,host smtp.wrotethebook.com, user

craig@smtp.wrotethebook.com

The host value displayed by the first test shows that mail addressed to a user on an external host is sent through the mail relay host. In the generic configuration, mail addressed to an external system is sent directly to that system or to its MX server, using the esmtp mailer. On the nullclient system, the mail is sent to the relay host using the relay mailer. In this example, the client then relies on smtp.wrotethebook.com to relay the mail to tyler@example.com.

The second test is very similar to the first. In the second test, mail is addressed to another host within the local wrotethebook.com domain. Again, the mail is sent to the relay server instead of directly to the external host.

Probably the most interesting is the third test, which shows how mail is delivered to the local username craig. Normally, mail addressed in this manner would be handled by the local mailer and delivered directly to the local user’s mailbox. Under the nullclient configuration, this mail is sent to the relay host for delivery, even though the mail is addressed to a user who has an account directly on the local system.

Note that the -bv test is often the best way to view delivery information. In this particular case, a test using -bt could have given a confusing result. For example, assume you decided to run sendmail -bt and use the /parse command to examine the mail delivery triple. You would see something like the following:

# cat > special-test 

/parse tyler@science.foo.edu

/parse sara@crab

/parse craig  

CTRL-D 

# sendmail -bt < special-test | grep '^mailer' 

mailer relay, host smtp.wrotethebook.com, user tyler@science.foo.edu

mailer relay, host smtp.wrotethebook.com, user sara@crab.wrotethebook.com

mailer local, user craig

The first two results obtained by /parse provide the correct information. The third result, however, is potentially misleading. You might look at this and think that, even with the nullclient configuration in place, mail addressed to local users is handled by the local mailer instead of being forwarded to the relay server. The problem comes from assuming that parsing the delivery address is the end of the story. In this case, it isn’t. Because the mailer is the local mailer, the delivery address is processed through the aliases database. When sendmail finishes aliasing, it processes the localaddr ruleset (ruleset 5) if the local mailer has the F=5 flag set, which it does by default. It is the localaddr ruleset that then decides this mail needs to be sent to the mail relay, as the following -bt test shows:

# sendmail -bt

ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)

Enter <ruleset> <address>

> localaddr craig

localaddr          input: craig

MailerToTriple     input: < server . wrotethebook . com > craig < @ smtp .

wrotethebook . com >

MailerToTriple   returns: $# relay $@ smtp .

wrotethebook . com $: craig < @ smtp .

wrotethebook . com >  localaddr        returns: $# relay $@ smtp .

wrotethebook . com $: craig < @ smtp .

wrotethebook . com >

> /quit

It can be confusing trying to remember when to call each ruleset. In general, it is easier to use -bv when all you want is information about the mail delivery.

In addition to sending all mail through the relay server, the nullclient configuration replaces the hostname of the client with the name of the server in the email sender address. A sendmail -bt test demonstrates this function of the nullclient configuration:

# sendmail -bt

ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)

Enter <ruleset> <address>

> /tryflags HS

> /try relay kathy@giant.wrotethebook.com

Trying header sender address kathy@giant.wrotethebook.com for mailer relay

canonify           input: kathy @ giant . wrotethebook . com

Canonify2          input: kathy < @ giant . wrotethebook . com >

Canonify2        returns: kathy < @ giant . wrotethebook . com . >

canonify         returns: kathy < @ giant . wrotethebook . com . >

1                  input: kathy < @ giant . wrotethebook . com . >

1                returns: kathy < @ giant . wrotethebook . com . >

HdrFromSMTP        input: kathy < @ giant . wrotethebook . com . >

PseudoToReal       input: kathy < @ giant . wrotethebook . com . >

PseudoToReal     returns: kathy < @ giant . wrotethebook . com . >

MasqSMTP           input: kathy < @ giant . wrotethebook . com . >

MasqSMTP         returns: kathy < @ giant . wrotethebook . com . >

MasqHdr            input: kathy < @ giant . wrotethebook . com . >

MasqHdr          returns: kathy < @ smtp . wrotethebook . com . >

HdrFromSMTP      returns: kathy < @ smtp . wrotethebook . com . >

final              input: kathy < @ smtp . wrotethebook . com . >

final            returns: kathy @ smtp . wrotethebook . com

Rcode = 0, addr = kathy@smtp.wrotethebook.com

> /quit

The /tryflags command specifies the particular address we wish to process. In this case, we ask to see the processing of the header/sender (HS) address.The /try command specifies the mailer for which the address should be processed (relay) and the email address that is to be processed (kathy@giant.wrotethebook.com). The result shows that the sender’s hostname (giant.wrotethebook.com) is replaced by the mail relay host’s name (smtp.wrotethebook.com). This example uses the sender’s fully qualified domain name, but it could have used any hostname alias found in class $=w. Any of them would be replaced by smtp.wrotethebook.com in this test.

The two line configuration shown sends all mail that originates on the local host to the relay for processing. It also masquerades that mail so that it appears to originate from the mail relay host. The nullclient configuration is intended for systems that depend on the mail server for all email needs. The classic examples of systems that might use such a configuration are diskless clients that depend completely on a server. But the benefits of the nullclient configuration have far wider utility. Centralizing mail services can simplify queue management, mail policy control, security, and logging. Many sites use the nullclient configuration on desktop workstations.