Chapter 18

SMTP - Simple Mail Transport Protocol
 

 
 
In this chapter:
 
 
* Understanding mail delivery principles
* Customizing the mail setup with SuSE's standard methods
* Creating your own configuration using the m4 macro processor
 
 
 
An even more popular Internet service than the Web is electronic mail (e-mail). Almost everyone with an Internet connection has an e-mail address. E-mail became a new medium to exchange information in most business environments. While using e-mail is pretty easy, the setup of a mail server can be a difficult task. SuSE Linux uses sendmail as the SMTP (mail) server.
 
Sendmail is known for its cryptic configuration file, and requires a 1000+ page manual (sendmail; Bryan Costales and Eric Allman; O'Reilly; ISBN 1-56592-222-0) to explain its configuration.
 
A common saying is that a system administrator will try to set it up once, but never will try it a second time. The configuration file consists of large set of rules which interact with each other. It has been proven that sendmail is Turing Complete, which means you can use it to compute everything that is computable using sendmail. In fact, someone implemented 'The Towers of Hanoi' in sendmail. Well, that's pretty impressive, but that's not what we are going to try here.
 
SuSE uses sendmail as its standard Mail Transport Agent (MTA). All mail, whether incoming or outgoing, is handled by this daemon. Because the configuration is so difficult, there exist a couple of macro sets that make your life a whole lot easier. SuSE uses one of these macro sets to generate its sendmail configuration. For standard configurations, SuSE makes it even easier. You can configure sendmail just by setting some variables in /etc/rc.config.
 
We'll look at these variables first and see what features you have without altering the default configuration. After that, we'll see how to create a custom sendmail configuration using the m4 macro set that is shipped with SuSE Linux.
 
18.1 SuSE's standard configuration
 

Like for almost all other services, the setup of sendmail is done by setting variable values in /etc/rc.config. The first thing to decide, is if you want sendmail to run as a daemon at all. If so, set SMTP to yes.
 

TIP You need to do this only if you expect mail to be sent to your machine by SMTP. If you use POP or UUCP for incoming mail and use the SMTP protocol only for outgoing mail, you can set it to no. You don't need sendmail running all the time in this case. You should however call sendmail -q each time you polled mail with UUCP, or POP and fetchmail, to process the mail queue and deliver mail to local users.
 
 
The variable SENDMAIL_TYPE decides if the sendmail configuration should be created by the script SuSEconfig using the values set in /etc/rc.config. If the standard configurations fit your needs, you should set it to yes. If you need a customized configuration, you will have to set it to no, otherwise your configuration will be overwritten every time you run YaST or SuSEconfig.
 
How does SuSE do this anyway? Each time YaST changes a value in /etc/rc.config or installs a new package, it starts the script SuSEconfig. If you don't use YaST to change this file, you should start it manually.
 
NOTE SuSEconfig then (among other things) executes /sbin/conf.d/SuSEconfig.sendmail to create a new /etc/sendmail.cf, the sendmail configuration. This script opens the m4 macro processor, and feeds it with a macro set generated on the fly, using the settings in /etc/rc.config and writing to /etc/sendmail.cf. This however is only done, when SENDMAIL_TYPE is not no. So if you have your own version of /etc/sendmail.cf you want set it to no to protect it from over writing.
 
 
But back to the configuration. The next variable is SENDMAIL_SMARTHOST. Here you can define a host where to send all the mail which cannot delivered locally. You can use this when you are connected to a provider who forces you to use his mailserver for delivering mail to the outside instead of connecting your target hosts directly, or in a LAN, where one dedicated mailserver takes care of all outgoing mail. Also if you sent your mail via UUCP, you specify your next UUCP hop in this variable.
 
If you don't want to deliver any mail locally, you have to set your mail host in SENDMAIL_RELAY. All mail will be forwarded to this host. This setting is useful in environments where the users are administered on a central server, which serves the network clients with the user home directories and mail folders. If this variable is set, no mail will be delivered locally.
 
When sendmail gets started as a daemon (SMTP set to yes), you can specify its parameters in SENDMAIL_ARGS. The default is -bd -q30m -om. This means to run sendmail as a daemon (-bd), process the outgoing queue every 30 minutes (-q30m) and mimefy (convert eight bit input to seven-bit MIME format) messages (-om). Refer to the man page sendmail(8) to see all possible options. The most parameter most likely to be changed is the -q30m setting. Processing the outgoing queue every thirty minutes does not mean that outgoing mail has to wait until the queue is processed. Sendmail tries to deliver mail the moment it gets it. If the mail can't be delivered immediately, sendmail will put it place in the outgoing queue.
 
TIP You can modify this behavior by setting SENDMAIL_EXPENSIVE to yes, which will direct sendmail not to try to deliver it until the queue gets processed. This is useful, when delivering mail is 'expensive', i.e. will require to dial out and so create costs. If you set SENDMAIL_EXPENSIVE to yes, you probably also should remove -q30m form the parameter line, or set it to a higher value. If you remove it, mail will only be sent when you call sendmail -q manually.
 
 
Also connected to the costs factor of mail is SENDMAIL_NOCANONIFY. If set to yes, sendmail will not try to canonify hostnames found in mail headers. Canonifying names is done by sending DNS queries, which may also require a connection to your ISP. If you don't deliver mails directly, but send them to your ISP's mailserver, there is no need to let sendmail do this. The mailhost which delivers the mails will canonify them anyway. In this case, it's safe to set it to yes.
 
The next variable determines the behavior of sendmail when mail is received from remote hosts. The default is to accept mail only for the local host. If you run a mail server in a network, you may want to accept mail for several hosts, or even for several domains. SMTP and DNS interfere at this point. DNS allows you to specify so called MX-Records (Mail eXchange Records).
 
These records tell the sending machine where mail for a specific host should be delivered too. You can see the MX records by looking up the DNS records for a host. For example all hosts in the domain suse.com are handled by mail.suse.com, as you can see in the following output of the host command for some machines in the SuSE domain:
 
 
> host suse.com  
suse.com has address 209.0.51.1  
suse.com mail is handled (pri=42) by mail.suse.com  
suse.com mail is handled (pri=69) by mail.alameda.net  

 
> host www.suse.com www.suse.com is a nickname for goldengate.suse.com goldengate.suse.com has address 209.0.51.1 goldengate.suse.com mail is handled (pri=69) by mail.alameda.net goldengate.suse.com mail is handled (pri=42) by mail.suse.com
 
> host ftp.suse.com ftp.suse.com has address 209.81.41.5 ftp.suse.com mail is handled (pri=69) by mail.alameda.net ftp.suse.com mail is handled (pri=42) by mail.suse.com
 
> host ssl.suse.com ssl.suse.com has address 209.0.51.2 ssl.suse.com mail is handled (pri=69) by mail.alameda.net ssl.suse.com mail is handled (pri=42) by mail.suse.com
 
 
You see that the host command not only returns the IP address of a host, but also the hints for mail delivery given by the MX-Records. There can be more than one MX record for each host. The priority decides which of these pointers should be tried first (mail.suse.com in this example), where a lower value indicates a higher priority. If the host with the highest priority is down, or refuses to accept the mail, the next in the list will be tried and so on. If none of these host accepts the mail, it'll be spooled by the sending machine and tried again after a specified time (30 minutes in the standard SuSE Linux setup).
 
If you have a setup where one machine receives mail for a set of hosts, you have to tell sendmail that it should accept mail for these machines. A list of host or domain names you are willing to accept mail for can be given in SENDMAIL_LOCALHOST. Mail will be accepted for the host name and all names listed in this variable.
 
The last feature you can specify in /etc/rc.config is a list of domain names you may want to remap for outgoing mail. This fits into the picture drawn above. If you have a set of hosts and a central server to handle mail for these machines, you may want to have a standardized (generic) return address for outgoing mail. You also may want to change the username in the outgoing address, for example if a group of people take care of sales related customer requests, you may want to map those mails to the address sales@my-domain.com. A table for these translations can be given in the file /etc/mail/genericstable. The format of this table is discussed in the next section. However it will only be used for the domain the mail server belongs too. If you have additional domains to remap, you have to specify them in SENDMAIL_GENERICS_DOMAIN. The generics table will be used for each domain listed in here and the local domain.
 
18.2 Features of the SuSE setup
 

We've seen some of sendmail's features while talking about the variables in /etc/rc.config. But there is more. The directory /etc/mail contains a set of tables used by sendmail to remap addresses in different ways:
 

18.2.1 aliases
 

The system alias table. This file is a link to /etc/aliases, the traditional location of the alias table in SuSE Linux. It moved into /etc/mail to fit the File System Hierarchy Standard (FHS).
 
You can create alias names for local accounts in this table. The format is pretty simple. Each line contains one alias, where the alias name comes first and separated by a colon (:) an arbitrary number of recipients for this address follows. You can alias one address to another or, to a list of addresses:
 

 
sysadmin:      root  
superuser:     root  
root:          homer  

 
Arthur.Dent: arthur Charlie.Brown: charlie Homer.Simpson: homer Al.Bundy: al Peggy.Bundy: peggy
 
sales: arthur, peggy tech: homer, al
 
 
The example shows some common things you can use aliases for. The first three entries redirect mail addressed to sysadmin and superuser to the root account, and then specifies to deliver all root mail to homer. The second paragraph gives every user an alias to enable the use of the full name in e-mails. The last two entries assign individual accounts to more abstract addresses like sales and tech.
 
It is very important that you call the command newaliases every time you make a change to this file. Without doing this, sendmail will not know about the changes you made. Newaliases does two things. It creates an index for the alias table to improve reading performance, and it sends a signal to sendmail to notify it that a change has been made and sendmail needs to reread this table.
 
18.2.2 genericstable
 

This table allows certain addresses originating in the local domain or a domain listed in SENDMAIL_GENERICS_DOMAIN to be turned into another ("generic") form, which can change both the domain name and the user name. The key for this table is either the full address or the unqualified username (the former is tried first); the value is the new user address. If the new user address does not include a domain, the local domain is used. Note that the address being looked up must be fully qualified.
 
We already talked about this feature when we discussed the variable SENDMAIL_GENERICS_DOMAIN. Besides of the already mentioned uses, you could translate the local usernames into full names. If you have these full names in your alias table, your local usernames will be hidden to the outside. Given the alias table shown above, a generics table like this would be a useful addition to your setup:
 

 
root      Homer.Simpson  
homer     Homer.Simpson  
arthur    Arthur.Dent  
charlie   Charlie.Brown  
al        Al.Bundy  
peggy     Peggy.Bundy  
 
 
TIP Like the alias table, this table has an index to optimize the access to it. Unfortunately there is no convenient command to rebuild this index like newaliases for the alias table. You have to change into the directory /etc/mail and issue the command
 
 
 
# makemap hash genericstable.db < genericstable}  
 
 
every time you make a change to this file to rebuild the index. You also have to tell sendmail to reread it, by sending the signal HUP:
 
 
# killall -1 sendmail  
 
 
Otherwise sendmail will not respect the new version of this table.
 
NOTE Note that sendmail won't replace a From: line if it's already present. It only set's the envelope address and the Return-Path: to the specified value. If your mail user agent (MUA) (the application you use to read and write mail) sets a From: line, you should make sure, that you specify the correct address in the configuration of your MUA.
 
 
18.2.3 virtusertable
 

This table allows you to do a domain-specific form of aliasing, allowing multiple virtual domains to be hosted on one machine. For example, if you host several Webservers on your machine, with different domain names - lets say you have www.simpsons.com, www.bundy.com and www.peanuts.com - you may want to have separate Web master addresses for each domain. But you can have only one user Webmaster. So by default, this user would get the mail for all three Websites. The virtusertable allows to create aliases with specification of the domain. For the three sites listed above, you can have a virtusertable like this:
 

 
Webmaster@peanuts.com   charlie  
Webmaster@bundy.com     peggy  
Webmaster@simpsons.com  homer  
 
 
Then mail addressed to Webmaster@peanuts.com will be sent to the user charlie on the local host. You can also specify address of remote machines on the right handside, in which case the mail will be forwarded to that address.
 
Virtusertable also offers to forward all addresses to a domain to one address, or just to the same user at another domain:
 
 
@peanuts.com    schulz  
@simpsons.com   %1@comics.net  
@bundy.com      %1@sitcom.org  
 
 
With this table, all mails addressed to any user in the domain peanuts.com will be sent to the local user schulz. Mail addressed to somebody@simpsons.com will go to somebody@comics.net, same for the domain bundy.com.
 
NOTE The domain names in the left hand side entries must be listed in SENDMAIL_LOCALHOST. Otherwise no mails for these domains will be accepted.
 
 
TIP Like the other tables, an index has to be created and sendmail needs to be signaled to reread the table after every change. It's done in the same as we've seen it for the genericstable:
 
 
# cd /etc/mail  
# makemap hash virtusertable.db < virtusertable  
# killall -1 sendmail  
 
 
 
18.2.4 mailertable
 

This table represents a database containing the routing information for various domains. For example, the table may look like this:
 

 
.simpsons.net            xnet:%1.simpsons.net  
powerplant.simpsons.net  suucp:uusimpsons  
.simpsons.com            smtp:comics.net  
 
 
The semantics are simple. Any LHS (left hand side) entry that does not begin with a dot matches the full host name indicated. LHS entries beginning with a dot match anything ending with that domain name. You can think of it as having a leading * wildcard. Matching is done in order of most-to-least qualified. For example, even though .simpsons.net is listed first in the above example, an entry of powerplant.simpsons.net will match the second entry since it is more explicit.
 
The RHS (right-hand-side) should always be a mailer:host pair. The mailer is the configuration name of a mailer. The host is the hostname passed to that mailer. In domain-based matches (that is, those with leading dots) the %1 may be used to interpolate the wildcarded part of the host name. For example, the first line above sends everything addressed to anything.simpsons.net to that same host name, but using the (presumably experimental) xnet mailer.
 
In some cases you may want to temporarily turn off MX records, particularly on gateways. For example, you may want to MX everything in a domain to one machine that then forwards it directly. To do this, you might use the DNS configuration:
 
 
*.domain. IN MX 0 relay.machine  
 
 
and on relay.machine use the mailertable:
 
 
.domain smtp:[gateway.domain]  
 
 
The [square brackets] turn off MX records for this host only. If you didn't do this, the mailertable would use the MX record again, which would give you an MX loop.
 
CAUTION These are very sensitive areas, and you should only do this if you've gone over everything carefully and are sure you know exactly what to do. Altering MX records and mailertables can easily destroy your whole mail setup. Again, carefully review the documentation on sendmail and the macro set included before you consider using these features. Build a test environment before you go live on your main mail server. Your users will appreciate your consciousness.
 
18.2.5 userdb
 


 
This table does almost the same thing as the virtusertable, genericstable and aliases files do. It's needed only in some very special cases and usually you are better off using the other mechanisms. It's listed in here only for completeness, but it doesn't really add any new functionality.
 

18.3 Using m4 macros to set up sendmail
 

If you need to extend the standard features provided by SuSE, you will have to create your own /etc/sendmail.cf. Like mentioned earlier, this can be a real pain, as the format of this file is everything but easy to understand. Fortunately, even if the standard setup doesn't fit your needs, SuSE provides a way to avoid direct editing of /etc/sendmail.cf.
 
The sendmail configuration used by SuSE is generated using the m4 macro processor and a set of macro definitions created by Eric Allman for the Berkeley, CA university. The C programmers among you may know m4, as it's often used as C preprocessor to process the hash # macros found in your sourcefiles, like #include, or #define. Where m4 in the case of C is invoked by the C-compiler, we have to start it manually to create a sendmail configuration in this case.
 
In the directory /etc/mail you'll find the file linux.mc. It contains the definitions used to create SuSE's standard /etc/sendmail.cf and is a good starting point for custom configurations. It looks confusing on a first glance, but if you remove all comment lines (starting with dnl), you'll see, that it doesn't contain that much lines, and most of the made definitions are pretty self explanatory:
 

 
include(`/usr/share/sendmail/m4/cf.m4')  
VERSIONID(`linux setup for SuSE')dnl  
OSTYPE(`linux')dnl  
define(`STATUS_FILE', `/var/log/sendmail.st')  
dnl define(`confDEF_USER_ID', `daemon:daemon')dnl  
define(`PROCMAIL_MAILER_PATH', `/usr/bin/procmail')dnl  
define(`confCOPY_ERRORS_TO', `Postmaster')dnl  
define(`UUCP_MAILER_MAX', `2000000')dnl  
define(`confQUEUE_LA', `12')dnl define(`confREFUSE_LA', `18')dnl  
define(`confPRIVACY_FLAGS', `authwarnings,novrfy,noexpn')dnl  
define(`confTRUSTED_USERS', `mdom wwwrun')dnl  
FEATURE(`always_add_domain')dnl  
FEATURE(`local_procmail')dnl  
FEATURE(`mailertable', `hash -o /etc/mail/mailertable.db')dnl  
FEATURE(`genericstable', `hash -o /etc/mail/genericstable.db')dnl  
FEATURE(`virtusertable', `hash -o /etc/mail/virtusertable.db')dnl  
MAILER(`local')dnl  
MAILER(`procmail')dnl  
MAILER(`smtp')dnl  
MAILER(`uucp')dnl  
MAILER(`bsmtp')dnl  
MAILER(`fido')dnl  
 
 
Now -- how to use this to create an actual sendmail configuration? The answer is easy; Just run it through m4:
 
 
# m4 < /etc/mail/linux.mc > /tmp/sendmail.cf  
 
 
This creates a sendmail.cf file in the directory /tmp. To customize the setup, you may want to edit /etc/mail/linux.mc, or even better create a copy and work on this. We won't discuss the features of the m4 macro set here. A good documentation of this macro set can be found in /usr/share/sendmail/README. It explains the format of the macros and gives hints when to use which feature.
 
CAUTION Before you use your own configuration, you should make sure, that SuSEconfig doesn't replace it with it's own version the next time you run YaST. To ensure this, set the variable SENDMAIL_TYPE in /etc/rc.config to no. This tells SuSEconfig not to create a new sendmail configuration.
 
 
 
Summary:
  The daemon sendmail is the standard Mail Transport Agent (MTA) in SuSE Linux. It's function is to deliver mail; local to user mailboxes and remote to other systems. The configuration of this service is fairly complex. The most used features however, can be changed easily, by modifying the sendmail related variables in /etc/rc.config. Different kinds of translation tables are available to map addresses and forward mail to other users or systems.
 
A m4 macro set is available to set up more complex configurations, without editing the sendmail configuration directly.
 
--
Back Up Contents Next
--

Copyright (c) 1999 by Terrehon Bowden and Bodo Bauer
To contact the author please sent mail to bb@bb-zone.com