Get cron/alert mails to external address using Postfix+Gmail

Share your own howto's etc. Not for support questions!

Get cron/alert mails to external address using Postfix+Gmail

Postby kyl » 2013-09-26 17:02

Use the Postfix MTA to re-route all local mail to an external address using GMail or Google Apps for Domains

Goal, disclaimer and credits

The high level goal of this howto

Be able to read mail from cron-jobs and other system services with your normal e-mail account.

The detailed goals of this howto

  1. To be a better alternative then ssmtp, nullmailer and similar MTA:s. In my experience all of them have problems which does not exist in this set up.
  2. Set up the Mail Transfer Agent (MTA) Postfix to re-route all local mail to a single external address. The local user who generally recieves the most mail is root. After following this howto the local users will not recieve a single mail, they will all be re-routed to the external address of your choice.
  3. Remove the default MTA Exim and all its configuration files. However, if you skip the purge command lines your configuration will not be removed.
  4. Go against the Debian way and use Postfix as your MTA instead of Exim. The only reason Postfix is used is that I found it a bit easier when researching MTA:s. If you have one MTA working already I would suggest that you stick with it. This howto is primarely aimed at those who have not touched their MTA since installing Debian and who have never read any local mail.
  5. Use a single Google account to send mail using Google's SMTP servers. You can use your regular account or create a dedicated one.
  6. All local addresses will be valid, not only those of existing accounts in /etc/passwd or aliases in /etc/aliases. The advantage to this is that all mail will always reach you as if their senders were configured correctly. The downside to this is if you stop using this MTA solution all misconfigured senders will have their mails bounced. However in that scenario postmaster (which you should check, or as by default forward to root which in turn is forwarded to you local account) will be informed so you will be able to correct them. In practise I think the downside is neglectable for 99% of the users.
  7. This set up will be able to send mail to arbitrary external addresses, but as it sends through GMail and does not concern itself with responses we will not know if the mail arrived or not. It makes the set up unsuitable for forums and other systems where arbitrary external addresses are sent mail and it's necessary to check if the sent mail arrived or not. However, it works well for recieving cron mails and other system mails at an external address which you actually check
Disclaimer
  • I take no responsiblity for the correctness of this howto or any damages to your system or family it might cause. I have done what I can to see that it works and that it is secure. I am using this set up myself.
  • Give me any feedback you have and I will try to correct any errors in this post or make other improvements.
This howto wouldn't be possible without these resources
  1. I found out about virtual_maps through an answer on askubuntu.com.
  2. A blog post on rtcamp.com thought me how to send mail through GMail.
  3. The Postfix documentation in general and especially the postconf part as it thought me how to configure /etc/postfix/main.cf.

Installation and configuration
Perform all commands below as root unless otherwise is specified. If you use sudo issue sudo -i to become root and on other systems you simply issue su:
  1. Install Postfix by issuing apt-get install postfix, this will also uninstall Exim but keep its configuration files, in case you change your mind. You will be presented with some package configuration dialogs for Postfix:
    1. General type of mail configuration: Internet Site
    2. System mail name: Just press Ok and accept the default
  2. Stop Postfix (which has automatically been started) using service postfix stop as it's not ready yet
  3. Remove the Exim configuration files using apt-get purge exim4 exim4-base exim4-config exim4-daemon-light if you had never touched them since installing Debian and want to clean up a bit. If you are the least bit unsure, skip this step!
  4. Since you won't be fetching mail using procmail any more it's safe to remove it apt-get remove procmail. By default it doesn't have any configuration, which is why remove is used instead of purge. (If it turns out that you are using it without knowing it, simply re-install it using apt-get install procmail. But you are most likely not using it.)
  5. Replace the contents of /etc/postfix/main.cf by first clearing it using cat /dev/null >/etc/postfix/main.cf and then filling it with the following contents using nano by issuing nano /etc/postfix/main.cf
    Code: Select all
    ##
    ## Only listen for mail from the local machine and only trust the local
    ## machine as an SMTP client
    ##

    inet_interfaces = loopback-only
    mynetworks = loopback-only

    ##
    ## Redirect local mail according to /etc/aliases (ie. postmaster => root)
    ##

    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases

    ##
    ## Redirect all local mail to
    ##

    virtual_maps = regexp:/etc/postfix/virtual-regexp

    ##
    ## Send through GMail
    ##

    relayhost = [smtp.gmail.com]:587

    ##
    ## SMTP client authenticates using SASL using a user:password pair
    ## stored in a separate file. Do not allow anonymous authentication
    ## and use TLS if it is available
    ##
    smtp_sasl_auth_enable = yes
    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
    smtp_sasl_security_options = noanonymous
    smtp_tls_CAfile = /etc/postfix/cacert.pem
    smtp_use_tls = yes
  6. Create a SASL password mapping file which only root can access using (umask 166 && nano /etc/postfix/sasl_passwd) (the paranthesis are important) and fill it with a single line
    Code: Select all
    [smtp.gmail.com]:587    sendingusername@gmail.com:thepassword
    where you replace sendingusername and thepassword accordingly. If you use Google Apps for Domains you simply replace gmail.com with your domain.
  7. Create /etc/postfix/virtual-regexp by issuing nano /etc/postfix/virtual-regexp and fill it with a single line
    Code: Select all
    /.+@.+\.localdomain/ alllocalmailgoeshere@anydomain.com
    where you replace alllocalmailgoeshere@anydomain.com with the mail address where you want to recieve all local mail.
  8. Create the Postfix lookup tables (the files which Postfix actually reads) for the above two files by issuing postmap /etc/postfix/virtual-regexp and postmap /etc/postfix/sasl_passwd.
  9. Copy the certificate used for authenticating with GMail's SMTP servers into the Postfix directory using cp -v /etc/ssl/certs/Thawte_Premium_Server_CA.pem /etc/postfix/cacert.pem.

Starting Postfix and verifying the installation
First make sure that you have all the necessary files with correct permissions. Your output from ls -l /etc/postfix/ | egrep 'main|cacert|sasl|virtual' should look exactly like this (except that the text file sizes may vary 1 byte depending on if you have a trailing newline or not):
Code: Select all
-rw-r--r-- 1 root root  1155 Sep 21 03:18 cacert.pem
-rw-r--r-- 1 root root   829 Sep 21 02:55 main.cf
drwxr-xr-x 2 root root  4096 Mar  6  2013 sasl
-rw------- 1 root root    51 Sep 21 03:07 sasl_passwd
-rw------- 1 root root 12288 Sep 21 03:25 sasl_passwd.db
-rw-r--r-- 1 root root    44 Sep 21 04:10 virtual-regexp
-rw-r--r-- 1 root root 12288 Sep 21 04:10 virtual-regexp.db

Start Postfix by issuing service postfix start, it should say that the start up went OK. Make sure that there are no error messages in /var/log/mail.err using cat /var/log/mail.err.

Create a test function called testsend which we will use to send a few mails by copy pasting this into your command line
Code: Select all
function testsend { u=$1;echo -e "Hello $u\n\nLucky nr: $RANDOM" | mail -s "Postfix test message to $u at $(date)" $u; }

We will now test the different behaviors using the testsend function we just created.
Test sending mail to a local user
  1. Send a test mail to root using testsend root
  2. Check for errors in /var/log/mail.err
  3. Check for warnings in /var/log/mail.warn
  4. Check that you actually recieved the mail at the mail account you want all local mails sent to
  5. Look in /var/log/mail.info and see how it was routed

Test sending mail to a non existing local user
  1. Send a test mail to nonexistinguser using testsend nonexistinguser
  2. Check for errors in /var/log/mail.err
  3. Check for warnings in /var/log/mail.warn
  4. Check that you actually recieved the mail at the mail account you want all local mails sent to
  5. Look in /var/log/mail.info and see how it was routed

Test sending mail to an external mail account
  1. Send a test mail to an external mail address you can check which is not the normal address for local mail, using testsend someone@somewhere.com where you replace someone@somewhere.com accordingly
  2. Check for errors in /var/log/mail.err
  3. Check for warnings in /var/log/mail.warn
  4. Check that you actually recieved the mail at that mail account
  5. Look in /var/log/mail.info and see how it was routed

Check how sending mail to an external mail account which does not exist works
  1. Send a test mail to a non existing mail account using testsend idontexist@example.com
  2. Google will say that sending went OK and there will be no error in /var/log/mail.err
  3. Nor any warnings in /var/log/mail.warn
  4. Look in /var/log/mail.info and see that it was routed as the other external address
  5. But a reply will be sent from mailer-daemon@googlemail.com to the account you are using to send mail when Google realizes that this recipient does not exist.

The last case works as it does as it's impossible to know if a recipient exists or not straight away for certain addresses. Google will try to deliver the mail several times over a time period of a day or two to make sure that the delivery is a permanent failure. That behavior makes this MTA set up unsuitable for sending mail from a forum and other instances when we need to know if the mail arrived or not and the mail address is dynamic.

It took me quite a while to reach this set up, mostly due to my inexperience with MTA:s. Enjoy! :D Feel free to ask questions!
kyl
 
Posts: 13
Joined: 2013-09-11 13:47

Re: Get cron/alert mails to external address using Postfix+G

Postby daubneyi » 2014-03-01 10:21

So useful thank you, and I learned stax along the way. :D
daubneyi
 
Posts: 2
Joined: 2013-04-19 02:08


Return to Docs, Howtos, Tips & Tricks

Who is online

Users browsing this forum: No registered users and 5 guests

fashionable