92

Although I use some alias to do ssh tunnel or reverse tunnel, I never understand how it works. Does somebody know how to explain it in very simple way?

I think the 3 primary uses are:

First of all, I can use my home computer to ssh to foo.mycompany.com, without using any password (foo is a server at work)

  1. How to make foo.mycompany.com:8080 go to my home computer's localhost:3000 ?

  2. If at home, I cannot access http://bar.mycompany.com, but foo can access bar, how to make the home computer able to access http://bar.mycompany.com?

  3. If at home, I cannot access MySQL db at db.mycompany.com, but foo can, how to make it possible to access db.mycompany.com also using ssh tunnel.

Can it be explain in very simple terms? Are there actually some other popular use besides these 3? thanks.

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • 4
    Not sure if this is a better fit for SU/SF than SO? – BoltClock Mar 12 '11 at 06:06
  • There are many ssh tunneling tutorials out there. – Paul Beckingham Dec 29 '13 at 14:23
  • 1
    I'm with @太極者無極而生 on this one, all these tutorials out there alway explain how to set them up, but nothing ever gives a basic explanation of what SSH Tunnelling exactly is, even the youtube vids specifically titled "SSH Tunnelling Explained"! – Guy Park Sep 26 '18 at 00:47
  • 2
    I found this unix stackexchange answer extremly helpful (the diagrams): https://unix.stackexchange.com/a/118650/24024 – ted May 18 '22 at 16:02

6 Answers6

84

1) Assuming you connect from home to foo, you need a reverse tunnel (-R)

ssh -R 8080:localhost:3000 foo.mycompany.com

This will enable processes running at foo to connect to localhost:8080 and actually speak to your home computer at port 3000. If you want other computers at your work to be able to connect to foo:8080 and access your home computer at port 3000, then you need

ssh -R 0.0.0.0:8080:localhost:3000 foo.mycompany.com

but for this to work you also need this option to foo's sshd_config

 GatewayPorts yes

2) The best way to create an http proxy with ssh is with socks. First connect with

ssh -D 8888 foo.company.com

then go to your browser connection settings and enable proxy connection, choose socks4/5 and host: localhost, port 8888. Then just type http://bar.mycompany.com in your browser's address bar.

3) Now you need a local port forward (-L).

ssh -L 3333:db.mycompany.com:3306 foo.mycompany.com

This means that you will be able to connect at localhost:3333 from your home computer and everything will be forwarded to db.mycompany.com:3306 as if the connection was made by foo.mycompany.com. Host db will see foo as the client connecting, so you need to login with the same username and password you use when working from foo.

Adding -g flag will enable other computers from your home network to connect to your computer port 3333 and actually access db:3306.

forcefsck
  • 2,725
  • 1
  • 17
  • 12
  • 4
    It's great that you can provide an example, but the question is really about "What is SSH Tunnelling". If you could explain more on your descriptions, and leave the bash commands for later, that would be good. – Guy Park Sep 26 '18 at 00:48
  • perfect examples, better than what I find with google search on explanatory sites, thanks! – culebrón Oct 19 '18 at 13:40
9

Quite an old question, but see if this page helps explain it for you, it's got pretty pictures and all. :)

https://www.ssh.com/ssh/tunneling/

Basically, a SSH Tunnel is a tunnel that can be used to pass (tunnel) data from one place to another, encrypted.

It is also commonly used to route traffic (via a tunnel, think wormhole) to somewhere else, which allows for things such as tunnelling through a firewall or redirecting traffic (encrypted port forwarding).

Let's say you have a firewall between you and the server. The server can access another server (server2) on it's internal network.

[client]--------||------[server]----[sever2]

Let's say you want to access a web server on server2, and for obvious reasons you can't do this directly. Let's say that port 22 (ssh) is open on the firewall. So what we would do is create an SSH tunnel (on server) from server to server2. This will mean that any (outbound?) traffic on port 22 will be sent, via this tunnel, from server:22 -> server2:80.

[client]--------||------[server:22]======[sever2:80]

So (as I understand it), if we connect to server:22, it should redirect traffic on port 22 to the web server on server2:80 using this new SSH tunnel. (as far as I understand, the data is only encrypted in the tunnel, so the end will be decrypted data, if you're wondering if server:80 has to be SSL).

I suppose in one way that using SSH, is in itself, an SSH Tunnel for your old telnet communication. It's just that in most times you hear about SSH Tunnelling, people are referring to the (secure) port forwarding feature it offers, without having to have access to the firewall admin, which is a nifty little feature that a lot of hackers like to use to get around security.

On the more legitimate reasons; it's great way to relay certain traffic to an internal server that works on a different port, should you be limited by a firewall and such, or you want to secure the traffic between two machines (like the SSH program does).

Hope this helps.

EDIT

Found this over at the UNIX SO https://unix.stackexchange.com/questions/46235/how-does-reverse-ssh-tunneling-work, lots of answers with very clear (and pictorial) explanations of what you need!

Guy Park
  • 959
  • 12
  • 25
  • This also might help; when you SSH Tunnel, your (new) SSH session will contain the tunnel. So if you wanted to have `http://localhost:4562/` open `http://www.google.com/`, you would create the tunnel (a new SSH session) and in that session, any requests to `localhost:4562` would appear as if you called `www.google.com:80`. The different between this and port forwarding is that you can specify a different host (and ports), but all the data between connecting to `localhost:4562` and the `www.google.com` would be encrypted. We have `https` for this, but might give you an idea of usage. – Guy Park Sep 26 '18 at 03:13
6

SSH tunnelling is very simple. It opens a listening socket at one end. Whenever anyone connects to that listening socket, it opens a corresponding connection from the other end to the configured location, then forwards all information both ways between the two, over the SSH link.

Ben
  • 34,935
  • 6
  • 74
  • 113
  • 2
    can you list how to do the 3 things in the question and mention how it accomplish it? – nonopolarity Mar 12 '11 at 09:26
  • The question was "Does somebody know how to explain it in very simple way" :-) – Ben Mar 12 '11 at 14:42
  • 1
    Sorry, not to be snarky, forcefsck has given a good explanation above. – Ben Mar 12 '11 at 15:32
  • 1
    I found @forcefsck description to be to much straight into the technicals. What would be great is diagram of sorts to explain the communication. :) – Guy Park Sep 26 '18 at 00:53
2

First of all I will explain SSH:

SSH is remote login shell that helps you to connect remote machines using encrypted connection. So once you made ssh connection to any remote host the connection between hosts are secure and encrypted.

SSH tunneling is routing your traffic through SSH secure connection.

In simple words SSH tunneling is nothing but one connection is encapsulated by another connection. By taking this as a advantage we make tunnels by using SSH client.

Following command helps you to create simple socks proxy

ssh -D 8080 user@sshserverip
Hari krishna
  • 156
  • 9
0

Sharing a nice tutorial I found with some diagrams: https://iximiuz.com/en/posts/ssh-tunnels/

Local Port Forwarding

E.g. Accessing an online server's database (MySQL, Postgres, Redis, etc.) using a fancy UI tool from your laptop.

ssh -L [local_addr:]local_port:remote_addr:remote_port [user@]sshd_addr

The -L flag indicates we're starting a local port forwarding.

What it actually means is:

  • On your machine, the SSH client will start listening on local_port (likely, on localhost).
  • Any traffic to this port will be forwarded to the remote_private_addr:remote_port on the machine you SSH-ed to.

enter image description here

Remote Port Forwarding

Expose a local service to the outside world, e.g. exposing a dev service from your laptop to the public Internet for a demo.

ssh -R [remote_addr:]remote_port:local_addr:local_port [user@]gateway_addr

The -R flag indicates we're starting a remote port forwarding.

enter image description here

Mukesh Chapagain
  • 25,063
  • 15
  • 119
  • 120
-11

Read the man page, specifically the -L, -R and -D options. I don't think someone rewriting this, and possibly introducing mistakes, is useful. If you don't understand it though you could ask more specific questions.

-D gives a SOCKS proxy, which is another useful application of ssh tunnelling.

river
  • 1,508
  • 1
  • 12
  • 17
  • 17
    one of the worst answers is: read the man page or read the book. Right now the man page is 888 lines long, with 5704 words, on Ubuntu 10.10.10 – nonopolarity Mar 12 '11 at 05:53
  • The -L option, for example, is 12 lines. – river Mar 12 '11 at 05:55
  • 1
    his question was pretty specific IMO. – mpen Mar 12 '11 at 05:58
  • 16
    @anm... you know you can answer every single question on StackOverflow: read the man page, or read the Programming [Ruby] book. – nonopolarity Mar 12 '11 at 06:29
  • Hm, I really meant more specific questions about what you don't understand in the manual. For example, certain terms. What is stopping you from being able to work out how to answer the question, given the manual? Then it will be possible to help without simply rewriting it. – river Mar 12 '11 at 11:10
  • 1
    sometime I really wonder if the man pages are written for people to understand, such as this on Mac OS X: `-D [bind_address:]port` Specifies a local 'dynamic' application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS [...] – nonopolarity Mar 12 '11 at 13:27
  • 3
    Actually, this is a well written part of the manual page, it is a complete and clear explanation of -D in a few lines. You have to understand that these are not manuals for how to use a washing machine, you're required to understand some technical terms, like socket, application-level, bind address. If you want to learn the tool, then you have to not be lazy and actually study and do the required research. – forcefsck Mar 12 '11 at 20:14