4 Replies Latest reply on Nov 4, 2016 12:12 PM by Justas D

    Wildfly 10 JMS bridge over HTTPS configuration issues

    Justas D Newbie

      Hey, I have working JMS bridge over HTTP, but I need it to be secure.

       

      I faced some challenges:

      • when connecting to remote ip, remote server returns its local hostname and next client connections to the server fails, because of now client connects to the  hostname, which is unreachable. For now, I added hostname to hosts file - no longer this strange issue.
      • on client http-connector trust-store-path does not work - javax.net.ssl.trustStore does
      • failed to open server undertow index page with browser (ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, NS_ERROR_NET_INADEQUATE_SECURITY)
      • Issue i couldn't solve: Connector towards NettyConnector [host=myhost, port=8080, httpEnabled=false, httpUpgradeEnabled=true, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] failed. - after, looks like to be successful connection through https, client tries to connect through http again... as well to the hostname....

       

      Current configuration is the following, bolded, updated from the default. Can you help me to find the issue?

       

      Client:

      <subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">

                  <server name="default">

                      <security-setting name="#">

                          <role name="guest" delete-non-durable-queue="true" create-non-durable-queue="true" consume="true" send="true"/>

                      </security-setting>

                      <address-setting name="#" message-counter-history-day-limit="10" page-size-bytes="2097152" max-size-bytes="10485760" expiry-address="jms.queue.ExpiryQueue" dead-letter-address="jms.queue.DLQ"/>

                      <http-connector name="http-connector" endpoint="http-acceptor" socket-binding="https">

                          <param name="http-upgrade-endpoint" value="http-acceptor" />

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

                          <param name="trust-store-path" value="C:\server.truststore"/>  <!-- does not work??? -->

                          <param name="trust-store-password" value="xxx"/>  <!-- does not work??? -->

                      </http-connector>

                      <http-connector name="http-connector-throughput" endpoint="http-acceptor-throughput" socket-binding="https">

                          <param name="http-upgrade-endpoint" value="http-acceptor-throughput" />

                          <param name="batch-delay" value="50"/>

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

                          <param name="trust-store-path" value="C:\server.truststore"/> <!-- does not work??? -->

                          <param name="trust-store-password" value="xxx"/> <!-- does not work??? -->

                      </http-connector>

                      <in-vm-connector name="in-vm" server-id="0"/>

                      <http-acceptor name="http-acceptor" http-listener="default"/>

                      <http-acceptor name="http-acceptor-throughput" http-listener="default">

                          <param name="batch-delay" value="50"/>

                          <param name="direct-deliver" value="false"/>

                      </http-acceptor>

                      <in-vm-acceptor name="in-vm" server-id="0"/>

                      <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>

                      <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>

                      <jms-queue name="myqueue.input" entries="queue/myqueue.input java:jboss/exported/jms/queues/myqueue.input java:/jms/queue/myqueue/input"/>

                      <connection-factory name="InVmConnectionFactory" factory-type="XA_GENERIC" entries="java:/ConnectionFactory" connectors="in-vm"/>

                      <connection-factory name="RemoteConnectionFactory" factory-type="XA_GENERIC" reconnect-attempts="-1" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>

                      <pooled-connection-factory name="activemq-ra" transaction="xa" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm"/>

                  </server>

                  <jms-bridge name="myqueue-bridge" add-messageID-in-header="true" max-batch-time="100" max-batch-size="10" max-retries="-1" failure-retry-interval="60000" quality-of-service="ONCE_AND_ONLY_ONCE">

                      <source destination="queue/myqueue.input" connection-factory="ConnectionFactory"/>

                      <target password="xxx" user="jmsuser" destination="jms/queues/myqueue.input" connection-factory="jms/RemoteConnectionFactory">

                          <target-context>

                              <property name="java.naming.factory.initial" value="org.jboss.naming.remote.client.InitialContextFactory"/>

                              <property name="java.naming.provider.url" value="https-remoting://111.111.111.111:8443"/>

                              <property name="java.naming.security.principal" value="jmsuser"/>

                              <property name="java.naming.security.credentials" value="xxx"/>

                          </target-context>

                      </target>

                  </jms-bridge>

              </subsystem>

              <subsystem xmlns="urn:jboss:domain:remoting:3.0">

                  <endpoint/>

                  <http-connector name="http-remoting-connector" connector-ref="https" security-realm="ApplicationRealm"/>

              </subsystem>

       

      Server:

      <subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">

                  <server name="default">

                      <security-setting name="#">

                          <role name="guest" delete-non-durable-queue="true" create-non-durable-queue="true" consume="true" send="true"/>

                      </security-setting>

                      <address-setting name="#" message-counter-history-day-limit="10" page-size-bytes="2097152" max-size-bytes="10485760" expiry-address="jms.queue.ExpiryQueue" dead-letter-address="jms.queue.DLQ"/>

                      <http-connector name="http-connector" endpoint="http-acceptor" socket-binding="http"/>

                      <http-connector name="http-connector-throughput" endpoint="http-acceptor-throughput" socket-binding="http">

                          <param name="batch-delay" value="50"/>

                      </http-connector>

                      <in-vm-connector name="in-vm" server-id="0"/>

                      <http-acceptor name="http-acceptor" http-listener="https">

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

                          <param name="key-store-path" value="/opt/wildfly/standalone/configuration/server.keystore"/>

                          <param name="key-store-password" value="xxx"/>

                      </http-acceptor>

                      <http-acceptor name="http-acceptor-throughput" http-listener="https">

                          <param name="batch-delay" value="50"/>

                          <param name="direct-deliver" value="false"/>

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

                          <param name="key-store-path" value="/opt/wildfly/standalone/configuration/server.keystore"/>

                          <param name="key-store-password" value="xxx"/>

                      </http-acceptor>

                      <in-vm-acceptor name="in-vm" server-id="0"/>

                      <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>

                      <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>

                      <jms-queue name="myqueue.input" entries="queue/myqueue.input java:jboss/exported/jms/queues/myqueue.input java:/jms/queue/myqueue/input"/>

                      <connection-factory name="InVmConnectionFactory" factory-type="XA_GENERIC" entries="java:/ConnectionFactory" connectors="in-vm"/>

                      <connection-factory name="RemoteConnectionFactory" factory-type="XA_GENERIC" reconnect-attempts="-1" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>

                      <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>

                  </server>

              </subsystem>

              <subsystem xmlns="urn:jboss:domain:remoting:3.0">

                  <endpoint/>

                  <http-connector name="http-remoting-connector" connector-ref="https" security-realm="ApplicationRealm"/>

              </subsystem>

        • 1. Re: Wildfly 10 JMS bridge over HTTPS configuration issues
          Justin Bertram Master

          Couple of things:

          1. If you want to connect two instances of Artemis (i.e. the messaging broker used by Wildfly) together then a "core" bridge is probably quite a bit simpler than a JMS bridge.  The JMS bridge is really mean to be used between different message broker implementations.
          2. The http-acceptor doesn't manage it's own socket (i.e. 8080 by default).  That's done by the embedded web server (i.e. undertow).  Therefore, you can't configure HTTPS properties on it.  You'd have to configure those on the web server (assuming that's even possible).  That said, if you want to use SSL I would recommend just using a remote-connector (on the client) and remote-acceptor (on the server) that doesn't go through undertow.
          3. Even though your JNDI lookup using the IP address of the target server, the JNDI lookup will return a stub to the JMS bridge containing connector information based on where Wildfly is actually bound (which is almost certainly to the hostname).
          • 2. Re: Wildfly 10 JMS bridge over HTTPS configuration issues
            Justas D Newbie

            I appreciate your answer, however I'm a bit lost, as there are no up to date documentation regarding JMS. I need to browse the hell out of internet to collect examples of multiple use cases, different versions to combine into something working..

            Could you please provide working example for this use case: to create core bridge between local queue (myqueue.input) and remote (111.111.111.111) queue (myqueue.input) over remote-connector (or whatever works best) using encrypted connection with self signed server certificate, while supporting XA (ONCE_AND_ONLY_ONCE) reliable messaging?

             

            Thanks.

            • 3. Re: Wildfly 10 JMS bridge over HTTPS configuration issues
              Justin Bertram Master

              ...there are no up to date documentation regarding JMS.

              Couple of places to look:

              • Wildfly messaging documentation.
              • Artemis 1.1 documentation. You can use this documentation to understand the capabilities of the broker and general configuration concepts.  However, specific configuration details are subject to the Wildfly messaging subsystem schema (see next point).
              • Messaging configuration schema in <WILDFLY_HOME>/docs/schema/wildfly-messaging-activemq_1_0.xsd

               

              Could you please provide working example for this use case: to create core bridge between local queue (myqueue.input) and remote (111.111.111.111) queue (myqueue.input) over remote-connector (or whatever works best) using encrypted connection with self signed server certificate, while supporting XA (ONCE_AND_ONLY_ONCE) reliable messaging?

              I don't have enough time to create a full working example, but I can get you started down the right path.  To be clear, the core bridge doesn't strictly support XA.  However, the guarantees that XA provides are implemented via automatic duplicate detection which you can read more about in the documentation.

               

              Client:

              <?xml version="1.0" ?>
              <server xmlns="urn:jboss:domain:4.2">
                  ...
                  <profile>
                      ...
                      <subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
                          <server name="default">
                              <security-setting name="#">
                                  <role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
                              </security-setting>
                              <address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
                              <http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/>
                              <http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
                                  <param name="batch-delay" value="50"/>
                              </http-connector>
                              <remote-connector name="bridge-connector" socket-binding="bridge">
                                  <param name="ssl-enabled" value="true"/>
                                  <param name="trust-store-path" value="C:\server.truststore"/>
                                  <param name="trust-store-password" value="xxx"/>
                              </remote-connector>
                              <in-vm-connector name="in-vm" server-id="0"/>
                              <http-acceptor name="http-acceptor" http-listener="default"/>
                              <http-acceptor name="http-acceptor-throughput" http-listener="default">
                                  <param name="batch-delay" value="50"/>
                                  <param name="direct-deliver" value="false"/>
                              </http-acceptor>
                              <in-vm-acceptor name="in-vm" server-id="0"/>
                              <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
                              <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>
                              <jms-queue name="myqueue.input" entries="queue/myqueue.input java:jboss/exported/jms/queues/myqueue.input java:/jms/queue/myqueue/input"/>
                              <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/>
                              <connection-factory name="RemoteConnectionFactory" connectors="http-connector" entries="java:jboss/exported/jms/RemoteConnectionFactory"/>
                              <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>
                              <bridge name="myqueue-bridge" queue="jms.queue.myqueue.input" forwarding-address="jms.queue.myqueue.input" retry-interval="60000" reconnect-attempts="-1" use-duplicate-detection="true" user="jmsuser" password="xxx" static-connectors="bridge-connector"/>
                          </server>
                      </subsystem>
                      ...
                  </profile>
                  ...
                  <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
                      ...
                      <outbound-socket-binding name="bridge">
                          <remote-destination host="111.111.111.111" port="5445"/>
                      </outbound-socket-binding>
                  </socket-binding-group>
              </server>
              

               

              Server:

              <?xml version="1.0" ?>
              <server xmlns="urn:jboss:domain:4.2">
                  ...
                  <profile>
                      ...
                      <subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
                          <server name="default">
                              <security-setting name="#">
                                  <role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
                              </security-setting>
                              <address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
                              <http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/>
                              <http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
                                  <param name="batch-delay" value="50"/>
                              </http-connector>
                              <in-vm-connector name="in-vm" server-id="0"/>
                              <http-acceptor name="http-acceptor" http-listener="default"/>
                              <http-acceptor name="http-acceptor-throughput" http-listener="default">
                                  <param name="batch-delay" value="50"/>
                                  <param name="direct-deliver" value="false"/>
                              </http-acceptor>
                              <remote-acceptor name="bridge-acceptor" socket-binding="bridge">
                                  <param name="ssl-enabled" value="true"/>
                                  <param name="key-store-path" value="/opt/wildfly/standalone/configuration/server.keystore"/>
                                  <param name="key-store-password" value="xxx"/>
                              </remote-acceptor>
                              <in-vm-acceptor name="in-vm" server-id="0"/>
                              <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
                              <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>
                              <jms-queue name="myqueue.input" entries="queue/myqueue.input java:jboss/exported/jms/queues/myqueue.input java:/jms/queue/myqueue/input"/>
                              <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/>
                              <connection-factory name="RemoteConnectionFactory" connectors="http-connector" entries="java:jboss/exported/jms/RemoteConnectionFactory"/>
                              <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>
                          </server>
                      </subsystem>
                      ...
                  </profile>
                  ...
                  <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
                      ...
                      <socket-binding name="bridge" port="5445"/>
                  </socket-binding-group>
              </server>
              
              • 4. Re: Wildfly 10 JMS bridge over HTTPS configuration issues
                Justas D Newbie

                Apart from that queue should be queue-name in the bridge tag, everything works fine! Thanks a lot!