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?


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


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


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...

  • You don't need the two sets of tunnels you have - you can ssh to one machine and tunnel out of it into another machine. Answer updated to include that. – EightBitTony Aug 23 '11 at 18:13
  • What's the point of redirecting ports 1099? Could you precise whether bastion-host can connect to server1 and server2 without a firewall being involved? – Stéphane Gimenez Aug 24 '11 at 16:27
  • Have you tried using the most simple option, at the bottom of my answer, and if so, what error / problem did it give? – EightBitTony Aug 24 '11 at 17:32
  • @EightBitTony - Unfortunately this wont work, since rmi opens a random port once connection is established. The purpose of the -D option is to tell the rmi server what port it should use. However, I can only specify the SOCKS proxy port once in visualvm, and my 2 tunnels cannot share the -D option. – toolkit Aug 24 '11 at 19:41
  • See stackoverflow.com/questions/1706685/… – toolkit Aug 24 '11 at 19:42

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.

|improve this answer|||||
  • This answer looks helpful, I was about to write something similar, could the downvoter give some reason? – Stéphane Gimenez Aug 24 '11 at 15:59

From the ssh manpage:

 -D [bind_address:]port
         Specifies a local “dynamic” application-level port forwarding.
         This works by allocating a socket to listen to port on the local
         side, optionally bound to the specified bind_address.  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.  Only root can forward privileged ports.
         Dynamic port forwardings can also be specified in the configura‐
         tion file.

You're specifying the same local port to forward from twice; Try -D 9697 on your second setup.

|improve this answer|||||
  • Unfortunately it appears that visualvm only lets me set this once. Is there a way around this? – toolkit Aug 23 '11 at 17:14
  • Use -L, not -D, as specified in @EightBitTony's answer. -D is for SOCKS-style proxing - eg, routing HTTP through an SSH tunnel. – John Hart Mar 21 '14 at 16:55

The last step says enough: It can't start listening at port 9696. That's because if it's your second tunnel you should use another port while 9696 is handling the first one.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.