0

Suppose I have a computer compute_mine. I have ssh access to two remote computers compute_remote_1 and compute_remote_2. I would like to forward a port from compute_remote_1 to compute_remote_2. However, I would like to initiate and control the port forwarding process from compute_mine. No data from compute_remote_1 or compute_remote_2 should be forwarded to compute_mine.

I need the port forwarding to be automatically terminated when the process on compute_mine terminates for whatever reason. I would also like to avoid multiple ssh instances.

A rough approximation would be an ssh ProxyCommand issued from compute_mine as follows: On compute_mine: ssh into compute_remote_2 'ProxyCommand forward port from compute_remote_1 to local port on compute_remote_2'

I have tried various ssh ProxyCommands but nothing has worked so far. Any suggestions ?

I have tried various ssh ProxyCommands issued from compute_mine to remote_compute_2. For example: ssh -o 'ProxyCommand=ssh -W host:port user@remote_compute_1 -v' user@remote_compute_2 -P port_number -NTC

This quit with the error: banner exchange: Connection to UNKNOWN port 65535: invalid format

2
  • Do you get the same thing if you try -J instead, like ssh -J remote_1 user@remote_2 from compute_mine? The banner exchange error you got looks like ssh choked on the banner from the server side - take a look through the troubleshooting steps here unix.stackexchange.com/q/656631/247007 to see if you can suppress it or get a more detailed error
    – Cpt.Whale
    Commented Oct 17, 2023 at 17:52
  • The machines I am using run an older version of ssh which does not support ProxyJump. In any case, wont the jump command run a tunnel from remote_2 to compute_mine via remote_1 ? I would need a tunnel between only remote_1 and remote_2. Computer compute_mine should not listen, only issue the command for the tunnel between remote_1 and remote_2 to start. Commented Oct 17, 2023 at 18:40

3 Answers 3

0

Try this to run on 'compute_mine':

ssh -L localhost:8081:localhost:8080 -o "ProxyCommand=ssh -W %h:%p user@compute_remote_2" user@compute_remote_1 -N

This command sets up the SSH tunnel using ProxyCommand instead of -J. The -W option in ProxyCommand specifies the host and port to forward to (%h:%p will be replaced by the target host and port).

0

This isn't exactly what you asked for, but it might solve your problem:

ssh compute_remote_1 ssh -L 8080:localhost:80 compute_remote_2 sleep 10

Assuming you are going to run something on your machine that uses the tunnel. You have 10 seconds to start using the tunnel after the above command has been executed (change the sleep 10 for a different value).

Once the SSH tunnel is in use the SSH commands won't terminate, however as soon as the last connection stops using the tunnel the SSH commands will terminate - which will tear down the tunnel.

You could also nohup the remote ssh command if you want your local SSH command to return immediately.

0

I don't think ProxyCommand can help you. It acts as an alternative for the raw TCP connection. To get the idea, see this answer where ProxyCommand is not used for proxying. No matter what command you specify as ProxyCommand while invoking ssh -L or ssh -R on compute_mine, one end of the tunnel will be compute_mine. And the command specified as ProxyCommand is run locally, so if you in turn use ssh -L or ssh -R inside ProxyCommand then one end of the tunnel will be compute_mine as well.

Similarly with ssh -J all connections begin on the local computer, i.e. on compute_mine in your case. If ssh -J is run on compute_mine, a port forwarding with -L or -R will involve compute_mine.

To forward a port from compute_remote_1 to compute_remote_2 not via compute_mine, you need an SSH connection that starts at compute_remote_1 or compute_remote_2.

From compute_mine you can do this:

# not an answer yet
ssh compute_remote_1 'ssh -NL 5678:localhost:1234 compute_remote_2'

The tunnel will be established by ssh -NL … compute_remote_2 started on compute_remote_1. The problem is this ssh won't exit automatically when ssh running on compute_mine is terminated.

A solution is to use ssh -tt on compute_mine:

ssh -tt compute_remote_1 'exec ssh -NL 5678:localhost:1234 compute_remote_2'

(-t is usually enough, but -tt will do what we want even if there is no local terminal.)

This will allocate a tty on compute_remote_1 and start a shell as the controlling process of the tty. The shell will execute exec ssh … an thus replace itself with ssh. The point is we want ssh to be the controlling process. Some shells exec the last command automatically (an optimization, a sane behavior when there is nothing more to do), but it's better to exec explicitly in case the shell on compute_remote_1 is not that smart.

The easiest way to terminate the port forwarding by acting on compute_mine is to type Ctrl+c it the terminal where our ssh -tt runs (if such terminal exists). This won't directly kill ssh -tt, ^C will get to compute_remote_1 and the tty there will kill ssh -NL (see this answer). Our local ssh -tt will exit later.

ssh on compute_mine may exit first for whatever reason, e.g. you may kill it. If this happens and if sshd on compute_remote_1 notices (depending on circumstances it may or may not notice immediately, see this answer), then the tty on compute_remote_1 will be closed and the controlling process will get SIGHUP. We made sure the controlling process is ssh that handles the port forwarding, SIGHUP will terminate it. This way the port forwarding is automatically terminated when the ssh process on compute_mine terminates.

It's up to you if you ssh -tt from compute_mine to compute_remote_1 or to compute_remote_2; and if you use ssh -NL or ssh -NR there. The "target" of port forwarding does not have to be localhost, so e.g. ssh -NL 5678:compute_remote_2:1234 compute_remote_3 on compute_remote_1 may make sense. Adjust the solution to your needs.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .