After having set up a mail server for the company I work at (I'm a technician at a SEO, PPC and web marketing company) we quickly came across a problem. One of our employees tried to send a mail through our server from outside our network, which resulted in an error.
The first problem I figured was because pretty much all ISPs in Sweden block port 25 (SMTP). It was quickly solved by routing incoming port 587 to internal port 25 on our server. Yup, it solved the problem. But only the first problem, because after we could actually connect to the server from outside the network we got another problem. An authentication problem. Duh, I should've known.
It's supposed to block attempts to spam through our server from outside but I never considered the possibility that it'll block legitimate mail as well. What I had to do was obviously set up some kind of authentication, and the way to do it is SASL. I use Dovecot on the server, so Dovecot SASL is what I'll be using in this guide. If you followed my guide to Postfix+Dovecot your server should be compiled with support for it already.
First of all we need to enable it in Postfix. To do that simply add the following lines to your Postfix configuration (main.cf) some place appropriate:
broken_sasl_auth_clients = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
You will also want to add permit_sasl_authenticated somewhere in the "smtpd_recipient_restrictions" list.
Next up is Dovecot, so open up your dovecot.conf. You can start by adding "login" to the mechanisms row, so it'll look like this:
mechanisms = plain login
After that change the client path row to:
path = /var/spool/postfix/private/auth
I also changed both user and group to postfix instead of dovecot.
That should be all you need to do to enable SASL for your mail server, now all that's left is to test it. Run the following four commands to completely stop and start the mail server:
pkill -9 dovecot
To test the SASL authentication the first thing we have to do is to base64-encode our username and password so we can send it to the server. Normally the mail client does this, but since we're telneting we have to do it ourselves. Run the following command in the terminal:
perl -MMIME::Base64 -e 'print encode_base64("\000user\@domain.tld\000password")'
The string of random characters it returned is the base64-encoded version of "\email@example.com\0password."
Now let's try authenticating ourselves when sending a mail through telnet!
telnet localhost 25
Connected to localhost.
Escape character is '^]'.
220 server.domain.tld ESMTP Postfix
AUTH PLAIN AHVzZXJAZG9tYWluLnRsZABwYXNzd29yZA==
235 2.7.0 Authentication successful
From here on send a mail as usual, with "MAIL FROM", "RCPT TO" and "DATA."
That's all there was to it - now you, like me and my company's employees, should be able to send mail from outside the local network. ;)