top | item 26053323

A visual guide to SSH tunnels

963 points| brendanfalk | 5 years ago |robotmoon.com | reply

80 comments

order
[+] fooblat|5 years ago|reply
Great write up!

One thing to add is that you can even open tunnels during an interactive session without disconnection.

To do this, type the escape command sequence ~C (will not show) and it will drop you to the control prompt. You can then add tunnels.

     ssh>
     ssh> -L 8000:localhost:9000 
     Forwarding port.
[+] macintux|5 years ago|reply
I’ve been using ssh for 25+ years, I wrote a (in hindsight, pretty awful) article about it for Linux Journal, and I never knew this.
[+] fooblat|5 years ago|reply
Since this tip is popular I'll share another related tip.

When using nested ssh session, you can send escape commands to any of them by the number of tildes. For example, if you ssh into Server A and then from Server A to Server B:

    ~~.   # drop session from Server A to Server B
    ~.    # drop original session into Server A
[+] nerdponx|5 years ago|reply
Is ~ a literal ~ character? Or notation for some modifier key? I only knew about ^ to mean "control".
[+] xvf22|5 years ago|reply
Well, there's something I didn't know. Thank you for the time and tab savings!
[+] px43|5 years ago|reply
There's a really fancy new -R feature that I love (added in 2017 I think).

ssh <target> -R <just a port number>

This opens up a localhost port on the target that acts as a socks server which tunnels all your traffic through the source machine.

This is great for machines that you can SSH into, but are otherwise completely isolated from the network, or are monitored heavily. You can jump on, and pull down everything you need from the existing SSH connection, rather than using the machine to make requests out to the internet directly.

This is also good if the source machine is a web server or something on a secured network which can SSH out, but not much else, and the destination is your command and control server on the internet. Then it opens up a socks port on the C&C machine that gives full access to the internal network, impersonating the source machine.

Every other -R is a point to point TCP connection, but setting up a SOCKS proxy with -R is magic. More analogous to a reverse -D than a reverse -L. Super useful.

[+] LukeShu|5 years ago|reply
> (added in 2017 I think)

Indeed: committed in September 2017, released in v7.6 in October 2017.

[+] metahost|5 years ago|reply
This[1] is probably the best, easiest and most (visually) effective way to learn about SSH tunnels.

[1] : https://unix.stackexchange.com/a/118650/289353

[+] mottosso|5 years ago|reply
At least this one is actually visual. Perhaps the author meant "A written guide to SSH tunnels"?
[+] qwertox|5 years ago|reply
This is the one I always come back to when I'm a bit confused about the ordering of ips and ports.
[+] larodi|5 years ago|reply
definitely more visual than this article...
[+] dloss|5 years ago|reply
Drawing some diagrams helped me understand remote port forwarding and OpenSSH's port:host:port syntax: http://dirk-loss.de/ssh-port-forwarding.htm
[+] giuseppeciuni|5 years ago|reply
Thanks! I pinned your page on my evernote.. I always get confuse everytime I need to make a ssh port forward. After a while I get it but I spend time (and some bad words :P)
[+] tatref|5 years ago|reply
I think it's way clearer!
[+] walrus01|5 years ago|reply
One common use is to secure vnc, which has no crypto built into it.

On the remote host, have the vnc server listen only on localhost:5901

This assumes everyone who can ssh to the server should be allowed access.

On your workstation, form an ssh tunnel to that remote host and its port, and link it your own localhost:5901

Open your vnc client GUI and set it to open 127.0.0.1:5901, voila, vnc session.

More fun things: say for example you have a big remote xen dom0 with a lot of unique qemu HVM VMs running on it. Configure each of their .cfg files for xen to spawn a vnc server on localhost only and a unique port number per domU (5902,5903,5904,etc). Then use the same method to connect.

[+] labawi|5 years ago|reply
Note that it still exposes the connection to all local processes, on both hosts (except network-restricted services or with non-typical host-local firewall rules), though it should be fine, if you're using semi-reasonable passwords.

SSH supports unix domain socket forwarding and even cross unix/ip forwarding with a syntax like:

  ssh -L /path/to/sock:/path/to/sock
  ssh -L /path/to/sock:localhost:5901
  ssh -L 5091:/path/to/sock
Then you can have user-authenticated host and transit secure password-less VNC connections.

Unfortunately I haven't been able to convince tigervnc viewer to connect to a unix domain socket, so I don't have a fully scripted connection, but remmina and tigervnc server work fine.

Also, forwardings / connections fail if the socket already exists when the listening side starts up (often an unclosed leftover), so I rm them before starting the ssh connection / vnc server and it works reliably.

[+] m463|5 years ago|reply
I do this for a number of hosts simultaneously with macos and map them specifically in my .ssh/config:

  Host mac-a
    ...
    LocalForward 5903 localhost:5900

  Host mac-b
    ...
    LocalForward 5904 localhost:5900
then I open the directory /System/Library/CoreServices in the Finder and drag Screen Sharing.app to the dock.

to remote into machine mac-b, in a terminal window:

  ssh mac-b
The first time, click on "screen sharing" in the dock, and in the connect dialog enter localhost:5904

After that, you can right-click on screen-sharing in the dock - even when it's not running - and you will see a context menu item for "mac-b 5904.vncloc"

By the way, mac to mac screen sharing is very well done (will they axe it next?)

- it is very fast

- the keyboard stuff just works

- you can copy/paste even rich text between the local and remote macs

- you can drag and drop files from the remote desktop to the local one

[+] chrisandchris|5 years ago|reply
I am always amazed at what is possible with the linux command line, and it‘s something one can really fall in love with.
[+] ohazi|5 years ago|reply
SSH tunnels are my favorite tool for NAT-busting. I always have to look up the cryptic syntax, but with one strategically placed Raspberry Pi, you can basically get from anywhere to anywhere.

And it works just as well on a locked down corporate network as it does on a home network. Why people put up with garbage VPN software is beyond me.

[+] accrual|5 years ago|reply
One can further tunnel SSH inside of TLS with Stunnel [0] to get through firewalls that block SSH but permit arbitrary TLS connections. Loading a website through this requires three layers of TCP but assuming the connection is good this should be okay.

A couple reasons for a regular VPN: they can be made automatic and persistent so the tunnel is always ready for use, they can tunnel other protocols besides TCP, they can tunnel entire networks, and using UDP as the tunnel protocol helps avoid the TCP-in-TCP congestion issues.

[0] https://en.wikipedia.org/wiki/Stunnel

[+] lxgr|5 years ago|reply
SSH isn’t a replacement for VPNs. I’d argue that they complement each other.

For example, SSH port forwarding is TCP only, so if you need UDP, you‘ll need a VPN.

[+] labawi|5 years ago|reply
Why don't people use unix domain sockets for local connections? They are pretty much the same thing as local IP connections, except access rights apply as on files, so you're not exposing connections to pretty much all processes.

Domain sockets can be forwarded via ssh with the same -L and -R arguments, including cross unix/ip forwardings.

[+] aidenn0|5 years ago|reply
It's a relatively recent feature in openssh (in the past decade for upstream; not sure when it first landed in an Ubuntu LTS, which for practical purposes is the earliest one might start using it regularly)
[+] chaosfox|5 years ago|reply
last time I tried ssh does not delete the socket file when the connection closes and complains the file already exists on a new connection.
[+] framecowbird|5 years ago|reply
Is it just me or is this site a bit of a disaster on mobile?
[+] catoc|5 years ago|reply
Could read just fine on iPhone 12p after zooming out; even in portrait
[+] dexterdog|5 years ago|reply
On desktop firefox all of the code snippets are black-on-black so I have to select the code to read it.
[+] mfgs|5 years ago|reply
Yep, but it works well for me in landscape view.
[+] beermonster|5 years ago|reply
Nice reference.

Reaching target hosts multiple jump-hosts away, and going the wrong way through multiple firewalls segregating those lans, is another use-case of tunnels I've found handy.

i.e.

your_remote_client_host->internet->fw1->lan1->fw2->lan2->fw3->target_host

Target_host can be reached by doing tunnel-in-tunnel-in-tunnel-in-tunnel. Each tunnel gets you past one firewall. The final tunnel you can just ssh to fw3 via a local tunnel and a local port on your_remote_client now takes you straight to target_host.

[+] franga2000|5 years ago|reply
Absolutely brilliant! I've had to explain local/reverse/dynamic port forwarding to people enough times that I've written a text file I can just send them, but I can finally replace that with a link to this page.
[+] IgorBog61650384|5 years ago|reply
Really nice and clear. One addition: the final example uses ProxyCommand, I find ProxyJump much more useful: you can specify multiple hops clearly and even specify different private keys for each hop.
[+] shawnz|5 years ago|reply
ProxyCommand is useful for proxying with a non-SSH protocol. For example when combined with proxytunnel or similar you can run your SSH connections over an HTTPS proxy, which appears as regular web traffic to the network operator.
[+] hmsimha|5 years ago|reply
ProxyJump indeed seems more useful, but has less support (it's a "newer" SSH feature). Do you know if it needs to be supported by the openssh libs of intermediate hosts, or just the initiating client?
[+] MaxBarraclough|5 years ago|reply
Great resource. Most tutorials on SSH tunnels are strangely incomplete. This one seems to cover all the important points, and does so in an approachable way.
[+] zxcvbn4038|5 years ago|reply
Every once in a while I wonder how the SOCKS5 stuff works at the protocol level, I would like to be able to SSH out without running a proxy process locally, just talk to the ssh deamon on the relay server directly. The OpenSSH code is a bit dense but it looks like it creates dynamic tunnels that are torn down when the connection closes. Anyone confirm that is what happens behind the scenes?
[+] johnchristopher|5 years ago|reply
Great, I can refer people (and myself) to this page !

A lot of tunneling tutorial, medium articles and blog post mixes local and remote port forwarding and use the words interchangeably which cause a lot of confusion.

[+] unilynx|5 years ago|reply
There’s also -w which sets up a point to point tunnel which you can route over - even more powerful than the SOCKS server