Monday, March 30, 2015

ActiveMQ: Encrypt ActiveMQ Console Password

Introduction

ActiveMQ console, by default, use jetty as web container. The login credentials are not encrypted. In the enterprise application, this will not pass the security scan. Thus we need to encrypt the password. This blog will document the process for such a purpose.

Executive Summary

  • Download Jetty Utility from: http://download.eclipse.org/jetty/
  • run: java -cp lib/jetty-util-$JETTY_VERSION.jar org.eclipse.jetty.util.security.Password admin admin
  • replace the admin password in jetty-realm.properties

Detailed Procedures

Download Jetty Utlity

The jetty utility can be downloaded from http://download.eclipse.org/jetty/. At the writing, the latest version is stable-9. For linux, you will need to download .tgz file. Unpack the archive file using the following command:

tar vxzf /software/JETTY/jetty-distribution-9.2.10.v20150310.tar.gz

In my case, I install the jetty under

/opt/app/amq/jetty/

Once you unzip the file, you can use the following command to create encrypted password:

java -cp lib/jetty-util-$JETTY_VERSION.jar org.eclipse.jetty.util.security.Password admin admin

Here is the output

java -cp lib/jetty-util-$JETTY_VERSION.jar org.eclipse.jetty.util.security.Password admin admin
2015-03-30 15:19:15.977:INFO::main: Logging initialized @48ms
admin
OBF:1u2a1toa1w8v1tok1u30
MD5:21232f297a57a5a743894a0e4a801fc3
CRYPT:adpexzg3FUZAk

Now we can copy the line of: CRYPT:adpexzg3FUZAk to the file of jetty-realm.properties, and here is the how the file looks like:

$ cat jetty-realm.properties
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements.  See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License.  You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------

# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: CRYPT:adpexzg3FUZAk, admin
user: CRYPT:us6EKZMmfBVwI, user

As you can see the original password: "admin" is replaced with "CRYPT:adpexzg3FUZAk". Now you can restart the activemq.

Saturday, March 14, 2015

Broker-To-Broker Network Connector With SSL And JAAS Plugin

Introduction

In my previous blogs, I have explained many topics related to enterprise messaging with ActiveMQ from simple installation to complicated configuration with Network-Of-Brokers. In this blog, I am going to demonstrate in detail how to setup a Network-Of-Brokers using SSL for network connection. Currently, there is little detailed documentation available with regard to how to setup network of brokers using SSL. One of my goals of this blog is to fill this gap.

Topology

As shown in the above picture, I have setup two clusters, name WEST and EAST. Each cluster has a master-slave pair of ActiveMQ instances. The master-slave instance are located on the same Linux server. Thus, I have two Linux servers, name SERVER01 and SERVER02.

Generate Keys and Certificates

Generate Private and Public Keys On SERVERV01

First, I created the following dir:

[amq@SERVERV01 dev1certs]$ pwd
/opt/app/activemq/cluster/master-slave/certificates/dev1certs

Generate Private Key

Then, I will need to create private key namd serverv01.ks as the following:

[amq@SERVERV01 dev1certs]$ keytool -genkey -alias serverv01 -keyalg RSA -keystore serverv01.ks
Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  Gary Liu
What is the name of your organizational unit?
  [Unknown]:  OU
What is the name of your organization?
  [Unknown]:  OG
What is the name of your City or Locality?
  [Unknown]:  MyCity
What is the name of your State or Province?
  [Unknown]:  PA
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Gary Liu, OU=OU, O=OG, L=MyCity, ST=PA, C=US correct?
  [no]:  yes

Enter key password for 
        (RETURN if same as keystore password):
serverv01.ks

Enter password as amqadmin@. We will need this password later. Make sure you use the alias the same as host name, so that we can update the key based on the unique alias, if necessary. As you can see, we have created a private key, name serverv01.ks. We interrogate this key by the following command:

[amq@SERVERV01 democerts]$ keytool -list -keystore serverv01.ks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

serverv01, Mar 14, 2015, PrivateKeyEntry,
Certificate fingerprint (SHA1): 31:43:79:2B:33:3E:73:8A:C1:1C:3C:D1:EA:68:ED:00:6A:8C:F6:D3

Generate Public Key

After generating private key, we need to create public key. Outside world will use this key to communicate with ActiveMQ broker. Here is the command to generate public key [sametimes, it is called certificates. It is the same thing.].


 keytool -export -alias server1 -keystore server1.ks -file server1_cert

Here is the details:

 [amq@SERVERV01 democerts]$ keytool -export -alias serverv01 -keystore serverv01.ks -file serverv01_cert
Enter keystore password:
Certificate stored in file 
[amq@SERVERV01 democerts]$ ls
serverv01_cert  serverv01.ks

We can also verify the public key by the following command:

keytool -printcert -file serverv01_cert

Here are the details

[amq@SERVERV01 democerts]$ keytool -printcert -file serverv01_cert
Owner: CN=Gary Liu, OU=OU, O=OG, L=Jessup, ST=PA, C=US
Issuer: CN=Gary Liu, OU=OU, O=OG, L=Jessup, ST=PA, C=US
Serial number: 5a47ce77
Valid from: Sat Mar 14 13:57:23 CDT 2015 until: Fri Jun 12 13:57:23 CDT 2015
Certificate fingerprints:
         MD5:  C7:90:BC:22:C6:F9:E8:D0:CA:EB:DE:55:AF:D3:90:F8
         SHA1: 31:43:79:2B:33:3E:73:8A:C1:1C:3C:D1:EA:68:ED:00:6A:8C:F6:D3
         SHA256: B2:EE:9F:AE:89:88:00:E9:9D:E8:6C:34:BF:11:82:11:0A:A1:A9:4C:80:35:39:C2:66:08:58:02:BE:9A:89:97
         Signature algorithm name: SHA256withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 9D E7 60 DE 70 93 6E 2B   EA 19 D0 98 44 D9 9B AE  ..`.p.n+....D...
0010: DC C4 B3 AD                                        ....
]
]

Generate Shared Keystore shared.ks

We need to have shared public key store to include all the public keys in one file. Thus client can use this file communicated with server. And ActiveMQ brokers can communicate with each other. Now, we will create a file named shared.ks using the following commands:

 keytool -import -alias serverv01 -keystore shared.ks -file serverv01_cert

And here are the details:

 [amq@SERVERV01 democerts]$ keytool -import -alias serverv01 -keystore shared.ks -file serverv01_cert
Enter keystore password:
Re-enter new password:
Owner: CN=Gary Liu, OU=OU, O=OG, L=Jessup, ST=PA, C=US
Issuer: CN=Gary Liu, OU=OU, O=OG, L=Jessup, ST=PA, C=US
Serial number: 5a47ce77
Valid from: Sat Mar 14 13:57:23 CDT 2015 until: Fri Jun 12 13:57:23 CDT 2015
Certificate fingerprints:
         MD5:  C7:90:BC:22:C6:F9:E8:D0:CA:EB:DE:55:AF:D3:90:F8
         SHA1: 31:43:79:2B:33:3E:73:8A:C1:1C:3C:D1:EA:68:ED:00:6A:8C:F6:D3
         SHA256: B2:EE:9F:AE:89:88:00:E9:9D:E8:6C:34:BF:11:82:11:0A:A1:A9:4C:80:35:39:C2:66:08:58:02:BE:9A:89:97
         Signature algorithm name: SHA256withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 9D E7 60 DE 70 93 6E 2B   EA 19 D0 98 44 D9 9B AE  ..`.p.n+....D...
0010: DC C4 B3 AD                                        ....
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore

So far I have performed 3 tasks:

  • Generate private key
  • Generate public key
  • Create a shared keystore

And I have executed the following commands:

  keytool -genkey -alias serverv01 -keyalg RSA -keystore serverv01.ks
  keytool -export -alias serverv01 -keystore serverv01.ks -file serverv01_cert
  keytool -import -keystore shared.ks -file serverv01_cert
  keytool -list -keystore shared.ks

Generate Private And Public Keys On The Second Server

Now, we need execute the same commands on the other server. In my case, the other server is name as SERVERV02. During the execution of the commands, replace all host name by the server name. [In my case, I replace serverv01 with serverv02].

And I have executed the following commands:

  keytool -genkey -alias serverv02 -keyalg RSA -keystore serverv02.ks
  keytool -export -alias serverv02 -keystore serverv02.ks -file serverv02_cert
  keytool -import -keystore shared.ks -file serverv02_cert
  keytool -list -keystore shared.ks

At this point, on each server we have 3 files:

  1. HOSTNAME.ks
  2. HOSTNAME_cert
  3. shared.ks

This means for each host we have a private key, a public key, and shared key. The next step is to exchange public key and update the shared key.

Exchange Public Keys

In order for the ActiveMQ brokers to authenticate each other, we need to change the public keys. So that copy the file of HOSTNAME_cert to each other's server. In my case, I use scp. Here is the command for copy from server 2 to server 1:

scp gliu@serverv02:/opt/app/activemq/cluster/master-slave/certificates/democerts/serverv02_cert .

From server 1 to server 2:

scp gliu@serverv01:/opt/app/activemq/cluster/master-slave/certificates/democerts/serverv01_cert .

Now we need to import the newly copied public key to the shared keystore, namely shared.ks. Thus on server 1[serverv01] execute the following commands:

keytool -import -alias serverv02 -keystore shared.ks -file serverv02_cert

And on the server 2[serverv02], execute the following command:

keytool -import -alias serverv01 -keystore shared.ks -file serverv01_cert

We can check what is the content of the shared keystore by following command:

[amq@SERVERV02 democerts]$ keytool -list -keystore shared.ks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

serverv02, Mar 15, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): AB:21:A4:20:2B:81:E3:23:79:37:7D:07:45:9E:0A:D0:B6:71:4B:6B
serverv01, Mar 15, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): 31:43:79:2B:33:3E:73:8A:C1:1C:3C:D1:EA:68:ED:00:6A:8C:F6:D3

From the above output, we can see that the public keys from two servers [serverv01 and serverv02] are included in the shared.ks file. Upon this point, we have completed the key generation procedure. It seems a long procedure, but it is pretty straight forward in reality.

Remember, in the large network of brokers, many servers many involved. In order for the client to connect any server in the clusters, we will need to add all the keys to the shared.ks file. With this file, client will be able to connect to the all the brokers.

ActiveMQ Configuration

For each broker, we need to copy the private key [HOSTNAME.ks] and shared.ks to the $ACTIVEMQ_BASE/conf. Once that is done, we need to update the activemq.xml file.

Update activemq.xml On The WEST Cluster

The in my case, the west cluster has two nodes [WEST-NORTH and WEST-SOUTH] playing as master-slave pair. In my design, I use WEST cluster as the active part which contains the networkConnector configuration, while the EAST cluster does not define any network connector. This is desired configuration. Firstly, it is simple to define duplex connection than define two separate one-way connection. Secondly, in the enterprise application, there may be firewall restriction which prevent us from having two one-way connections. Here is the relevant configuraiton:


        ...

        
            
        

        
            
                     
                        
                     
            
            
                     
                        
                     
            
        

        ...

         
          

          
            
              
                
                  
                  

                  
                  

                  
                

                
                  
               
              
            
          
        

        
            
            
        


        
            
        

        ...


Update activemq.xml On The EAST Cluster

The configurations of the EAST cluster are almost the same as the WEST cluster, except we do not need to define the networkConnector as explained in the previous section.

Trouble Shooting

Make Sure Ports Open On Firewall

When you run the network of brokers, make sure the ports are open. If you use 61617, for example, as ssl connection, make sure that port is open from firewallusing command of:

 sudo iptables -L -v -n]

Make Sure HOSTNAME.ks and shared.ks Aviable

In my example, I explicitly tell ActiveMQ the location of the private and public keys. In that way, I know which key I am using.

Check Log

$ACTIVEMQ_BASE/data/activemq.log contains very important server information. Alway check the log after you start the broker. If connection are established, you should see something like this:
2015-03-13 16:18:28,710 | INFO  | Establishing network connection from vm://WEST-NORTH?async=false&network=true to failover:(nio+ssl://serverv02:61617,nio+ssl://serverv02:61627)?randomize=false&maxReconnectAttempts=0 | org.apache.activemq.network.DiscoveryNetworkConnector | ActiveMQ Task-1
2015-03-13 16:18:28,711 | INFO  | Connector vm://WEST-NORTH started | org.apache.activemq.broker.TransportConnector | ActiveMQ Task-1
2015-03-13 16:18:28,724 | INFO  | Establishing network connection from vm://WEST-NORTH?async=false&network=true to failover:(nio+ssl://serverv02:61617,nio+ssl://serverv02:61627)?randomize=false&maxReconnectAttempts=0 | org.apache.activemq.network.DiscoveryNetworkConnector | ActiveMQ Task-1
2015-03-13 16:18:29,017 | INFO  | Successfully connected to nio+ssl://serverv02:61617 | org.apache.activemq.transport.failover.FailoverTransport | ActiveMQ Task-1
2015-03-13 16:18:29,021 | INFO  | Successfully connected to nio+ssl://serverv02:61617 | org.apache.activemq.transport.failover.FailoverTransport | ActiveMQ Task-1

Test Configuration

In order to test the configuration of the Network-Of-Broker with nio+ssl, I use the sample code that comes with ActiveMQ. We need to test:

  1. Failover From Both Clusters
  2. Producing And Consuming Messages

Test Failover

To test failover, we need stop one ActiveMQ broker at a time. Make sure the connection between two cluster are established correctly

The above picture shows that the EAST cluster has established 2 connections with the EAST cluster on the EAST-NORHT broker. One is for queue and the other for the topic connection. If we stop the north broker from the WEST cluster, we should see the new connection establish from the WEST to the EAST cluster.

Test Message Exchanging

Here are the basic messaging changing patterns need to be tested. Basically, we need to make sure if producers and consumers are located at the same cluster, they can exchange messages. In this case, we need to make sure messages are not automatically bridged to the other cluster. Another test is to make sure if producers and consumers are located at different cluster, the brokers can bridge messages to the other brokers. Here are the 4 test cases:
  1. Produce and Consumer Messages From WEST cluster
  2. Produce and Consumer Messages From EAST cluster
  3. Produce Messages From WEST Cluster and Consumer FROM EAST Cluster
  4. Produce Messages From EAST Cluster and Consumer FROM WEST Cluster

In order to execute the above test cases, I created 4 scripts as shown in the following.

publishToDev1.sh

#!/bin/bash
# publishToDev1.sh
#
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer \
 -Durl="failover:(nio+ssl://serverv01.mycompany.com:61617,nio+ssl://serverv01.mycompany.com:61627)" \
 -Duser="hmuser" \
 -Dpassword="admin123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/dev1cert/shared.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/dev1cert/shared.ks

consumeFromDev1.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant consumer  \
 -Durl="failover:(nio+ssl://serverv01.mycompany.com:61617,nio+ssl://serverv01.mycompany.com:61627)" \
 -Duser="hmuser" \
 -Dpassword="admin123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/dev1cert/shared.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/dev1cert/shared.ks

publishToDev2.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer \
 -Durl="failover:(nio+ssl://serverv02.mycompany.com:61617,nio+ssl://serverv02.mycompany.com:61627)" \
 -Duser="admin" \
 -Dpassword="admin" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/dev2cert/shared.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/dev2cert/shared.ks

consumeFromDev2.sh

consumeFromDev2.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
# -Durl="failover:(nio+ssl://serverv02.mycompany.com:61617,nio+ssl://serverv02.mycompany.com:61627)" \
ant consumer  \
 -Durl="failover:(nio+ssl://serverv02.mycompany.com:61617,nio+ssl://serverv02.mycompany.com:61627)" \
 -Duser="hmuser" \
 -Dpassword="admin123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/dev2cert/serverv02.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/dev2cert/shared.ks

Conclusion And Summary

The main purpose of this blog is explain the ActiveMQ configuration for a Network-Of-Brokers using nio+ssl. I have included the test scripts so that admin can test the configuration without writing any new java code.

Tuesday, March 10, 2015

ActiveMQ Security Using JAAS Authentication

Introduction

By default, ActiveMQ does not provide access to the message broker anonymously. That means we don't need to pass user name and password. This is not desired. There are two simple authentication schemes. The firsts use simple authentication and the second one uses JAAS plugin. JASS plugin can be used with LDAP.

In this blog, I am going explain how to use jaasAuthenticationPlugin.

Configuration Changes

To configure ActiveMQ using JAAS authentication plugin requires to modify the following files [all these files are located at $ACTIVEMQ_HOME/conf:

  1. login.config
  2. users.properties
  3. groups.properties
  4. activemq.xml

activema.xml


       ...
       
         

         
           
             
               
                 
                 

                 
                 

                 
               

               
                 
              
             
           
         
       
       ...



login.config

activemq-domain {
    org.apache.activemq.jaas.PropertiesLoginModule required
        debug=true
        org.apache.activemq.jaas.properties.user="users.properties"
        org.apache.activemq.jaas.properties.group="groups.properties";
};

Note: configuration="activemq-domain" in the activemq.xml implies that ActiveMQ will look for the entry of activemq-domain in the login.config file.

users.properties

admin=admin
hmuser=user123@

groups.properties

admins=admin
users=hmuser

Test Configuration

To test the configuration, you can run the following scripts:

producer: runProducerOneWay.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer \
 -Durl="nio+ssl://localhost:61617" \
 -Duser="hmuser" \
 -Dpassword="user123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/client.ts

consumer: runConsumerOneWay.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant consumer  \
 -Durl="nio+ssl://localhost:61617" \
 -Duser="hmuser" \
 -Dpassword="user123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts

Saturday, March 7, 2015

Enable HTTPS For ActiveMQ Brower

Introduction

ActiveMQ embedded web console is jetty. In enterprise applications, plain http is not recommended. Thus we should enable HTTPS. In my previous blogs, I have demonstrated how to enable nio+ssl for mutual authentication or one-way authentication. In this blog, I am going to show you how to enable HTTPS for the embedded ActiveMQ console.

Configuration Changes

The configuration file we need to change is ${AMQ_HOME}/conf/jetty.xml. Uncomment out the bean with id of "SecureConnecor" and remove the id with "Connector" as shown below:


    ...
    

        
            
                
                    
                    
                    
                

            
        

        
            
                
                    
                        
                        
                    
                
            
        

    



Run The ActiveMQ

Start ActiveMQ the same way as before. Go to brower with URL of https://hostname:8162, use the same user id and password [admin/admin].

Friday, March 6, 2015

Configure ActiveMQ Using nio+ssl With One-Way Authentication

Introduction

In my previous blog http://ggl-consulting.blogspot.com/2015/02/configure-activemq-transport-connector.html, I have explained the activemq configuration with mutual authentication. In most case, we don't need to have the server to check client's certificates, but rather client just need to send the server's certificate, or broker trust store together with client key.

I should point out that in large enterprise, normally the certificates are not generated by admin. There will be certified organization to issue the certificates. My blogs are just demonstrate how to setup ActiveMQ and run the producers and consumers.

All the certificate generation procedures are still the same except that we don't need to generate broker.ts file. For the completeness, I will provide the complete procedure in this blog, including how to run the producers and consumers.

Generate Keystore and Truststore

For one-way authentication, we will need 3 files as the following:

  1. broker.ks : server keystore
  2. client.ks : client keystore
  3. client.ts : client truststore

Here is the procedure to generate these files:

cd $ACTIVEMQ_HOME/conf
keytool -genkey -alias broker -keyalg RSA -keystore broker.ks
keytool -genkey -alias client -keyalg RSA -keystore client.ks
keytool -export -alias broker -keystore broker.ks -file broker_cert
keytool -import -alias broker -keystore client.ts -file broker_cert

Modify activemq.xml


       ...
       
            
            
        
 
        
            
            
        
        ...

For large network of ActiveMQ Clustering, please refer my other blog: http://ggl-consulting.blogspot.com/2015/03/broker-to-broker-network-connector-with.html

As you can see, comparing the two-authentication case, we only need the keyStore of the broker, which include the broker's key and certificates

Run Producer and Consumer

For running producer, I have created a scrirpt named runProducerOneWay.sh with the following contents:

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer -Durl="nio+ssl://localhost:61617" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts 

Run the above script at $ACTIVEMQ_HOME/examples/openwire/swissarmy

The script for running consumer, namely, runConsumerOneWay.sh has the following contents:

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant consumer -Durl="nio+ssl://localhost:61617" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts 

As you can see, we don't need to know the server's keyStore password. We still need the client's keyStore information in order for the server to know the decryption algorithms.

Friday, February 27, 2015

Configure ActiveMQ Transport Connector With nio+ssl With Mutual Authentication

Introduction

In my previous blogs about ActiveMQ, I have covered the topics about how to setup high availability with various topologies and configuration. In this blog, I am going to explain in details about how to setup transport connection using nio+ssl. In detail I will explain the following areas:

  1. A brief introduction of nio+ssl transport
  2. Create SSL keystore and truststore files using keytool
  3. Enable SSL transport ActiveMQ with trusted clients
  4. How to run producer and consumers

NIO SSL Transport

NIO is the same as TCP except the New I/O Java library is use. The NIO provide better performance over TCP. In the ActiveMQ transport connector, we can replace with tcp by nio. nio+ssl is SSL [Secure Sockets Layer] over TCP using java New I/O packaging. This transport is recommended for the enterprise messaging system as it provide better security by encrypt the message over the wire.

The above figure illustrates the scenarios for mutual authentication between server and client. The client and server establish connection by exchanging the server and client certificates which are stored in the file broker.ts and client.ts for server and client, respectively.

Generate Keystore and Truststore

In order to achieve the mutual authentication, we need to generate 4 files:

  1. broker.ks : server keystore
  2. broker.ts : server trusstore
  3. client.ks : client keystore
  4. client.ts : client truststore

Here is the procedure to generate these files:

cd $ACTIVEMQ_HOME/conf
keytool -genkey -alias broker -keyalg RSA -keystore broker.ks
keytool -genkey -alias client -keyalg RSA -keystore client.ks
keytool -export -alias broker -keystore broker.ks -file broker_cert
keytool -export -alias client -keystore client.ks -file client_cert
keytool -import -alias broker -keystore client.ts -file broker_cert
keytool -import -alias client -keystore broker.ts -file client_cert

Modify activemq.xml


       ...
       
            
            
        
 
        
            
            
        
        ...


Start ActiveMQ

After you start the ActiveMQ server [by activemq start command], in the server log, you should see the following log:

2015-02-27 15:49:04,544 | INFO  | Refreshing org.apache.activemq.xbean.XBeanBrokerFactory$1@2c90f71b: startup date [Fri Feb 27 15:49:04 CST 2015]; root of context hierarchy | org.apache.activemq.xbean.XBeanBrokerFactory$1 | main
2015-02-27 15:49:05,672 | INFO  | PListStore:[/opt/app/amq/Transport/NioSsl/data/NioSsl/tmp_storage] started | org.apache.activemq.store.kahadb.plist.PListStoreImpl | main
2015-02-27 15:49:05,783 | INFO  | Using Persistence Adapter: KahaDBPersistenceAdapter[/amqdata/master-slave/data/kahadb] | org.apache.activemq.broker.BrokerService | main
2015-02-27 15:49:05,798 | INFO  | JMX consoles can connect to service:jmx:rmi://localhost:44444/jndi/rmi://localhost:11099/jmxrmi | org.apache.activemq.broker.jmx.ManagementContext | JMX connector
2015-02-27 15:49:06,563 | INFO  | KahaDB is version 5 | org.apache.activemq.store.kahadb.MessageDatabase | main
2015-02-27 15:49:06,581 | INFO  | Recovering from the journal ... | org.apache.activemq.store.kahadb.MessageDatabase | main
2015-02-27 15:49:06,605 | INFO  | Recovery replayed 634 operations from the journal in 0.036 seconds. | org.apache.activemq.store.kahadb.MessageDatabase | main
2015-02-27 15:49:06,751 | INFO  | Apache ActiveMQ 5.10.0 (NioSsl, ID:SANDBOXFUSEV01-33072-1425073746626-0:1) is starting | org.apache.activemq.broker.BrokerService | main
2015-02-27 15:49:06,803 | INFO  | Listening for connections at: nio+ssl://SANDBOXFUSEV01:61617?maximumConnections=1000&wireFormat.maxFrameSize=104857600 | org.apache.activemq.transport.TransportServerThreadSupport | main
2015-02-27 15:49:06,808 | INFO  | Connector nio+ssl started | org.apache.activemq.broker.TransportConnector | main
2015-02-27 15:49:07,066 | INFO  | Connector https started | org.apache.activemq.broker.TransportConnector | main
2015-02-27 15:49:07,069 | INFO  | Apache ActiveMQ 5.10.0 (NioSsl, ID:SANDBOXFUSEV01-33072-1425073746626-0:1) started | org.apache.activemq.broker.BrokerService | main
2015-02-27 15:49:07,073 | INFO  | For help or more information please see: http://activemq.apache.org | org.apache.activemq.broker.BrokerService | main
2015-02-27 15:49:07,077 | ERROR | Temporary Store limit is 51200 mb, whilst the temporary data directory: /opt/app/amq/Transport/NioSsl/data/NioSsl/tmp_storage only has 9820 mb of usable space - resetting to maximum available 9820 mb. | org.apache.activemq.broker.BrokerService | main
2015-02-27 15:49:07,405 | INFO  | ActiveMQ WebConsole available at http://0.0.0.0:8161/ | org.apache.activemq.web.WebConsoleStarter | main
2015-02-27 15:49:07,449 | INFO  | Initializing Spring FrameworkServlet 'dispatcher' | /admin | main
2015-02-27 15:49:07,634 | INFO  | jolokia-agent: No access restrictor found at classpath:/jolokia-access.xml, access to all MBeans is allowed | /api | main

Note the line of particular interesting:

2015-02-27 15:49:06,803 | INFO  | Listening for connections at: nio+ssl://SANDBOXFUSEV01:61617?maximumConnections=1000&wireFormat.maxFrameSize=104857600 | org.apache.activemq.transport.TransportServerThreadSupport | main
2015-02-27 15:49:06,808 | INFO  | Connector nio+ssl started | org.apache.activemq.broker.TransportConnector | main
2015-02-27 15:49:07,066 | INFO  | Connector https started | org.apache.activemq.broker.TransportConnector | main
2015-02-27 15:49:07,069 | INFO  | Apache ActiveMQ 5.10.0 (NioSsl, ID:SANDBOXFUSEV01-33072-1425073746626-0:1) started | org.apache.activemq.broker.BrokerService | main

The above log indicate the server has started with nio+ssl transport over port 161617

.

Run Producer and Consumer

I create a scirpt name runProducer.sh with the following contents:

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer -Durl="nio+ssl://localhost:61617" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts \
 -Djavax.net.ssl.trustStorePassword=amqadmin@

Run the above script at $ACTIVEMQ_HOME/examples/openwire/swissarmy

The script for running consumer, namely, runConsumer.sh has the following contents:

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant consumer -Durl="nio+ssl://localhost:61617" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts \
 -Djavax.net.ssl.trustStorePassword=amqadmin@

If the consumer is running, you can check the connections. The following is what I can see:

Note: the URL takes the following form:

url="nio+ssl://localhost:61617"

Summery

In this blog, I have explained the procedures to setup nio+ssl transport for ActiveMQ with the procedures of testing. This should give us a clear picture on how the nio+ssl transport works

Wednesday, February 25, 2015

Setup JBoss Fuse Service Works In Domain Mode

Introduction

First of all, at this writing, the JBoss FSW does not work in domain mode. Hopefully, in the next release, this issue will be resolved. Run JBoss FSW in domain mode has a lot of advantages over standalone mode, in particular, with respect to the deployment and management.

In this blog, I will look into the details about the domain mode setup for JBoss EAP. In my previous blogs about JBoss FSW, I have covered the following topics:

  1. How to install and start JBoss FSW http://ggl-consulting.blogspot.com/2014/10/jboss-service-works-explained.html
  2. How to build, deploy, and test a simple JBoss FSW applications http://ggl-consulting.blogspot.com/2014/10/build-deploy-test-and-debug-jboss-fuse.html
  3. How to cluster JBoss FSW using TCP stack http://ggl-consulting.blogspot.com/2015/02/clustering-jboss-fsw-switchyard.html
  4. Run JBoss FSW As Service In Standalone Mode http://ggl-consulting.blogspot.com/2015/02/run-jboss-fsw-as-service.html

To setup domain mode, we need the following service components:

  1. Domain Controller: control the service nodes under the domain through the communication between domain controller --> host controller --> service nodes
  2. Host Controller: Responsible for the communication between service nodes and domain controller.
  3. Service Nodes: the container for JEE services.

The Topology

I have configured three RHL sandboxes for the setup of domain mode as shown in the following figure:

Setup Domain Controller

To setup domain controller, we need to edit two files [in my case JBOSS_FSW=/opt/app/fsw]:

$JBOSS_FSW/jboss-eap-6.1/domain/configuration/domain.xml
$JBOSS_FSW/jboss-eap-6.1/domain/configuration/host-master.xml

Modify domain.xml

For domain.xml, the only change need to made is the section of server-groups as the following:

  
    ...
    
        
            
                
                
            
            
        
    
 

Modify host-master.xml

The only change I need to make is the following line:




In the enterprise application, you may need to adjust the default jvm and ports options. In my previous blogs, I have covered how to enable various tcp ports by using the tool of system-config-firewall.

Add A Domain Admin User

In order for the host controller to communicate with domain controller, domain controller need to know which credential to use. And this is the purpose we have to create a domain admin user. This admin user will also be use to provision JBoss FSW nodes using cli commands as shown in later secsion. Here is the procedure to create doamin admin user:

[fuse@SANDBOXFUSEV04 bin]$ ./add-user.sh

What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): a

Enter the details of the new user to add.
Realm (ManagementRealm) :
Username : domainadmin
Password :
Re-enter Password :
About to add user 'domainadmin' for realm 'ManagementRealm'
Is this correct yes/no? yes
Added user 'domainadmin' to file '/opt/app/fsw/jboss-eap-6.1/standalone/configuration/mgmt-users.properties'
Added user 'domainadmin' to file '/opt/app/fsw/jboss-eap-6.1/domain/configuration/mgmt-users.properties'
Is this new user going to be used for one AS process to connect to another AS process?
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
yes/no? yes
To represent the user add the following to the server-identities definition 
[fuse@SANDBOXFUSEV04 bin]$

The last line of stdout contains the following text:


Make sure you save the line, we will need it to configure host controller.

Start Up The Domain Controller

To start the domain controller use the following command:

./domain.sh -b 10.66.13.120 -bmanagement 10.66.13.120 --host-config=host-master.xml

Note: the 10.66.13.120 is the ip address of the host of domain controller. You may setup service daemon as I did for standalone mode in the blog: http://ggl-consulting.blogspot.com/2015/02/run-jboss-fsw-as-service.html

Check The Domain Controller Using Web Browser

After starting the domain controller, we can check the status of the domain controller by enter the the url: sandboxfuse02:9990/console. It will promote login. You can use the domain admin credential or the one we setup earlier during the installation. The web browser should should the following.

As you can see, there is not server connected to the domain controller yet. This will change after we setup and start the host controller.

Setup Host Controller

Configuration

The only file to be modified in order to setup host controller is:

$JBOSS_FSW/jboss-eap-6.1.0/domain/configuration/host-slave.xml

There are three places need to be modify in the host-slave.xml as the follows:


    ...

            
                
                     
                     
                
    ....

    
       
    
    ...

    
        
    

  1. The is obtained during our creation of domainadmin user.
  2. In the domain-controller part, I add username="domainadmin". To me this should be put inside the server-identities.
  3. The last part is to define servers controlled by the host controller.

Start Host Controller

The host controller can be started using the following command:

./domain.sh -b 10.66.13.108 -bmanagement 10.66.13.108 -Djboss.domain.master.address=10.66.13.120 --host-config=host-slave.xml

Do the exactly the same for the other host controller. In my case the host controller will run on the host sandboxfusev04. As I start and stop the host congtroller, I can see the following stdout from the domain controller.

[Host Controller] 09:46:26,318 INFO  [org.jboss.as.domain] (slave-request-threads - 1) JBAS010918: Registered remote slave host "sandboxfusev03", JBoss Red Hat JBoss Fuse Service Works 6.0.0.GA-redhat-2 (AS 7.2.1.Final-redhat-10)
[Host Controller] 09:47:17,631 INFO  [org.jboss.as.domain] (slave-request-threads - 1) JBAS010918: Registered remote slave host "sandboxfusev04", JBoss Red Hat JBoss Fuse Service Works 6.0.0.GA-redhat-2 (AS 7.2.1.Final-redhat-10)
[Host Controller] 11:51:06,139 INFO  [org.jboss.as.domain] (Remoting "sandboxfusev02:MANAGEMENT" task-1) JBAS010925: Unregistered remote slave host "sandboxfusev03"
[Host Controller] 11:51:11,160 INFO  [org.jboss.as.domain] (Remoting "sandboxfusev02:MANAGEMENT" task-3) JBAS010925: Unregistered remote slave host "sandboxfusev04"

Looking Inside

After starting both host controller, we can also check the server status by using be web brower. First, let view the domain information from the domain controller as shown in the figure below:

We can see that two hosts are added: sandboxfusev03, sandboxfusev04. If we want to change the host name, we can add name="..." into host-slave.xml.

Summary

In this blog, I have covered the configuration of JBoss FSW in domain mode. In order to get familiarized the JBoss FSW, you may look into the log. If you encounter a problem, you should increase the level of server log by modifying logging.properties which is also under domain/configuration. You should also check which ports are open from firewall by using the command:
sudo iptables -L -v -n

Anypoint Studio Error: The project is missing Munit lIbrary to run tests

Anypoint Studio 7.9 has a bug. Even if we following the article: https://help.mulesoft.com/s/article/The-project-is-missing-MUnit-libraries-...