I have been trying to get my head around ssh tunnels lately as I need to be able to access a development web server on our private network that doesn't have an IP accessible from the internet.
It's taken me a while to understand what is going on; it can be pretty confusing.
I'd recommend the following for a good explanation of what ports are used, e.g. when your browser requests a page:
And I thought this was probably the best single page explanation of tunneling:
What I found helped me was thinking about this from both perspectives; from the client -> server request and the resulting server -> client response.
The only thing the bitvise article misses (if I'm understanding this correctly) is that the ssh server must change the packet going to the forwarded port so that the response from the server on that port goes back through the ssh tunnel to the client. It would be pointless of course if the request went through the encrypted ssh tunnel one way but then got sent back directly in cleartext to the originating IP.
On a windows box, you can set up a tunnel using putty like so:
Alternatively you can use plink (that comes with putty), e.g.
plink -v -L 8080:ultimate-destination-hostname:80 user@ssh-server-hostname
This would connect port 8080 on your windows box to port 80 of your ultimate-destination-hostname via your ssh server ssh-server-hostname. The ssh-server-hostname needs to be a machine you have an ssh account on and needs to be internet routable as well as being on your private network.
The other gotcha with this stuff is that the ultimate-destination-hostname is with respect to the ssh server, i.e. it doesn't matter if that host doesn't resolve from your local machine, just that it IS resolvable from the ssh server.