Sunday, January 29, 2017

More Fun and Games with SSL and Netty

To run the test program, you should have maven and git installed.

Download the Project

git clone git://github.com/ClarkHobbie/ssltest.git

Compile the Project

mvn package

Download Netty

http://dl.bintray.com/netty/downloads/netty-4.1.7.Final.tar.bz2

Run the Server

java -cp ssltest\target\ssltest-1.0-SNAPSHOT.jar;netty-all-4.1.7.Final.jar \
    SslServer






NOTE: this must be run in the same directory as the keystores

Run the Client

java -cp ssltest\target\ssltest-1.0-SNAPSHOT.jar;netty-all-4.1.7.Final.jar \
    SslClient






NOTE: this must be run in the same directory as the keystores
Hopefully, SslClient prints out "It worked!" and terminates.
The program uses the keystores created in the previous posts, testing that SSL works.

Saturday, January 28, 2017

Fun and Games with SSL and Netty

I had so much fun with SSL and netty that I will relay my solutions here.

This servers two purposes: firstly, anyone trying to do this can refer to my notes, and hopefully avoid the hours of frustration I endured, but mostly, this will serve as a reminder when I have to do this again.  Which, given my luck will be tomorrow.

Paths

You will need to setup your paths so that openssl and keytool can be executed directly.

openssl

This post assumes that you have openssl.  I use windows so I got mine from


You can get openssl for different platforms form

Credit Where Credit is Due

This post borrows heavily for the Oracle docs for creating and using a certificate authority.  You can find theses posts at:

A Note on Passwords

For this example I am using the string "whatever" as my password to all the key stores.  You can use something else but the examples all assume "whatever" is the password.

What I am Trying to Achieve

I am trying to have Miranda nodes communicate with SSL.  So all the Miranda nodes need certificates.  Rather than getting CERTs for all the nodes, I am going to create a new certificate authority, sign all the keys and then use that CA when I use SSL.  

Instructions

  1. Create a New CA
  2. Create a tust store
  3. Create keys for each node
  4. Create certificate signing requests for each key
  5. Sign each request keys with the CA
  6. Import the CA to each node's keystore
  7. Import each CERT to the node's keystore

Create a New CA

I used the instructions on this link to create a new CA.  Briefly, here they are:

openssl req -new -x509 -keyout ca-key.pem.txt -out ca-certificate.pem.txt -days 365

I used "whatever" as the password and took the defaults for the key.

Alternate Procedure for Creating the CA

openssl genrsa -out ca-key 2048
openssl req -x509 -new -key ca-key -out ca-certificate -days 365

Create a Trust Store

After a bit of trial-and-error, I came up with this command:

keytool -import -keystore truststore -file ca-certificate.pem.txt -alias ca -keyalg rsa -storepass whatever


I entered "yes" to accept the key.

Create Keys for the Sever

Going back to the Oracle docs, I used the following:

keytool –keystore serverkeystore –genkey –alias server -keyalg rsa -storepass whatever

I took the defaults.

Create a Certificate Singing Request for Each Key

Once again, from the Oracle docs:

keytool –keystore serverkeystore -storepass whatever –certreq –alias server –keyalg rsa –file server.csr

Sign the Server Request with the CA

From the Oracle docs:

openssl x509 -req -CA ca-certificate.pem.txt -CAkey ca-key.pem.txt -in server.csr -out server.cer  -days 365 -CAcreateserial





Import the CA to the Server's Keystore

keytool -import -keystore serverkeystore -storepass whatever -file ca-certificate.pem.txt -alias ca -keyalg rsa



It asked me whether I trusted the key ("yes").

Import the CERT to the Server's Keystore

From the Oracle docs:

keytool -import -keystore serverkeystore -storepass whatever -file server.cer -alias server -keyalg rsa

At this point, you should have a key store called "severkeystore" that contains the server keys and the CA.  You should also have a key store called "truststore" that contains just the CA.  You are now ready to test it out (in my next post).

Sunday, January 8, 2017

File Structure

Miranda has the following directory structure:

Name Default Description
com.ltsllc.miranda.ClusterFile data/cluster.json Where the system keeps information about the cluster
com.ltsllc.miranda.UserFile data/users.json Where the system keeps information about the users
com.ltsllc.miranda.TopicsFile data/topics.json Where the system keeps information about the system topics
com.ltsllc.miranda.SubscriptionsFile data/subscriptions.json Where the system keeps information about the subscriptions
com.ltsllc.miranda.MessagesDirectory data/messages The directory where the system keeps the messages files
com.ltsllc.miranda.DeliveriesDirectory data/deliveries The directory where the system keeps the deliveries files

Miranda keeps several messages files. Each one holds 100 messages.  The files are named with the index of the first message in the file, so the first one is named "1.json" the next "101.json" and so on.

Deliveries are kept in a directory with the name of the subscription, with the files named for the index of the first message in the file.  The deliveries are kept in groups of 100 so the first file is named "1.json" the second "101.json" and so on.

All files are JSON, cluster.json contains a list of hosts, users.json contains a list of users, topics.json contains a list of topics and suscriptions.json contains a list of subscriptions.

The messages file contains messages in the system.  Each of the files in the deliveries directory   contains a list of delivery objects.

Friday, January 6, 2017

Property Augmentation

Property Augmentation is the process of adding new properties to an object without doing anything to existing properties.

Miranda uses this when it defines its properties and their default values.

Miranda looks at the command line for a properties file, but if it doesn't find one it looks in the system properties for a property named MirandaProperties.PROPERTY_SYSTEM_PROPERTIES (currently defined to be "com.ltsllc.miranda.Properties").  If that is not defined then the system uses the default name (currently "miranda.properties").

The system augments the system properties with default values (defined by MirandaProerties.DEFAULT_PROPERTIES) and then, if the properties file exists.  It tries to load that file and it uses that to augment the system properties.

One of the things about augmentation is that the last write wins, so this is really a long winded way of getting the system properties.

Wednesday, January 4, 2017

Properties

I think that all the files for Miranda will be JSON; except I'm not sure about the main properties file.

I can't decide if it will be a "regular" properties file (one that java.utils.Propertis can handle) or JSON.

The application properties file will have things like what the other files are, what ports Miranda listens to, etc.

I will probably "decide" several times so I don't know what I'm worrying about.

I think that, at first, I will go with a standard properties file, and change my mind if circumstances dictate otherwise.

Sunday, January 1, 2017

Prospero

The name Prospero comes form the play The Tempest by William Shakespeare.  The  original Prospero system was written by Chris Chew in Erlang with a little help from me (I wrote a module that parsed XML).

Miranda is a Java port of Prospero with a few changes.  First of all it is written in Java instead of Erlang. It was very difficult to find people who had done functional programming (other than JavaScript) let alone Erlang so I view this as an improvement.

Secondly, Miranda doesn't need RabbitMQ.  This meant that you needed a whole other cluster devoted to RabbitMQ which had to have fast access to your nodes to work.

Finally, Prospero used Mnesia.  In addition to backups (Mnesia had the unfortunate habit of corrupting its files), Mnesia didn't cross AWS availability zones too well.  Miranda is designed to run with nodes in different availability zones.