Postfix: Dovecot SMTP AUTH and TLS

As the subject says, I'm toying around with building a new mail erver, this time including some more security. I run into problems when trying to use Dovecot SASL with TLS as SMTP AUTH. I have seen similar subjects before but with no (at least for me) solution, so I'm going to try here and see if there's any luck ;)

My components are (all built from ports):
Code:
postfix-2.10.2,1
dovecot-2.2.6
cyrus-sasl-saslauthd-2.1.26
cyrus-sasl-2.1.26_3

(One could argue that Cyrus probably isn't necessary when I use Dovecot, but I tried with Cyrus first before I settled on Dovecot so that's why they're still there)

And the system (GENERIC kernel) running:
Code:
# uname -rm
9.2-RELEASE amd64

Certificate:
Self signed (http://www.e-rave.nl/create-a-self-signed-ssl-key-for-postfix), also mentioned a bit further down.

Postfix has been built with the options I require:
Code:
# postconf -a
cyrus
dovecot

I have set up a Postfix/Dovecot platform with virtual domains and users, and the login process (using IMAP) via Dovecot is working flawlessly (also via SSL/TLS). So, I decided my next step would be to add more security to SMTP via submission and configure my webmail client to use submission by default.

I enabled submission on it's default port 587:
Code:
# netstat -an |grep 587
tcp4       0      0 *.587                  *.*                    LISTEN

If I comment out any TLS configuration and thereby use simple PLAIN authentication, things work, but naturally I'd prefer a little more than unencrypted authentication.

I decided to used a self-signed certificate to get things rolling, and for that I followed the following guide: http://www.e-rave.nl/create-a-self-signed-ssl-key-for-postfix.

My contents of /usr/local/etc/postfix/main.cf is until now the following (server FQDNs and IP-adressed masked out):

Code:
queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
data_directory = /var/db/postfix
mail_owner = postfix
unknown_local_recipient_reject_code = 550
mynetworks_style = host
smtpd_banner = $myhostname ESMTP
append_dot_mydomain = no
debug_peer_level = 2

debugger_command =
	 PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
	 ddd $daemon_directory/$process_name $process_id & sleep 5

newaliases_path = /usr/local/bin/newaliases
mailq_path = /usr/local/bin/mailq
setgid_group = maildrop
html_directory = /usr/local/share/doc/postfix
manpage_directory = /usr/local/man
sample_directory = /usr/local/etc/postfix
readme_directory = /usr/local/share/doc/postfix
inet_protocols = ipv4

### TLS
smtpd_use_tls = yes
#smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /usr/local/etc/postfix/ssl/OMITTED.com.crt
smtpd_tls_key_file = /usr/local/etc/postfix/ssl/OMITTED.com.key
smtpd_tls_CAfile = /usr/local/etc/postfix/ssl/cacert.pem
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 300s
smtpd_tls_loglevel = 3
tls_random_source = dev:/dev/urandom

### Cyrus SASL
smtpd_tls_auth_only = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous, noplaintext
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
broken_sasl_auth_clients = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

myhostname = mail.OMITTED.com
mydomain = OMITTED.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = $mydomain
mydestination =
	OMITTED.com
	mail.OMITTED.com
	localhost.OMITTED.com
	localhost
mynetworks =
	127.0.0.0/8
	SERVER_IP_OMITTED
message_size_limit = 15000000
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
dovecot_destination_recipient_limit = 1

smtpd_helo_required = yes
smtpd_helo_restrictions =
	permit_mynetworks
	check_helo_access cidr:/usr/local/etc/postfix/postfix_helo_access
	reject_non_fqdn_hostname
smtpd_client_restrictions =
	permit_mynetworks
	check_client_access cidr:/usr/local/etc/postfix/postfix_clnt_access
smtpd_sender_restrictions =
	permit_sasl_authenticated
	permit_mynetworks
	reject_non_fqdn_sender
	reject_unknown_sender_domain
	reject_unauth_pipelining
smtpd_recipient_restrictions =
	permit_sasl_authenticated
	permit_mynetworks
	reject_unauth_destination
	check_policy_service unix:private/policy  # SPF
	check_policy_service inet:127.0.0.1:10023 # Greylisting
	reject_non_fqdn_recipient
	reject_unknown_recipient_domain
	reject_rbl_client cbl.abuseat.org
	reject_rbl_client sbl.spamhaus.org

header_checks = regexp:/usr/local/etc/postfix/header_checks
virtual_transport = dovecot
virtual_mailbox_base = /var/vmail
virtual_mailbox_domains = /usr/local/etc/postfix/virtual_domains
virtual_mailbox_maps = hash:/usr/local/etc/postfix/virtual_mailbox_maps
sendmail_path = /usr/local/sbin/sendmail

And the contents of /usr/local/etc/postfix/master.cf:
Code:
smtp      inet  n       -       n       -       -       smtpd
submission inet n       -       n       -       -       smtpd
pickup    unix  n       -       n       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
tlsmgr    unix  -       -       n       1000?   1       tlsmgr
rewrite   unix  -       -       n       -       -       trivial-rewrite
bounce    unix  -       -       n       -       0       bounce
defer     unix  -       -       n       -       0       bounce
trace     unix  -       -       n       -       0       bounce
verify    unix  -       -       n       -       1       verify
flush     unix  n       -       n       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       n       -       -       smtp
relay     unix  -       -       n       -       -       smtp
showq     unix  n       -       n       -       -       showq
error     unix  -       -       n       -       -       error
retry     unix  -       -       n       -       -       error
discard   unix  -       -       n       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil
scache    unix  -       -       n       -       1       scache


policy	unix	-	n	n	-	-	spawn
	user=nobody argv=/usr/bin/perl /usr/local/etc/postfix/postfix-spf/postfix-policyd-spf-perl


dovecot	unix	-	n	n	-	-	pipe
	flags=DRhu user=vmail:vmail argv=/usr/local/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}

The problem occurs when I try to connect to the mailserver, issue STARTTLS and supply a EHLO localhost. It looks like this when doing it manually:

Code:
# telnet localhost 587
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.OMITTED.com ESMTP
STARTTLS
220 2.0.0 Ready to start TLS
EHLO localhost
Connection closed by foreign host.

Very little information. I start by looking in /var/log/maillog to see what's going on:

Code:
# tail -13 /var/log/maillog
Nov  5 11:17:05 server postfix/smtpd[9718]: initializing the server-side TLS engine
Nov  5 11:17:05 server postfix/smtpd[9718]: connect from localhost[127.0.0.1]
Nov  5 11:17:12 server postfix/smtpd[9718]: setting up TLS connection from localhost[127.0.0.1]
Nov  5 11:17:12 server postfix/smtpd[9718]: localhost[127.0.0.1]: TLS cipher list "aNULL:-aNULL:ALL:!EXPORT:!LOW:+RC4:@STRENGTH"
Nov  5 11:17:12 server postfix/smtpd[9718]: SSL_accept:before/accept initialization
Nov  5 11:17:12 server postfix/smtpd[9718]: read from 802077320 [80220A000] (11 bytes => -1 (0xFFFFFFFFFFFFFFFF))
Nov  5 11:17:19 server postfix/smtpd[9718]: read from 802077320 [80220A000] (11 bytes => 11 (0xB))
Nov  5 11:17:19 server postfix/smtpd[9718]: 0000 45 48 4c 4f 20 6c 6f 63|61 6c 68                 EHLO loc alh
[color="Red"]Nov  5 11:17:19 server postfix/smtpd[9718]: SSL_accept:error in SSLv2/v3 read client hello A
Nov  5 11:17:19 server postfix/smtpd[9718]: SSL_accept error from localhost[127.0.0.1]: -1
Nov  5 11:17:19 server postfix/smtpd[9718]: warning: TLS library problem: 9718:error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol:s23_srvr.c:628:[/color]
Nov  5 11:17:19 server postfix/smtpd[9718]: lost connection after STARTTLS from localhost[127.0.0.1]
Nov  5 11:17:19 server postfix/smtpd[9718]: disconnect from localhost[127.0.0.1]

And this is where I'm at now. So far I have been unable to pinpoint the errors and possible fixes to these SSL errors. I have tried to recreate the self signed certificate several times (and from several guides as well).

Code:
# openssl version
OpenSSL 0.9.8y 5 Feb 2013

(This is the version provided by FreeBSD)

And here's a connection attempt via OpenSSL (I have cut out the certificate BEGIN/END, chain information etc out):
Code:
# openssl s_client -connect localhost:587 -starttls smtp
<...certificate output omitted...>
No client certificate CA names sent
---
SSL handshake has read 1862 bytes and written 372 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 0DBF3F0642A2D2155E066959C083D2B56C27563C79D74F55A76A73CDF12C370D
    Session-ID-ctx: 
    Master-Key: 202C7DB630F7ADF4EA5C81A48E47381DB0F26335A4A50C69A0D9093415F6E53D5DCE8C7180185C16563F8586C8F4B359
    Key-Arg   : None
    Start Time: 1383647097
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
250 DSN
read:errno=0

Do any of you have any ideas about what I can try to do, or have any of your also had this exact problem before? I'd appreciate any advice! If I have forgotten any information of value, please let me know.

Thanks!
Klaus
 
klaus said:
...
The problem occurs when I try to connect to the mailserver, issue STARTTLS and supply a EHLO localhost. It looks like this when doing it manually:

Code:
# telnet localhost 587
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.OMITTED.com ESMTP
STARTTLS
220 2.0.0 Ready to start TLS
EHLO localhost
Connection closed by foreign host.

Very little information. I start by looking in /var/log/maillog to see what's going on:

Code:
# tail -13 /var/log/maillog
Nov  5 11:17:05 server postfix/smtpd[9718]: initializing the server-side TLS engine
Nov  5 11:17:05 server postfix/smtpd[9718]: connect from localhost[127.0.0.1]
Nov  5 11:17:12 server postfix/smtpd[9718]: setting up TLS connection from localhost[127.0.0.1]
Nov  5 11:17:12 server postfix/smtpd[9718]: localhost[127.0.0.1]: TLS cipher list "aNULL:-aNULL:ALL:!EXPORT:!LOW:+RC4:@STRENGTH"
Nov  5 11:17:12 server postfix/smtpd[9718]: SSL_accept:before/accept initialization
Nov  5 11:17:12 server postfix/smtpd[9718]: read from 802077320 [80220A000] (11 bytes => -1 (0xFFFFFFFFFFFFFFFF))
Nov  5 11:17:19 server postfix/smtpd[9718]: read from 802077320 [80220A000] (11 bytes => 11 (0xB))
Nov  5 11:17:19 server postfix/smtpd[9718]: 0000 45 48 4c 4f 20 6c 6f 63|61 6c 68                 EHLO loc alh
[color="Red"]Nov  5 11:17:19 server postfix/smtpd[9718]: SSL_accept:error in SSLv2/v3 read client hello A
Nov  5 11:17:19 server postfix/smtpd[9718]: SSL_accept error from localhost[127.0.0.1]: -1
Nov  5 11:17:19 server postfix/smtpd[9718]: warning: TLS library problem: 9718:error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol:s23_srvr.c:628:[/color]
Nov  5 11:17:19 server postfix/smtpd[9718]: lost connection after STARTTLS from localhost[127.0.0.1]
Nov  5 11:17:19 server postfix/smtpd[9718]: disconnect from localhost[127.0.0.1]

And this is where I'm at now. So far I have been unable to pinpoint the errors and possible fixes to these SSL errors. I have tried to recreate the self signed certificate several times (and from several guides as well).

telnet is not the right tool for testing TLS, it is not SSL aware, for this reason you see the error.


klaus said:
...
And here's a connection attempt via openssl (I have cut out the certificate BEGIN/END, chain information etc out):
Code:
# openssl s_client -connect localhost:587 -starttls smtp
<...certificate output omitted...>
No client certificate CA names sent
---
SSL handshake has read 1862 bytes and written 372 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 0DBF3F0642A2D2155E066959C083D2B56C27563C79D74F55A76A73CDF12C370D
    Session-ID-ctx: 
    Master-Key: 202C7DB630F7ADF4EA5C81A48E47381DB0F26335A4A50C69A0D9093415F6E53D5DCE8C7180185C16563F8586C8F4B359
    Key-Arg   : None
    Start Time: 1383647097
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
250 DSN
read:errno=0
...

This looks good so far. You got a TLS connection to postfix smtpd, and still on the s_client CLI, you could manually continue the session, submitting EHLO, AUTH, mail-to, rcpt-from, data, etc.

In addition, I would suggest to stay with the dovecot as the smtpd_sasl_type, because this means that postfix would delegate the authentication process to Dovecot and this means that SMTP Auth is done effectively against the same user db as for your working IMAP authentication. In this case, you may clean-up the respective section of your main.cf. Only the following is necessary:
Code:
smtpd_sasl_auth_enable              = yes
smtpd_sasl_type                     = dovecot
smtpd_sasl_path                     = private/auth

Perhaps you find this HOWTO on a related subject interesting.
 
Hi roflheinrich and thanks for your reply, I'm grateful for your help!

rolfheinrich said:
telnet is not the right tool for testing TLS, it is not SSL aware, for this reason you see the error.




This looks good so far. You got a TLS connection to postfix smtpd, and still on the s_client CLI, you could manually continue the session, submitting EHLO, AUTH, mail-to, rcpt-from, data, etc.

I haven't used openssl very much, so pardon me in advance for probably asking a few rookie questions here, but the command simply terminates after the final "read:errno=0" line and not allowing me to enter further input, i.e. EHLO, etc. Could you tell me how to go interactive with the openssl s_client ... command so that I could send it further SMTP commands, i.e. EHLO localhost?

CORRECTION:
I think I know why openssl goes back to the shell. When I look in /var/log/maillog I see this:

Code:
Nov  5 15:12:16 server postfix/smtpd[14533]: initializing the server-side TLS engine
Nov  5 15:12:16 server postfix/smtpd[14533]: connect from localhost[127.0.0.1]
Nov  5 15:12:16 server postfix/smtpd[14533]: setting up TLS connection from localhost[127.0.0.1]
Nov  5 15:12:16 server postfix/smtpd[14533]: localhost[127.0.0.1]: TLS cipher list "aNULL:-aNULL:ALL:!EXPORT:!LOW:+RC4:@STRENGTH"
Nov  5 15:12:16 server postfix/smtpd[14533]: SSL_accept:before/accept initialization
Nov  5 15:12:16 server postfix/smtpd[14533]: read from 8020772B0 [80220A000] (11 bytes => 11 (0xB))
[...Lots of certificate data cut away...]
Nov  5 15:12:16 server postfix/smtpd[14533]: 003a - <SPACES/NULLS>
Nov  5 15:12:16 server postfix/smtpd[14533]: SSL_accept:SSLv3 flush data
Nov  5 15:12:16 server postfix/smtpd[14533]: Anonymous TLS connection established from localhost[127.0.0.1]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)
[color="Red"]Nov  5 15:12:16 server postfix/smtpd[14533]: fatal: no SASL authentication mechanisms[/color]

I'm going to dig into this, too.
END OF CORRECTION

I tried to change my webmail client (squirrelmail) away from SMTP:25 and over to 587 and enable Secure SMTP (TLS). Squirrelmail then points me to a .PHP file which can be used to test, and this page reports failure. The web-version of the page is useless, so I executed it manually and got this where it seemingly complains about version numbers:

Code:
root@mail:/home/www/docroot/webmail/src # php configtest.php | grep -A12 fsockopen
PHP Warning:  fsockopen(): SSL operation failed with code 1. OpenSSL Error messages:
error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number in /home/www/docroot/webmail/src/configtest.php on line 386
Warning: fsockopen(): SSL operation failed with code 1. OpenSSL Error messages:
error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number in /home/www/docroot/webmail/src/configtest.php on line 386
PHP Warning:  fsockopen(): Failed to enable crypto in /home/www/docroot/webmail/src/configtest.php on line 386

Warning: fsockopen(): Failed to enable crypto in /home/www/docroot/webmail/src/configtest.php on line 386
PHP Warning:  fsockopen(): unable to connect to tls://IP_OMITTED:587 (Unknown error) in /home/www/docroot/webmail/src/configtest.php on line 386

Warning: fsockopen(): unable to connect to tls://IP_OMITTED:587 (Unknown error) in /home/www/docroot/webmail/src/configtest.php on line 386
tls://IP_OMITTED:587
<p>&nbsp;&nbsp;&nbsp;&nbsp;<font color="red"><b>ERROR:</b></font> Error connecting to SMTP server "IP_OMITTED:587".Server error: (0) </p>
</body></html>

I think one of my primary concerns now is that I am unsure how to correctly test SMTP AUTH and that I do not know what SSL/TLS errors/warnings are caused by actual errors/misconfigurations or simply caused by lack of knowledge (i.e. testing via telnet instead of openssl)



rolfheinrich said:
In addition, I would suggest to stay with the dovecot as the smtpd_sasl_type, because this means that postfix would delegate the authentication process to Dovecot and this means that SMTP Auth is done effectively against the same user db as for your working IMAP authentication. In this case, you may clean-up the respective section of your main.cf. Only the following is necessary:
Code:
smtpd_sasl_auth_enable              = yes
smtpd_sasl_type                     = dovecot
smtpd_sasl_path                     = private/auth

Perhaps you find this HOWTO on a related subject interesting.

I will definitely be sticking to the Dovecot so that I can utilize my existing Dovecot userdatabase as SMTP authorization as well. I am certainly going to read your thread in depth tonight when I have more time, it looks very promising!
 
Okay, I sorted out the problem with the SASL authentication mechanisms below.

Code:
Nov  5 15:12:16 server postfix/smtpd[14533]: SSL_accept:SSLv3 flush data
Nov  5 15:12:16 server postfix/smtpd[14533]: Anonymous TLS connection established from localhost[127.0.0.1]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)
Nov  5 15:12:16 server postfix/smtpd[14533]: fatal: no SASL authentication mechanisms

A slight correction had to be made to my /usr/local/etc/dovecot/dovecot.conf file, more specifically I had to edit the auth_mechanisms directive to this, which works for now:

Code:
# grep mech /usr/local/etc/dovecot/dovecot.conf 
auth_mechanisms = plain login cram-md5 digest-md5

After this, I was able to interact with a connection by using OpenSSL.

My webmail client, Squirrelmail, does however not work at all (same errors as I pasted in a previous posting in this thread) when I change SMTP:25 to SMTP:587 and enable TLS. As far as I can see it could possibly hint a coding issue when you read http://php.net/manual/en/transports.inet.php, but I have no real proof of that, it's merely a guess at this point and I'm probably going to try an alternative when I arrive home later.

At least, OpenSSL is working, that's a start, and big thanks to you Rolf for getting me this far until now ;)

EDIT:
I'm marking this solved as the root problem has been explained and verified. Big thanks to Rolf!
 
Back
Top