forward march
Had an interesting problem to solve over the weekend - how to get RMI to work across a restrictive firewall.
Not an uncommon occurence, you might think - there is a FAQ on the topic. In the FAQ item, there is talk of HTTP encapsulation and all manner of weird and wonderful things. Ah, but you see, I don’t really want to run a webserver to get two RMI aware processes to talk to one another, do I ? If I wanted to use HTTP, I would have done that in the first place. WebDav anyone ?
So, no… the FAQ doesn’t really seem to address the problem in the way I wanted it solved.
Now what ?
A quick examination of the endpoint connections made by RMI revealed some more information - RMI always connects to port 1099, the rmiregistry… Thereafter, it uses a variable (negotiated) port number, much like FTP. Has anyone tried to tunnel FTP through a firewall ? No, it’s not fun. There’s a reason for weird things like PASV FTP. Clearly, the RMI people hadn’t figured out that explicitly specified connection endpoints were a good idea, at least when it comes to negotiating opening ports with a suspicious and paranoid firewall admin.
First step: I had to write a RMISocketFactory and setup the connections to always use one or more of ports 3801, 3802, 3803. That takes care of incoming calls. Now, one quick SSH forwarding later, I could get incoming messages through the firewall.
Outgoing ? This is where it got interesting. OpenSSH (and indeed, other ssh clients for all I know) has an interesting command line switch, -D.
This works by allocating a socket to listen to port on the local side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server.
Ye gods. SSH can act as a socks server. Well, RMI can use a socks server to send outgoing calls through a firewall. Anything in Java that uses ServerSockets can use Socks to communicate.
Yeah. That seemed like it would work. And so it did. Two ssh invocations and one RMISocketFactory subclassing later, RMI packets were humming through the firewall.
Just say it
Can't post a comment ? Any other commenting problems ? email lair - at - fierydragon . org