Version 36


    This wiki outlines the various steps required to secure a remote connection to JBossMQ using SSL.


    The code, build script and configuration files are all attached at the bottom of this page




    Grab a copy of a JBossAS 4.x release and create two new server configurations (based on /default) named respectively /jmsprovider and /client


    Provider configuration


    Step 1: Generate a private-public key pair using keytool


        $ ./j2sdk1.4.2_07/bin/keytool -genkey -alias sslmq -keyalg RSA -keystore sslmq.keystore
        Enter keystore password:  jbossmq
        What is your first and last name?
        What is the name of your organizational unit?
          [Unknown]:  Some dot com
        What is the name of your organization?
          [Unknown]:  Security
        What is the name of your City or Locality?
          [Unknown]:  SomeCity
        What is the name of your State or Province?
          [Unknown]:  Washington
        What is the two-letter country code for this unit?
          [Unknown]:  US
        Is, OU=Some dot com, O=Security, L=SomeCity, ST=Washington, C=US correct?
          [no]:  yes
        Enter key password for <jbossmq>
                (RETURN if same as keystore password):


      And copy sslmq.keystore to /server/jmsprovider/conf




    Step 2: Create a JAAS security domain that uses sslmq.keystore


      Create a new MBean configuration ssl-domain-service.xml (see the attached example) and save it in /server/jmsprovider/deploy

       <?xml version="1.0" encoding="UTF-8"?>
           <mbean code=""
                   <arg type="java.lang.String" value="SSL"></arg>
               <attribute name="KeyStoreURL">resource:sslmq.keystore</attribute>
               <attribute name="KeyStorePass">jbossmq</attribute>




    Step 3: Create a new UIL2 deployment descriptor ssl-uil2-service.xml and save it in /server/jmsprovider/deploy/jms


       <?xml version="1.0" encoding="UTF-8"?>
           <mbean code=""
               <depends optional-attribute-name="Invoker"></depends>
               <attribute name="ConnectionFactoryJNDIRef">SSLUIL2ConnectionFactory</attribute>
               <attribute name="XAConnectionFactoryJNDIRef">SSLUIL2XAConnectionFactory</attribute>
               <!-- The bind address -->
               <attribute name="BindAddress">${jboss.bind.address}</attribute>
               <attribute name="ServerBindPort">8193</attribute>
               <attribute name="PingPeriod">60000</attribute>
               <attribute name="EnableTcpNoDelay">true</attribute>
               <!-- Used to disconnect the client if there is no activity -->
               <!-- Ensure this is greater than the ping period -->
               <attribute name="ReadTimeout">70000</attribute>
               <!-- The size of the buffer (in bytes) wrapping the socket -->
               <!-- The buffer is flushed after each request -->
               <attribute name="BufferSize">2048</attribute>
               <!-- Large messages may block the ping/pong -->
               <!-- A pong is simulated after each chunk (in bytes) for both reading and writing -->
               <!-- It must be larger than the buffer size -->
               <attribute name="ChunkSize">1000000</attribute>
               <attribute name="ClientSocketFactory"></attribute>
               <attribute name="ServerSocketFactory"></attribute>
               <attribute name="SecurityDomain">java:/jaas/SSL</attribute>



    Client configuration


    Step 1: Create JMS client


    The JMS client code is embedded in an MBean called JBossService. It has got a RW property ProviderURL that stores the IpAddress:[Port|port] of the remote provider. Its default value can be changed in jboss-service.xml or updated on the fly using the jmx console.


       public void sendMessages() throws NamingException, JMSException
 "sending JMS message to queue bound to JNDI name: "+QUEUE_NAME);
          Properties properties = new Properties();
          properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
          properties.put(Context.URL_PKG_PREFIXES, "org.jnp.interfaces");
          properties.put(Context.PROVIDER_URL, providerURL);
          InitialContext ctx = new InitialContext(properties);
          connectionFactory = (ConnectionFactory)ctx.lookup("SSLUIL2ConnectionFactory");
          queue = (Destination)ctx.lookup(QUEUE_NAME);
          connection = connectionFactory.createConnection();
          session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
          producer = session.createProducer(queue);
          for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
             Message m = session.createObjectMessage(new Integer(i));
 + " messages sent to " +providerURL);


    Notice the JNDI name of the ConnectionFactory (configured in /server/jmsprovider/ssl-uil2-service.xml)



    Step 2: Create the truststore for the client


      When an SSL client connects to an SSL server, it receives a certificate of authentication from the server. The client then validates the certificate against a set of certificates in its truststore.


        Create the certificate
        $ ./j2sdk1.4.2_07/bin/keytool -export -alias sslmq -keystore sslmq.keystore -rfc -file provider.cer
        Enter keystore password:  jbossmq
        Import this certificate into a client truststore
        $ ./j2sdk1.4.2_07/bin/keytool -import -alias sslmq -file provider.cer -keystore client.truststore
        Enter keystore password:  jbossmq


    Copy client.truststore to /server/client/conf


    We now ready to set the location of the client truststore using two JVM properties; and Since we are running 2 servers out of the same installation, we should not set them globally in run.bat or Instead we use the Properties service.


      Edit /server/client/deploy/properties-service.xml and add the following to the 'jboss:type=Service,name=SystemProperties' MBean:


        <attribute name="Properties">


    Note: in run.conf it would translate into






    Step 1: Compile and deploy


    From the attachment section download the archive, explode it in the same directory where you put JBossAS then point a command line to the /build directory. Note: Make sure to change the jboss.bundle.dir property.


        $ ./src/build/ant -f build.xml


    In /server/client/deploy, you should have now a SAR archive named jmsssl.sar


    Step 2: Have fun


    If you are testing on the same pc, I recommend configuring 2 static ip addresses and binding a JBossAS instance to each one using the option (or -b).


    So for instance to start the "provider" you would use

      $ sh ./bin/ -c jmsprovider -b

    and this for the client

      $ sh ./bin/ -c client -b


    To execute the client code, open the jmx console, find the service JBossService in the JMSSSL domain.

    Scroll down and invoke the go() operation. In the client log, you should see the following:

     21:52:07,906 INFO  [JMSSSL:name=JBossService] sending JMS message to queue bound to JNDI name: queue/A
     21:52:08,031 INFO  [JMSSSL:name=JBossService] 5 messages sent to

    In another web browser, open the jmx console and check the size of Queue A (name=A,service=Queue in the domain)

    The attribute QueueDepth is now 5 (was zero previously). To see what those messages look like, you may invoke the operation listMessages located further down in the page.



    Common problems


       Coming soon...


    I want to use SSL to "authenticate" the client?


    Typically, only the client authenticates the server with SSL.


    You would need your own


    as JBoss's does not perform or allow this configuration