Once upon a time, I was doing on-site support for a hardware install at a hotel a few years ago. The remote tech’s remote desktop software didn’t want to play with my Linux laptop, so he couldn’t get into the switch he needed to configure, to make the install work. I asked if it had an SSH port he could use, were he were in the room with me. Of course it did, but that didn’t do him much good. I ran a reverse SSH tunnel out to my public server, and pointed it at the switch on the local side. I convinced him to SSH to my server on the given port, and he was magically connected to his switch. He was literally in awe of that trick, and demanded to know how it could be done. SSH is magical, but tunneling traffic over SSH is straight-up wizardry. [Shawn Powers] agrees, and decided to help the rest of us understand the process.
There are two basic ways to launch a tunnel, the first being a local tunnel, that listens on the local machine, and forwards it to the remote machine. On the other hand, a remote tunnel will listen on the remote machine, and deliver the traffic to the local machine. The real fun begins when you have multiple SSH sessions, and connect one tunnel to another, to route something just where you need it. For extra credit, check out the hidden SSH command line, by pressing Enter, then tilde
and the C
key, each one at a time. Also for extra credit, check out the rest of [Shawn]’s Linux content, to learn some extra Linux goodness.
Also, more recently SSH implemented ProxyJump which is fantastic for when you need to SSH through a series of servers. Instead of copy your key through every server or setting up a new tunnel at every level, you can use ProxyJump to magically forward your authentication to each server.
any example?
Suppose to reach “target” you need to ssh to “bastion”, “client”, then “target” each with separate keys. You could setup your ~/.ssh/config file like so:
Host target
HostName 192.168.1.10
User bob
Port 7654
IdentityFile ~/.ssh/target.key
ProxyJump client
Host client
HostName 192.168.10.20
User bb
Port 10022
IdentityFile ~/.ssh/client.key
ProxyJump bastion
Host bastion
HostName example.com
Port 22
User bastionuser
IdentityFile ~/.ssh/id_rsa
Now when you ‘ssh target’ OpenSSH will know to first go to client, but when it looks up client, it will know to go to bastion first. At each level, it will pass the appropriate key from you config and use the appropriate settings, prompting you for any additional keys that are needed like 2FA or key passwords.
In the simplest case, you can just use the shorthand “-J” option: “ssh -J bastion client”
That will tell SSH to first ssh to bastion, then forward your key to client after. You can specify multiple “-J” entries
You can also use this with SCP for file transfer through multiple layers, but you have to use the format: scp -o “ProxyJump bastion” file target:/tmp/
You could do this before as well with ProxyCommand and ssh -W, but ProxyJump is easier to use since you don’t have to remember the exact command to proxy with.
I just use the SSH certificate authority support and make sure any new systems I setup trust that CA. Any public key signed by the CA is trusted by the server and will login in the same way as public key authentication. You can of course set expiration and restrict it to certain usernames.
> more recently SSH implemented ProxyJump
ProxyJump is great and I’ve used it for years, but is 2016 all that recent?
More recent that traffic forwarding/tunneling. :D
It’s not always that simple, for instance RedHat/CentOS releases often stay on one version while they backport security fixes to that version. So if you use that for your production server it might take a while before you get that feature.
This is great for troubleshooting a Chomium Web App for the Raspberry Pi. It lets you get a remote view and console for Chrome. Life saver!
Real magic is sshuttle. That’s quite close to a true VPN, while just working with (almost) any ssh access. I am using that while being in home office, because the official VPN has limited bandwidth. Also you can configure it such that only some internal IP Address range is tunneled, instead of routing the entire traffic through the VPN.
Interesting. Thank you; I learned something today.
Another great tool is “Dynamic” proxies which are really just SOCKS5 tunnels that work over SSH. You can use Proxychains-ng or redsocks to tunnel most anything in Linux (proxychains-ng also works on OSX).
Here is a neat SSH trick for remote support. Similar than the one described in the post, but more refined IMO.
Description: https://www.system-rescue.org/scripts/reverse_ssh/
Source: https://gitlab.com/systemrescue/systemrescue-sources/-/blob/main/airootfs/usr/share/sysrescue/bin/reverse_ssh
How can one leave out tsocks. Use it at work everyday where i need to work with different bastions concurrently
Ah ssh tunnels, saved the day more than once at work
Another trick without opening a port is to use remote.it. You can go directly to the server or set up a bastion host. No open port/no IP allow list. Also works in cellular/Satellite CGNAT situations.
> hidden SSH command line
I really hope you’re not just screwing with us… Time to go fire up the penguin machine!