This is information I found extremely useful to help me set up sendmail and fetchmail. Recently I went back to the noether website only to find it gone! Luckily I had a copy of this page I had stored for personal use. I emailed M. Holland at the address below to find out if this page had been moved but I never recieved any reply. I also searched the web for any newer versions of this but didn't find anything.

If anyone knows what happened to the noether website then let me know, and likewise if M Holland wants me to remove this page then I shall.

If there is something you want changed on this page (i.e. a correction) then mail me about it.

Valid CSS!

How to send and receive mail on freeserve

Version 3: 8 October 1999

Please email comments or suggestions to: Martin P Holland m.holland@noether.freeserve.co.uk


This information is useful for the following situation:

If you just have one user on your machine then you probably shouldn't bother with fetchmail and sendmail, it's a lot easier to use kmail or netscape for your mail specifying the smtp and pop as smtp.freeserve.net and pop.freeserve.net. The details for doing this for kmail can be found here.

Disclaimer: If you mess up your linux box trying to follow these instructions don't blame me! Never make any changes that you don't know how to reverse. If in doubt back up any files before you change them.

OK then let's suppose that you are the sysadmin for your linux box and your user account is called marge and let's suppose that you have some other users homer, bart and lisa who want to get their mail from your freeserve node simpsons.freeserve.co.uk.

This is what marge has to do:

First off su to root.

Loopback interface

On a working system the loopback interface is configured at boot time. Test it is working:

$ ping -c 5 127.0.0.1

PING 127.0.0.1 (127.0.0.1) from 127.0.0.1 : 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=0.3 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=255 time=0.2 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=255 time=0.2 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=255 time=0.2 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=255 time=0.2 ms
 
--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.3 ms

If you see something like this then skip to the next section. If it hangs and when you CTRL-c you get 100% packet loss then you need to configure your loopback interface. The commands to do this are
/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0 broadcast 127.255.255.255
/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo
Type them now. They also need to be issued each time the system boots. This should happen during your machine's Sys V initialisation process. Where exactly is appropriate depends on your distribution. For Red hat these commands are issued in /etc/rc.d/init.d/network and you can make sure this is run (at the next boot) with /sbin/chkconfig --add network

Hostname and /etc/hosts

We need to make sure that your /etc/hosts file is in a sane condition and reflects the hostname of your machine.

When you boot up into linux your linux box goes through a process of byzantine complexity called system V initialisation. One of the key things that happens in this process is that your hostname gets set. To find out what (the first part of) your hostname is now type hostname. You will quite likely get the response localhost but you might not.

Exactly where the hostname gets set on your machine depends on your distribution. Look through you /etc/rc.d directory (or similar) for a file with a line like

hostname mumble
For Redhat 6 the appropriate file is /etc/rc.d/rc.sysinit and the line where the hostname gets set is a bit more complicated. It looks like
# Set the hostname.
action "Setting hostname ${HOSTNAME}" hostname ${HOSTNAME}
As you can probably guess the hostname gets set to whatever is is the enviroment variable HOSTNAME. So we need to look at the file in which HOSTNAME gets set: /etc/sysconfig/network. To see what the hostname is set to now you should examine the HOSTNAME= line. Also you should make sure that NETWORKING=yes is set. The file will probably look something like this (I have omitted some lines for clarity)

NETWORKING=yes
HOSTNAME="localhost.localdomain"
saying that the hostname will be set to localhost.localdomain but it might be set to localhost. Your /etc/hosts should reflect that. If the hostname is localhost.localdomain it will read
127.0.0.1	localhost.localdomain	localhost
or just
127.0.0.1	localhost
in the other case. (Note that the fields in the hosts file are separated by tabs not spaces.)

If you are a newbie then you should make sure that the hostname is set to one of these two default choices and that the hosts file corresponds to that choice and then skip on to the next section. (If you had to make a change to the hostname bear in mind that this change won't come into effect until you next reboot. Although it is possible to change the hostname from the command line you will probably find it easier to reboot your computer after making all the configuration changes I suggest below. It's worth pointing out that below I am assuming that your machine name is doh.simpsons rather than localhost.localdomain or localhost. So everywhere you see a doh.simpsons read it as localhost.localdomain or localhost.)

Not for newbies On the other hand if you are a bit more experienced or you have a LAN then you should choose a private IP and fully qualified domain name (FQDN) for your machine.

The first step is to invent a private FQDN. Let's call it doh.simpsons. The first part doh is the hostname and the second part simpsons is the domain name. You must ensure that simpsons does not belong to someone else on the internet. i.e. is not one of com, edu, gov, mil, org, net, uk or any other country designator. More generally, you can have a domain name that contains some dots like random.simpsons.springfield so in that case you would make sure that everything after the last dot, springfield in this case, is not one of com, edu, gov, mil, org, net, uk or any other country designator.

Next we have to choose a private IP address for our machine Again we have to make sure to choose an IP address that doesn't belong to a machine on the internet. Luckily the ranges
10.0.0.0 - 10.255.255.255
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255
are set aside for private networks and so we can use one of these (except that you shouldn't choose the zeroth one in any of these ranges). In this case we'll use 192.168.0.1 but 10.1.5.6 or 172.17.0.2 would have been equally good choices.

The next step is to make sure the hostname gets set to doh on boot up. As mentioned above for Redhat this involves editing the file /etc/sysconfig/network. (But for other distributions you will have to search out exactly where the hostname gets set in the Sys V init process.) You need to change the HOSTNAME= line

NETWORKING=yes
HOSTNAME="doh"
This change won't take effect until the next time you reboot your computer. If you want to you can reset your hostname now though by typing hostname doh at the command line. I advise exiting X before you do this though. Most people will probably find it easiest to reboot their computer after making all the configuration changes I suggest.

Next we need to check that /etc/hosts is in a sane condition. It should be like this (with the fields separated by tabs not spaces):

127.0.0.1	localhost
192.168.0.1	doh.simpsons	doh
You'll notice that the IP 127.0.0.1 is associated to localhost and that the IP 192.168.0.1 is associated to our new machine name.

We are nearly done with the FQDN and IP address now. The last step is to associate each IP address in /etc/hosts with an interface. Now on a working system 127.0.0.1 is already associated with an interface, lo, so we just have to deal with 192.168.0.1. We are going to associate it with a dummy interface. (If you have an ethernet card then you don't need to use the dummy interface so skip to here.)

You must have the dummy interface compiled into the kernel or as a module for this.

To decide this, type /sbin/ifconfig dummy 192.168.0.1. If you get a silent response from this command then you have dummy support compiled into the kernel and you can proceed to the next step.

If the response is "No such device" then you do not have dummy compiled into the kernel but it still may be compiled in as a module. This is in fact most likely if you are still using the kernel supplied with your distribution. So now try /sbin/ifconfig dummy0 192.168.0.1. A silent response indicates that you have the dummy interface compiled as a module but "No such device" means that you will have to recompile the kernel with support for the dummy interface. (Choose CONFIG_DUMMY=y or if you use make xconfig then look in the "Network device support" section for "Dummy net driver support" and choose "yes".)

We configure the dummy interface at boot-time and the right place for this on RH6 is in the /etc/rc.d/init.d/network file. For your distribution it may be called something slightly different. If you have dummy support in the kernel insert the code

/sbin/ifconfig dummy 192.168.0.1 netmask 255.255.255.255
/sbin/route add -host 192.168.0.1 dev dummy
into the start) section of /etc/rc.d/init.d/network to configure a dummy interface corresponding to 192.168.0.1. If you have dummy support compiled as a module the code should be
/sbin/ifconfig dummy0 192.168.0.1 netmask 255.255.255.255
/sbin/route add -host 192.168.0.1 dev dummy0
On RH6 I put this just after lo is set up
start)
        ipv4_forward_set

        action "Bringing up interface lo" ./ifup ifcfg-lo
As usual this will not take effect until you reboot. If you don't plan to reboot just type the two commands at the command line. Make sure that the network script runs as boot time by typing /sbin/chkconfig --add network at the command prompt.

This assumes you just have one machine. If you have a network then associate the private IP with eth0 and forget about dummy. The analogous commands for eth0 are

/sbin/ifconfig eth0 192.168.0.1 netmask 255.255.255.0 up
/sbin/route add -net 192.168.0.0 netmask 255.255.255.0 eth0
but you may find it easier to use a GUI tool like Redhat's netcfg to set this up.

Sendmail daemon

The sendmail daemon has to be running for fetchmail to work. (One reason we care about this because we are going to use fetchmail to get our mail from freeserve.) This is more system V initialisation yoga. On Redhat the scripts to start services at bootup and shut them down at shutdown live in /etc/rc.d/init.d. Then in the folders /etc/rc.d/rc.0 through /etc/rc.d/rc.6 are symbolic links to these scripts with names like S80service and K30service. The S stands for start and the K stands for kill. The idea is that there are run levels 0-6 and that services start and stop at different runlevels. The symbolic links are just a way to encode this information. Luckily you don't have to understand all the details of this :-) To tell the sendmail daemon to start up at boot up run /sbin/chkconfig --add sendmail. Alternatively you can use one of the several GUI runlevel editing tools. For example, on RH6 run /usr/sbin/ntsysv and select sendmail as a starting service. Note that the sendmail daemon will not yet be running; we just asked it to run on the next reboot. Next we have to make sure that the sendmail daemon is getting started with the correct parameters. The code to start up sendmail is in the /etc/rc.d/init.d/sendmail script. The section of the script dealing with start needs to have a line something like this
	daemon /usr/sbin/sendmail -bd
The important thing is that there shouldn't be any option like -q1h (or -q30m). These options don't really do any harm, they tell sendmail to try to send any queued mail every hour (or every 30 minutes). However, if you don't have a permanent internet connection these queuing attempts waste processor activity and will also mean that you get annoying emails from sendmail saying that it has been trying to deliver a message for the past n hours. For Redhat 6.0 the actual line in the script is a bit more complicated than the idealised version I gave above. It looks like
daemon /usr/sbin/sendmail $([ "$DAEMON" = yes ] && echo -bd) \
		$([ -n "$QUEUE" ] && echo -q$QUEUE)
As you can probably guess this will give us our idealised line if DAEMON=yes and QUEUE="". To do this you have to edit /etc/sysconfig/sendmail and make sure it contains the lines
DAEMON=yes
QUEUE=

I said above that the sendmail daemon has to be working for fetchmail to work. This is not really true; another way is to start it on demand from inetd.conf using the -bs switch. This has some security advantages too. I might explain this in a future version of this tutorial.

On the subject of security, if sendmail is running as a daemon then relaying should be turned off to avoid spammers using your box. The default redhat 5x/6.0 configuration for sendmail has relaying turned off except for hosts specified in the access database. The database is generated from the text file /etc/mail/access. If you edit this file you need to rebuild the database with


makemap hash /etc/mail/access < /etc/mail/access

There are other potential problems with sendmail running as a daemon. Anyone can telnet to port 25 on your machine and start talking to sendmail. Here is homer sending a mail to marge by this method.

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 doh.simpsons ESMTP Sendmail 8.9.3/8.9.3; Sun, 10 Oct 1999 12:43:55 +0100
helo doh
250 doh.simpsons Hello IDENT:homer@localhost [127.0.0.1], pleased to meet you
mail from: homer@doh
250 homer@doh... Sender ok
rcpt to:marge
250 marge... Recipient ok
data
354 Enter mail, end with "." on a line by itself
Mmmm chocolate
.
250 MAA01267 Message accepted for delivery
Of course this could just as easily have been a conection attempt from outside doh.simpsons by a malicious person. If there is a bug in sendmail that the cracker can exploit then this could be bad news. For this reason you should always make sure you keep your sendmail up to date. You should also consider using a firewall to stop any unauthorized connections to port 25. You can find a generic firewall in the security section of this site.

Edit sendmail.cf

Configuration of sendmail is setup in the rather complicated file /etc/sendmail.cf. The stock redhat version of this file works pretty well, so I suggest only making minimal changes to it. One change that you must make is to set the "smart host" to freeserve. This basically transfers responsibility for delivering mail and doing lookups to freeserve. Using sendmail seems not to work if you don't do this. To make this change look for the line in the file that says DS and change it to
# "Smart" relay host (may be null)
DSsmtp.freeserve.net
Finally you need to find the line that says DM and change it to
# who I masquerade as (null for no masquerading) (see also $=M)
DMsimpsons.freeserve.co.uk
so that doh.simpsons masquerades as simpsons.freeserve.co.uk. This has the effect that your emails come from marge@simpsons.freeserve.co.uk rather from marge@doh.simspons. This is a good thing as the latter doesn't exist as far as the internet is concerned! Most likely mail from root will not be masqueraded though, so watch out for that.

You will also want to make sure that sendmail knows that simpsons.freeserve.co.uk is an alias for your machine. If a file called /etc/sendmail.cw exists then edit it so that it contains a line

simpsons.freeserve.co.uk
If this file doesn't exists then you can just edit the line in /etc/sendmail.cf beginning Cw to read
Cwlocalhost simpsons.freeserve.co.uk

Sendmail.mc

This section is optional so you can skip to the next if you want to. However if you want to do something more complex with sendmail you need to learn about the sendmail.mc file. The changes we made in the previous section to the sendmail.cf file can also be achived by editing a more human-readable file, sendmail.mc, and then using this file to regenerate the cf file. To do this you have to find your sendmail.mc file (on RH6 this is in /etc). Now backup this file (and sendmail.cf) and insert the lines
define(`SMART_HOST',`smtp.freeserve.net')
MASQUERADE_AS(simpsons.freeserve.co.uk)
FEATURE(use_cw_file)
(The last line might already be there so don't add it again in that case.) Note that there are two different sorts of single-quotes being used here so use them exactly as indicated. Then run m4 sendmail.mc > /etc/sendmail.cf in the directory where your sendmail.mc file is. The permissions on your sendmail.cf should be 644. This change won't be registered by sendmail until you restart it.

This is over-the-top to make two small changes to our sendmail configuration file but if you wanted to enact some more complicated changes it is better to use the mc file. As an example of this, you might consider adding

FEATURE(`masquerade_envelope')
which not only masquerades all the essential headers but the entire envelope. This is not really necessary but I found it useful in one instance. These days people sometimes send messages with a Return-Receipt-To: header. If your mailer is configured to it will send out a message confirming delivery of the mail to whoever was specified in the header. Personally I think this is a bit of an annoying invasion of privacy/waste of bandwidth. However, if you don't object to this then using FEATURE(`masquerade_envelope') seems to stop these confirmations bouncing. The change it makes to the sendmail.cf file is a one-liner but it is a rather complicated line.

One thing to look out for in your mc file are any lines that allow relaying. It's best to remove them and regenerate the cf file. For example, FEATURE(`promiscuous_relay') should definitely be deleted, if present.

A locally written mail addressed to say marge should be delivered immediately but this may not be the case for local mail addressed to marge@simpsons.freeserve.co.uk. If it isn't, and mail addressed to marge@simpsons.freeserve.co.uk still gets queued and not delivered immediately then add

FEATURE(`nocanonify') 
to mc and regenerate your cf file.

Aliases

Next we need to cope with the fact that your users may well have email addresses that are different from their login names. To handle this we need to tell sendmail about these aliases for local usernames. For example homer might like his mail sent to hjs@simpsons.freeserve.co.uk

You shouldn't be routinely logging on as root so we'll also make sure that any mail for root gets delivered to marge. In the stock Redhat aliases postmaster is an alias for root. So the combination of these two aliases means mail addressed to postmaster goes to marge. You should have a postmaster address so put one in if it's not there. Edit /etc/aliases and add some lines at the end like

# Person who should get root's mail
root:			marge

# This bit is new!
hjs:			homer
user:			marge
at the end. (The fields are separated by tabs.) Note that user is the address freeserve (now) send to for their newsletter and that kind of thing. After doing this you must run /usr/bin/newaliases so that sendmail knows about these changes.

Fetchmail configuration

The best way to collect your mail from your ISP is with fetchmail. To configure it you need to create a file /root/.fetchmailrc looking like this:
set postmaster "marge"
set no bouncemail      

poll pop.freeserve.net proto pop3
localdomains "simpsons.freeserve.co.uk"
envelope "Envelope-to" no dns timeout 60
username "simpsons.freeserve.co.uk" password "xxxxxxxx" to * here
This file is appropriate to version 5 of fetchmail so if you have trouble with an earlier version consider upgrading. Make sure that this file has the correct permissions with chmod 0600 /root/.fetchmailrc otherwise fetchmail won't run (and this protects your password from casual inspection). You might well want to collect mail as marge too so you should

cp /root/.fetchmailrc /home/marge/.fetchmailrc
chown marge.marge /home/marge/.fetchmailrc
chmod 0600 /home/marge/.fetchmailrc

This will send any mail for the foo@simpsons.freeserve.co.uk to either:

So whatever happens no mail should be lost and if you forget to put an alias in /etc/aliases marge will get a reminder to fix it. Once you are sure that this is all working properly you might consider removing the set no bouncemail option from .fetchmailrc. This option is is telling fetchmail that if a mail for a non-existent user arrives then an error message should not be bounced back to the sender. However, a word of caution is in order, especially if you get a lot of mail. Imagine that Freeserve change their mail setup and drop the Envelope-to header which the above relies on. Although you won't lose any mail you will send bounce messages to everyone who emails you, until you fix things. Ouch! I recommend keeping the set no bouncemail option.

If you just have one real user on your machine you may want to simplify things by sending all incoming mail to that user with the .fetchmailrc

poll pop.freeserve.net proto pop3 timeout 60
user "simpsons.freeserve.co.uk" there with password "xxxxxxx" is marge here

Setting up your mail client

For mail you don't need to do anything. For kmail select "sendmail" for "Sending mail" and "Local mailbox" for "Incoming mail" on the "Network" tab. Make sure that on the "Composer" tab "Send mail now" is set.

Sending and collecting mail

Next time you start up your linux box the sendmail daemon should be running from boot. But assuming you haven't done that we need to start sendmail manually by typing /etc/rc.d/init.d/sendmail start When you are connected to freeserve you can send any queued mail for the whole machine by typing

/usr/sbin/sendmail -q
To collect your mail you type
/usr/bin/fetchmail
When you are testing you might want to use the -k switch for fetchmail. This doesn't delete the mail from the server so if you made a mistake with the delivery options you won't lose any mail. You can also test that you didn't make a syntax error in the .fetchmailrc file by typing fetchmail -V. This doesn't run fetchmail but tells you what fetchmail will do when you do run it.

If you want your users other than marge and root to be able to download the mail when they connect to freeserve you will need a copy of the .fetchmailrc file above in their home directory. Make sure it has the right permissions and ownership. Any user can send the queued mail with /usr/sbin/sendmail -q because sendmail is suid root.

If things go wrong you might get some clues from /var/log/maillog. (This is where Redhat logs the output from syslog relating to mail). fetchmail just logs to standard out by default so you might want to insert set syslog in your .fetchmailrc to send its logging to the same file. Have a look to see if mail is being queued by typing /usr/bin/mailq or by looking in /var/spool/mqueue. See if it is arriving in the files in /var/spool/mail.

Here's how a queued message shows up in the log

Sep 13 12:07:06 doh sendmail[1119]: MAA01119: from=lisa, size=1864, class=0, pri=31864, nrcpts=1, msgid=<99100810354200.00600@doh>, relay=localhost [[UNIX: localhost]]
Sep 13 12:07:06 doh sendmail[1119]: MAA01119: to=skinner@springfield.high, delay=00:00:00, mailer=relay, stat=queued
and when it gets sent this is recorded
Sep 13 14:13:35 doh sendmail[1288]: MAA01119: to=skinner@springfield.high, ctladdr=marge (500/500), delay=02:06:29, xdelay=00:0
0:02, mailer=relay, relay=relay.pol.net.uk. [195.92.193.214], stat=Sent (OK id=11QVwT-00086w-00)
Here's what one message arriving looks like in the log.
Sep 13 18:56:27 doh fetchmail[2447]: 1 messages for simpsons.freeserve.co.uk at pop.freeserve.net (1960 octets).
Sep 13 18:56:28 doh fetchmail[2447]: reading message 1 of 1 (1960 octets)
Sep 13 18:56:29 doh  sendmail[2460]: SAA02460: from=, size=2113, class=0, pri=32113, nrcpts=1, msgid=, proto=ESMTP, relay=IDENT:root@localhost [127.0.0.1]
Sep 13 18:56:29 doh fetchmail[2447]:  flushed
Sep 13 18:56:29 doh sendmail[2467]: SAA02460: to=lisa, delay=00:00:01, xdelay=00:00:00, mailer=local, stat=Sent

Congratulations! You've setup sendmail and fetchmail. Send me some mail! m.holland@noether.freeserve.co.uk

Automation

You can automate fetching and sending of mail. By putting
/usr/bin/fetchmail
/usr/sbin/sendmail -q
in your /etc/ppp/ip-up.local. The permissions should be chmod 755. Some distributions don't have this file. In which case you can just put this stuff in /etc/ppp/ip-up. You won't see any output from ip-up.local so you might want to play a sound at the end of the script so you know it's time to stop browsing and disconnect. A minimalist solution to this is use the humble beep with the code
echo -e "\a" >/dev/console
(The /dev/console is here because ip-up.local executes in the background so without the redirection you wouldn't see (or hear!) its standard output.)

As a further refinement you could get fetchmail and sendmail to both run at the same time to get the most out of your bandwidth. Here's a snippet from my ip-up.local

/usr/sbin/sendmail -q &
/usr/bin/fetchmail &
# Now wait for these two background processes to finish before
# making a beep
wait
echo -e "\a" >/dev/console

Procmail

Procmail can be used to further filter the mail that you have received. It can also be used to run a script with input any mail of some particular form.

Turning off DNS

Sendmail by default will look-up any addresses that come its way. So for example if someone sends you a message that is also addressed to a thousand other people then it will happily do a DNS lookup on all of those addresses, which takes a little time and uses up some of your bandwidth. For this reason turning off DNS can be a big win. Think first though whether this is appropriate to your enviroment. (For example, if you allow access to port 25 someone could spam all your users.) To achieve this all you have to do is create a file /etc/service.switch with content
hosts files
aliases files

Switching beween ISPs

If you want to switch between ISPs this is easy to do. All you need to to is create a sendmail.cf.ISP2 for your second ISP. You should make sure that the DM and DS lines are appropriate for the second ISP. Then, after connecting to ISP2 you should replace your current sendmail.cf by sendmail.cf.ISP2 and restart sendmail. Then you can send mail using your second ISP's smart host. Obviously you can can automate this in ip-up.local This gives you a backup so that you can still send mail even if your usual ISP's mail server is down.