luni, 12 iunie 2017

Client/Server SSL certificate authentication (using self signed certificates)


Let's discuss today about how you can configure a JBoss application server to accept secure connections only from clients who possess the associated client certificates.   We're going to generate and use self signed certificates (a generated EV SSL certificate from a trusted certificate provider will cost up to $300 per year).


The steps to configure a secure client server connection, where the server only accepts connections from clients who possess an associated client certificate to the server one.  This approach is useful where you have front office applications exposed over the internet, and you want only certain users to be able to connect to them.

The process is the following (in short):  
  1. generate the certificate authority, 
  2. generate the server certificate based on the generated CA and keys, 
  3. generate the client certificate based on the generated CA and keys, 
  4. then configure the app server and the browser with server and client certificates respectively (after applying required certificate formats transformations)



A  Certificate generation

1 Download and install Openssl

2 Generate a CA (certificate authority) - use the same pass for all certificates created
2.1 openssl req -out ca.pem -new -x509
-generates CA file "ca.pem" and CA key "privkey.pem"

3 Generate server certificate/key pair
3.1 openssl genrsa -out server.key 1024
3.2 openssl req -key server.key -new -out server.req
3.3 openssl x509 -req -in server.req -CA CA.pem -CAkey privkey.pem -CAserial file.srl -out server.pem
-contents of "file.srl" is a two digit number.  eg. "00" (i.e. on linux run echo “00” >> file.srl)

4 Generate client certificate/key pair
4.1 Either choose to encrypt the key(a) or not(b)
        a. Encrypt the client key with a passphrase
            openssl genrsa -des3 -out client.key 1024
        b. Don't encrypt the client key  - I only tested this option
            openssl genrsa -out client.key 1024
4.2 openssl req -key client.key -new -out client.req
4.3 openssl x509 -req -in client.req -CA CA.pem -CAkey privkey.pem -CAserial file.srl -out client.pem
-contents of "file.srl" is a two digit number.  eg. "00"

B  Client configuration

5 Convert client certificates from pem to pfx
5.1 cat client.pem ca.pem >> clientcertchain.pem
5.2 openssl pkcs12 -export -in clientcertchain.pem -out clientcertchain.pfx
5.3 openssl pkcs12 -export -in ca.pem -out ca.pfx

6 Import client certificates into browser
6.1 Chrome browser: type in chrome://settings/advanced.   Search for SSL, click on manage certificates.  Navigate to “Trusted Root Certificate Authorities”, import certificate ca.pfx.
6.2 Chrome browser: type in chrome://settings/advanced.   Search for SSL, click on manage certificates.  Navigate to “Personal”, import certificate clientcertchain.pfx.

C  Server configuration

7 Convert server certificates from pem to pfx
7.1 openssl pkcs12 -export -out server.pkcs12 -CAfile ca.pem -chain -noiter -in server.pem -inkey server.key
7.2 openssl pkcs12 -export -out ca.pkcs12 -noiter -in ca.pem -inkey privkey.pem

8 Copy certificates
8.1 Copy them to the JBoss configuration folder

9 Convert server certificates to JKS format for JBoss usage - copy them on the JBoss server - keytool is a java command
9.1 keytool -importkeystore -srckeystore ca.pkcs12 -srcstoretype pkcs12 -srcalias 1 -destkeystore ca_keystore.jks -deststoretype jks -deststorepass xxxxx -destalias ca_server_jboss
-make sure the src alias match by running the command keytool -v -list -storetype pkcs12 -keystore ca.pkcs12
-destination store password needs to be set as well - this should be identical with the certificate store password due to a JBoss implemenation limitation
9.2 keytool -importkeystore -srckeystore server.pkcs12 -srcstoretype pkcs12 -srcalias 1 -destkeystore server_keystore.jks -deststoretype jks -deststorepass xxxxx -destalias server_jboss
-make sure the src alias match by running the command keytool -v -list -storetype pkcs12 -keystore server.pkcs12
-destination store password needs to be set as well - this should be identical with the certificate store password due to a JBoss implemenation limitation

10 JBoss configuration
10.1 Adjust the SSL connector with the bolded info
<ssl name="20150914" password=“xxxxxcertificate-key-file="../standalone/configuration/server_keystore.jks" protocol="TLSv1.1,TLSv1.2" verify-client="true" ca-certificate-file="../standalone/configuration/ca_keystore.jks" ca-certificate-password=“xxxxx”/>

D Connection check

11 Point the browser to the SSL JBoss port and check connection.   At this point any other browser that does not have the client certificates should not be able to connect.





miercuri, 18 ianuarie 2017

JBoss clustering in the cloud

This is a short post on some JBoss clustering options when working with cloud platforms.  There are also other possibilities such as using tunnels but I will cover that in a later post.   I am also not going to write right now about other considerations such as security, reliability etc.

I am currently a Solution Architect and I work on designing Cloud Services solutions.  We're making use of Microsoft Azure Cloud Platform to deliver our services to clients.

I am going to outline a few thoughts regarding JBoss clustering in the cloud.

As you might be aware, usually cloud infrastructures do not allow for IP multicasts.  Usually a cluster configuration needs to account for this and choose alternate protocol stacks to work around this limitation.  

Usually this means dropping UDP, relying on TCP and either configuring the nodes IPs in the cluster configuration files or relying on TCPGOSSIP to emulate the multicast for you.   The TCP alternative is less scalable since more network traffic is involved between the JBoss nodes as opposed to UDP.

I will focus on two ways of handling the clustering: TCP + TCPPING and TCP + TCPGOSSIP.

TCP + TCPPING
This configuration usually involves manually configuring JBoss nodes within the cluster configuration.   While it is simpler to setup, it has the drawback that one needs to adjust the configuration if the cluster needs to scale dynamically - for instance if you need to adjust the number of cluster members based on the current system load (automatic provisioning of cloud resources).

<subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="tcpping">
    <stack name="tcpping">
        <transport type="TCP" socket-binding="jgroups-tcp"/>
        <protocol type="TCPPING">
            <property name="initial_hosts">1.1.1.1[7600],1.1.1.2[7600]</property>
            <property name="num_initial_members">2</property>
            <property name="port_range">0</property>
            <property name="timeout">2000</property>
        </protocol>
        <!-- ... -->
    </stack>
</subsystem>

TCP + TCPGOSSIP
If you go the TCPGOSSIP route, then the server or servers hosting the TCPGOSSIP instances need access to all the JBoss nodes.  The good news is that you can configure more than one TCPGossip instance so you are covered from the availability standpoint.  All traffic between the JBoss nodes is routed through the TCPGOSSIP instances.

<subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="tcpgossip">
    <stack name="tcpgossip">
        <transport type="TCP" socket-binding="jgroups-tcp"/>
        <protocol type="TCPGOSSIP">
            <!-- GossipRouters -->
            <property name="initial_hosts">1.1.1.1[12001],1.1.1.2[12001]</property>
            <property name="num_initial_members">2</property>
            <property name="timeout">3000</property>
        </protocol>
        <!-- ... -->
    </stack>
</subsystem>


Enjoy :)