Mike Chirico (mchirico@users.sourceforge.net) or (mchirico@comcast.net)
Copyright (c) 2005 (GNU Free Documentation License)
Last Updated: Thu Nov 10 19:59:05 EST 2005
[http://souptonuts.sourceforge.net/postfix_sbr.html]


Postfix 2nd Instance for Sender-based Routing: Multiple Gmail and Comcast Accounts

These instructions are still in BETA. Separate keys need to be setup. /etc/postfix2/main.cf needs to be checked.

Sender-based routing allows delivery actions on email to be made based on the sending address. This makes it possible for each Gmail and or Comcast account to have separate authentication rules. In summary, your home Postfix system can support Gmail and Comcast accounts for all of your family and friends.

Quick Background

You will need an initial postfix setup. To get the initial setup please reference and follow Gmail on Home Linux Box using Postfix and Fetchmail, since this article builds on it. Please make sure you have that initial setup working. The first Postfix instance will change from the previous article to relay mail to the second Postfix instance on a separate IP address, with a distinguished hostname. The second instance will log entries as "postfix2" for easier problem tracking. Outgoing mail can still be configured on the original IP address to accommodate firewall rules. All of this is explained with examples below. Please read on.


Add Additional IP Address and Modify /etc/hosts

1.1 Second IP (ifcfg-eth0:1)

A second instance of Postfix will run on it's own IP address. Therefore, you will need to add an additional IP address to your server's NIC (Network Interface Card). If you're running Red Hat or Fedora, you will add the file "/etc/sysconfig/network-scripts/ifcfg-eth0:1". The simplest way to do this is by copying the existing ifcfg-eth0 file.

     $ cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0:1

Edit this file and change the IP address to the second address. My second IP address is 192.168.1.82.Take a look at my two files (ifcfg-eth0, ifcfg-eth0:1 ). Note both settings IPADDR=192.168.1.82 and DEVICE=eth0:1 in ifcfg-eth0:1. Yes, the filename does have a ":" colon in it.

1.2 Modify /etc/hosts

Bind the name to the IP address. This can be done by editing the /etc/hosts file. Below is the file I used to bind the name squeezel2.squeezel.com to the second IP address 192.168.1.81.

     cat /etc/hosts
      192.168.1.81    squeezel.squeezel.com squeezel
      192.168.1.82    squeezel2.squeezel.com

1.3 Restart Network Services

The following command, executed as root, will restart the network services.

     $ /etc/init.d/network restart    

1.4 Confirm 2nd IP

At this stage both IP addresses should be working on the card. Check this with the ifconfig command.

      $ ifconfig
      eth0      Link encap:Ethernet  HWaddr 00:11:11:8A:BE:3F
                inet addr:192.168.1.81  Bcast:192.168.99.255  Mask:255.255.252.0
                inet6 addr: fe80::211:11ff:fe8a:be3f/64 Scope:Link
                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                RX packets:264369 errors:0 dropped:0 overruns:0 frame:0
                TX packets:243745 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:1000
                RX bytes:59584619 (56.8 MiB)  TX bytes:34479618 (32.8 MiB)
                Interrupt:169
      
      eth0:1    Link encap:Ethernet  HWaddr 00:11:11:8A:BE:3F
                inet addr:192.168.1.82  Bcast:192.168.3.255  Mask:255.255.252.0
                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                Interrupt:169
      
      lo        Link encap:Local Loopback
                inet addr:127.0.0.1  Mask:255.0.0.0
                inet6 addr: ::1/128 Scope:Host
                UP LOOPBACK RUNNING  MTU:16436  Metric:1
                RX packets:163487 errors:0 dropped:0 overruns:0 frame:0
                TX packets:163487 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:0
                RX bytes:107287251 (102.3 MiB)  TX bytes:107287251 (102.3 MiB)


Create Second Postfix Instance

You can use the current copy of postfix install, everything under "/etc/postfix", as a starting point for creating the second instance.

     $ cp -rp /etc/postfix  /etc/postfix2

Above the "-r" performs a recursive copy of any subdirectories and "-p" preserves mode, ownership, and timestamps of the files. The mode and ownership should be preserved.

2.1 /etc/postfix2/main.cf Initial Modifications

The following entries are made at the end of the /etc/postfix2/main.cf file.

     # DNS name of second IP address
     inet_interfaces = squeezel2.squeezel.com
     myhostname = squeezel2.squeezel.com
     queue_directory = /var/spool/postfix2
     # Inform 2nd instance of other version
     alternative_config_directories = /etc/postfix
     smtp_bind_address = 192.168.1.81
     # Separate Logging
     syslog_name=postfix2
     # Make sure settings go to /etc/postfix2
     transport_maps = hash:/etc/postfix2/transport

The DNS name, use your specific values in /etc/hosts, should be the value assigned to inet_interfaces. The queue_directory is necessary so that the spool files for the second instance of Postfix do not conflict with the first.

The smtp_bind_address parameter forces outgoing mail from the second Postfix instance to bind to the original IP address. This can be a convenience, since existing Firewall rules can be accommodated. However, the second IP address could have been used instead. The syslog_name parameter prefaces log entries with "postfix2".

2.2 Create Second Spool Directory

The next step is to create an additional spool directory. In the above step note the queue_directory = /var/spool/postfix2 change, which is necessary for the command below to work.

     $ mkdir /var/spool/postfix2
     $ postfix -c /etc/postfix2 check

After running the step above, you should have the following contents in this directory.

     $ ls -l /var/spool/postfix2
     total 112
     drwx------  2 postfix root     4096 Nov  1 19:43 active
     drwx------  2 postfix root     4096 Nov  1 19:43 bounce
     drwx------  2 postfix root     4096 Nov  1 19:43 corrupt
     drwx------  2 postfix root     4096 Nov  1 19:43 defer
     drwx------  2 postfix root     4096 Nov  1 19:43 deferred
     drwx------  2 postfix root     4096 Nov  1 19:43 flush
     drwx------  2 postfix root     4096 Nov  1 19:43 hold
     drwx------  2 postfix root     4096 Nov  1 19:43 incoming
     drwx-wx---  2 postfix postdrop 4096 Nov  1 19:43 maildrop
     drwxr-xr-x  2 root    root     4096 Nov  1 19:43 pid
     drwx------  2 postfix root     4096 Nov  1 19:43 private
     drwx--x---  2 postfix postdrop 4096 Nov  1 19:43 public
     drwx------  2 postfix root     4096 Nov  1 19:43 saved
     drwx------  2 postfix root     4096 Nov  1 19:43 trace

2.3 Create Second Start-up Script

The following is the /etc/init.d/postfix2 start-up script for the second instance. If you're using Red Hat or Fedora, you can configure this to start automatically with the following, executed as root.

     $ wget http://ftp1.sourceforge.net/souptonuts/postfix2.txt -O /etc/init.d/postfix2 
     $ chmod 2744 /etc/init.d/postfix2
     $ chkconfig --add postfix2

The first step above saves the file as postfix2. The next step makes the file executable. The third step configures the file to startup when your system boots. To check that the following steps, execute the following:

     $ chkconfig --list postfix2
     postfix2        0:off   1:off   2:on    3:on    4:on    5:on    6:off

As you can see above, postfix2 will run on levels 2,3,4 and 5. This is fine, but you only need levels 3 and 5. It's easy enough to make the change.

     $ chkconfig --level 01246 postfix2 off

Take a look at postfix2 at the line "chkconfig: 2345 80 30", since the change could have been made here as well to "chkconfig: 35 80 30". The 80 and 30 refer to the start priority and stop priority respectively.


Sender-Based Routing: Account Specific Controls in Second Instance

Further modifications are needed in main.cf so that the routing path will be determined by the sender, hence the name sender-based routing. For example, the Linux account zchirico, the sender, should connect and authenticate as zoe.chirico@gmail.com with password zP3ssw04d.

3.1 /etc/postfix2/main.cf

Configure the second instances to support sender-based routing.

    # Changes in /etc/postfix2/main.cf
     sender_based_routing = yes
3.2 /etc/postfix2/master.cf

If you copied the /etc/postfix/master.cf from the previous article, you should remove the "-o smtp_generic_maps=" switch in the second instance. Below is the correct output of "/etc/postfix2/master.cf" for 4 accounts. Please view the complete /etc/postfix2/master.cf.

      relay     unix  -       -       n       -       -       smtp
          -o fallback_relay=
      smtp_act1      unix  -       -       n       -       -       smtp
          -o smtp_sasl_password_maps=hash:/etc/postfix2/sasl_passwd_act1
      smtp_act2      unix  -       -       n       -       -       smtp
          -o smtp_sasl_password_maps=hash:/etc/postfix2/sasl_passwd_act2
      smtp_act3      unix  -       -       n       -       -       smtp
          -o smtp_sasl_password_maps=hash:/etc/postfix2/sasl_passwd_act3
      smtp_act4      unix  -       -       n       -       -       smtp
          -o smtp_sasl_password_maps=hash:/etc/postfix2/sasl_passwd_act4

There will be 4 accounts setup as follows:

 smtp_sasl_password_mapsLinux NameEmail NamePassword
 sasl_passwd_act1zchiricozoe.chirico@gmail.comZp3ssw04
 sasl_passwd_act2achiricoabby.chirico@gmail.comAp3ssw04
 sasl_passwd_act3lchiricoleah.chirico@gmail.comLp3ssw04
 sasl_passwd_act4mchiricomchirico@comcast.netMp3ssw04

Note that the first 3 accounts map to Gmail and the forth account is a Comcast account. The account information will be put into the respective sasl_passwd_act(N) files. See below.

3.3 sasl_passwd

     #/etc/postfix2/sasl_passwd_act1
     [smtp.gmail.com]      zoe.chirico@gmail.com:Zp3ssw04

As you will see with each file, you need to run postmap and change the permissions on these files.

     $ cd /etc/postfix2
     $ postmap sasl_passwd_act1
     $ chown root.postfix sasl_passwd*
     $ chmod 0640 sasl_passwd*
     #/etc/postfix2/sasl_passwd_act2
     [smtp.gmail.com]      abby.chirico@gmail.com:Ap3ssw04
     $ cd /etc/postfix2
     $ postmap sasl_passwd_act2
     $ chown root.postfix sasl_passwd*
     $ chmod 0640 sasl_passwd*

     #/etc/postfix2/sasl_passwd_act3
     [smtp.gmail.com]      leah.chirico@gmail.com:Lp3ssw04

     $ cd /etc/postfix2
     $ postmap sasl_passwd_act3
     $ chown root.postfix sasl_passwd*
     $ chmod 0640 sasl_passwd*

     #/etc/postfix2/sasl_passwd_act4
     [smtp.comcast.net]      mchirico@comcast.net:Lp3ssw04

     $ cd /etc/postfix2
     $ postmap sasl_passwd_act4
     $ chown root.postfix sasl_passwd4*
     $ chmod 0640 sasl_passwd4*

3.4 /etc/postfix2/transport

The transport map in the second postfix instance will need to be modified.

     #/etc/postfix2/transport
     zoe.chirico@gmail.com        smtp_act1:[smtp.gmail.com]
     abby.chirico@gmail.com       smtp_act2:[smtp.gmail.com]
     leah.chirico@gmail.com       smtp_act3:[smtp.gmail.com]
     mchirico@comcast.net           smtp_act4:[smtp.comcast.net]

Make sure to run postmap on this file.

     $ cd /etc/postfix2
     $ postmap transport


Modify First Instance /etc/postfix

The first instance of Postfix needs to be modified.

4.1 /etc/postfix/main.cf Modifications

The first instance of Postfix relays email to the second instance, with the command below.

   #/etc/postfix/main.cf
   relayhost = [squeezel2.squeezel.com]
   inet_interfaces = squeezel.squeezel.com
   myhostname = squeezel.squeezel.com
   alternative_config_directories = /etc/postfix2

4.2 /etc/postfix/generic

The generic file in the first Postfix instance will be used to rewrite the addresses.

     # /etc/postfix/generic
     zchirico@squeezel.squeezel.com    zoe.chirico@gmail.com
     achirico@squeezel.squeezel.com    abby.chirico@gmail.com
     lchirico@squeezel.squeezel.com    leah.chirico@gmail.com
     mchirico@squeezel.squeezel.com    mchirico@comcast.net

Run postmap on this file.

     $ cd /etc/postfix
     $ postmap generic

4.3 /etc/postfix/transport

Take out specific reference to Comcast or Gmail in the first Postfix transport map.


Restart postfix2 and postfix

At this stage postfix and postfix2 should be restarted.

   $ /etc/init.d/postfix2
   $ /etc/init.d/postfix


Fetchmail

Below is the example .fetchmailrc file for zchirico to access the zoe.chirico@gmail.com account. Note that the smtphost setting (smtphost squeezel.squeezel.com) references the first Postfix instance.

#
#
# Sample .fetchmailrc file for Gmail
#
# Check mail every 90 seconds
set daemon 90
set syslog
set postmaster zchirico
poll pop.gmail.com with proto POP3
 user 'zoe.chirico@gmail.com' \
        with pass "Zp3ssw04"  is 'zchirico' here \
        options ssl sslcertck  sslcertpath '/home/zchirico/certs/.certs'
# Note smtphost is First Postfix instance
  smtphost squeezel.squeezel.com

You will need to download Goole's certificates. Reference section 5 in the tutorial Gmail on Home Linux Box using Postfix and Fetchmail


Trouble Shooting

Review the logs, and check the configuration of each instance using the "-c" option with the postconf command as follows:

     $ postconf -c /etc/postfix2

The above command will give a listing of all options.

Deferring Mail

It's possible to defer email only on the second instance as follows:

   $ postconf -c /etc/postfix2 -e "defer_transports=smtp"
   $ postfix -c /etc/postfix2 reload

Now, send an email and the message will be defered. You'll see it in the logs.

    $ tail /var/log/maillog
 Nov  6 20:14:34 laptop postfix2/qmgr[30596]: 26F43AB038F: from=<mike.chirico@comcast.net>, size=620, nrcpt=1 (queue active)
 Nov  6 20:14:34 laptop postfix2/qmgr[30596]: 26F43AB038F: to=<mchirico@gmail.com>, relay=none, delay=0, status=deferred (delivery temporarily suspended: deferred transport)

You can see the message in the queue with the following command.

    $ find /var/spool/postfix2/deferred/ -iname '*' -type f
    /var/spool/postfix2/deferred/2/26F43AB038F

It's also possible to see the contents of that email too with the postcat command.

   $ postcat /var/spool/postfix2/deferred/2/26F43AB038F
# postcat /var/spool/postfix2/deferred/2/26F43AB038F
*** ENVELOPE RECORDS /var/spool/postfix2/deferred/2/26F43AB038F ***
message_size:             620             333               1               0
message_arrival_time: Sun Nov  6 20:14:34 2005
named_attribute: rewrite_context=remote
sender: mike.chirico@comcast.net
named_attribute: client_name=squeezel.squeezel.com
named_attribute: client_address=192.168.1.81
named_attribute: message_origin=squeezel.squeezel.com[192.168.1.81]
named_attribute: helo_name=squeezel.squeezel.com
named_attribute: protocol_name=ESMTP
original_recipient: mchirico@gmail.com
recipient: mchirico@gmail.com
*** MESSAGE CONTENTS /var/spool/postfix2/deferred/2/26F43AB038F ***
Received: from squeezel.squeezel.com (squeezel.squeezel.com [192.168.1.81])
        (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
        (No client certificate requested)
        by squeezel2.squeezel.com (Postfix) with ESMTP id 26F43AB038F
        for <mchirico@gmail.com>; Sun,  6 Nov 2005 20:14:34 -0500 (EST)
Received: by squeezel.squeezel.com (Postfix, from userid 504)
        id B1D24BB868C; Sun,  6 Nov 2005 20:14:33 -0500 (EST)
To: mchirico@gmail.com
Subject: test more
Message-Id: <20051107011433.B1D24BB868C@squeezel.squeezel.com>
Date: Sun,  6 Nov 2005 20:14:33 -0500 (EST)
From: mike.chirico@comcast.net

this is a message
*** HEADER EXTRACTED /var/spool/postfix2/deferred/2/26F43AB038F ***
*** MESSAGE FILE END /var/spool/postfix2/deferred/2/26F43AB038F ***

To instruct Postfix to deliver that message, execute the following commands.

   $ postconf -c /etc/postfix2 -e "defer_transports ="
   $ postfix -c /etc/postfix2 reload
   $ postfix -c /etc/postfix2 flush

Other Tutorials

Linux System Admin Tips: There are over 200 Linux tips and tricks in this article. That is over 150 pages covering topics from setting and keeping the correct time on your computer, permanently deleting documents with shred, making files "immutable" so that root cannot change or delete, setting up more than one IP address on a single NIC, monitoring users and processes, setting log rotate to monthly with 12 months of backups in compressed format, creating passwords for Apache using the htpasswd command, common Perl commands, using cfengine, adding users to groups, finding out which commands are aliased, query program text segment size and data segment size, trusted X11 forwarding, getting information on the hard drive including the current temperature, using Gnuplot, POVRAY and making animated GIFs, monitoring selective traffic with tcpdump and netstat, multiple examples using the find command, getting the most from Bash, plus a lot more. You can also down this article as a text document here for easy grepping.

Linux Quota Tutorial: This tutorial walks you through implementing disk quotas for both users and groups on Linux, using a virtual filesystem, which is a filesystem created from a disk file. Since quotas work on a per-filesystem basis, this is a way to implement quotas on a sub-section, or even multiple subsections of your drive, without reformatting. This tutorial also covers quotactl, or quota's C interface, by way of an example program that can store disk usage in a SQLite database for monitoring data usage over time.

Breaking Firewalls with OpenSSH and PuTTY: If the system administrator deliberately filters out all traffic except port 22 (ssh), to a single server, it is very likely that you can still gain access other computers behind the firewall. This article shows how remote Linux and Windows users can gain access to fire walled samba, mail, and http servers. In essence, it shows how openSSH and Putty can be used as a VPN solution for your home or workplace.

Create a Live Linux CD - BusyBox and OpenSSH Included : These steps will show you how to create a functioning Linux system, with the latest 2.6 kernel compiled from source, and how to integrate the BusyBox utilities including the installation of DHCP. Plus, how to compile in the OpenSSH package on this CD based system. On system boot-up a filesystem will be created and the contents from the CD will be uncompressed and completely loaded into RAM -- the CD could be removed at this point for boot-up on a second computer. The remaining functioning system will have full ssh capabilities. You can take over any PC assuming, of course, you have configured the kernel with the appropriate drivers and the PC can boot from a CD. This tutorial steps you through the whole processes.

SQLite Tutorial : This article explores the power and simplicity of sqlite3, first by starting with common commands and triggers, then the attach statement with the union operation is introduced in a way that allows multiple tables, in separate databases, to be combined as one virtual table, without the overhead of copying or moving data. Next, the simple sign function and the amazingly powerful trick of using this function in SQL select statements to solve complex queries with a single pass through the data is demonstrated, after making a brief mathematical case for how the sign function defines the absolute value and IF conditions.

The Lemon Parser Tutorial: This article explains how to build grammars and programs using the lemon parser, which is faster than yacc. And, unlike yacc, it is thread safe.

How to Compile the 2.6 kernel for Red Hat 9 and 8.0 and get Fedora Updates: This is a step by step tutorial on how to compile the 2.6 kernel from source.

Virtual Filesystem: Building A Linux Filesystem From An Ordinary File. You can take a disk file, format it as ext2, ext3, or reiser filesystem and then mount it, just like a physical drive. Yes, it then possible to read and write files to this newly mounted device. You can also copy the complete filesystem, sinc\ e it is just a file, to another computer. If security is an issue, read on. This article will show you how to encrypt the filesystem, and mount it with ACL (Access Control Lists), which give you rights beyond the traditional read (r) write (w) and execute (x) for the 3 user groups file, owner and other.

Working With Time: What? There are 61 seconds in a minute? We can go back in time? We still tell time by the sun?


Errata



Next Article: Spam filtering, IMAP and SquirrelMail

The next article will be a how-to on Spam filtering, IMAP and SquirrelMail. If you would like to receive a single email when this article is finished, then, click on this link .


Chirico img Mike Chirico, a father of triplets (all girls) lives outside of Philadelphia, PA, USA. He has worked with Linux since 1996, has a Masters in Computer Science and Mathematics from Villanova University, and has worked in computer-related jobs from Wall Street to the University of Pennsylvania. His hero is Paul Erdos, a brilliant number theorist who was known for his open collaboration with others.


Mike's notes page is souptonuts. For open source consulting needs, please send an email to mchirico@comcast.net. All consulting work must include a donation to SourceForge.net.

SourceForge.net Logo


SourceForge.net Logo