SSH tunnelling with multiple dynamic port forwardings

port-forwardingssh

I am trying to monitor multiple JVMs running on different servers through an ssh tunnel.

Thanks to one of the UNIX gurus here, I have managed to get this running for a single server by:

  1. Run jstatd on the target server
  2. Set up Visual VM to use 9696 as its socks proxy port.
  3. On my local PC, run:

    ssh -L 2222:server1:22 bastion-host
    
  4. On my local PC, run:

    ssh -o port=2222 -D 9696 -L 1099:localhost:1099 localhost
    

This does the trick. Now when I try and tunnel to a second server I try:

  1. On my local PC, run:

    ssh -L 3333:server2:22 bastion-host
    
  2. On my local PC, run:

    ssh -o port=3333 -D 9696 -L 2099:localhost:1099 localhost
    

However, the last step complains with:

bind: Address already in use
channel_setup_fwd_listener: cannot listen to port: 9696

Has anyone managed to do something similar?

Update:

The reason this is so complex is that jstatd is an RMI server application:

http://download.oracle.com/javase/1.5.0/docs/tooldocs/share/jstatd.html

As with RMI applications, these register with an rmiregistry. Using rmi through a firewall requires me to use SOCKS as described here:

http://download.oracle.com/javase/1.4.2/docs/guide/rmi/faq.html#firewallOut

Unfortunately, visualvm only lets me set the SOCKS proxy port once, and the -D option won't allow me to forward the same local port to both servers…

Best Answer

Am I right in thinking you've got your computer (computer A), and say two servers (A and B) which you can't connect to directly on a certain port and so want to tunnel to them over SSH?

If so, you create two tunnels from your machine (one to each target server) on different local ports using -L not -D, and then in your monitoring tool you connect to your local machine (no proxy settings) as if it was the remote server you want to check.

ssh -L 9000:localhost:<local port jstatd listens on> user@server1
ssh -L 9001:localhost:<local port jstatd listens on> user@server2

Then using your local monitor you connect to localhost:9000 and localhost:9001 and those tunnels connect you to your target jstatd's.

If there's an intermediate server, then a two hop tunnel,

ssh -L 9000:server1:<local port jstatd listens on> user@bastion-host
ssh -L 9001:server2:<local port jstatd listens on> user@bastion-host

Hmm, if bastion-host can talk to all the JVM's, then

ssh -D 9000 user@bastion-host

Is enough to create a socks proxy you can then just use over port 9000.

Related Question