Setup Postfix with a remote SMTP relay host
Platforms:
any Linux distro
any Linux distro
Sending outgoing email thru a 3rd party SMTP relay service is a quick and easy alternative to setting up a full fledged local email server. Google Apps/Gmail, Yahoo, and many ISPs provide SMTP relaying for free. This guide will cover configuring Postfix on a CentOS server to relay outgoing email to a 3rd party.
Most Linux distros come with Sendmail already installed, and is usually the default mail client used by the running services. However, Postfix beats the crap out of Sendmail and is a complete, seamless replacement. Here's how I got it going on my CentOS box.
Install
Install Postfix and cyrus-sasl with your application manager of choice. If you're compiling from source, be sure to make Postfix with the -DUSE_SASL_AUTH flag for SASL support and -DUSE_TLS for TLS support.
Note: CentOS 6+ now packages cyrus-sasl-plain separately, so if it's not specifically installed, you'll get a "Authentication failed: cannot SASL authenticate to server ...: no mechanism available" error.
$ yum install postfix cyrus-sasl cyrus-sasl-plain |
Stop the sendmail service
$ /etc/init.d/sendmail stop |
Remove sendmail from the startup runlevels
$ chkconfig --del sendmail |
Typical Setup
Edit /etc/postfix/main.cf
# Set this to your server's fully qualified domain name. # If you don't have a internet domain name, # use the default or your email addy's domain - it'll keep # postfix from generating warnings all the time in the logs mydomain = local.domain myhostname = host.local.domain # Set this to your email provider's smtp server. # A lot of ISP's (ie. Cox) block the default port 25 # for home users to prevent spamming. So we'll use port 80 relayhost = yourisp.smtp.servername:80 smtpd_sasl_auth_enable = yes smtpd_sasl_path = smtpd smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_type = cyrus smtp_sasl_auth_enable = yes # optional: necessary if email provider uses load balancing and # forwards emails to another smtp server # for delivery (ie: smtp.yahoo.com --> smtp.phx.1.yahoo.com) smtp_cname_overrides_servername = no # optional: necessary if email provider # requires passwords sent in clear text smtp_sasl_security_options = noanonymous |
There's roughly a 99.9% chance that your email provider's SMTP server requires authentication. We need to set that up with the username and password given by your email provider.
Add the following line to /etc/postfix/sasl_passwd
yourisp.smtp.servername:80 username:password |
The above server hostname and port must exactly match the value for "relayhost" in /etc/postfix/main.cf.
Generate a postfix lookup table from the previous file
$ postmap hash:/etc/postfix/sasl_passwd |
Test the lookup table, if all is good then the following will return the specified username:password
$ postmap -q yourisp.smtp.servername:80 /etc/postfix/sasl_passwd |
Make sure the sasl_passwd and sasl_passwd.db files are readable/writable only by root
$ chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db |
Add postfix to be started at boot
$ chkconfig --add postfix |
Fire up Postfix
$ /etc/init.d/postfix start |
Test it out using sendmail alias from the command prompt
$ $ sendmail -t To: to.address@example.com From: from.address@example.com Subject: Test 123 Postfix is good to go. . |
Gmail Setup
If you're attempting to relay mail using Gmail, then it will be necessary to use TLS with Postfix. You'll have to point Postfix at your server's trusted CA root certificate bundle, but luckily "...client-side certificates are not required when relaying mail to GMail".
First, double-check that Postfix was configured with SSL support (ie. ldd should return at least one line starting with libssl):$ whereis -b postfix postfix: /usr/sbin/postfix /etc/postfix /usr/libexec/postfix $ ldd /usr/sbin/postfix ... libssl.so.6 => /lib/libssl.so.6 (0x00111000) ... |
$ locate ca-bundle.crt /etc/pki/tls/certs/ca-bundle.crt |
relayhost = smtp.gmail.com:587 # your FQDN, or default value below mydomain = local.domain # your local machine name, or default value below myhostname = host.local.domain myorigin = $myhostname # SASL smtpd_sasl_path = smtpd smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_type = cyrus smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous # TLS smtp_use_tls = yes smtp_tls_CAfile = /path/to/your/ca-bundle.crt smtp_sasl_tls_security_options = noanonymous |
smtp.gmail.com:587 username:password |
Generate a postfix lookup table from the previous file
$ postmap hash:/etc/postfix/sasl_passwd |
Make sure the sasl_passwd and sasl_passwd.db files are readable/writable only by root
$ chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db |
$ postfix reload $ sendmail -t To: to.address@example.com From: from.address@example.com Subject: Testing 123 Test relay thru Gmail . |
If this is a new Google email account, make sure to login to the gmail web interface with it first. You'll need to accept the Google TOS before you can send any email thru the account.
Note that Google places daily limits on the amount of emails and recipients.
Sending from multiple email accounts
Postfix 2.3+ can also be setup to authenticate, relay, and send from multiple email accounts (see Configuring Sender-Dependent SASL authentication). Postfix will lookup and relay to the appropriate host based on the sender address specified by the client. This can be configured using a per-sender relayhost file that maps each sender addresses to a relay provider. Clients must specify a sender address when composing an email so that Postfix can lookup the appropriate sender's relay host info.
Let's assume we'll be sending from two email accounts: foo@foo.com (which uses smtp.gmail.com:587) and bar@bar.com (which uses smtp.bar.com:666). We'll first add them to the /etc/postfix/sasl_passwd, along with a default relay host and user (smtp.gmail.com:587/foo@bar.com) which will be used as the sender in case a client omits the sender address or a matching sender address is not found:
foo@foo.com foo@foo.com:password bar@bar.com bar@bar.com:password smtp.gmail.com:587 foo@foo.com:password |
Generate a postfix lookup table from the previous file
$ postmap hash:/etc/postfix/sasl_passwd |
Next, add the senders and their providers to a new /etc/postfix/sender_relay file
foo@foo.com smtp.gmail.com:587 bar@bar.com smtp.bar.com:666 |
Generate a postfix lookup table from the previous file
$ postmap hash:/etc/postfix/sender_relay |
Make sure the all above files are readable/writable only by root
$ chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db /etc/postfix/sender_relay /etc/postfix/sender_relay.db Next, add the following directives to /etc/postfix/main.cf for multiple relay host support (this assumes you've already added the smtp_sasl_* directives mentioned earlier in this article) |
# multiple sender relayhost maps sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay smtp_sender_dependent_authentication = yes |
Finally, reload Postfix and send some test messages
$ /etc/init.d/postfix reload $ sendmail -tf "foo@foo.com" To: to.address@example.com From: foo@foo.com Test email should be from foo@foo.com . $ sendmail -tf "bar@bar.com" To: to.address@example.com From: bar@bar.com This test email should be from bar@bar.com . Note: the sendmail -f argument is required for Postfix to select the appropriate sender and relay host. Also, if the "From:" message header is omitted, Postfix will automatically set the NAME environment variable as the sender's display name (the correct sender relay host is still used). Use the -F argument to set a custom display name, or specify the "From:" message header (though this latter option seems to be buggy and is ignored). |
A quick note about sending email from WordPress
At the current version of 3.6.1, WordPress does not set the sender on outgoing emails. So on a server configured to relay thru multiple outgoing email accounts, all outgoing WordPress emails will be sent via the default relay host (specified in /etc/postfix/sasl_passwd).
A quick fix is to set the Sender attribute of WordPress's phpmailer object. This can be done by adding the following code to your theme's functions.php file, which will set the sender as the address specified in theWordPress admin > General Settings > Email Address.
function phpmailer_set_sender_address( $phpmailer ){ $phpmailer ->Sender = get_option( 'admin_email' ); } add_action( 'phpmailer_init' , 'phpmailer_set_sender_address' , 10, 1); |
Alternatively, the sender address could be hardcoded above instead of using the WordPress admin email.
Other notes
Anytime you change the /etc/postfix/sasl_passwd or /etc/postfix/sender_relay files, remember to rehash them and reload Postfix
$ postmap hash:/etc/postfix/sasl_passwd $ postmap hash:/etc/postfix/sender_relay $ /etc/init.d/postfix reload |
Troubleshooting
Monitor postfix mail log in a separate session with the following command
$ tail -f /var/log/maillog |
If the log is displaying the following error
(Authentication failed: cannot SASL authenticate to server ...: no mechanism available) |
then set this variable in /etc/postfix/main.cf
smtp_sasl_security_options = noanonymous |
If the log is displaying this error
553 Sorry, that domain isn't in my list of allowed rcpthosts. (in reply to RCPT TO command) |
check your username and password in /etc/postfix/sasl_passwd. Your user name is usually your full email address. If you have to fix it, don't forget to use postmap to generate a new lookup table.
No comments:
Post a Comment