Multi-hop ssh tunnel - howto : Creating a SSH tunnel with port forwarding between multiple hosts

How to create a multi-hop ssh tunnel or how to chain multiple ssh tunnels. (or SSH inception)

For security reasons sometimes you need to jump through hoops in order to connect to a server in SSH and from that server SSH to another server and so on

Consider the following scenario :

  • An application is deployed on a tomcat server on the host3 and listens on the port 8080
  • From my local machine I need to access the tomcat server on the machine host3 but it's not reachable from my machine
  • I need to carry out some tests that need a graphical browser (Firefox, Chrome, etc.)
  • host3 is only accessible from host2which is only accessible from host1

SSH tunneling can help you in this scenario; you can find more information regarding here by forwarding requests on a given port to another port on another machine all through a (or in our case multiple)SSH connection(s)

Below is a graphical representation of what I'm trying to accomplish :

So without anymore delay let's get to it :

All of the following commands are issued from a single terminal, prompt, shell or whatever you want to call it, that needs to remain open to keep alive the tunnels.

1.Connect the local machine to host1 (create the first tunnel)

[ufasoli@local]> ssh -L38080:localhost:38080 ufasoli@host1

2.Connect to host2 from host1 (create the second tunnel)

[ufasoli@host1]>ssh -L38080:localhost:38080 ufasoli@host2

3.Connect to host3 from host2 (create the third and last tunnel)

[ufasoli@host2]>ssh -L38080:localhost:8080 ufasoli@host3

4.Checking the result

Now if everything went as expected you should be able to see your tomcat application by firing your favorite browser with the and entering the target remote URL as a localhost URL with the 38080 port, like for example http://localhost:38080/mywebapp

5.Bonus points

If you prefer you can do all of the above steps in one giant SSH command using the -t flag to chain commands( I also added the -v flag for a more verbose output)

[ufasoli@local]> ssh -v -L38080:localhost:38080 ufasoli@host1  -t ssh -v -L38080:localhost:38080 ufasoli@host2 -t ssh -v -L38080:localhost:8080 ufasoli@host3

17 comments:

  1. good job
    it works
    thanks

    ReplyDelete
  2. Works very well, especially that tip about "ssh -t" to chain commands together.
    Thanks!

    ReplyDelete
  3. Hi thanks for the feedback! glad it was helpful to you ;)

    ReplyDelete
  4. Can you do the same thing if host3 doesn't have ssh? Like it's a windows server? From client, through host1, through host2, to 8080 on host3 that doesn't have ssh.

    ReplyDelete
  5. In that case skip the 3rd ssh, modify second tunnel to be ssh -L38080:host3:8080 ufasoli@host2

    ReplyDelete
  6. can we do this programmatically by passing commands in program using Jsch library in java

    ReplyDelete
  7. Hi,
    I have no experience with this library, but if you can use it to send any linux command through it I would guess yes.

    ReplyDelete
  8. This takes SSH capabilities to a whole nother level! Thank you for sharing this!

    ReplyDelete
  9. Glad it was useful, thanks for the comment!

    ReplyDelete
  10. thank you so much for sharing. So may I just pick any port for the intermediate servers?( host 1 and host2) because I only know the specific ports for host3 and localHost

    ReplyDelete
  11. Hi,
    Yes you can pick any port you want as long as that port is available on the intermediate servers

    ReplyDelete
  12. Is it possible to accomplish this with putty? If yes can you detail it? Coz my local host is windows and hops are all linux machines.

    ReplyDelete
    Replies
    1. Yes you can do this with Putty. SSH is SSH as long as you are in a terminal (putty or moba xterm) you can do this. just use the part where he strings it together or uses the seperate parts. It does not matter if you are on windows if you are using putty.

      Delete
  13. I want to connect from local mobaterm to abc@101.231.245.190(jump server 1).
    Then I need to connect to jump server 2 i.e. (xyz@101.188.214.125).

    I tried below but does not work:

    [nitin@local]> ssh -L38080:localhost:38080 abc@101.231.245.190
    [abc@101.231.245.190]>ssh -L38080:localhost:8080 xyz@101.188.214.125

    Please help here

    ReplyDelete

OSX show used ports or listening applications with their PID

On OSX you can display applications listening on a given port using the lsof the commands described below will show listening application...