Protege Client Server RMI

From Protege Wiki

Revision as of 09:09, February 23, 2009 by Tredmond (Talk | contribs)

Jump to: navigation, search

How Does RMI Work?

This page is part of the Protege client-server tutorial.

First a disclaimer. I am not an expert on the RMI protocol. The following is based on observations of how the RMI protocol behaves and debugging problems that can happen in ordinary practice. This behavior is further confirmed by the "black magic" tricks (running an rmi server through NAT and tunneling a connection to an rmi server) that we describe in this section. I enthusiastically encourage others to correct or improve these pages.

This page discusses the interaction of a server, rmi registry and a client. The simplest case is shown in the figure below.

RMIProtocol01.png

The steps in the protocol are:

  1. The server registers (Registry.bind) a remote object with the RMI registry giving it a name. Inside the remote object is the hostname of the server. It turns out that this hostname comes from the -Djava.rmi.server.hostname=... jvm parameter.
  2. The client goes to the RMI registry to get the remote object bound to a particular name.
  3. The client invokes the remote object and contacts the server.
Even just this bit of information can be helpful debugging problems. For example, occasionally - often due to a system misconfiguration, the line
 HOSTNAME_PARAM=-Djava.rmi.server.hostname=`hostname`

from the run_protege_server.sh script will provide the wrong information. In particular sometimes the hostname command simply returns localhost. This means that the remote object registered in the RMI registry and therefore the object given to the client will indicate that it can be found on localhost. This will not work unless the client is on the same host as the server.

Black Magic Trick #1: Tunneling RMI out of a private network

Note that this example is not as well motivated as the next one but it is a little less dangerous. If you do this technique then you should make sure that you understand the security implications. Also I only currently know how to set this up on unix machines (including osx). I am sure that this works on Windows but there is one step where I don't know the magic incantation.

Sometimes you will have permission to access a private network but will be temporarily working outside the private network. The simplest way to gain access to the servers on the private network is to use a VPN. The Cisco VPN seems to be very popular. But VPN's have disadvantages. They often come with policies that make work difficult and they are not always available. An alternative that is occasionally useful is to use a tool such as ssh to tunnel the connection from your machine to the private network.

If you have ssh access then it is not difficult to set up the tunnels. Suppose that the machine you are connecting to is called my.office.com and the Protege server listens on port 5200 and the rmi registry is listening on port 5300. A command like

     ssh -L 5300:localhost:5300 -L 5200:localhost:5200 my.office.com

will do the trick. Then when you connect in the Protege client, you specify the machine as localhost:5300. Protege will then tunnel straight to the RMI registry and the RMI registry successfully returns the server object to you. However, unless you do something more, this technique still won't succeed. What happens is shown in the figure below.

RMIProtocol02.png

The problem is that when the server registers the server object with the rmiregistry, the hostname specified in the server object is my.office.com. The client successfully connects to the registry through the tunnel but when it gets the server object it tries to access it through my.office.com:5200. We some how need to convince the client to use localhost:5200 instead of my.office.com:5200.

This is where the magic unix incantation comes in. As root, you can edit the /etc/hosts file and add a line

     127.0.0.1    my.office.com

What this does is to falsely convince the client that the address my.office.com refers to is located at 127.0.0.1. Now the client goes to 127.0.0.1 when accessing the server object and the behavior is as shown below.

RMIProtocol03.png

Success!

Black Magic Trick #2: Exporting RMI from a NAT'd server

In this case you are the adminstrator of a private network which has a server that you want to expose. Unfortunately the private network is protected by NAT so that the server host inside the network is not visible outside the private network. But you can still win!

This technique is more likely to be useful than the previous trick but it requires a bit more care. When changing the settings on a router you run the risk of breaking the router functionality and causing the network to fail. When I first started playing with settings on my router I came to a phase where I grew over-confident. I used to tunnel to a remote network and access the router remotely. It only took a couple of misconfigurations for me to realize that I needed to be a bit more careful. You have been warned.

One thing that you can sometimes do before configuring a router is to save the router settings first. For example, the Linksys router has a place to save the configuration under Administration->Manage Configurations. I have seen this configuration in other routers also (Netgear I think).

RMIProtocol-RouterSave.png

First, it is clear that you will only succeed if the router at the boundry of your network forwards requests to your server and your RMI registry. So you need to access the router configuration and set up some forwarding requests.

RMIProtocol-Router.png

The collab1 and collab2 entries are the ones that I needed. I was a little surprised to see the vnc line but at least it was not enabled. At this point what you are hoping for is the behavior below.

RMIProtocol04.png

However as before, the problem is that the object that the server registers with the server say it can be found on the host 192.168.2.62. This address makes no sense to the client and the protocol fails.

But this is easy to fix. We simply change the hostname line in the run_protege_server.sh script as follows:

     HOSTNAME_PARAM=-Djava.rmi.server.hostname=24.4.236.98
Now the server object registered with the rmiregistry will say it can be found at 24.4.236.98. When the client tries to access this it goes to the router who redirects the request to the server.
Personal tools