Simple Troubleshooting For SMTP Via Telnet And Openssl: Difference between revisions
No edit summary |
mNo edit summary |
||
Line 534: | Line 534: | ||
{{NeedSME|SME1|SME2|Copyeditor}} | {{NeedSME|SME1|SME2|Copyeditor}} | ||
[[Category: Author:Ajcody]] | [[Category: Author:Ajcody]] | ||
[[Category: Zeta Alliance]] |
Revision as of 20:18, 7 June 2016
Simple Troubleshooting For SMTP Via Telnet And Openssl
Purpose
Simple Troubleshooting For SMTP Via Telnet And Openssl
Resolution
First - Understanding Your Authentication Requirements In ZCS
In the admin console, under the MTA tab, you see two options:
- Enable Authentication
- Attribute Name = zimbraMtaSaslAuthEnable [yes or no]
- zmprov gacf zimbraMtaSaslAuthEnable or zmprov gs `zmhostname` zimbraMtaSaslAuthEnable
- Description = Value for postconf : smtpd_sasl_auth_enable = yes
- Attribute Name = zimbraMtaSaslAuthEnable [yes or no]
- TLS Authentication Only
- Attribute Name = zimbraMtaTlsAuthOnly [TRUE or FALSE]
- zmprov gacf zimbraMtaTlsAuthOnly or zmprov gs `zmhostname` zimbraMtaTlsAuthOnly
- Description Value for postconf : smtpd_tls_auth_only = yes
- Attribute Name = zimbraMtaTlsAuthOnly [TRUE or FALSE]
A good reference to understanding exactly what these options mean and do is the SASL_READ at the postfix.org site. I'll include the highlights below.
When you do the telnet test below and issue the EHLO state, you'll see a return that states [example]:
esx2:~ ajcody$ telnet zcs723.EXAMPLE.com 25 Trying 10.137.27.32... Connected to zcs723.EXAMPLE.com. Escape character is '^]'. 220 zcs723.EXAMPLE.com ESMTP Postfix helo myworkstation 250 zcs723.EXAMPLE.com ehlo myworkstation 250-zcs723.EXAMPLE.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-STARTTLS 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN
When you check, "Enable Authentication" [remember its specific to SASL] in the admin console and reload postfix you will then see the AUTH line when you do the telnet test above and AUTH will say LOGIN and PLAIN. AUTH supports a number of different types of protocols: PLAIN LOGIN DIGEST-MD5 CRAM-MD5 GSSAPI. Zimbra only supports the use of LOGIN and PLAIN though.
What is LOGIN and PLAIN and the difference?
--enable-login You wish to support the Outlook Express 5.x client, which uses the non-standard, undocumented LOGIN protocol. Passwords are passed over the wire in the clear. This is disabled by default. --disable-plain Do not use the PLAIN protocol, which sends the password in plaintext. This is enabled by default and should only be used for testing unless you are encrypting the session via TLS, IPsec, or other mechanism.
So, the above might be alarming. The postfix SASL_README gives us some context though, "Plaintext mechanisms (PLAIN, LOGIN) send credentials unencrypted. This information should be protected by an additional security layer such as a TLS-encrypted SMTP session (see: TLS_README)." Also note, both PLAIN and LOGIN use BASE64 encoding of the username and password but those strings can be ran through a mime-decoder to discover what they are. You see this in my telnet examples below.
The other variable/options for the "Postfix SMTP Server policy - SASL mechanism properties" you will need to know about are:
- /opt/zimbra/postfix/conf/main.cf
- smtpd_sasl_security_options =
- smtpd_sasl_tls_security_options = [note, this can reuse smtpd_sasl_security_options with $smtpd_sasl_security_options]
- noanonymous Don't use mechanisms that permit anonymous authentication.
- Always set at least the noanonymous option. Otherwise, the Postfix SMTP server can give strangers the same authorization as a properly-authenticated client.
- noplaintext Don't use mechanisms that transmit unencrypted username and password information.
- nodictionary Don't use mechanisms that are vulnerable to dictionary attacks.
- forward_secrecy Require forward secrecy between sessions (breaking one session does not break earlier sessions).
- mutual_auth Use only mechanisms that authenticate both the client and the server to each other.
- noanonymous Don't use mechanisms that permit anonymous authentication.
Mail relay authorization options to know are: [From the SASL_READ] With permit_sasl_authenticated the Postfix SMTP server can allow SASL-authenticated SMTP clients to send mail to remote destinations. Examples:
# With Postfix 2.10 and later, the mail relay policy is # preferably specified under smtpd_relay_restrictions. /opt/zimbra/postfix/conf/main.cf: smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination # Older configurations combine relay control and spam control under # smtpd_recipient_restrictions. To use this example with Postfix ≥ # 2.10 specify "smtpd_relay_restrictions=". /opt/zimbra/postfix/conf/main.cf: smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination ...other rules...
Envelope sender address authorization options: [From the SASL_READ] By default an SMTP client may specify any envelope sender address in the MAIL FROM command. That is because the Postfix SMTP server only knows the remote SMTP client hostname and IP address, but not the user who controls the remote SMTP client.
This changes the moment an SMTP client uses SASL authentication. Now, the Postfix SMTP server knows who the sender is. Given a table of envelope sender addresses and SASL login names, the Postfix SMTP server can decide if the SASL authenticated client is allowed to use a particular envelope sender address:
/opt/zimbra/postfix/conf/main.cf: virtual_mailbox_maps = proxy:ldap:/opt/zimbra/conf/ldap-vmm.cf smtpd_sender_login_maps = $virtual_mailbox_maps smtpd_recipient_restrictions = ... reject_sender_login_mismatch permit_sasl_authenticated ...
The controlled_envelope_senders table specifies the binding between a sender envelope address and the SASL login names that own that address [see above, ZCS will have in main.cf a line showing virtual_mailbox_maps = proxy:ldap:/opt/zimbra/conf/ldap-vmm.cf]:
/opt/zimbra/conf/ldap-vmm.cf server_host = ldap://zcs723.EXAMPLE.com:389 server_port = 389 search_base = query_filter = (&(zimbraMailDeliveryAddress=%s)(zimbraMailStatus=enabled)) result_attribute = zimbraMailDeliveryAddress version = 3 start_tls = yes tls_ca_cert_dir = /opt/zimbra/conf/ca bind = yes bind_dn = uid=zmpostfix,cn=appaccts,cn=zimbra bind_pw = XXXXXXXXXXX timeout = 30
A default postfix install [non-ZCS] might have something like:
/etc/postfix/controlled_envelope_senders # envelope sender owners (SASL login names) john@example.com john@example.com helpdesk@example.com john@example.com, mary@example.com postmaster admin@example.com @example.net barney, fred, john@example.com, mary@example.com
With this, the reject_sender_login_mismatch restriction above will reject the sender address in the MAIL FROM command if smtpd_sender_login_maps does not specify the SMTP client's login name as an owner of that address.
See also reject_authenticated_sender_login_mismatch and reject_unauthenticated_sender_login_mismatch for additional control over the SASL login name and the envelope sender.
Second - Encoding Username And Passwords For AUTH Sequence
Here is an example of getting the base64 encoding for a username and also how to check if the encoding was correct. This might expose how special characters threw off the encoding.
[USERNAME EXAMPLE - If you use the domainname, you'll have to \ the @] # perl -MMIME::Base64 -le 'print encode_base64("ajcody\@zcs723.EXAMPLE.com");' YWpjb2R5QHpjczcyMy5FWEFNUExFLmNvbQ== # perl -MMIME::Base64 -le 'print decode_base64("YWpjb2R5QHpjczcyMy5FWEFNUExFLmNvbQ==");' ajcody@zcs723.EXAMPLE.com [PASSWORD EXAMPLE] # perl -MMIME::Base64 -le 'print encode_base64("MySimplePa33");' TXlTaW1wbGVQYTMz # perl -MMIME::Base64 -le 'print decode_base64("TXlTaW1wbGVQYTMz");' MySimplePa33 [USERNAME And PASSWORD - For Auth PLAIN. The \000 is for a space .] # perl -MMIME::Base64 -le 'print encode_base64("ajcody\@zcs723.EXAMPLE.com\000MySimplePa33");' YWpjb2R5QHpjczcyMy5FWEFNUExFLmNvbQBNeVNpbXBsZVBhMzM= # perl -MMIME::Base64 -le 'print decode_base64("YWpjb2R5QHpjczcyMy5FWEFNUExFLmNvbQBNeVNpbXBsZVBhMzM=");' ajcody@zcs723.EXAMPLE.comMySimplePa33
For ESMTP Auth is LOGIN - Example
If you are using TLS you will need to encrypt your username & password before transiting it.
For Auth is LOGIN you'll need to get the login encoding as described above. When AUTH is Login, it requires username and password to be separate :
For example [I've mangled the hash below by the way]:
perl -MMIME::Base64 -e 'print encode_base64("ajcody\@zcs723.EXAMPLE.com");' YYYYYYY5QHpjczcyMy51cy56aW1icmFsYWIuY29t perl -MMIME::Base64 -e 'print encode_base64("Somepasswd");' YYYYYYYkMW0=
The working example now using telnet:
esx2:~ ajcody$ telnet zcs723.EXAMPLE.com 25 Trying 10.137.27.32... Connected to zcs723.EXAMPLE.com. Escape character is '^]'. 220 zcs723.EXAMPLE.com ESMTP Postfix helo myworkstation 250 zcs723.EXAMPLE.com ehlo myworkstation 250-zcs723.EXAMPLE.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-STARTTLS 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH LOGIN 334 VXNlcm5hbWU6 YYYYYYY5QHpjczcyMy51cy56aW1icmFsYWIuY29t 334 UGFzc3dvcmQ6 YYYYYYYkMW0= 235 2.7.0 Authentication successful mail from: <ajcody@zcs723.EXAMPLE.com> 250 2.1.0 Ok rcpt to: <ajcody2@zcs723.EXAMPLE.com> 250 2.1.5 Ok data 354 End data with <CR><LF>.<CR><LF> From: Adam <ajcody@zcs723.EXAMPLE.com> To: Adam 2 <ajcody2@zcs723.EXAMPLE.com> Subject: Test ESMTP Auth LOGIN testing . 250 2.0.0 Ok: queued as 361C11E78D1 quit 221 2.0.0 Bye Connection closed by foreign host.
For ESMTP Auth is Plain - Example
If you are using TLS you will need to encrypt your username & password before transiting it.
When AUTH is PLAIN, the username and password will be in the same encoding. For example [I've mangled the hash below by the way]:
perl -MMIME::Base64 -e 'print encode_base64("\000ajcody\@zcs723.EXAMPLE.com\000mypassword");' AGFqY29keUB6Y3M3MjMXXXXXXXXXXXXXXXXXX5MzkzMWQxbQ==
The working example now using telnet:
esx2:~ ajcody$ telnet zcs723.EXAMPLE.com 25 Trying 10.137.27.32... Connected to zcs723.EXAMPLE.com. Escape character is '^]'. 220 zcs723.EXAMPLE.com ESMTP Postfix helo myworkstation 250 zcs723.EXAMPLE.com ehlo myworkstation 250-zcs723.EXAMPLE.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-STARTTLS 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH PLAIN AGFqY29keUB6Y3M3MjMXXXXXXXXXXXXXXXXXX5MzkzMWQxbQ== 235 2.7.0 Authentication successful mail from: <ajcody@zcs723.EXAMPLE.com> 250 2.1.0 Ok rcpt to: <ajcody2@zcs723.EXAMPLE.com> 250 2.1.5 Ok data 354 End data with <CR><LF>.<CR><LF> From: Adam <ajcody@zcs723.EXAMPLE.com> To: Adam 2 <ajcody2@zcs723.EXAMPLE.com> Subject: Test ESMTP Auth PLAIN testing . 250 2.0.0 Ok: queued as 804E01E78D1 quit 221 2.0.0 Bye Connection closed by foreign host.
For TLS/SSL - Example
Basic telnet does not support SSL or TLS, so you have to use openssl or stunnel to make your connection to the smtp server. To connect to a server using TLS/SSL run something like this:
openssl s_client -starttls smtp -crlf -connect zcs723.EXAMPLE.com:25
Now you can run one of the above telnet sessions like you had before. You will most likely still need to log in.
Default zimbra ports to be aware of and test:
- port 25
- smtp [mta] - incoming mail to postfix
- port 465
- smtps [mta] - incoming mail to postfix over ssl (Outlook only)
- port 587
- smtp [mta] - Mail submission port over tls
- "RFC 3207 specifies only the well-known port 25 and the "Submission port," which is TCP port 587, for the STARTTLS command, the precursor for an encrypted SMTP session using TLS. It makes no mention of the unofficial port 465." SMTP on Wikipedia
An example login is below :
esx2:~ ajcody$ openssl s_client -starttls smtp -crlf -connect zcs723.EXAMPLE.com:25 CONNECTED(00000003) depth=0 /C=US/ST=N/A/O=Zimbra Collaboration Suite/OU=Zimbra Collaboration Suite/CN=zcs723.EXAMPLE.com verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 /C=US/ST=N/A/O=Zimbra Collaboration Suite/OU=Zimbra Collaboration Suite/CN=zcs723.EXAMPLE.com verify error:num=27:certificate not trusted verify return:1 depth=0 /C=US/ST=N/A/O=Zimbra Collaboration Suite/OU=Zimbra Collaboration Suite/CN=zcs723.EXAMPLE.com verify error:num=21:unable to verify the first certificate verify return:1 --- Certificate chain 0 s:/C=US/ST=N/A/O=Zimbra Collaboration Suite/OU=Zimbra Collaboration Suite/CN=zcs723.EXAMPLE.com i:/C=US/ST=N/A/L=N/A/O=Zimbra Collaboration Suite/OU=Zimbra Collaboration Suite/CN=zcs723.EXAMPLE.com --- Server certificate -----BEGIN CERTIFICATE----- MIICsjCCAhugAwIBAgIFE2MYV2EwDQYJKoZIhvcNAQEFBQAwgZUxCzAJBgNVBAYT [cut] LrFtuUlX6mb5Uq8dx8D25QWqsyeDXA== -----END CERTIFICATE----- subject=/C=US/ST=N/A/O=Zimbra Collaboration Suite/OU=Zimbra Collaboration Suite/CN=zcs723.EXAMPLE.com issuer=/C=US/ST=N/A/L=N/A/O=Zimbra Collaboration Suite/OU=Zimbra Collaboration Suite/CN=zcs723.EXAMPLE.com --- No client certificate CA names sent --- SSL handshake has read 1528 bytes and written 360 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 1024 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: 06F03A7C2AB0EA3E97cut7CD4A4A6166D551B Session-ID-ctx: Master-Key: 1A2FF452C3E09F9D7B2DECEcutFB67158960BA6 Key-Arg : None Start Time: 1370375286 Timeout : 300 (sec) Verify return code: 21 (unable to verify the first certificate) --- 250 DSN helo myworkstation 250 zcs723.EXAMPLE.com ehlo myworkstation 250-zcs723.EXAMPLE.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH LOGIN 334 VXNlcm5hbWU6 YYYYYYY5QHpjczcyMy51cy56aW1icmFsYWIuY29t 334 UGFzc3dvcmQ6 YYYYYYYkMW0= 235 2.7.0 Authentication successful mail from:<ajcody@zcs723.EXAMPLE.com> 250 2.1.0 Ok rcpt to: <ajcody2@zcs723.EXAMPLE.com> 250 2.1.5 Ok data 354 End data with <CR><LF>.<CR><LF> From: Adam <ajcody@zcs723.EXAMPLE.com> To: Adam 2 <ajcody2@zcs723.EXAMPLE.com> Subject: Test Auth LOGIN TLS Example test . 250 2.0.0 Ok: queued as BA68B1E78D1 quit 221 2.0.0 Bye closed
Testing Against Port 465
References on Port 465:
$ openssl s_client -crlf -connect zcs723.EXAMPLE.com:465 CONNECTED(00000003) [cut of repeated data above] --- 250 DSN helo myworkstation 250 zcs723.EXAMPLE.com ehlo myworkstation 250-zcs723.EXAMPLE.com 250-PIPELINING 250-SIZE 8388608 250-VRFY 250-ETRN 250-AUTH PLAIN LOGIN 250-AUTH=PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH PLAIN [cut - emailaddress/password string goes here] !!! note - you get the auth plain string by doing [don't remove the \000 parts]: !!! perl -MMIME::Base64 -e 'print encode_base64("\000user\@mdomain.com\000your_password");' 235 2.7.0 Authentication successful mail from:<ajcody@zcs723.EXAMPLE.com> 250 2.1.0 Ok rcpt to: <ajcody2@zcs723.EXAMPLE.com> 250 2.1.5 Ok data 354 End data with <CR><LF>.<CR><LF> From: Adam <ajcody@zcs723.EXAMPLE.com> To: Adam 2 <ajcody2@zcs723.EXAMPLE.com> Subject: Test Auth LOGIN TLS Example test . 250 2.0.0 Ok: queued as BA68B1E78D1 quit 221 2.0.0 Bye closed
Example of logs events in /var/log/zimbra.log on the mta server [different test from the one above]:
Jun 7 08:28:52 zcs806 postfix/smtps/smtpd[8151]: connect from unknown[10.X.X.110] Jun 7 08:28:52 zcs806 postfix/smtps/smtpd[8151]: Anonymous TLS connection established from unknown[10.1X.X.110]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) Jun 7 08:31:53 zcs806 saslauthd[3317]: zmauth: authenticating against elected url https://zcs806.us.DOMAIN.com:7071/service/admin/soap/' ... Jun 7 08:31:53 zcs806 saslauthd[3317]: zmpost: url='https://zcs806.us.DOMAIN.com:7071/ service/admin/soap/' returned buffer->data='<soap:Envelope xmlns:soap=" http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"> <change token="75599"/></context></soap:Header><soap:Body><AuthResponse xmlns="urn:zimbraAccount"><authToken>0_b47233e5e226eb1c0519cd9c35da2fc198f[cut]272 613b</authToken><lifetime>172800000</lifetime><skin>serenity</skin></AuthResponse> </soap:Body></soap:Envelope>', hti->error='' Jun 7 08:31:53 zcs806 saslauthd[3317]: auth_zimbra: admin@zcs806.us.DOMAIN.com auth OK Jun 7 08:32:47 zcs806 postfix/smtps/smtpd[8151]: 0279C3434: client=unknown[10.X.X.110], sasl_method=PLAIN, sasl_username=admin@zcs806.us.DOMAIN.com Jun 7 08:33:32 zcs806 postfix/qmgr[3484]: 0279C3434: from=<admin@zcs806.us.DOMAIN.com>, size=400, nrcpt=1 (queue active) Jun 7 08:33:33 zcs806 postfix/dkimmilter/smtpd[9661]: connect from localhost[127.0.0.1] Jun 7 08:33:33 zcs806 postfix/dkimmilter/smtpd[9661]: Anonymous TLS connection established from localhost[127.0.0.1]: TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits) Jun 7 08:33:33 zcs806 postfix/dkimmilter/smtpd[9661]: 0F798344C: client=localhost[127.0.0.1] Jun 7 08:33:33 zcs806 postfix/cleanup[9638]: 0F798344C: message-id=<20140607153247.0279C3434@DOMAIN.com> Jun 7 08:33:33 zcs806 postfix/smtp[9660]: 0279C3434: to=<test@zcs806.us.DOMAIN.com>, relay=127.0.0.1[127.0.0.1]:10030, delay=63, delays=63/0.06/0.07/0.07, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 0F798344C) Jun 7 08:33:33 zcs806 postfix/dkimmilter/smtpd[9661]: disconnect from localhost[127.0.0.1] Jun 7 08:33:33 zcs806 postfix/qmgr[3484]: 0F798344C: from=<admin@zcs806.us.DOMAIN.com>, size=627, nrcpt=1 (queue active) Jun 7 08:33:33 zcs806 postfix/qmgr[3484]: 0279C3434: removed Jun 7 08:33:38 zcs806 postfix/smtps/smtpd[8151]: disconnect from unknown[10.X.X.110]
To Confirm An Auth User Can't Send With Another FROM Address
The below example is using an auth has for ajcody@zcs723.EXAMPLE.com .
esx2:~ ajcody$ telnet zcs723.EXAMPLE.com 25 Trying 10.137.27.32... Connected to zcs723.EXAMPLE.com. Escape character is '^]'. 220 zcs723.EXAMPLE.com ESMTP Postfix helo myworkstation 250 zcs723.EXAMPLE.com ehlo myworkstation 250-zcs723.EXAMPLE.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-STARTTLS 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH PLAIN AGFqY29[cut]bQA5MzkzMWQxbQ== 235 2.7.0 Authentication successful mail from: <admin@zcs723.EXAMPLE.com> 250 2.1.0 Ok rcpt to: <ajcody2@zcs723.EXAMPLE.com> 553 5.7.1 <admin@zcs723.EXAMPLE.com>: Sender address rejected: not owned by user ajcody@zcs723.EXAMPLE.com
Notice how this is different when I'm telnet'ing from the server [localhost] back to itself.
[root@zcs723 ~]# telnet localhost 25 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 zcs723.EXAMPLE.com ESMTP Postfix helo myworkstation 250 zcs723.EXAMPLE.com ehlo myworkstation 250-zcs723.EXAMPLE.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-STARTTLS 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH PLAIN AGFqY29kAAAAAAAAAAAAAAAAAAAAAAAmNvbQA5MzkzMWQxbQ== 235 2.7.0 Authentication successful mail from: <admin@zcs723.EXAMPLE.com> 250 2.1.0 Ok rcpt to: <ajcody2@zcs723.EXAMPLE.com> 250 2.1.5 Ok Subject: Test mynetwork bypasses From match to AUTH 221 2.7.0 Error: I can break rules, too. Goodbye. Connection closed by foreign host.
Additional Content
- No related content.