12 Replies Latest reply on Jun 27, 2014 11:02 AM by Justin Bertram

    SSL

    Justin Bertram Master

      I was looking through the documentation and the code to figure out how to configure one-way SSL security using self-signed certs.  In general this requires a self-signed certificate on the server stored in a keystore and a trust-store on the client into which the server's certificate has been imported.  It shouldn't require a truststore on the server or a keystore on the client.  This is the simplest and probably most common SSL use-case.  However, this doesn't appear possible with current implementation because:

       

      1. If you configure Netty SSL connector/acceptor pair the server won't start unless you define a trust-store on the acceptor.  Here's the configuration:

       

            <acceptor name="netty-ssl">

               <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>

               <param key="host" value="localhost"/>

               <param key="port" value="5500"/>

               <param key="ssl-enabled" value="true"/>

               <param key="key-store-path" value="hornetq.example.keystore"/>

               <param key="key-store-password" value="hornetqexample"/>

            </acceptor>

       

      And here's the exception:

       

      11:43:33,381 SEVERE [org.hornetq.core.server.impl.HornetQServerImpl] (MSC service thread 1-4) Failure in initialisation: java.lang.IllegalStateException: Unable to create NettyAcceptor for localhost:5500

                at org.hornetq.core.remoting.impl.netty.NettyAcceptor.start(NettyAcceptor.java:344) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.remoting.server.impl.RemotingServiceImpl.start(RemotingServiceImpl.java:240) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.server.impl.HornetQServerImpl.initialisePart2(HornetQServerImpl.java:1495) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.server.impl.HornetQServerImpl.access$1200(HornetQServerImpl.java:138) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.server.impl.HornetQServerImpl$SharedStoreLiveActivation.run(HornetQServerImpl.java:1919) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.server.impl.HornetQServerImpl.start(HornetQServerImpl.java:366) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.jms.server.impl.JMSServerManagerImpl.start(JMSServerManagerImpl.java:277) [hornetq-jms-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.jboss.as.messaging.jms.JMSService.start(JMSService.java:73) [jboss-as-messaging-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]

                at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA-redhat-1.jar:1.0.2.GA-redhat-1]

                at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA-redhat-1.jar:1.0.2.GA-redhat-1]

                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_13]

                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_13]

                at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_13]

      Caused by: java.lang.Exception: Failed to find a store at hornetq.truststore

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.validateStoreURL(SSLSupport.java:200) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.loadKeystore(SSLSupport.java:145) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.loadTrustManager(SSLSupport.java:129) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.createServerContext(SSLSupport.java:64) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                at org.hornetq.core.remoting.impl.netty.NettyAcceptor.start(NettyAcceptor.java:340) [hornetq-core-2.2.16.Final-redhat-1.jar:2.2.16.Final (HQ_2_2_16_FINAL, 122)]

                ... 12 more

       

       

      1. If you go ahead and define a trust-store on the acceptor the server will start, but the client will fail unless you define a keystore on the connector.  Here's the configuration I tried:

       

            <connector name="netty-ssl">

               <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>

               <param key="host" value="localhost"/>

               <param key="port" value="5500"/>

               <param key="ssl-enabled" value="true"/>

            </connector>

       

      And here's the exception on the client:

       

      WARNING: connector.create or connectorFactory.createConnector should never throw an exception, implementation is badly behaved, but we'll deal with it anyway.

      java.lang.IllegalStateException: Unable to create NettyConnector for localhost

                at org.hornetq.core.remoting.impl.netty.NettyConnector.start(NettyConnector.java:342)

                at org.hornetq.core.client.impl.ClientSessionFactoryImpl.getConnection(ClientSessionFactoryImpl.java:1136)

                at org.hornetq.core.client.impl.ClientSessionFactoryImpl.getConnectionWithRetry(ClientSessionFactoryImpl.java:993)

                at org.hornetq.core.client.impl.ClientSessionFactoryImpl.connect(ClientSessionFactoryImpl.java:224)

                at org.hornetq.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:747)

                at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:601)

                at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:119)

                at com.redhat.example.jms.PlainMessageSender.main(PlainMessageSender.java:22)

                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                at java.lang.reflect.Method.invoke(Method.java:601)

                at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

      Caused by: java.lang.Exception: Failed to find a store at hornetq.keystore

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.validateStoreURL(SSLSupport.java:200)

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.loadKeystore(SSLSupport.java:145)

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.loadKeyManagers(SSLSupport.java:168)

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.createClientContext(SSLSupport.java:73)

                at org.hornetq.core.remoting.impl.ssl.SSLSupport.getInstance(SSLSupport.java:87)

                at org.hornetq.core.remoting.impl.netty.NettyConnector.start(NettyConnector.java:337)

                ... 12 more

       

      1. There no way to define a trust-store on the client.  The connector doesn't support "trust-store-path" or "trust-store-password" parameters, and it doesn't obey the universal "javax.net.ssl.trustStore" and "trustStorePassword" Java system properties either.

       

      As noted previously, I don't believe either of these artifacts should be required for this use-case.  As I understand it, a server-side truststore and a client-side keystore should only be required when performing 2-way SSL (i.e. mutual authentication).  We should definitely support 2-way SSL, but that support shouldn't complicate the configuration for 1-way SSL.

       

      I can do the work to implement this, but I wanted to make sure my understanding here is correct on all points.