"Linux Gazette...making Linux just a little more fun!"


Mail for the Home Network

Sendmail

By JC Pollman and Bill Mote


Sendmail has a bad reputation because of security issues in the past and because its configuration file, sendmail.cf, is a horrible, ugly, wart infested, sadistic file to understand and edit. As an example, would you like to make changes to this bit:

# localize and dispose of route-based addresses
R@ $+ : $+              $@ $>96 < @$1 > : $2            handle <route-addr>

Sendmail is a rules based program: the rules determine how sendmail should react. O'Reilly has published "The Bat Book" on sendmail: it is 1021 pages! We are not going to discuss the rules here - we just want to get it up and running.  After you are happy with the basic setup, sendmail is a very deep mine you can excavate for all the gold you want. There are a number of files you have to edit to make sendmail work. Here we take them one at a time.

Prerequisite: For the initial setup of sendmail, make a user with the same login name as your email account on your ISP, e.g. my ISP email account is jpollman@deniz.com so I have an account on my mail server: jpollman@kulai.org. After sendmail is working with this setup, you can go to the Sendmail-Address_Rewrite Howto for using a different local name.

/etc/mail/aliases: Depending on your distribution, this file might be /etc/aliases. It has two main purposes: to allow all the admin-users/daemons to send reports to somebody, and to create group lists. If you are interested in the group lists, read the sendmail man page. By default, the daemons send their reports to root, but since you do NOT log in as root on a regular basis, (really, I know you don't!) it is better to send all of root's mail to you. Edit the file, and usually at the bottom are these two lines:

# Person who should get root's mail
root:   jpollman@kulai.org

Usually there is a # in front of the second line (with root: at the beginning). Remove the # and put your home email address to the right of the ":".  After you save the file, type:

    newaliases [Enter]

Newaliases will convert the aliases file to a format that sendmail can read efficiently, and save it as: aliases.db. Almost everyone who has ever played with sendmail, sooner or later, has edited the aliases file, restarted sendmail, and got mad because the new aliases where not functioning. Remember to run newaliases!

/etc/mail/relay-domains: Again, this file maybe /etc/relay-domains. This file tells sendmail that if it gets mail from the computers listed in this file it should handle them. If this file is empty, you can not use sendmail as your SMTP host for your network because it will not accept any mail from other computers. It should list each computer that will be using your server. There are probably more posts about problems with relaying on the comp.mail.sendmail than any other topic. From the sendmail FAQ:

You need to add the fully-qualified host name and/or IP address of each client to class R, the set of relay-allowed domains. For  8.9.X, it is typically etc/mail/relay-domains . Note: if your DNS is problematic, you may need to list the IP address in square brackets (e.g., [1.2.3.4]) to get the ${client_name} macro to work properly; in general, however, this should not be necessary.
My relay_domains file looks like this:
jc.kulai.org
phillip.kulai.org
fserver.kulai.org
/etc/sendmail.cw: this file helps sendmail know where it is and any aliases for the server it runs on. Mine has a single line: kulai.org.

/etc/sendmail.cf: And now for the monster itself! Fortunately for us, life has gotten much much much easier than it used to be. Here is the gist of what we are going to do: modify a generic sendmail.mc file, run it through m4, copy it to /etc/sendmail.cf, and restart sendmail. Actually, it is pretty easy.

Go to /usr/lib/sendmail-cf/cf. There should be a generic file with a mc extension. If not, there maybe one named redhat.mc. And if that is missing, you can copy this file to that directory. Personally, we recommend you start with our file as we know it works :^) Now copy that file to another name, like maybe the name of your server: master.mc. You want to keep the original file unchanged so if you really screw things up you can at least start over from scratch.  Edit your mc file.  There are many rules already defined, and they work well as the default. To make it work on your server, add these lines to the bottom of the file. Note: my smtp server is: ix.deniz.com and my ISP is deniz.com, yours is different, so do not simply copy these lines without editing them!

define(`SMART_HOST',`smtp:[ix.deniz.com]')
MASQUERADE_AS(`deniz.com')
FEATURE(`masquerade_envelope')
define(RELAY_MAILER, TCP)
FEATURE(`accept_unqualified_senders')
SMART_HOST: this is your ISP's SMTP host. This is where sendmail will send email that is not for the kulai.org domain, i.e. ix.deniz.com for me.
MASQUERADE_AS(`deniz.com'): this will rewrite part of the "From:" line on your emails so they will look like they come from deniz.com, which is where my email address on the internet is, Note: change deniz.com to your ISP - otherwise deniz.com might get excited about other people (spammers?) trying to use their service. In other words, deniz.com will not allow mail from jpollman@kulai.org but will allow mail from jpollman@deniz.com. This is because of their relay-domains file.
masquerade_envelope: this will rewrite some of the email header so it will look like the mail came from deniz.com
RELAY_MAILER, TCP: This is not strictly necessary, but it does not hurt.
accept_unqualified_senders: this is so, if you have jpollman@deniz.com in your From: line in your email program, sendmail will accept the mail. Normally it is expecting a kulai.org as the domain.

Also note that sendmail uses both tick marks: ` and '.

Now, to take this relatively easy-to-read file and turn it into sendmail-speak, type:

m4 master.mc > _master.cf [Enter]
where master.mc is the file you were editing and _master.cf is the name we are telling m4 to give the file it creates. This happens very quickly: on my pentium II 266 it takes about 2 seconds. The _master.cf is the complete sendmail.cf - we probably could have typed: m4 master.mc > /etc/sendmail.cf, but it is good to keep an extra copy around. Now, copy _master.cf to: /etc/sendmail.cf - which will over write your previous copy of sendmail.cf: probably ought to make a copy of the original just in case. Restart sendmail by doing a: killall -HUP sendmail (in Redhat: /etc/rc.d/init.d/sendmail restart). Sendmail has a number of options when you start it. Click here to see those options. In review:
cp /etc/sendmail.cf /etc/sendmail.original
m4 master.mc > _master.cf
cp _master.cf /etc/sendmail.cf
killall -HUP sendmail


If everything went ok, you are now done except for testing. Send email to someone on your network. Send email to your ISP account email address. If all this works, you can point the other computers on your network, including those running any Microsoft operating systems, to your email server for SMTP services.

There are 3 fixes you may have to perform manually if things are not working as you would like them:

1. If sendmail can not "find" your email server:
Edit your /etc/sendmail.cf and look for this line:
#Dj$w.Foo.COM
and change it to:
Djmaster.kulai.org
Where master.kulai.org is the name of your email server.  Note: remove the # at the front of the line as # means: ignore - this is a comment line. This is one of sendmail's rules and it tells sendmail what the name of the email server is - in case dns, or other ways, do not tell sendmail what it wants.

2. Masquerading based on destination:
I had the hardest time trying to get sendmail to masquerade only the mail sent to the internet and not local mail, e.g. I wanted local mail to show the sender as: bmote@kulai.org and not bmote@deniz.com, but obviously I wanted mail that went out into the internet to show: bmote@deniz.com.  To solve this you have to manually edit the /etc/sendmail.cf. Find the definitions of local rulesets 10 and 30 within sendmail.cf, (hint: search for S10 and S30) and delete these 2 lines - or put a # in front of them:

#  Envelope sender rewriting
#
S10
R<@>        $n              errors to mailer-daemon
R@ <@ $*>   $n              temporarily bypass Sun bogosity
R$+         $: $>50 $1      add local domain if needed
R$*         $: $>94 $1      do masquerading  <-- delete this line
#
#  Header sender rewriting
#
S30
R<@>        $n              errors to mailer-daemon
R@ <@ $*>   $n              temporarily bypass Sun bogosity
R$+         $: $>50 $1      add local domain if needed
R$*         $: $>93 $1      do masquerading  <-- delete this line

There is no m4-based solution for this, so you have to modify sendmail.cf directly. You need to restart sendmail afterwards, of course.

Note: I have jpollman@kulai.org in my From: line in my email program, so sendmail will masquerade only out-going mail. Many thanks to: Achim Löbbert for the solution.

3. Using unqualified names fails:
If you type just the user's name in the To: part of the email and it disappears into the internet, you may have to tell sendmail where to put email with unqualified names. Add this to the bottom of your master.mc:

define(`LOCAL_RELAY',`mail.kulai.org')

LOCAL_RELAY: again: instead of mail.kulai.org, put your mail server's name here. This line will make sendmail send unqualified names, like just "bmote", to your mail server, i.e. sendmal will add the kulai.org onto bmote for you. This way you can type just bmote in the To: field in your email program instead of bmote.kulai.org. Of course you will have to do the m4, copy, restart routine again to make it take effect.


I have no idea how many times I have m4'ed my sendmail.mc files and then did the copy - restart routine. I wrote a shell script to do this for me. Now, all I have to do is edit the master.mc file and type: ./newsendmail (the name of the script). Here it is:

#!/bin/sh
m4 master.mc > _master.cf
cp _master.cf /etc/sendmail.cf
/etc/rc.d/init.d/sendmail restart
Put this in your /usr/lib/sendmail-cf/cf directory and make it executable
chmod 700 newsendmail [Enter]


Copyright © 1999, JC Pollman and Bill Mote
Published in Issue 45 of Linux Gazette, September 1999