Sunday, May 7, 2017

Certificate Authorities

When a new instance of Miranda is created the user(s) need to create a new Certificate Authority (CA).  The CA can be self-singed or signed by a recognized authority like Verisign.  The CA signs the certificate that a Miranda node is required to present upon joining the cluster.

This authenticates the server to the clients and validates a client wanting to join the cluster.

The clients need the CA's certificate so that when they communicate with the server, to publish a new event for example, they can establish an SSL connection.  The other severs need the CA's certificate to verify other sever's certificates when a remote system tries to join the cluster.

The CA's certificate thus has to be added to all the client trustores  as well as all the server trustores.

Saturday, May 6, 2017

2 Phase Commits

Events and Deliveries  are controlled by remote policies, but creates/updates and deletes of User, Topics and Subscriptions go through a 2 phase commit.

The node that initiated the operation takes on the role of coordinator

During phase 1, nodes agree that a write is OK and prepare to go through with the operation (commit) or abort the operation.  If any node signals that they are not ready then the coordinator should abort the operation.

During phase 2 the coordinator tells the rest of the node to either commit or abort.  Assuming all the nodes responded that they were ready during phase 1, the coordinator signals that the nodes should commit.

As a concrete example, suppose an admin wants to add a new user to the system.  The node that the admin contacts acts as the coordinator.  The admin supplies the required information and the system announces it's intention to add the user to the rest of the nodes.  In this case, the other nodes check to see if they already have a user with the same name. Assuming they don't they signal that they are ready to add the user.  The coordinator issues a commit and the new user is added to the system.

Monday, May 1, 2017

Cross Origin Resource Sharing (CORS)

When I decided to split Miranda into two parts, I had to deal with CORS.  This is because the pages reside in one origin, but the servlets come from another.  It turns out that a servlet needs to implement the HTTP OPTIONS method and return the following headers:

Allow: *
Access-Control-Allow-Origin: *;
Access-Control-Allow-Headers: origin, content-type, accept, authorization, Access-Control-Allow-Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
Access-Control-Max-Age: 1209600

The servlet itself needs to return the following header:

Access-Control-Allow-Origin: *

The following header needs to be added to the request:


Sunday, April 30, 2017

To Divide or not to Divide?

I was thinking of making the part of Miranda that serves web pages separate from the rest of the system.

On the pro side this makes Miranda a bit more secure and reliable.  The web side can go down without bringing down the rest of the system.  If an attacker gains control of the web side the rest of the system is OK.

On the con side, Miranda will still have to host servlets, and they will probably be hosted by the same software as the web pages (Jetty).

Decisions, decisions.

I will divide Miranda into two parts because it offer more security and flexibility.  The Miranda side can use something that is optimized for servlets while the web side can use something optimized for HTML.

Saturday, April 29, 2017

Miranda & Logins

Miranda doesn't do passwords.

This is partially for security reasons (a system that deals in password may not be secure) but mostly because passwords are a pain.

Passwords are a pain because to do them properly, you can't store them in cleartext (an attacker who gained access to the system could get them) and, even encrypted or hashed they are still sensitive information.

Since Miranda already requires user to register a public key it uses that.  When a user "logs in" they simply provide their user name.  The system determines whether they already have an active session, If they do, the system returns it.  If they do not have an active session the system creates one.

When the system creates a session, it uses a random, 8-byte integer to identify it, the session id. When the system hands the session id back to the user, it first encrypts the value with the user's public key.  When the user gets this encrypted value, they decrypt it with their private key.

The user supplies the session id with all their requests, so the system validates their identity.

It is extremely unlikely that an attacker could guess a valid session id, and most operations could be modified to limit the number of failed attempts.  The exception are new events which require the system to process them as quickly as possible.

The alternative  is to detect when a large number of failed uses of session ids has occurred. Something for my todo list!

Tuesday, April 18, 2017

Introducing Miranda: Certificate Authorities

In preparation for a talk I'm giving at DOSUG I'm going to post my thoughts as they develop. At this point, I'm filling in the gaps so things may skip around a lot.

By default, you define a new certificate authority when you install Miranda.  The new certificate authority signs the certificates of all the Miranda nodes so that they can join the cluster.

When a node tries to join the cluster, it is asked to present a certificate. The cluster checks that the certificate is signed by the certificate authority before the node is allowed to join the cluster.  When clients contact the system with the web interface, this is also the certificate that is used by SSL/TLS.

The certificate authority itself can be signed by something like Verisign or it can be self-signed.  The default is to use a self-signed certificate.  This allows people to take Miranda for a "test drive" without requiring them to get a certificate first.

Sunday, April 16, 2017


Everything goes through the Miranda object.  This is because the Miranda object knows to tell the rest of the cluster about things like new Sessions and new Events. This also makes for a cluttered Miranda class since it has to know about the details of lots of operations.

The solution, as I see it, is to create a temporary subsystem for each operation: an Operation class. An object capable of receiving messages is required, hence a subsystem, and it knows about the details of the operation, thus the Miranda class is less cluttered.

The first of these operations is the login operation.  It is created when the Miranda object is asked to perform a login.  It looks up the user and creates a session for them.  If the user doesn't exist, then it signals this and terminates.