SSH Tunnel Through a Jump Host for Arbitrary Services

  • In making an SSH Tunnel, let's start with a simple description: we have a final host (the machine that we want to access), a jump host (the intermediary), and a workstation at which we are sitting. We want to be able to issue an SSH command from the final workstation and get access directly to the final host, but neither the final host nor the workstation can talk directly through each other, so need a mutually accessible intermediary.

    While this process can be used to pass SSH from the final host to the workstation, that is just one protocol option. SSH is the VPN technology here, not necessarily the end use application. A common reason to do this might be to use virt-manager remotely, to connect to Cockpit remotely, or to work on a locally hosted web GUI that is otherwise inaccessible.

    To start, we need a tunnel from the final host to the intermediary. Such as below.

    ssh -fN -R 10022:localhost:22 [email protected]

    Then we need to make the tunnel from our workstation to the jump server. Something like this:

    ssh -L 8888: [email protected]

    Now on the workstation you can use port 8888 to reach port 22 on the final host! So let's talk about what is happening here a little. First of all, this is a VPN, just a single port VPN.

    Next, we have three ports involved here: 22 on our final location, 8888 on our workstation, and 10022 on our intermediary. All three of these are more or less arbitrary. The port on the final host has to be the port that you want to reach. This would be 22 for SSH, 443 for HTTPS, 3306 for MySQL, whatever. The intermediary port, or 10022 in our example, has to be the same on both lines, but is any available high number port (port over 1024) that you want to use. And the local access port of 8888 is, likewise, any high number port that is available locally on the workstation that you want to use.

    The first command is making a reverse tunnel (the -R does this) where the SSH tunnel is being used to provide a resource rather than to consume it like SSH normally would do. So it is a "server" action, rather than a workstation action. The first command creates this reverse tunnel from the final host to the intermediary server, so that it is waiting for use. The second command creates a tunnel from the workstation to the intermediary server. Once we do both, we have both legs of our connection and can begin work.

    Of course, doing this with port 22 isn't very exciting. But try it with port 443 or 9090 for Cockpit and you have something extremely useful.

  • What is "interesting" about this process is that the final host logs into the jump box (intermediary) and the workstation also does. The one machine that you never need to run a command on is the jump box.

  • You need to clarify (more) that you are building a tunnel with SSH for other things to run. This is not about simply connecting to a remote host with SSH via a jump box.

    I know you used the word tunnel, but the reading of your post is murky.

    For reference to others, connecting through a jump host with SSH is simply


    A real example

    ssh -J

  • @JaredBusch added additional language to make it more clear.

  • When I looked into different options for ssh tunneling here on ML in this thread, I learned that -R and -L are TCP port forwarding but in different directions.

    But there is also the dynamic port forwarding, socks proxy, option. And then the real VPN tunnel option where you use ssh to create a tun device. That can be used to route traffic.

    There are lots of ssh tunneling trickery on this page:

  • @Pete-S yeah, it is crazy powerful.

  • I've already used this guide again. LOL, boy this is handy.

Log in to reply