Postfix: email done properly

Feb 21, 2013 11:27

So, last post, I suggested that a VPN was simpler than setting up my home email server to relay when I'm not at home. It was simple, but, when running on a Rasberry Pi, it's awfully slow. To the point of despair. And that's when I'm standing still. If I move around, my android phone has a tendency to disconnect from one wifi hotspot, and connect to another, which disconnects the VPN (admittedly, this may be because I'm in a large building, with eduroam. But at the end-user interface, the cause is irrelevant). All in all, it works, but not brilliantly.

Since I'm off to Redemption '13 this weekend, and the VPN set up is looking a bit untenable. Admittedly, it'll mostly be twitter, but I figured I'd get the email working.

Turns out that, in fact, it was trivial. I'd done all the work before, but, ahem. Forgotten to open the port...

Postfix's default configuration is geared towards not allowing spam. Indeed, the documentation includes:
In a distant past, the Internet was a friendly environment. Mail servers happily forwarded mail on behalf of anyone towards any destination. On today's Internet, spammers abuse servers that forward mail from arbitrary systems, and abused systems end up on anti-spammer blacklists. See, for example, the information on http://www.mail-abuse.org/ and other websites.

By default, Postfix has a moderately restrictive approach to mail relaying. Postfix forwards mail only from clients in trusted networks, from clients that have authenticated with SASL, or to domains that are configured as authorized relay destinations. For a description of the default mail relay policy, see the smtpd_relay_restrictions parameter in the postconf(5) manual page, and the information that is referenced from there.

Actually, I'm using postfix 2.9.3, so I've got stmpd_recipient_restrictions, not smptd_relay_restrictions (which only comes in with 2.10), but the theory's the same. The default value for this is: permit_mynetworks, reject_unauth_destination . Which, fairly obviously means that my mail server will relay anything sent from "my" network to the outside world (and, independently of this will accept any mail from anywhere, as long as it's meant for my server). But it won't allow outside networks to use my server as a relay. So it's fairly sensible, with the proviso that my phone can't send email via the server, if I'm on a different network. Which is where the whole story starts, and the VPN solves.

The correct solution is to change smtpd_recipient_restrictions to permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, and then anything which has been authenticated can also bounce mail through the server.


Postfix's documentation is at http://www.postfix.org/SASL_README.html#server_sasl_enable

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

Actually, that doesn't quite work: it produces postfix/smtpd[29083]: fatal: no SASL authentication mechanisms in /var/log/mail.err. Which isn't entirely surprising, since this doesn't include changing the relevant Dovecot configuration. This is mentioned at the top of the postfix page, and the relevant Dovecot page is http://wiki2.dovecot.org/HowTo/PostfixAndDovecotSASL . Looking at the supplied /etc/dovecot/conf.d/10-master.conf, it already had the necessary section, just the with lines commented out. Uncommenting them gives:

service auth {
unix_listener auth-userdb {
mode = 0666
user =
group =
}
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
user = $default_internal_user
}

And then, after restarting both dovecot and postfix, the error messages go away. Postfix even has a test, and it works! Note that the supplied example is supplying a username and password of test/testpass, and while this isn't human readable, it's only base64 encoded, and not secure.


http://postfix.state-of-mind.de/patrick.koetter/smtpauth/postfix_tls_support.html has some good stuff, but it's a long slog through it.
The short version is:

smtpd_tls_cert_file=/etc/ssl/certs/smtpd-mrwolf.crt
smtpd_tls_key_file=/etc/ssl/private/smtpd-mrwolf.key
smtpd_tls_CAfile = /etc/ssl/certs/cacert-mrwolf.pem
smtpd_tls_auth_only = yes
smtpd_use_tls = yes
smtpd_tls_loglevel = 3
smtpd_tls_received_header = yes

The first two lines are my security certificate and key. The third is the certificate of my issuer (in my case, it's self signed, so I get a warning message). The tls_auth_only line means that authentication is now only offered once the TLS encryption is enabled (comment this out if testing with telnet!). And the last two lines are tracing.

And it all works, from home. But my phone, configuring it from work, keeps complaining.


I'd actually configured all of the above stuff before. And had it working. But it didn't work reliably. And I've finally figured out why: everything I'd set up on my phone was still talking to port 25 (the normal SMTP port). Which, of course, worked fine at home, and worked on some "other" networks, but not all. In particular, eduroam blocks it. So I needed to get it talking to port 587, the normal TLS port. And postfix configures that entirely independently from the TLS configuration above. In a penny dropping moment, I ran nmap and realised that configuring TLS didn't open the TLS port. Instead, I needed to go into /etc/postfix/master.cf and uncomment the line:

submission inet n - - - - smtpd
And there you go: port 587 opens up, and everything works direct from my phone. No VPN needed!

Interestingly, it turns out that authenticate email over TLS uses exactly the same communication irrespective of the port: it starts off in plain text, swapping EHLO acknowledgements, and it's only the STARTTLS instruction that turns the encryption on. Obviously, the server could refuse to allow TLS on port 25, and refuse to continue conversations on port 587 if the client doesn't activate TLS, but if these are left optional, there's no difference between the two ports. So blocking port 25 doesn't stop people running their own SMTP servers. It just means they've got to offload their communications to port 587, and everything else is unchanged (well, you might need to find a different server to off-load to. But the port number doesn't magically ensure a sensible configuration).

security, email

Previous post
Up