Chapter 9. Beyond Default

Table of Contents
9.1 The Home User
9.2 The Home Network Configuration
9.3 The Corporate Environment
9.4 The Service Provider

We will cover three styles of configuration in this section. First the home user. Then the corporate environment and then finally we'll dig into some ISP configurations.

9.1 The Home User

The home users environment could be very simple or very complex depending on the number of users on their system, whether they have a networked environment or a stand alone environment, and their type of connection and service provider.

9.1.1 The Stand Alone Configuration

If your machine does not have a network card and is not connected to a Local Area Network (LAN) and you use your MTA to send mail to the net over a PPP connection, a cable modem, or a Digital Subscriber Line (DSL) connection then this section is for you. We will not be dealing with the connectivity issues as that is beyond the scope of this document, but we will work through the configuration you need to be able to send mail through Postfix while off-line and on-line, how to kick the queue once you've connected and those types of issues.

Here is a sample “/etc/postfix/” configuration and some comments:

    #sample /etc/postfix/ for a dial-up user
    # your ISP's SMTP server name or IP address goes here
    relayhost =
    # this line disables spontaneous PPP connections
    defer_transports = smtp
    # this line disables DNS lookups for mail. As you are using a relay you really 
    # don't need DNS. If you use this you should use an IP address for $relayhost.
    disable_dns_lookups = yes
    # you will need all of the default stuff included as well
    # defaults
    queue_directory = /var/spool/postfix
    program_directory = /usr/libexec/postfix
    command_directory = /usr/sbin
    daemon_directory = /usr/libexec/postfix
    mail_owner = postfix
    default_privs = nobody
    mail_spool_directory = /var/spool/mail
    mailbox_command = /usr/bin/procmail
    local_destination_concurrency_limit = 2 
    default_destination_concurrency_limit = 10
    debug_peer_level = 2
    debugger_command = PATH=/usr/bin:/usr/X11R6/bin, xxgdb $daemon_directory/$process_name $process_id & sleep 5
    # you shouldn't need any more in this next line for a stand alone host
    mynetworks =
    # host specific information
    myhostname =
    mydomain =
    myorigin = $mydomain
    # where do we receive mail and who do we accept/receive mail for?
    inet_interfaces = all
    mydestination = $myhostname, localhost.$mydomain, $mydomain
    # no uucp here
    default_transport = smtp
    # let's get the envelope right
    masquerade_domains =

The masquerade_domains line above is critical. YOU MUST HAVE THIS LINE IN ALMOST ALL CASES for the stand alone environment using a dial-up connection. Why is this so important? Let's compare an e-mail message to a letter sent through the postal service. When you address the envelope you normally provide several pieces of information so that the postal service can do their job correctly. You would write the person's name and address that you want to send it to and you would also write your name and mailing address so that if the letter can't be delivered it can be safely returned to you. So after you post the letter what does the postal service do? They pick it up and attempt to deliver it based on the information you provided. Now... if you had a criminal mind and intended to mail something malicious you wouldn't put your correct return address on the envelope would you? Probably not. So if you put a false return address and the message was ultimately undeliverable the postal service wouldn't be able to return it to you would they? In this example everything is very anonymous and you really can send out garbage without being held accountable. Just a few short months ago Internet based electronic mail worked the same way. You could send out garbage with a false return address and it wouldn't be returned to you if it proved undeliverable. Granted, this is not a very nice thing to do but it happened all the time. So... what happened is that the people who develop code for Mail Transfer Agents (MTAs -or- the post office in our scenario) started to tighten things up a little bit. These much improved MTAs now check that the sender's envelope address is valid before they will relay, or deliver, a message. This is a good thing but it has caused problems for many people, particularly those who use an MTA rather than client software to send their mail... translation... the dial-up user with a Linux box is likely to get a bunch of bounced mail unless he or she configures their MTA to masquerade the envelope.

It's not enough to set the From: and Reply-To: addresses in a piece of e-mail client software because, much like a regular letter, all this does is tell the person who receives the message who it's from (maybe). The newer versions of sendmail (particularly 8.9.x) and other modern MTAs like Postfix are more concerned with which mail server or MTA it was sent from than they are with which user sent the message so they read the message envelope. They're not looking for the person that sent it by checking the sender's From: or Reply-To: email address, they're checking to see if the "post office" or MTA the message came from is a valid host. This is equivalent to checking the zip code of origin on a letter. Once this information is excerpted from the message, it's verified via reverse DNS to see if the sending post office exists (in other words, would the sending MTA receive a bounce if the intended recipient didn't exist) and if that post office (the sending MTA) doesn't exist then the receiving MTA will reject the message with prejudice. So we fix this by configuring our MTA to masquerade the envelope and then we relay our messages through our service provider's mail host which gives our mail the final stamp of legitimacy it needs.

So when using Postfix the keys to getting this right are using the right values for $relay_host, $masquerade_domains, $mydomain and $myorigin, and sometimes even the next entry (sender_canonical_maps). While we're on the subject, here's a fine example of how Postfix should respond to a message sent from a host which is not properly masquerading the envelope:

    Date: Fri, 12 Nov 1999 23:48:27 -0500 (EST) 
    From: Mail Delivery System <> 
    To: Postmaster <> 
    Subject: Postfix SMTP server: errors from[]

Now if you know what you're looking at you'd know this is trouble just from seeing the subject line. Nobody's MTA should be sending “direct” from a dial-up connection, and if it did the reverse DNS wouldn't have the access port as the PTR it'd be a domain name.

    Transcript of session follows.
    Out: 220 ESMTP Postfix (Postfix-19990906-pl06) 
    In: HELO

Now you can see just how messed up the sender really is. Reverse DNS says they're on a UUNET dialup but their HELO command is trying to say they're from a completely different country and as it happens this hostname does not exist at all anywhere. Now in some cases this issue will jump up and bite legitimate users, but in the case of this example this is nothing but pure spam and is exactly what the increased restrictions were designed to prevent.

    Out: 250 
    In: MAIL FROM: <> 
    Out: 250 Ok 
    In: RCPT TO:<> 
    Out: 450 <[]>: Sender address rejected: Domain not found
    In: RSET
    Out: 250 Ok
    In: QUIT
    Out: 221 Bye
    # be sure to rewrite our address if we need to
    sender_canonical_maps = hash:/etc/postfix/sender_canonical

The above configuration is an elegant way to fix some common problems which arise when configuring mail clients. All it does is map what *is* to what you want it to be. Here is an example:

Now run the command postmap sender_canonical and if you run ls you will see a new file is in /etc/postfix called sender_canonical.db. This works together with the masquerading we discussed earlier to get your outgoing e-mail address (yes... the From: and Reply-To: addresses) mapped from your login, which would be bob, to robert.smith.

    # let's handle any aliases we might need
    alias_maps = hash:/etc/postfix/aliases
    alias_database = hash:/etc/postfix/aliases
    # special stuff below here
    # end

There you have a working configuration for a dial-up user with no local network. Once you have this done you will need to do a couple of things. One: execute the newaliases command. Two: execute postfix reload if Postfix is already running and if it's not the execute /etc/rc.d/init.d/postfix start.

You will also want to add a line to your PPP connect script to flush the queue whenever the link is connected. This line would do what's needed:

    /usr/sbin/sendmail -q

9.1.2 Fetching the mail

The next part of our discussion details a tool which is currently maintained by Eric S. Raymond. The name of the tool is fetchmail and it is an outstanding tool for people in your situation. You have a net connection and an MTA but you don't have a real domain and you need to get your e-mail.

First let's make sure that fetchmail is installed:

    [root@boss sbin]# rpm -q fetchmail 

Ah... in our case it is... but if you get a null response don't panic. It comes on your distribution CD-ROM and you can easily install it if it's not there already.

So now that we've verified that it's installed what do we do next?

Well... it's just not a problem. Fetchmail, like most Linux tools, uses a simple, text based configuration file with simple syntax. The file goes in your home directory and it's called .fetchmailrc (note the dot, or period, in the filename). If we continue on with our scenario this is what the text of the file should look like:

    poll proto POP3 user bob is bob here password hidden

What this means is that we want to 'poll' the machine called '' with the POP3 protocol using the username bob with the password hidden. Now all this means, quite simply, is that we're going to connect to using the POP3 protocol, logging in as bob, using the password hidden, and that any mail for bob which is there should be transferred to the mail spool which belongs to the user bob here on the local machine. Note that if your local user name was tom instead of bob but your remote user name was still bob you would change this line to look like this:

    poll proto pop3 user bob is tom here password hidden

Now we're ready to run fetchmail. Here's what you do:

    [bob@boss bob]$ fetchmail -v -a 
    File /home/bob/.fetchmailrc must have no more than -rwx--x--- (0710) permissions.

Woops... an error message. But notice how decent an error message it is... it tells you exactly how to fix it. So let's do this:

    chmod 0710 /home/bob/.fetchmailrc
    [bob@boss bob]$ fetchmail -v -a 
    fetchmail: 5.1.0 querying (protocol POP3) at Tue, 23 Nov 1999 03:10:27 -0500 (EST) 
    fetchmail: POP3< +OK POP3 v7.59 server ready 
    fetchmail: POP3> USER bob 
    fetchmail: POP3< +OK User name accepted, password please 
    fetchmail: POP3> PASS * 
    fetchmail: POP3< +OK Mailbox open, 4 messages 
    fetchmail: POP3> STAT 
    fetchmail: POP3< +OK 4 1517 4 messages for bob at (1517 octets).
    fetchmail: POP3> LIST 
    fetchmail: POP3< +OK Mailbox scan listing follows 
    fetchmail: POP3< 1 382 
    fetchmail: POP3< 2 379 
    fetchmail: POP3< 3 378 
    fetchmail: POP3< 4 378 
    fetchmail: POP3< . 
    fetchmail: POP3> RETR 1 
    fetchmail: POP3< +OK 382 octets reading message 1 of 4 (382 octets)
    ...and it continues until...
    reading message 4 of 4 (378 octets) 
    fetchmail: SMTP> MAIL FROM:<> SIZE=378 
    fetchmail: SMTP< 250 Ok 
    fetchmail: SMTP> RCPT TO:<bob@localhost> 
    fetchmail: SMTP< 250 Ok 
    fetchmail: SMTP> DATA 
    fetchmail: SMTP< 354 End data with <CR><LF>.<CR><LF> #*
    fetchmail: SMTP>. (EOM) 
    fetchmail: SMTP< 250 Ok: queued as 782A3BD7B flushed 
    fetchmail: POP3> DELE 4 
    fetchmail: POP3< +OK Message deleted 
    fetchmail: POP3> QUIT 
    fetchmail: POP3< +OK Sayonara 
    fetchmail: SMTP> QUIT 
    fetchmail: SMTP< 221 Bye 
    fetchmail: normal termination, status 0

Notice the command string we used with fetchmail. We used a -v which means to use verbose mode for its output (so we can tell what it's doing) and we used -a which means to download all mail. But where did our mail go? Well... as we said in our .fetchmailrc we wanted the mail to go to the mail spool belonging to local user bob and that is exactly where it went. The order of events for this is quite simple. Fetchmail grabs the remote mail using POP3 (port 110) and then hands off the mail to Postfix (using port 25) which, after determining that the mail is for local delivery, passes off the mail to procmail (the default MDA on Red Hat Linux) which delivers the mail to the Inbox you specified with the “here” statement in your fetchmail command string. One potential problem with this is that sometimes the mail could be rejected as fetchmail tries to hand off to Postfix. If you see this happening add this line:

    localhost   RELAY

to your /etc/postfix/access file. The reason this might prove necessary is that sometimes Postfix may even reject relay from the localhost if it's not explicitly authorized.

9.1.3 Reading the mail

The mail spool for user bob is located in /var/spool/mail/bob and bob can read his mail in a myriad of ways but why don't we try one of the simplest, but most powerful ways to read it, the pine MUA.

The first time we run pine by typing 'pine' at the command prompt we will see a message on the screen which says this at the top:

    <<<This message will appear only once>>>

Simply press the 'Enter" key or the letter “e” and this will go away and you will see a menu that looks like this:

    ?           HELP               -  Get help using Pine             
    C           COMPOSE MESSAGE    -  Compose and send a message      
    I           MESSAGE INDEX      -  View messages in current folder 
    L           FOLDER LIST        -  Select a folder to view         
    A           ADDRESS BOOK       -  Update address book             
    S           SETUP              -  Configure Pine Options          
    Q           QUIT               -  Leave the Pine program

Just press “L” to see your default folders and then press the “Enter” key to see your “Inbox” and there are your four messages. Note that your default Inbox in pine is set to the file /var/spool/mail/bob.

So now your MTA is working properly for both outgoing and incoming mail.

9.1.4 A couple of tweaks to make it all nice

There are really two things which a dial-up user may want to add to this configuration. One thing is to add a /usr/sbin/sendmail -q line to your connect script to force Postfix to dump its queue after the connection is made and you also might want to do the same for fetchmail. Another thing which you could do is run fetchmail in daemon mode or as a cronjob and time it to force a connection hourly. As an alternative you could automate the connection itself and include the Postfix and fetchmail commands in the connection script as mentioned above. Here's a sample of how to run fetchmail as a daemon and as a cronjob:

    fetchmail -d 180

this would run fetchmail as a daemon and it tells it to poll the mail server every 180 seconds.

    0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,54,57 0-23 * * * fetchmail -f /home/bob/.fetchmailrc > /dev/null 2>&1

this cronjob would run fetchmail every 3 minutes for all 24 hours of every day