The Postfix MTA makes it easy to setup SMTP Auth so that remote users can relay mail out through your server. While the official documentation on this is very good, we're going to run through a streamlined version that covers what is arguably the simplest and the most popular deployment option using Dovecot for the SASL backend. Because we don't want login details being passed across the internet unprotected, we'll also enforce the use of encryption to create a secure tunnel.
This might look a bit long-winded, but it's actually very simple to setup. There's plenty of sample configuration and examples below to refer to.
Contents
1. Setting up Postfix for SMTP Auth with the Dovecot SASL backend
1. Assumptions
2. Procedure
1. Dovecot
2. Postfix - configure SASL auth
3. Testing basic SASL
4. Postfix - Enable TLS for encryption
5. Test that TLS is working as expected
6. Enabling the submission port
3. See also:
4. References/External Links
Assumptions
1. You're familiar with the mail technologies in use
2. We're implementing SMTP Auth on a Redhat Enterprise Linux 5 system, but the steps are easily translated to other distros like Debian
* We're using the stock set of vendor package repositories
3. You have a fully-working Postfix installation that can send/receive mail to/from the internet
4. You're already using Dovecot for authenticated POP/IMAP access. While it's not necessary, this is the easiest way to be sure your authentication backend will Just Work
* By extension, we assume you've got a set of authentication credentials you can use for testing
Procedure
We'll start by enabling Dovecot's SASL service, then hook Postfix into this. Postfix will then offer SMTP Auth to remote clients, provided that they're using TLS for encryption.
Dovecot
Dovecot will create a daemon socket that will listen for SASL requests.
1.
On some distributions, the Postfix daemons run chroot'ed. For this reason, it's preferred to place the socket somewhere that's guaranteed to be accessible. Use the postconf command to find your queue directory - in most cases it'll be /var/spool/postfix
Toggle line numbers
yoshino:~# postconf queue_directory
queue_directory = /var/spool/postfix
2.
Edit /etc/dovecot.conf. You'll need to work around whatever existing authentication you have setup, but it'll look something like this.
auth default {
# We support `login` for Outlook clients that use this obsolete mechanism
mechanisms = plain login
# These are the default username/password backends
passdb pam {
}
userdb passwd {
}
# These should be correct for most systems, adjust the path, user and group as appropriate
socket listen {
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}
3. Restart dovecot to create the auth socket
4.
Check that the socket has been created as expected. Check your mail logs and look for problems if you're unsure.
Toggle line numbers
yoshino:~# ls -lh /var/spool/postfix/private/auth
srw-rw---- 1 postfix postfix 0 2009-09-27 00:36 /var/spool/postfix/private/auth
Postfix - configure SASL auth
Reference documentation: http://wiki.dovecot.org/HowTo/PostfixAndDovecotSASL
1.
As a quick sanity-check, make sure your postfix has been compiled with support for Dovecot's SASL implementation
yoshino:~# postconf -a
cyrus
dovecot <-- this is what we need
2.
Edit your main.cf (/etc/postfix/main.cf) file and add the SASL directives
Toggle line numbers
# Notice that we use a relative path to the auth socket
# This will work regardless of whether the SMTP daemon is running chroot'ed,
# and is specified relative to the queue_directory that we discovered earlier
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
# Adds a header that reports the login name that was used. Good for accountability, bad if you're paranoid
smtpd_sasl_authenticated_header = yes
# Support those broken Microsoft clients that expect "AUTH=<mechanisms>"
broken_sasl_auth_clients = yes
# Finally, give authenticated clients free reign to relay mail
# You'll need to massage this into any existing restrictions you have
# Assuming default settings, it'll look something like this
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
3. Restart Postfix so the settings take effect
Testing basic SASL
1.
We need to generate a base64-encoded auth string to send during the SMTP session. Be aware that this gives away your username and password, we'll setup encrytion for this shortly. We're going to use support@anchor.net.au for the username, and securepassword for the password. The "\0" is intentional, they represent null bytes.
*
mimencode is in the metamail package on Debian-type systems
yoshino:~# printf '\0support@anchor.net.au\0securepassword' | mimencode
AHN1cHBvcnRAYW5jaG9yLm5ldC5hdQBzZWN1cmVwYXNzd29yZA==
*
You can use perl on Redhat-type systems, note that you need to escape the @-sign if you're using an email address as the username
yoshino:~# perl -MMIME::Base64 -e 'print encode_base64("\0support\@anchor.net.au\0securepassword")'
AHN1cHBvcnRAYW5jaG9yLm5ldC5hdQBzZWN1cmVwYXNzd29yZA==
2.
Connect to your Postfix, issue an EHLO (Extended HELO) and attempt to AUTH. It should look something like this
rosa@rokkenjima:~% telnet yoshino.meidokon.net 25
Trying 202.4.232.68...
Connected to yoshino.meidokon.net.
Escape character is '^]'.
220 yoshino.meidokon.net ESMTP Postfix
EHLO localhost
250-yoshino.meidokon.net
250-PIPELINING
250-SIZE 20480000
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN AHN1cHBvcnRAYW5jaG9yLm5ldC5hdQBzZWN1cmVwYXNzd29yZA==
235 2.0.0 Authentication successful
QUIT
221 2.0.0 Bye
Connection closed by foreign host.
3.
If you run into problems you'll need to have a look at your mail logs to get an idea of what's going wrong. Unfortunately it's difficult to enumerate all the possible failure cases here, but the Dovecot wiki has some good advice to start with: http://wiki.dovecot.org/Debugging/Authentication
To finalise the testing, we'll send a quick mail through the system. If you don't get a "Relay access denied" error then everything is in order. Make sure you run these tests from a remote host to ensure you're not getting a free pass from being on the local machine.
...
AUTH PLAIN AHN1cHBvcnRAYW5jaG9yLm5ldC5hdQBzZWN1cmVwYXNzd29yZA==
235 2.0.0 Authentication successful
MAIL FROM: support@anchor.net.au
250 2.1.0 Ok
RCPT TO: support@anchor.net.au
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: support@anchor.net.au
To: support@anchor.net.au
Subject: This is a test message
Hi, have a friendly test message.
Thanks!
.
250 2.0.0 Ok: queued as A463341E2C77
QUIT
221 2.0.0 Bye
Connection closed by foreign host.
If you inspect the received message, you can trace the path taken and confirm that everything is working as expected.
Return-Path: support@anchor.net.au
Delivered-To: support@anchor.net.au
Received: from gohda.rokkenjima.net (gohda.rokkenjima.net [202.4.224.0])
(Authenticated sender: support@anchor.net.au) <-- the result of "smtpd_sasl_authenticated_header = yes"
by yoshino.meidokon.net (Postfix) with ESMTP id 0745141C09EC
for <support@anchor.net.au>; Mon, 12 Oct 2009 12:51:42 +1100 (EST)
From: support@anchor.net.au
To: support@anchor.net.au
Subject: test mail
Message-Id: <20091012015145.0745141C09EC@yoshino.meidokon.net>
Date: Mon, 12 Oct 2009 12:51:42 +1100 (EST)
Hi, have a friendly test message.
Thanks!
Postfix - Enable TLS for encryption
This is well and good so far, but at the moment our login details are being passed around unencrypted, which leaves them vulnerable to being sniffed by any intermediate hosts. We'll generate an x509 certificate, have Postfix offer it to clients, then disable authentication for clients that aren't using TLS encryption.
1.
Generate an RSA key for the certificate. We keep our key/certificate pairs in /etc/ssl, but you can use anywhere that's convenient for you. We take care to ensure that the key is only readable by root.
cd /etc/ssl
touch smtpd.key
chmod 600 smtpd.key
openssl genrsa 1024 > smtpd.key
2. Now you need a certificate that matches the key. In most cases you can get away with a self-signed certificate, though clients may complain that it's not signed by a recognised CA. The alternative is to generate a Certificate Signing Request and have it signed by a CA - this will cost you money.
1.
Self-signed certificate. Just a few questions to answer here, the most important is the Common Name (CN) - this is the hostname that clients will use to connect to you, often something like mail.mycompany.com.au
openssl req -new -key smtpd.key -x509 -days 3650 -out smtpd.crt
2.
CA-signed, you're about to generate a CSR. Answer all the questions accurately, otherwise most CAs will fail to verify your identity
openssl req -new -key smtpd.key -out smtpd.csr
Once the signed certificate comes back you can drop that in next to the key.
3.
Edit your Postfix main.cf to enable TLS. These lines can be added to the bottom of the file
# Offer TLS encryption to clients
smtpd_tls_security_level = may
# As specified earlier
smtpd_tls_key_file = /etc/ssl/smtpd.key
smtpd_tls_cert_file = /etc/ssl/smtpd.crt
# Only offer SMTP AUTH when talking over an encrypted connection
smtpd_tls_auth_only = yes
# Add some useful logging entries to track the use of TLS, you can omit this if desired
smtpd_tls_loglevel = 1
# Add a header to mail received with TLS, can make debugging easier
smtpd_tls_received_header = yes
4. Restart Postfix and check the mail logs for any errors.
Test that TLS is working as expected
We'll open two connections, one with TLS and one without, to ensure we see what we expect.
*
Firstly without TLS
rosa@rokkenjima:~% telnet yoshino.meidokon.net 25
Trying 202.4.232.68...
Connected to yoshino.meidokon.net.
Escape character is '^]'.
220 yoshino.meidokon.net ESMTP Postfix
EHLO gohda.rokkenjima.net
250-yoshino.meidokon.net
250-PIPELINING
250-SIZE 20480000
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
QUIT
221 2.0.0 Bye
Connection closed by foreign host.
You'll notice that STARTTLS is now available, but AUTH is not offered.
*
Now with TLS, using openssl's client feature
rosa@rokkenjima:~% openssl s_client -connect yoshino.meidokon.net:25 -starttls smtp
CONNECTED(00000003)
<lots of SSL output>
EHLO gohda.rokkenjima.net
250-yoshino.meidokon.net
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
QUIT
DONE
openssl handles the TLS for us, and AUTH is now available, as we saw during previous testing.
Enabling the submission port
Many ISPs block access to port 25, meaning that the above setup won't work for a lot of users. For this reason, port 587 is available, and is configured only for "outbound" relay access. You can do this easily in Postfix.
1.Edit /etc/postfix/master.cf and enable the submission port by uncommenting a couple of lines. Make sure not to mess up the whitespace - a logical line is continued by whitespace on the subsequent lines.
# We enforce the use of TLS, and override the client restrictions to only allow authenticated relaying
submission inet n - - - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
2. Restart Postfix and test the submission port
rosa@rokkenjima:~% openssl s_client -connect yoshino.meidokon.net:587 -starttls smtp
See also:
*Using the Postfix LDA for delivery
References/External Links
*http://www.postfix.org/SASL_README.html
*http://wiki.dovecot.org/HowTo/PostfixAndDovecotSASL
* http://wiki.dovecot.org/Debugging/Authentication
* http://www.anchor.com.au/hosting/dedicated/Postfix-SASL-setup
This might look a bit long-winded, but it's actually very simple to setup. There's plenty of sample configuration and examples below to refer to.
Contents
1. Setting up Postfix for SMTP Auth with the Dovecot SASL backend
1. Assumptions
2. Procedure
1. Dovecot
2. Postfix - configure SASL auth
3. Testing basic SASL
4. Postfix - Enable TLS for encryption
5. Test that TLS is working as expected
6. Enabling the submission port
3. See also:
4. References/External Links
Assumptions
1. You're familiar with the mail technologies in use
2. We're implementing SMTP Auth on a Redhat Enterprise Linux 5 system, but the steps are easily translated to other distros like Debian
* We're using the stock set of vendor package repositories
3. You have a fully-working Postfix installation that can send/receive mail to/from the internet
4. You're already using Dovecot for authenticated POP/IMAP access. While it's not necessary, this is the easiest way to be sure your authentication backend will Just Work
* By extension, we assume you've got a set of authentication credentials you can use for testing
Procedure
We'll start by enabling Dovecot's SASL service, then hook Postfix into this. Postfix will then offer SMTP Auth to remote clients, provided that they're using TLS for encryption.
Dovecot
Dovecot will create a daemon socket that will listen for SASL requests.
1.
On some distributions, the Postfix daemons run chroot'ed. For this reason, it's preferred to place the socket somewhere that's guaranteed to be accessible. Use the postconf command to find your queue directory - in most cases it'll be /var/spool/postfix
Toggle line numbers
yoshino:~# postconf queue_directory
queue_directory = /var/spool/postfix
2.
Edit /etc/dovecot.conf. You'll need to work around whatever existing authentication you have setup, but it'll look something like this.
auth default {
# We support `login` for Outlook clients that use this obsolete mechanism
mechanisms = plain login
# These are the default username/password backends
passdb pam {
}
userdb passwd {
}
# These should be correct for most systems, adjust the path, user and group as appropriate
socket listen {
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}
3. Restart dovecot to create the auth socket
4.
Check that the socket has been created as expected. Check your mail logs and look for problems if you're unsure.
Toggle line numbers
yoshino:~# ls -lh /var/spool/postfix/private/auth
srw-rw---- 1 postfix postfix 0 2009-09-27 00:36 /var/spool/postfix/private/auth
Postfix - configure SASL auth
Reference documentation: http://wiki.dovecot.org/HowTo/PostfixAndDovecotSASL
1.
As a quick sanity-check, make sure your postfix has been compiled with support for Dovecot's SASL implementation
yoshino:~# postconf -a
cyrus
dovecot <-- this is what we need
2.
Edit your main.cf (/etc/postfix/main.cf) file and add the SASL directives
Toggle line numbers
# Notice that we use a relative path to the auth socket
# This will work regardless of whether the SMTP daemon is running chroot'ed,
# and is specified relative to the queue_directory that we discovered earlier
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
# Adds a header that reports the login name that was used. Good for accountability, bad if you're paranoid
smtpd_sasl_authenticated_header = yes
# Support those broken Microsoft clients that expect "AUTH=<mechanisms>"
broken_sasl_auth_clients = yes
# Finally, give authenticated clients free reign to relay mail
# You'll need to massage this into any existing restrictions you have
# Assuming default settings, it'll look something like this
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
3. Restart Postfix so the settings take effect
Testing basic SASL
1.
We need to generate a base64-encoded auth string to send during the SMTP session. Be aware that this gives away your username and password, we'll setup encrytion for this shortly. We're going to use support@anchor.net.au for the username, and securepassword for the password. The "\0" is intentional, they represent null bytes.
*
mimencode is in the metamail package on Debian-type systems
yoshino:~# printf '\0support@anchor.net.au\0securepassword' | mimencode
AHN1cHBvcnRAYW5jaG9yLm5ldC5hdQBzZWN1cmVwYXNzd29yZA==
*
You can use perl on Redhat-type systems, note that you need to escape the @-sign if you're using an email address as the username
yoshino:~# perl -MMIME::Base64 -e 'print encode_base64("\0support\@anchor.net.au\0securepassword")'
AHN1cHBvcnRAYW5jaG9yLm5ldC5hdQBzZWN1cmVwYXNzd29yZA==
2.
Connect to your Postfix, issue an EHLO (Extended HELO) and attempt to AUTH. It should look something like this
rosa@rokkenjima:~% telnet yoshino.meidokon.net 25
Trying 202.4.232.68...
Connected to yoshino.meidokon.net.
Escape character is '^]'.
220 yoshino.meidokon.net ESMTP Postfix
EHLO localhost
250-yoshino.meidokon.net
250-PIPELINING
250-SIZE 20480000
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN AHN1cHBvcnRAYW5jaG9yLm5ldC5hdQBzZWN1cmVwYXNzd29yZA==
235 2.0.0 Authentication successful
QUIT
221 2.0.0 Bye
Connection closed by foreign host.
3.
If you run into problems you'll need to have a look at your mail logs to get an idea of what's going wrong. Unfortunately it's difficult to enumerate all the possible failure cases here, but the Dovecot wiki has some good advice to start with: http://wiki.dovecot.org/Debugging/Authentication
To finalise the testing, we'll send a quick mail through the system. If you don't get a "Relay access denied" error then everything is in order. Make sure you run these tests from a remote host to ensure you're not getting a free pass from being on the local machine.
...
AUTH PLAIN AHN1cHBvcnRAYW5jaG9yLm5ldC5hdQBzZWN1cmVwYXNzd29yZA==
235 2.0.0 Authentication successful
MAIL FROM: support@anchor.net.au
250 2.1.0 Ok
RCPT TO: support@anchor.net.au
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: support@anchor.net.au
To: support@anchor.net.au
Subject: This is a test message
Hi, have a friendly test message.
Thanks!
.
250 2.0.0 Ok: queued as A463341E2C77
QUIT
221 2.0.0 Bye
Connection closed by foreign host.
If you inspect the received message, you can trace the path taken and confirm that everything is working as expected.
Return-Path: support@anchor.net.au
Delivered-To: support@anchor.net.au
Received: from gohda.rokkenjima.net (gohda.rokkenjima.net [202.4.224.0])
(Authenticated sender: support@anchor.net.au) <-- the result of "smtpd_sasl_authenticated_header = yes"
by yoshino.meidokon.net (Postfix) with ESMTP id 0745141C09EC
for <support@anchor.net.au>; Mon, 12 Oct 2009 12:51:42 +1100 (EST)
From: support@anchor.net.au
To: support@anchor.net.au
Subject: test mail
Message-Id: <20091012015145.0745141C09EC@yoshino.meidokon.net>
Date: Mon, 12 Oct 2009 12:51:42 +1100 (EST)
Hi, have a friendly test message.
Thanks!
Postfix - Enable TLS for encryption
This is well and good so far, but at the moment our login details are being passed around unencrypted, which leaves them vulnerable to being sniffed by any intermediate hosts. We'll generate an x509 certificate, have Postfix offer it to clients, then disable authentication for clients that aren't using TLS encryption.
1.
Generate an RSA key for the certificate. We keep our key/certificate pairs in /etc/ssl, but you can use anywhere that's convenient for you. We take care to ensure that the key is only readable by root.
cd /etc/ssl
touch smtpd.key
chmod 600 smtpd.key
openssl genrsa 1024 > smtpd.key
2. Now you need a certificate that matches the key. In most cases you can get away with a self-signed certificate, though clients may complain that it's not signed by a recognised CA. The alternative is to generate a Certificate Signing Request and have it signed by a CA - this will cost you money.
1.
Self-signed certificate. Just a few questions to answer here, the most important is the Common Name (CN) - this is the hostname that clients will use to connect to you, often something like mail.mycompany.com.au
openssl req -new -key smtpd.key -x509 -days 3650 -out smtpd.crt
2.
CA-signed, you're about to generate a CSR. Answer all the questions accurately, otherwise most CAs will fail to verify your identity
openssl req -new -key smtpd.key -out smtpd.csr
Once the signed certificate comes back you can drop that in next to the key.
3.
Edit your Postfix main.cf to enable TLS. These lines can be added to the bottom of the file
# Offer TLS encryption to clients
smtpd_tls_security_level = may
# As specified earlier
smtpd_tls_key_file = /etc/ssl/smtpd.key
smtpd_tls_cert_file = /etc/ssl/smtpd.crt
# Only offer SMTP AUTH when talking over an encrypted connection
smtpd_tls_auth_only = yes
# Add some useful logging entries to track the use of TLS, you can omit this if desired
smtpd_tls_loglevel = 1
# Add a header to mail received with TLS, can make debugging easier
smtpd_tls_received_header = yes
4. Restart Postfix and check the mail logs for any errors.
Test that TLS is working as expected
We'll open two connections, one with TLS and one without, to ensure we see what we expect.
*
Firstly without TLS
rosa@rokkenjima:~% telnet yoshino.meidokon.net 25
Trying 202.4.232.68...
Connected to yoshino.meidokon.net.
Escape character is '^]'.
220 yoshino.meidokon.net ESMTP Postfix
EHLO gohda.rokkenjima.net
250-yoshino.meidokon.net
250-PIPELINING
250-SIZE 20480000
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
QUIT
221 2.0.0 Bye
Connection closed by foreign host.
You'll notice that STARTTLS is now available, but AUTH is not offered.
*
Now with TLS, using openssl's client feature
rosa@rokkenjima:~% openssl s_client -connect yoshino.meidokon.net:25 -starttls smtp
CONNECTED(00000003)
<lots of SSL output>
EHLO gohda.rokkenjima.net
250-yoshino.meidokon.net
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
QUIT
DONE
openssl handles the TLS for us, and AUTH is now available, as we saw during previous testing.
Enabling the submission port
Many ISPs block access to port 25, meaning that the above setup won't work for a lot of users. For this reason, port 587 is available, and is configured only for "outbound" relay access. You can do this easily in Postfix.
1.Edit /etc/postfix/master.cf and enable the submission port by uncommenting a couple of lines. Make sure not to mess up the whitespace - a logical line is continued by whitespace on the subsequent lines.
# We enforce the use of TLS, and override the client restrictions to only allow authenticated relaying
submission inet n - - - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
2. Restart Postfix and test the submission port
rosa@rokkenjima:~% openssl s_client -connect yoshino.meidokon.net:587 -starttls smtp
See also:
*Using the Postfix LDA for delivery
References/External Links
*http://www.postfix.org/SASL_README.html
*http://wiki.dovecot.org/HowTo/PostfixAndDovecotSASL
* http://wiki.dovecot.org/Debugging/Authentication
* http://www.anchor.com.au/hosting/dedicated/Postfix-SASL-setup