Sendmail has got a reputation for being complex and a nightmare to configure. This is mainly due to the abstract syntax the parameters in the sendmail.cf file use. There are two reasons for this unusual nomenclature. Firstly, when sendmail was originally written, memory was very expensive and very small. The short tags were used to save space in memory. Also adding to the complexity is that sendmail has been designed to be very versatile so it can talk to a wide variety of computers using different communications methods.

These complexities have been partially addressed by the use of the m4 macro to create sendmail configuration files. This allows sendmail configuration files to be built based on a set of (fairly) plain english instructions.

However, understanding sendmail can still be baffling without some understanding of the sendmail configuration file. This article attempts to explain the basic elements of sendmail, so configuration can be tackled with more confidence.

sendmail.cf file

The sendmail.cf file, the sendmail configuration file, is the heart of sendmail and controls what happens to mail it's processing. The table below lists the configuration commands within sendmail.cf and what their purpose is.

V version, required to ensure old versions of sendmail don't break when readin g new versions of sendmail.cf e.g. V10 - sy ntax is version 10 so all version 10 features are enabled
M The mail delivery agent to be used, e.g.

Mlocal, P=/usr/bin/mail, F=lsDFMAw5:/l@rmn, S=10, R= 20/40

- which actually means that local mail should be delivered using mail program /usr/bin/mail with the parameters listed (which refer to rules and macros to use as we will see later).
D These are macros and are simliar to shell variables used in unix shell scrip ting. A value is assigned to the macro and when the macro is called, the value assigned to it is used. e.g.

DRmail.in2nix.com
D{REMOTE}mail.in2nix.com

The R and {REMOTE} macros have the string mail.in2nix.com as their values. $R and ${REMOTE} can then be used elsewhere in the sendmail.cf file. (Note: sendmail has some bui lt in variables, signified by a lower case letter, e.g.Dh which has the value of the recpients hostname.

R Rules, used to change mail addresses from one form to another to ensure the addresses conform to differing standards, e.g.

R$- $0 $1@$R user -> user@remote

This piece of apparently cryptic nonsense actually does the following. Mail a ddresses are compared to the rule on the left hand side, i.e. R$- and if they match that rule, the add ress is rewritten as per the rule on the right hand side, i.e. $0 $1@$R . The user -> user@remo te is a comment (effectively it's ignored as only the left hand rule and the right hand rules are processed). The comment actually explains what this rule does, which is nice. Addresses with the format user1< /i> are changed to user1@mail.in2nix.com (remembering that this is what we set $R to earlier in the macros section). Each part of the rule must be separated by one or more tabs.

S Rule sets. As writing the mail addresses may require several rules, rules ca n be organised into sets. All the rules following the S until the next S belong to that rule se t, e.g.

S0
Rlhs rhs # a comment
Rlhs2 rhs2 # another comment

C Class macro. If a macro has multiple values, a class macro is used. These values can be thought of as elements in an array, e.g.

CW localhost myserver.in2nix.com

C{MY_NAMES} name1 name2

The class macros can then be accessed later in the sendmail.cf in the format $=W or $={MY_NAMES}

F File class macro, similiar to a class macro except the values are stored in a file, e.g.

FW/etc/values

i.e. get the values from /etc/values . A program can also be used, e.g. FW|/usr/bin/getnames , program getnames will be run and the output used as values for the macro

O

Options used for running sendmail, e.g.

OQ/var/spool/mequeue - use /var/spool/mqueue as the mail queue directory.

H Headers, controls what must be included in the mail headers, e.g.

HReceived: $?sfrom $s $.by $j etc... which tell sendmail that a Received header line must be added to the header of each mail message containing the details as defined by the parameters following it.

P Sets the priority for different mail, e.g.

Pjunk = -100 , mail with a precedence header of junk should be processed last

T Trusted users. Software such as UUCP (what's that?....ed) needs to be able to tell sendmail whom the mail is from. If the software runs as a different user to that specified in the From: header, T can be used to define users who are trusted to override the From: address, e.g.

Troot daemon uucp i.e. users root, daemon and uucp are trusted.

K Keyed databases. Some information such as a list of UUCP hosts , is better maintained outside of the sendmail.cf file. Keyed databases can be used to provide faster access to this information. e.g.

Kuucp hash /etc/mail/uucphosts - the database with the symbolic name uucp with a type of hash, is located in /etc/mail/uucphosts .

E Environmental variable. When sendmail starts, all environmental variables set are erased and replaced with a small set of standard environmental variables. e.g. TZ and SYSTYPE . Further environmental variables can be defined bu using the E configuration parameter, e.g.

EPOSTGRESHOME=/home/postgres - assigns environmental variable POSTGRESHOME .

Common predefined Macros (D)

As mentioned, sendmail has some prefined macros. These don't need to be assigned values as they are automatically assigned values ny sendmail. The following list contains the most commonly used predefines macros

  • u - recipients user name
  • h - recipients hostname
  • n - identity of an error message sender
  • v - version of sendmail running
  • w - short hostname
  • j - canonical (official fully qualified) hostname. This can be dipslayed by running sendmail -Csendmail.cf -d0.1 -bt < /dev/null
  • m - domain name
  • k - UUCP node name
  • b - date in RFC 1123 format
  • - - indentification information
  • opMode - Current operating mode

To find out which macros are defined, run sendmail -d35.9 -Csendmail.cf -bt < /dev/null

As already mentioned, rules control how mail is processed by sendmail. Rulsets sets of rules grouped together.

Predefined Rulesets (S)

Sendmail has some predefined rulesets as listed below:

  • 0 - Resolve a mail delivery agent
  • 1 - Process the sender address
  • 2 - Process the recipient address
  • 3 - Preprocess all addresses
  • 4 - Postprocess all addresses
  • 5 - Rewrite unaliased local users
  • 6 - 9 - resevered for future use so don't use these numbers for your own rules!

To check rulesets

 1. enter sendmail -Csendmail.cf -bt to get an interactive session
 2. > =S 0 - shows rules in ruleset S0
 3. > 0 joe@bloggs.com - runs input against ruleset 0, get something like:
    rewrite: rulset 0 input: joe @ bloggs . com
    rewrite: ruleset 0 return: td @ bloggs . com

i.e. the input and the return are the same so rule doesn't match workspace ( the buffer where the tokenized (i.e. split up) version of joe@bloggs.com exists).

How the rules are processed

Rules in a ruleset are processed sequently, e.g. if ruleset S0 contains

Rx y
Rz x
Rx w

At prompt: >0 z - you'll get:

rewrite: ruleset 0 input: z
rewrite: ruleset 0 returns: w

So z has been transformed to w by ruleset 0.This works as follows:

Entry in workspace -> z
*
Does not match first rule Rx y so this rule is skipped
*
Exactly matches second rule Rz x so x now occupies the work space
*
x exactly matches the next rule Rx w so the workspace is changed to w
i.e. z is transformed into w

Rule Variables

The following variable are used on the left hand side (lhs) of a rule

  • $* - matches zero or more tokens
  • $- - matches exactly one token
  • $+ - matches one or more tokens
  • $=letter - matches any token which is equal to $letter e.g. $=m matches anything of the class m, which, as mentioned earlier in predefined macros, is normally set to the domain name

The right hand side (rhs)

  • $@ - action for rewrite and return
  • $>num - action for rewrite using the ruleset number num
  • $# - action for final delivery via the listed mailer * $: - define user e.g. $:$1 - user is positional parameter 1 . (Note: if the LHS is $+ , $1 refers to all of that. If LHS is $+.$+ , this represents $1 . $2 ).
  • $letter - Defined variable (macro) e.g. $m is equal to whatever Dm is set to
  • $number - equal to the token on LHS e.g. $1 is equal to the first token on the left hand side

The From address goes through rulesets 3,1,S & 4 The To address goes through rulesets 3,2,R & 4 R & S are sepcial rulesets dependent on the mailer as specified in the Mailer definition, e.g. Ruleset0 is used to decide which mailer to use.

sendmailflow.jpg

The functions of these rules is as follows:

  • RULE 3 - First rule, formats the addresses so the rest of the rules can understand, essentially it places < > around the hostname.
  • RULE 0 - Selects the delivery method on the basis of the recipients address
  • RULES 1 & 2 - These render and perform recipient transformations, e.g. If a hub is used, they can make the mail appear as though it's come from the hub
  • RULES S & R - These perform protocol dependent sender and recipient transformations
  • RULE 4 - Turns the address from the internal sendmail format back to the external format (removes < > from around the hostname)

Testing the rulesets

 1. /usr/lib/sendmail -Csendmail.cf -bt
 2. 3,0,2,61,4 joe@bloggs.com - checks the address against rulesets 3,0,2,61 & 4
 3. /tryflags er - check following as envelope recipient
 4. /parse joe@bloggs.com - check address against sendmail configuration

Some other sendmail bits and pieces!

  • D{Remote} is the name of the hub as it is known to the inside network, e.g. mailhost
  • D{Hub} is the name of the hub as it should appear to the outside world, e.g. mail.in2nix.com

Also note that macros and classes are stored independantly, e.g.

  • Dwprinter1
  • Cwprinter1

These are separate entries, to refer to the macro use $w and to refer to the class use $=w

Fw/a/file will add the contents of file, /a/file, to the w class macro. You can add -o (for optional) so sendmail will start even if the file doesn't exist,

e.g. Fw -o /a/file

Internal mail routing

The sendmail daemon only needs to run if the server is going to accept mail from other servers. If the mail is internally generated, the mail delvery agent will call sendmail . It is therefore necessary to have a valid sendmail.cf but the sendmail daemon doesn't have to run.

The only other reason to have the sendmail daemon running is to clear the mail spool queue for local mail that couldn't be delivered immediately, e.g. if you sent mail to a server which was down. If sendmail isn't running, the queue never gets cleared down. With Solaris, the default mode is queue mode, i.e. the sendmail daemon is running but is doesn't listen on port 25 . This can be changed by editing /etc/default/ sendmail .

Recent Changes