You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by "Benoit Tellier (Jira)" <se...@james.apache.org> on 2021/09/13 01:27:00 UTC

[jira] [Closed] (JAMES-3645) RemoteDelivery sslEnable parameter have no effect

     [ https://issues.apache.org/jira/browse/JAMES-3645?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Benoit Tellier closed JAMES-3645.
---------------------------------
    Fix Version/s: 3.7.0
       Resolution: Fixed

https://github.com/apache/james-project/pull/632 fixed this.

> RemoteDelivery sslEnable parameter have no effect
> -------------------------------------------------
>
>                 Key: JAMES-3645
>                 URL: https://issues.apache.org/jira/browse/JAMES-3645
>             Project: James Server
>          Issue Type: Improvement
>            Reporter: Benoit Tellier
>            Priority: Major
>             Fix For: 3.7.0
>
>          Time Spent: 1h 10m
>  Remaining Estimate: 0h
>
> h3. Description
> As an administrator I wish to secure my outgoing emails using SSL (SMTPS on port 465), and default to SMTP on port 25 (where STARTTLS can be used opportunistically).
> This need is a recurring one for Gitter users (often asked, known for years to be buggy).
> h3. Setting up test James servers
> I did write a simple docker-compose.yml file to experiment this:
> {code:java}
> version: '3'
> services:
>   james1:
>     image: apache/james:memory-latest
>     container_name: james1
>     hostname: james1
>     volumes:
>       - $PWD/keystore:/root/conf/keystore
>   james2:
>     image: apache/james:memory-latest
>     container_name: james2
>     hostname: james2
>     volumes:
>       - $PWD/keystore:/root/conf/keystore
> {code}
> I do embed two RcptHooks to diagnose where remoteDelivery connects on james2:
> {code:java}
> package org.apache.james;
> import org.apache.james.core.MailAddress;
> import org.apache.james.core.MaybeSender;
> import org.apache.james.protocols.smtp.SMTPSession;
> import org.apache.james.protocols.smtp.hook.HookResult;
> import org.apache.james.protocols.smtp.hook.RcptHook;
> public class SoutRcptHook implements RcptHook {
>     @Override
>     public HookResult doRcpt(SMTPSession session, MaybeSender sender, MailAddress rcpt) {
>         System.out.println("  <---> SSL activated: " + sender.asPrettyString() + " sends a message securely to " + rcpt.asString());
>         return HookResult.DECLINED;
>     }
> {code}
> And
> {code:java}
> package org.apache.james;
> import org.apache.james.core.MailAddress;
> import org.apache.james.core.MaybeSender;
> import org.apache.james.protocols.smtp.SMTPSession;
> import org.apache.james.protocols.smtp.hook.HookResult;
> import org.apache.james.protocols.smtp.hook.RcptHook;
> public class NoSSLRcptHook implements RcptHook {
>     @Override
>     public HookResult doRcpt(SMTPSession session, MaybeSender sender, MailAddress rcpt) {
>         System.out.println("  <---> NO SSL: " + sender.asPrettyString() + " sends a message securely to " + rcpt.asString());
>         return HookResult.DECLINED;
>     }
> }
> {code}
> Which then ellows configuring the SMTP server:
> {code:java}
> <smtpservers>
>     <smtpserver enabled="true">
>         <jmxName>smtpserver-global</jmxName>
>         <bind>0.0.0.0:25</bind>
>         <tls socketTLS="false" startTLS="true">
>             <keystore>file://conf/keystore</keystore>
>             <secret>james72laBalle</secret>
>             <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>             <algorithm>SunX509</algorithm>
>         </tls>
>         <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
>         <handlerchain>
>             <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
>             <handler class="org.apache.james.NoSSLRcptHook"/>
>         </handlerchain>
>     </smtpserver>
>     <smtpserver enabled="true">
>         <jmxName>smtpserver-TLS</jmxName>
>         <bind>0.0.0.0:465</bind>
>         <tls socketTLS="true" startTLS="false">
>             <keystore>file://conf/keystore</keystore>
>             <secret>james72laBalle</secret>
>             <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>             <algorithm>SunX509</algorithm>
>         </tls>
>         <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
>         <handlerchain>
>             <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
>             <handler class="org.apache.james.SoutRcptHook"/>
>         </handlerchain>
>     </smtpserver>
> </smtpservers>
> {code}
> We then can review logs to know which port was eventually used to receive emails (smtp logs also tells us if STARTTLS is used).
> I expect `sslEnable` parameter to govern this opportunistic SSL connection. Thus RemoteDelivery configuration looks like this:
> {code:java}
>         <processor state="relay" enableJmx="true">
>             <mailet match="All" class="RemoteDelivery">
>                 <outgoingQueue>outgoing</outgoingQueue>
>                 <bounceProcessor>bounces</bounceProcessor>
>                 <debug>true</debug>
>                 <mail.smtp.ssl.trust>*</mail.smtp.ssl.trust>
>                 <sslEnable>true</sslEnable>
>                 <startTLS>true</startTLS>
>             </mailet>
>         </processor>
> {code}
> We then can create some test data and send a mail from james1 to james2:
> {code:java}
> docker-compose up -d
> docker exec james1 james-cli adddomain james1
> docker exec james2 james-cli adddomain james2
> docker exec james1 james-cli adduser bob@james1 123456
> docker exec james2 james-cli adduser bob@james2 123456
> docker inspect james1
> telnet [james1] 25
> auth login
> Ym9iQGphbWVzMQ==
> MTIzNDU2
> ehlo james1
> mail from: <bo...@james1>
> rcpt to: <bo...@james2>
> data
> Subject: rueooerwbwerb
> veriobwerobwerbr
> rwebeberber
> .
> {code}
> Will generate james1 to remote-deliver a mail to james2, and we can in the process diagnose the remote delivery behaviour between the two.
> h3. Actual behaviour
> james1 attepts an SSL connection on port 25:
> {code:java}
> james1    | 06:56:43.405 [DEBUG] o.a.j.t.m.r.d.MailDelivrer - Could not connect to SMTP host: 172.30.0.2, port: 25
> james1    | javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
> james1    |     at java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:451)
> james1    |     at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:175)
> james1    |     at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:110)
> james1    |     at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
> james1    |     at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
> james1    |     at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
> james1    |     at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
> james1    |     at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:626)
> james1    |     at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:400)
> james1    |     at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
> james1    |     at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
> james1    |     at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
> {code}
> And james2 do not recognizes the commands:
> {code:java}
> james2    | 06:56:43.410 [DEBUG] o.a.j.p.a.h.CommandDispatcher - org.apache.james.protocols.api.handler.CommandDispatcher received: ZVVF�������E�F�8T�E'F��LO��#���
> james2    | 06:56:43.411 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command handler for command: ZVVF�������E�F�8T�E'F��LO��#���
> james2    | 06:56:43.437 [DEBUG] o.a.j.p.a.h.CommandHandlerResultLogger - org.apache.james.protocols.smtp.core.UnknownCmdHandler: [500 5.5.1 Command ZVVF�������E�F�8T�E'F��LO��#��� unrecognized.]
> james2    | 06:56:43.441 [DEBUG] o.a.j.p.a.h.CommandDispatcher - org.apache.james.protocols.api.handler.CommandDispatcher received: �5��98�#�'<�%�)G@�  �/��32��
> james2    | 06:56:43.442 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command handler for command: �5��98�#�'<�%�)G@� �/��32��
> james2    | 06:56:43.442 [DEBUG] o.a.j.p.a.h.CommandHandlerResultLogger - org.apache.james.protocols.smtp.core.UnknownCmdHandler: [500 5.5.1 Command �5��98�#�'<�%�)G@� �/��32�� unrecognized.]
> james2    | 06:56:43.443 [DEBUG] o.a.j.p.a.h.CommandDispatcher - org.apache.james.protocols.api.handler.CommandDispatcher received: ,*
> james2    | 06:56:43.443 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command handler for command: ,*
> {code}
> h3. Expected behaviour
> We expect the mail to be sent over SSL.
> We expect that if the target host do not support SSL on port 465 that we fallback to SMTP on port 25, and use STARTTLS.
> h3. Interesting notice
>  * MXHostAddressIterator is adding the protocol (smtp VS smtps) and the port (25 VS 465). While  setting these values according to SMTPS & 465 SSL is correctly performed.
> The management of the fallback behavior however requires a fallback host address to be generated (SMTP + 25 after the SMTPS one), and also requires handling down the line in MailDelivrerToHost (use of two sessions, one for SMTP, one for SMTPS).
>  * The use of self signed certificates for the distant server when using remoteDelivery :
> {code:java}
> <jvmFlag>-Djavax.net.ssl.trustStore=/root/conf/keystore</jvmFlag>
> {code}
>  * Fallback can be tested by disactivating the SSL SMTP port:
> {code:java}
> <smtpservers>
>     <smtpserver enabled="true">
>         <jmxName>smtpserver-global</jmxName>
>         <bind>0.0.0.0:25</bind>
>         <tls socketTLS="false" startTLS="true">
>             <keystore>file://conf/keystore</keystore>
>             <secret>james72laBalle</secret>
>             <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>             <algorithm>SunX509</algorithm>
>         </tls>
>         <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
>         <handlerchain>
>             <handler class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
>             <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
>             <handler class="org.apache.james.NoSSLRcptHook"/>
>         </handlerchain>
>     </smtpserver>
>     <smtpserver enabled="false">
>         <jmxName>smtpserver-TLS</jmxName>
>         <bind>0.0.0.0:465</bind>
>         <tls socketTLS="true" startTLS="false">
>             <keystore>file://conf/keystore</keystore>
>             <secret>james72laBalle</secret>
>             <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>             <algorithm>SunX509</algorithm>
>         </tls>
>         <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
>         <handlerchain>
>             <handler class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
>             <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
>             <handler class="org.apache.james.SoutRcptHook"/>
>         </handlerchain>
>     </smtpserver>
> </smtpservers>
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org