= Postfix/Authentication_and_confidentiality = There's a lot of confusion about how auth and crypto works in Postfix. I'd like to clarify some of that. Largely chunks originally written for http://archives.neohapsis.com/archives/postfix/2009-04/0644.html <> ---- == Concepts == "Security" is a very vague term when applied to Postfix. Let's break it down into our goals, the things we ''want'' out of Postfix: * "Our" users can login and send mail * When we login, passwords must not travel in the clear (unencrypted) * We'd like our mail to be encrypted as it travels between us and the server (negotiable, somewhat optional) The first goal uses ''SMTP Auth''. As part of the SMTP protocol, you send login details and authenticate, which authorises you to send mail to anyone. Normally, the server would only accept mail bound for addresses that it hosts. The second goal can be implemented in a couple of different ways; it's easiest if we just call this ''Encryption'', even if it's not strictly correct. The third goal isn't necessarily tied to the second goal of password-secrecy. It's nice to have though. The important thing to keep in mind is that '''SMTP Auth is separate from encryption - you can have one without the other'''. == SMTP Auth == Let's get SMTP Auth out of the way, it's pretty straightforward. I'm sending mail to `bob@example.com`. A certain scientific Postfix server accepts mail for example.com. The mail may be delivered to a mailbox on the server, or the server might just be an intermediary and passes all mail for example.com to another server. In any case, that server is a valid destination for mail to the example.com domain. However, that server doesn't accept mail for bob@yahoo.com - because the server isn't owned by Yahoo corp! If the server accepted that mail and forwarded it on, it could easily be abused by spammers - that would make it an open relay, which is bad. But what if my users, all employees of Example corp, need to send mail? This is what SMTP Auth is for: if a user successfully authenticates, you can let them bypass that relaying restriction and send mail to anywhere. Obviously you need to trust your users not to abuse this capability. One usually relies on policy and the threat of [[http://en.wikipedia.org/wiki/Kicked_in_the_Nuts| punishment]] to enforce good behaviour. SMTP Auth is really simple: you connect via SMTP, then announce that you wish to authenticate, sending your username and password down the tube in one form or another. There's no inherent security in this, so hurling your password down an insecure connection is less than ideal. There are various ways to address this deficiency, which we'll cover below. For now, this is where SMTP Auth stops - it's not smart, and doesn't know much about security. That's where encryption kicks in. == Encryption == === Explanation through bad analogy === As we all know, [[http://en.wikipedia.org/wiki/Series_of_tubes| the internet is a series of tubes]]. The tubes are made of clear glass, and anyone who's watching the tubes can see them. It's not ''trivial'' to do this, but whoever is in charge of your network can do this. There's lots of different pieces of network between you and the server, which means there's lots of places people can see your traffic. Quickly, what are we protecting? When you authenticate to send mail, you send your login details, then the mail itself. It looks like this: {{{ -------------glass internet pipe----------------------------------------- |---------| |-----------------------| | Message | | Username and password | ==> To the Server =======> |---------| |-----------------------| ------------------------------------------------------------------------- }}} Let's make another (bad) analogy. You can secure your traffic by wrapping it in opaque black plastic - that way noone can see in. SMTP gives you two ways to do this: 1. You could wrap the entire pipe in opaque plastic, noone can see anything (referred to as SSL or TLS) 1. You could wrap just your username and password in opaque plastic, that way your login details are secure (provided by your "authentication mechanism" - MD5 and NTLM might be considered er, more popular options) This is pure opinion, but I reckon a lot of people would agree with the statement that the first option is better. It's also very straightforward to understand, which is great. === Diversion: differences between SSL and TLS === They're very similar, but they're not interchangeable terms. While it's not 100% accurate, it's easiest to think of it in this way: * SSL is an encrypted pipe that goes around the whole SMTP session. SSL is negotiated before SMTP starts and is transparent to the MTA at each end * TLS is negotiated in-band, at least for SMTP. The session starts in plaintext, the server offers STARTTLS in its reply to EHLO, and the client can choose to initiate negotiation by sending "`STARTTLS`". Then the crypto kicks in and the session is protected. Each side then keeps talking SMTP as usual. [[http://en.wikipedia.org/wiki/STARTTLS| Wikipedia page on STARTTLS]] === Diversion: TCP ports used for mail === Now is a good time to get this out of the way. For various reasons, different ports are used to provide different services. This is largely convention and most mail clients will behave in this way. * Port 25 == regular SMTP, this must always be enabled if you want to receive mail from the internet * Port 465 == de-facto port for running SSL-mode SMTP * Port 587 == usual port for running "TLS" SMTP - this is exactly the same as port 25 however! You can talk plain SMTP to port 587 if you want, try it in a telnet session. Because port 25 and port 587 are configured separately in `master.cf`, you can have different settings. You can't ''enforce'' crypto on port 25 because that would break normal mail, but you can do that on port 587 if you want. === Encryption and authentication mechanisms === I mentioned earlier that there's two ways to secure your traffic (by security, I mean we're using encryption). One is to have an encrypted pipe, the other is to encrypt your packets. But these are actually independent possibilities. If you wanted to, you could encrypt your login details, and send them down a TLS/SSL connection! Which gives us the following matrix of "authentication mechanisms" (rows) vs. encrypted transports (columns): || || '''Unencypted pipe''' || '''Encrypted pipe (TLS/SSL)''' || || '''Plaintext mechanism''' || {X} || (./) || || '''Encrypted mechanism''' || (./) || (./) || A mechanism is just a way of sending your username and password down the pipe, nothing fancy. This gives us choices, which is great. Truth be told, only one of these is truly awesome (I'm assuming a new deployment with no dependencies on existing infrastructure). As I've mentioned, using TLS/SSL protects the entire transaction; this is very desirable. Need an reason? Your email login details probably have a fairly low, static "value" to an attacker (they can send spam, maybe impersonate you poorly). The value of the contents of your email are potentially much higher (financial details, personal information, etc). Using encrypted authentication mechanisms also has tradeoffs. There's too much detail to go into here, but it suffices to understand that the server needs to validate a user's details when they login. To do this it needs to have a database to check against. * Using a plaintext authentication mechanism means that the server can keep a hashed ("encrypted") copy of the password database. This is good because it mitigates against the risk of the whole database being stolen * Using an encrypted authentication mechanism requires the server to have a plaintext or effectively-plaintext copy of your password - that's not really cool === Encryption and auth in mail clients === Every client does this differently, and they all have some voodoo inside. Some of these notes are from the postfix-users thread, with commentary. * In Apple Mail, there are auth options of ntlm, md5 Challenge-Reponse, Kerberos, and Password * These are all authentication mechanisms. "Password" is plaintext and should be used with TLS/SSL. The rest are encrypted mechanisms * In Thunderbird I noticed there are no such options. There is None, TLS (optional), and SSL. And then this "Use secure auth" setting * None/TLS/SSL refers to an encrypted transport (the columns in the above matrix), while "Use secure auth" limits the mechanisms that Thunderbird will attempt. Exactly which mechanism is settles on seems unclear. === Conclusions on encryption === I think this is the best way to do things, you're free to disagree. * Do whatever you want on port 25, but you ''must'' accept unauthenticated, unencrypted mail from the greater internets (I assume you're on the internets here) * Setup the port 587 "submission" port for your users who need to authenticate and relay mail to external addresses * Enforce the use of TLS for all submission connections * Enforce authentication for all submission connection * Just use the `PLAIN` authentication mechanism (and `LOGIN` for Outlook compatibility) - this is part of your SASL configuration on the server === Implementing this in Postfix === A [[http://en.wikipedia.org/wiki/Copypasta#Copy_and_paste| copypasta]] dump from my own config. {{{ # we can allow relaying by forcing senders to authenticate first (by permit_sasl_authenticated in smtpd_recipient_restrictions) smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous <-- this is the default, BTW smtpd_tls_security_level = may <-- offer but don't require TLS broken_sasl_auth_clients = yes # server TLS parameters smtpd_tls_key_file = /etc/ssl/yoshino.meidokon.net_key smtpd_tls_cert_file = /etc/ssl/yoshino.meidokon.net_crt smtpd_tls_auth_only = yes <-- as mentioned, user can only auth on a secure connection smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes # client TLS parameters, forward mail via TLS if possible smtp_tls_security_level = may }}} * These parameters will apply to all smtpd processes (smtp,smtps,submission) in master.cf unless you override the specific settings there. * You may choose to enforce crypto on port 587 with "`-o smtpd_tls_security_level=encrypt`" but it's not technically necessary. * You'll usually add "`-o smtpd_tls_wrappermode=yes`" to the `smtps` definition to get "SSL" mode working. * I've personally got "`-o smtpd_client_restrictions=permit_sasl_authenticated,reject`" for my submission port.