Clayton's Tech Bits

Home

Contact

Resumé / C.V.

Links

Search this site:
Custom Search

Categories:

/ (224)
  Admin/ (86)
    Apache/ (7)
      HTTPS-SSL/ (4)
    Cherokee/ (1)
    LAN/ (4)
    LVM/ (3)
    Monitoring/ (2)
      munin/ (2)
    OpenVPN/ (1)
    SSH-Proxy/ (3)
    SSH-SSL/ (6)
    backups/ (16)
      SpiderOak/ (1)
      backuppc/ (5)
      dirvish/ (1)
      misc/ (6)
      rdiff-backup/ (1)
      rsync/ (1)
      unison/ (1)
    commandLine/ (11)
    crontab/ (1)
    databases/ (8)
      MSSQL/ (2)
      MySQL/ (5)
      PostgreSQL/ (1)
    dynamicDNS/ (2)
    email/ (9)
      Dovecot/ (1)
      deliverability/ (1)
      misc/ (1)
      postfix/ (6)
    iptables/ (2)
    virtualization/ (8)
      VMware/ (1)
      virtualBox/ (7)
  Coding/ (11)
    bash/ (1)
    gdb/ (1)
    git/ (2)
    php/ (4)
    python/ (3)
      Django/ (1)
  Education/ (1)
  Hosting/ (23)
    Amazon/ (14)
      EBS/ (3)
      EC2/ (11)
    Godaddy/ (2)
    NearlyFreeSpeech/ (3)
    Rackspace/ (1)
    vpslink/ (3)
  Linux/ (20)
    Awesome/ (3)
    CPUfreq/ (1)
    Chinese/ (1)
    Debian/ (5)
      WPA/ (1)
    audio/ (1)
    encryption/ (2)
    fonts/ (1)
    misc/ (4)
    router-bridge/ (2)
  SW/ (39)
    browser/ (2)
      Chrome/ (1)
      Firefox/ (1)
    business/ (25)
      Drupal/ (8)
      KnowledgeTree/ (6)
      Redmine/ (2)
      SugarCRM/ (6)
      WebERP/ (2)
      eGroupware/ (1)
    email/ (1)
    fileSharing/ (1)
      mldonkey/ (1)
    graphics/ (2)
    research/ (2)
    website/ (6)
      blog/ (6)
        blosxom/ (3)
        rss2email/ (1)
        webgen/ (1)
  Security/ (12)
    IMchat/ (1)
    circumvention/ (2)
    e-mail/ (4)
    greatFirewall/ (1)
    hacking/ (1)
    password/ (1)
    privacy/ (1)
    skype/ (1)
  Services/ (1)
    fileSharing/ (1)
  TechWriting/ (1)
  xHW/ (13)
    Lenovo/ (1)
    Motorola_A1200/ (2)
    Thinkpad_600e/ (1)
    Thinkpad_a21m/ (3)
    Thinkpad_i1300/ (1)
    Thinkpad_x24/ (1)
    USB_audio/ (1)
    scanner/ (1)
    wirelessCards/ (2)
  xLife/ (17)
    China/ (9)
      Beijing/ (5)
        OpenSource/ (3)
    Expatriation/ (1)
    Vietnam/ (7)

Archives:

  • 2012/03
  • 2012/01
  • 2011/12
  • 2011/11
  • 2011/10
  • 2011/09
  • 2011/08
  • 2011/07
  • 2011/06
  • 2011/05
  • 2011/04
  • 2011/02
  • 2010/12
  • 2010/11
  • 2010/10
  • 2010/09
  • 2010/08
  • 2010/07
  • 2010/06
  • 2010/05
  • 2010/04
  • 2010/03
  • 2010/02
  • 2010/01
  • 2009/12
  • 2009/11
  • 2009/10
  • 2009/09
  • 2009/08
  • 2009/07
  • 2009/06
  • 2009/05
  • 2009/04
  • 2009/03
  • 2009/02
  • 2009/01
  • 2008/12
  • 2008/11
  • 2008/10
  • 2008/09
  • Subscribe XML RSS Feed

    Sat, 04 Oct 2008


    /Admin/email/postfix: Relay Your E-mail Through Multiple Servers with Postfix

    Why would you want to do this? As mentioned in Simple Relay, if you have a lot of e-mail going out and you are trying to relay all of it through one poor free relay server, that relay server is probably going to reach a threshold at which it labels you a "spammer" and starts deferring or even bouncing your e-mails. So what I do is use my own server to send e-mails directly to their destination as much as possible. And for those domains that reject my direct connections (theoretically because my server is running on a dynamic ip) I relay through another server. Preferably I have several such "other" relay servers so as to spread the load around and not have to deal with bounced e-mail.

    Postfix is not really designed to do this, so what I will present here is a limited solution that will work under specific circumstances.

    Basically the problem is that any free SMTP server I have been able to find insists on authentication (logging in with a valid userid and password) and further insists that the envelope address of the e-mail you are sending must agree with the userid you are logging in with. For instance, if you have a sina.com account with userid=mysinaname and password=mysinapassword, if the envelope address is anything but mysinaname@sina.com, the sina SMTP server will reject the e-mail. Note that the "envelope address" is not necessarily the same as the "From:" address in the e-mail's header, although they are usually the same.

    If you are sending e-mail with an e-mail client, the client will of course take care of all of this. But if you are sending e-mail through your own local e-mail server, and then onwards to its destination (optionally through another relay server) things get a little more complicated as there may be e-mails being queued to the server from multiple sources, and Postfix appears to have no way of associating a given envelope address with a given destination address/domain.

    Postfix is capable of routing e-mails to different relay servers based upon their destination address. But it is left up to any software queuing e-mail to Postfix for external delivery to take care of making sure that the envelope address is correct for the relay server that Postfix will later relay to. That is what makes this a limited solution.

    Set Up Postfix

    The solution lies in /etc/postfix/transport. Here is mine:

        langex.net               local
    
        gmail.com               smtp:smtp.sohu.com
        hotmail.com             smtp:smtp.sohu.com
    
        sina.com                smtp:smtp.sina.com
        boltblue.com            smtp:smtp.sina.com
        msn.com                 smtp:smtp.sina.com
        onlineworkshop.net      smtp:smtp.sina.com
    
        *                       smtp
    

    Mail destined for langex.net never leaves my server and is delivered locally. gmail.com and hotmail.com are both relayed via SMTP through smtp.sohu.com. sina.com, msn.com, etc. are relayed via SMTP through smtp.sina.com. Everything else ("*") goes out via SMTP directly to the destination domain (no relay).

    Ensure that /etc/postfix/sasl_passwd contains userid:password for both smtp.sohu.com and smtp.sina.com, then run the following commands:

        postmap /etc/postfix/sasl_passwd
        postmap /etc/postfix/transport
        /etc/init.d/postfix restart
    

    Set Up PHP

    My main source of e-mail on this server is a PHP-driven website. In this website I have the following function:

            function emailWrap($thisEmailAddress, $thisSubject, $thisMessage, $thisReplyTo)
            {
    
              $toDomain = stristr( $thisEmailAddress, "@" ); // extract domain from e-mail address
              $toDomain = strtolower ( $toDomain ); // make all alphabetic characters lower case
    
              switch($toDomain)
              {
                default:
                  $headMe = 'webmaster@langex.net';
                break;
    
                case "@gmail.com":
                  $headMe = 'bjlangex@sohu.com';
                break;
    
                case "@hotmail.com":
                  $headMe = 'bjlangex@sohu.com';
                break;
    
                case "@sina.com":
                  $headMe = 'langexnet@sina.com';
                break;
    
                case "@boltblue.com":
                  $headMe = 'langexnet@sina.com';
                break;
    
                case "@msn.com":
                  $headMe = 'langexnet@sina.com';
                break;
    
                case "@onlineworkshop.net":
                  $headMe = 'langexnet@sina.com';
                break;
              }
    
              $headFrom = "From: Language Exchange Webmaster <" . $headMe . ">";
              $headReplyTo = "Reply-To: " . $thisReplyTo;
              $headContent = "Content-Type: text/plain; charset=GB2312";
              $addheader = $headFrom . "\n" . $headReplyTo . "\n" . $headContent;
    
              $addParam = "-f " . $headMe; // the PHP magic for setting the envelope address
              mail($thisEmailAddress, $thisSubject, $thisMessage, $addheader, $addParam);
            }
    

    There are two main things to take note of in this function:

    1. The contents of the switch must be kept in alignment with /etc/postfix/transport
    2. $addParam = "-f " . $headMe; is the statement that specifies/sets the envelope address within PHP.

    Re. item 2, I chased my tail for a long time before figuring out that the "additional parameter" to the PHP mail()[1] function was the Linux server way to do this. There is one particularly misleading PHP function called ini_set()[2] which DOES NOT WORK on Linux, and is apparently meant for Windows servers. In Summary

    For those e-mail destination domains (hopefully the vast majority) that do not give your server any grief, everything works just like a default Postfix server, ie. Postfix connects directly to the destination SMTP server and delivers the e-mail.

    For those domains that regularly give you delivery problems for whatever reason, if you can find a relay server that it will accept mail from, then use that relay server.

    But remember: any application on your server that queues an e-mail to Postfix for one of these problem destination domains, where you have not correctly configured the application to set the envelope address to correspond to the relay server, will result in bounced e-mail. This is a seriously non-trivial problem if you have other people using the server and/or e-mail being sent from multiple different sources. If you can limit the number of applications sending external e-mail to one, this method works really quite well.

    [1] http://www.php.net/mail
    [2] http://www.php.net/ini_set

    posted at: 03:38 | path: /Admin/email/postfix | permanent link to this entry