Secure relaying for outgoing mail - Postfix with Dovecot SASL
October 31st, 2008
Update, January 2011: Many aspects have changed in Ubuntu 10.10 "Maverick Meerkat". It is now much simpler than as described in this article, because the Ubuntu server packages are designed to work together now.
This is Part 2 of four parts:
- Part 1: incoming mail with spam and virus blockers
- Part 2: secure relaying for outgoing mail - authentication over SASL
- Part 3: secure IMAP and SMTP relaying with TLS for Dovecot and Postfix
- Part 4: the future - Apache JAMES?
As we explained in the introduction of Part 1, we're migrating from a Postfix / Dovecot / CyrusSASL based system to one which uses Psotfix and Dovcot IMAP and Dovecot SASL. Under Suse 10.1, the Postfix version that shipped did not work with Dovecot SASL. The version which ships with Ubuntu 8.04 does, so we won't need to use Cyrus. Cyrus SASL isn't involved at all in our setup.
We'll also activate IMAP service with Dovecot in this part, but there's basically nothing to do for that. Dovecot starts serving IMAP correctly when it is turned on.
What is the purpose of SASL? Why do we need it?
We have mail users in offices, and also at home, and traveling. They may use laptops to send a message from any location in the world. These messages must route through our mail server. Our mail server must relay messages from our users. But if we create an open relay, that relays for everyone, spammer will detect it and exploit it, causing problems for us and a lot of other people also.
The solution is to use authenticated relaying. In this usage, the mail user agent (MUA) is configured to offer authentication before it attempts to relay. Relaying is forbidden before authentication, and is permitted after. The SMTP protocol has an AUTH command that allows the MUA to supply credentials. We must configure Postfix to process this type of transaction correctly.
But the difficulty is that Postfix has no concept of users or authentication. It must rely on some external source for this. In the Linux world, the PAM system is normally used to authenticate users in a flexible way. In networked systems, LDAP is used. But neither of these is exactly suited to MTA use. PAM is Linux-only, whereas Postfix can run on a wide range of operating systems, many of which do not have PAM. LDAP is a somewhat complex server to set up and it doesn't provide all the authentication data Postfix might use, such as a way to process client certificates. Therefore, the Simple Authentication and Security Layer (SASL) is used.
The original "standard" SASL server for Linux was Cyrus. Cyrus is still widely used but it is a large and complex system. Fortunately, Dovecot is a simpler system, provides a good IMAP server, and can now provide SASL service. We're using Dovecot.
This is what the final result will look like:
Step 1: Install Dovecot
Very easy:
apt-get install dovecot
Step 2: Configure Dovecot to serve SASL so Postfix can do secure relaying
Find the auth default clause of the
/etc/dovecot/dovecot.conf file. The default
config file that comes with Dovecot has many notes and options,
but is nearly correct the way it is. Change
the auth default clause to be:
auth default {
mechanisms = plain login
# NOTE that this requires /etc/pam.d/dovecot to be configured
# an alternative is to just use passdb passwd which will
# then use the password file, or userdb passwd-file which
# specifies a plain text file directly
passdb pam {
}
# at least one userdb must be specified
userdb passwd {
}
# run as root, to be able to write into the Postfix spool directory
user = root
socket listen {
client {
path = /var/spool/postfix/private/dovecot-sasl-auth
mode = 0660
user = postfix
group = postfix
}
}
}
Postfix SMTPD, and most of the other Postfix processes, normally run within
a chroot
environment. Using chroot provides some additional
security, or at least protection against misconfigurations. Postfix' use
of chroot came about as a reaction against Sendmail's numerous
security problems. The Postfix designers decided to use small, isolated
processes, and run them in chroot as non-root users to give
them the minimum access possible, in contrast to Sendmail, which, at the time,
had one very complex do-everything process which ran as root all the time.
Therefore,
SMTPD does not have access to file outside of /var/spool/postfix.
This means that if you put the Unix socket path for SASL somewhere outside
of that directory, Postfix SMTPD will not be able to find it, and you will get errors
from postfix/smtpd
like
warning: SASL: Connect to /path/not/in/chroot failed: No such file or directory,
even though the file clearly exists, and smtpd will exit with
fatal: no SASL authentication mechanisms. The solution is to make
sure that the socket path is within SMTPD's chroot jail, normally /var/spool/postfix,
and make sure that Postfix is configured to use a path relative to the jail,
not to the root of the real filesystem.
The path specified in the client is the socket endpoint that Postfix
will use to access SASL. Later on, we will make
another change to require
client SSL certificates, and this clause is where we would add that requirement.
Passwords are great, but a client certificate provides another even
stronger security layer.
Restart Dovecot and see that the auth socket is available:
sudo ls -l /var/spool/postfix/private/dovecot-sasl-auth srw-rw---- 1 postfix postfix 0 2008-10-29 10:30 /var/spool/postfix/private/dovecot-sasl-auth
We see that there is a socket owned by postfix / postfix.
The path is under the /var/spool/postfix directory, which becomes
the root directory for SMTPD when it runs with chroot.
Step 3: Create a Postfix SMTPD for relaying that talks to Dovecot
Normally configuration of Postfix is done within the /etc/postfix/main.cf
file. However, in our configuration, we are running three
different instances of Postfix SMTPD:
- External SMTPD, listening on port 25, to receive incoming mail (configured in Part 1)
- Internal SMTPD, listening on Port 10026, for re-injected mail from Amavisd (configured in Part 1)
- Secure relaying SMTPD, on Port 10025, which we are configuring in this part
The first two SMTPDs don't do relaying and so don't need to use SASL.
Therefore all the SASL related parameters will be specified as overrides
in the /etc/postfix/master.cf file.
Make sure Postfix uses Dovecot for handling authentication. Add these
lines to the end of /etc/postfix/master.cf to create
a new SMTPD instance:
10025 inet n - - - - smtpd
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/dovecot-sasl-auth
-o smtp_sasl_auth_enable=no
-o smtpd_sasl_auth_enable=yes
-o smtpd_use_tls=no
-o smtp_use_tls=no
-o smtpd_tls_auth_only=no
-o smtpd_sasl_security_options=noanonymous
-o smtpd_recipient_restrictions=permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
-o smtpd_sasl_authenticated_header=yes
-o broken_sasl_auth_clients=no
At this point,
TLS is turned off. In the next
part we will change this to use TLS, but for now, we'll skip the TLS and
test that auth is working. The smtpd_sasl_path
is set to the location of the socket endpoint from Dovecot.
The path is relative to the chroot environment.
smtpd_sasl_authenticated_header is specified. It's not necessary
in this particular usage, because this SMTPD isn't going through a spam filter.
In other configurations, where there is only one SMTPD running, it is necessary
to use smtpd_sasl_authenticated_header to prevent authenticated
mail from being spam checked. smtpd_sasl_type is set to dovecot
to tell Postfix to use the Dovecot variation of SASL. There are slight differences
between how Dovecot and Cyrus serve SASL, and Postfix needs
to know which one to use.
Restart Postfix:
# /etc/init.d/postfix restart
It didn't work; in /var/log/mail.err there is:
Oct 24 17:58:30 cl-t145-020cl postfix/master[8268]: fatal: bind 0.0.0.0 port 10025: Address already in use
What is blocking it?
# netstat -l -e -p
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 localhost:10025 *:* LISTEN root 850762 7237/perl
Using ps we see that PID 7237 is spampd, the Spam Proxy Daemon,
which we are not using in this configuration. It shouldn't have been
installed. Uninstall it:
apt-get remove spampd
and restart Postfix. You shouldn't have spampd installed, but this illustrates
how to find which process is holding onto a port if you ever run into
Address already in use errors. Restart again:
# /etc/init.d/postfix restart * Stopping Postfix Mail Transport Agent postfix [ OK ] * Starting Postfix Mail Transport Agent postfix
Step 4: Test authentication
Our configuration uses the PLAIN authentication method, which
requires a Base64-encoded version of the username and password.
Construct a string as follows:
\0 + username + \0 + password
and encode it with Base64. The easiest way to do that is using the base64password.jar utility (source code is included in the JAR file):
% java -jar base64password.jar username password AHVzZXJuYW1lAHBhc3N3b3Jk
Now test with telnet:
telnet 70.38.78.37 10025 Trying 70.38.78.37... Connected to 70.38.78.37. Escape character is '^]'. 220 cl-t145-020cl.localdomain ESMTP Postfix (Ubuntu) EHLO HOST 250-cl-t145-020cl.localdomain 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH PLAIN Abbbbbbbbbbbbbbbbb== 235 2.7.0 Authentication successful quit 221 2.0.0 Bye Connection closed by foreign host.
Then try it again with a wrong password:
AUTH PLAIN Accccccccccccccccc=
535 5.7.8 Error: authentication failed:
where, of course, the passwords are the Base64 encoded strings generated using the tool above.
Dovecot is now providing authentication for Postfix over SASL.
Step 6: test relaying, both with and without authentication
The mail will indeed be in the mailbox. Try it with a recipient on another domain:
MAIL FROM: <joe@yahoo.com>
250 2.1.0 Ok
RCPT TO: <bill@microsoft.com>
554 5.7.1 <bill@microsoft.com>: Relay access denied
This is important. It's not relaying. If we authenticate before sending, it should now relay:
> telnet 70.38.78.37 10025
Trying 70.38.78.37...
Connected to 70.38.78.37.
Escape character is '^]'.
220 chiralsoftware.net ESMTP Postfix (Ubuntu)
AUTH PLAIN Aaaaaaaaaaaaaaaaa==
235 2.7.0 Authentication successful
MAIL FROM: <eric@chiralsoftware.net>
250 2.1.0 Ok
RCPT TO: <bill@microsoft.com>
250 2.1.5 Ok
QUIT
Relaying does work after authentication. That shows that relaying
is active and it is secured through the Dovecot SASL interface.
Note that I quit before sending anything, so I didn't actually
generate a spam to bill@microsoft.com.
Conclusion
We have created an SMTPD instance which performs secure relaying by using SASL to authenticate with Dovecot. Next steps are to turn on TLS
Also, Dovecot is now serving IMAP correctly. Test this with a mail client.
Now we can go on to Part 3: secure IMAP and SMTP relaying with TLS for Dovecot and Postfix.