Use Postfix to send email through Microsoft Exchange server

December 25, 2010

Last week, we installed the excellent Request Tracker (RT) 3.8.8 software on a Debian 5 Linux system for evaluation. RT is a powerful open source issue tracking system.

When tickets are updated, RT must send email messages to the relevant people. Since our organization’s email is handled by a hosted Microsoft Exchange server, we needed our Linux machine to automatically log in and send outgoing emails through our MS Exchange server.

There are many applications for this technique. For example, a system administrator might use maintenance scripts to send logs to interested parties.

The procedure below is a “cheat sheet” for this configuration. It is meant to show the steps as briefly as possible, with a minimal but complete explanation. It also notes any troubleshooting steps we followed.

Throughout this tutorial, personal information is obfuscated using xX and yY. Output is in bold text.

Install Postfix

The first step toward handling email on a Linux machine is to select a Mail Transfer Agent (MTA) or “mailer”. We use Postfix for our implementation.

First, install Postfix, which automatically removes Debian’s default MTA, exim4. Also install the modules necessary for SASL authentication:

debian:~# apt-get install postfix libsasl2-modules

After installation is complete, Postfix will prompt for some information.

General type of mail configuration: Internet site
System mail name: mydomain.com

System mail name is the default domain name from which email will originate (the “from” address, without a user prefix).

Optional: Send email manually via SMTP/telnet to make sure this works

Now that Postfix is installed, make sure we can use our Exchange server. Manually test ESMTP on our server over telnet. ESMTP is the protocol used by our Exchange server.

debian:~# telnet mail.mydomain.com 25

where mail.mydomain.com is the Exchange server’s fully qualified domain name or IP address, followed by its SMTP port.

Trying xXx.xXx.xXx.xx...
Connected to mail.mydomain.com.
Escape character is '^]'.
220 incoming-imf1.mydomain.com Microsoft ESMTP MAIL Service, Version: 6.0.3790.3959 ready at Thu, 23 Dec 2010 18:08:28 -0500

Say ehllo to the Exchange server from our email domain:

EHLO mydomain.com
250-incoming-imf1.mydomain.com Hello [xX.xXx.xX.xX]
250-TURN
250-SIZE 104857600
250-ETRN
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-8bitmime
250-BINARYMIME
250-CHUNKING
250-VRFY
250-X-EXPS GSSAPI NTLM LOGIN
250-X-EXPS=LOGIN
250-AUTH GSSAPI NTLM LOGIN
250-AUTH=LOGIN
250-X-LINK2STATE
250-XEXCH50
250 OK

Our Postfix configuration will use the AUTH LOGIN mechanism, so send that command here:

AUTH LOGIN

The following Base64 output decodes to “Username:”. Enter our username encoded in Base64 (do that here):

334 VXNlcm5hbWU6
xXxXxXxXxX

The server returns “Password:”. Enter our Base64-encoded password:

334 UGFzc3dvcmQ6
yYyYyYyYyY
235 2.7.0 Authentication successful.

We see this message and don’t hear any dolphins crying, so we’re clear to proceed as planned. Use MAIL FROM and RCPT TO commands to specify the “from” and “to” email addresses, respectively:

MAIL FROM:fritz@mydomain.com
250 2.1.0 fritz@mydomain.com....Sender OK
RCPT TO:fmahnke@yYyY.com
250 2.1.5 fmahnke@yYyY.com

Notice the “to” email address for the test is on a different domain. This is important, since mail servers may have different authentication requirements for same-domain and cross-domain email. Carefully compose a test message:

DATA
354 Start mail input; end with <CRLF>.<CRLF>
It was quite the dark and stormy afternoon.
omgwtfbbq
.

250 2.6.0 Queued mail for delivery
.
QUIT
221 2.0.0 incoming-imf1.mydomain.com Service closing transmission channel
Connection closed by foreign host.

By all accounts, this was successful, so open a beer and check the fmahnke@yYyY.com email account for a new message. If it’s there, we know we can control our mail server from this machine.

Postfix configuration

Postfix needs credentials to login to the server and send email. Add the mail server domain name and username:password (NOT encoded in Base64) of our user to /etc/postfix/sasl_passwd:

mail.mydomain.com fritz@mydomain.com:secretpassword

Secure the password file from the peons:

debian:~# chown root:root /etc/postfix/sasl_passwd
debian:~# chmod 600 /etc/postfix/sasl_passwd

Postfix does not work with plain text files. Update the password database (must be done whenever /etc/postfix/sasl_passwd is modified):

debian:~# postmap hash:/etc/postfix/sasl_passwd

Under no circumstances should root@mydomain.com be the reply to address for an email originating from our machine (this account does not exist on our hosted Exchange server), so we map (masquerade) it to an interested party. Add this and any other desired mappings to /etc/postfix/generic:

root@mydomain.com fritz@mydomain.com

Update the address maps database (must be done whenever /etc/postfix/generic is modified):

debian:~# postmap /etc/postfix/generic

Modify the main Postfix configuration file, aptly named /etc/postfix/main.cf:

# enable SASL for authentication
smtp_sasl_auth_enable = yes
# force AUTH LOGIN mechanism. Else Postfix might try something else
smtp_sasl_mechanism_filter = login
# Override Postfix default disallowing of plaintext AUTH LOGIN
smtp_sasl_security_options =
# use our password database for authentication
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
# map machine email addresses to internet addresses
smtp_generic_maps = hash:/etc/postfix/generic
# send mail through our Exchange ESMTP server
relayhost = mail.mydomain.com

We must restart Postfix when we make changes.

debian:~# postfix reload

It should now work perfectly. Let’s test.

debian:~# sendmail fmahnke@yYyY.com
Employees must wash hands before returning to work.
.

Postfix writes its output to syslog. Check the status of our message:

debian:~# tail /var/log/syslog

Dec 24 05:21:37 debian postfix/qmgr[4748]: EBE246625F: from=, size=307, nrcpt=1 (queue active)
Dec 24 05:21:38 debian postfix/smtp[4816]: EBE246625F: to=, relay=mail.mydomain.com[144.202.247.20]:25, delay=3.9, delays=2.1/0.03/1.2/0.55, dsn=2.6.0, status=sent (250 2.6.0 <20101224112136.EBE246625F@debian.localdomain> Queued mail for delivery)

Check fmahnke@yYyY.com for the new message. Is it there? Sweet. Postfix is configured successfully.

Further reading:

XFOR: Telnet to Port 25 to Test SMTP Communication
Troubleshooting SMTP Authentication using Telnet
Introduction to Microsoft Exchange Server 2003 – SMTP Auth Login

DiggDeliciousFacebookTwitterStumbleUponGoogle ReaderShare

7 Responses to “Use Postfix to send email through Microsoft Exchange server”

  1. Thanks a lot for this guide, it was exactly what I needed!

    Cheers, Mirko

  2. This is absolutely what I was looking for. It worked for me except it was giving me a warning

    warning: smtp_sasl_auth_enable is true, but SASL support is not compiled in.

    I just set the following parameter to no
    smtp_sasl_auth_enable = no

    & it started working. Thank you so much

  3. Hey, thanks for your feedback. Glad it worked for you.

    I found this surprisingly tricky to configure correctly. I did this how to so I would be able to get it right the next time I needed it. Glad to know others are finding it useful.

  4. This worked perfectly for me as well on Red Hat 6, thank you very much!

  5. Thank you very much. The only difference in my case is the type of authorization: 250-AUTH NTLM

    Also the guys in charge of Exchange Server, told us, we can use anonymus connection.

    Do you have an example with this authorization?

    Thanks in advance !!

  6. [...] do not allow anonymous relay if you are receiving that error. Try looking at the settings in this http://www.fritzmahnke.com/2010/12/2…change-server/ and this [...]

  7. You are a saviour!!!! I have been fiddling with Postfix for days to get it to send through our Exchange Server with no luck but your instructions were on the mark! Perfect! Thanks!

Leave a Reply