Port forwarding, or tunneling, is a way to forward otherwise insecure TCP traffic through SSH Secure Shell. You can secure for example POP3, SMTP and HTTP connections that would otherwise be insecure.
There are two kinds of port forwarding: local and remote forwarding. They are also called outgoing and incoming tunnels, respectively.
Local port forwarding forwards traffic coming to a local port to a specified remote port. For example, all traffic coming to port 1234 on the client could be forwarded to port 23 on the server (host).
Note: The value of localhost is resolved after the Secure Shell connection has been established – so when defining local forwarding (outgoing tunnels), localhost refers to the server (remote host computer) you have connected to.
Remote port forwarding does the opposite: it forwards traffic coming to a remote port to a specified local port. For example, all traffic coming to port 1234 on the server (host) could be forwarded to port 23 on the client (localhost).
Local port forwarding
Accessing a service (in this example SSH port tcp/22, but it could be anything like a web server on tcp/80) on a machine at work (172.16.10.10) from your machine at home (192.168.10.10), simply by connecting to the server work.example.org at work :
$ ssh [email protected] -L 10000:172.16.10.10:22
We see the service is available on the loopback interface only, listening on port tcp/10000 :
$ netstat -tunelp | grep 10000
tcp 0 0 127.0.0.1:10000 0.0.0.0:* LISTEN 1000 71679 12468/ssh
From your home machine, you should be able to connect to the machine at work :
$ ssh root@localhost -p 10000
Local port forward for anyone at home !
If you want other people on your home subnet to be able to reach the machine at work by SSH, add the option -g :
$ ssh [email protected] -L 10000:172.16.10.10:22 -g
We now see the service is available on all interfaces on your home computer, available for anyone to connect to on the local subnet :
$ netstat -tunelp | grep 10000
tcp 0 0 0.0.0.0:10000 0.0.0.0:* LISTEN 1000 72265 12543/ssh
Anyone on your local subnet should be able to connect to the machine at work by doing this :
$ ssh [email protected] -p 10000
Remote port forwarding
Giving access to a service (SSH port tcp/22) on your home machine (192.168.10.10) to people at work
$ ssh [email protected] -R 10000:192.168.1.10:22
We see on our server at work (on the loopback interface on port tcp/10000) that we have access to our SSH server at home :
work.example.org$ netstat -tunelp | grep 10000
tcp 0 0 127.0.0.1:10000 0.0.0.0:* LISTEN 0 73719534 3809/1
People logged in on the machine work.example.org now should be able to SSH into your home machine by doing :
work.example.org$ ssh user@localhost -p 10000
Remote port forwarding for anyone at work !
If you want everybody on the subnet at work to be able to SSH into your home machine, there’s no -g option for remote forward, so you need to change the SSH configuration of work.example.org, add to sshd_config :
GatewayPorts yes
Connect just as before :
home$ ssh [email protected] -R 10000:192.168.1.10:22
Now, it’s listening on all interfaces on the server at work :
work.example.org$ netstat -tunelp | grep 10000
tcp 0 0 0.0.0.0:10000 0.0.0.0:* LISTEN 0 73721060 4426/1
Anyone at work can now connect to your home machine by SSH via the server :
anyone.example.org$ ssh [email protected] -p 10000
Notes
– You would need to log in as root if you want services to listen on a port < 1024.
– Don’t forget to open necessary ports on any firewall either at home or work.
– Unfortunately you can only forward services running on TCP, but there’s a way to forward UDP through SSH using netcat
Great article, i used to do port forwarding through the router configuration file. Thanks for sharing thiat great information. Keep posting more. Thanks again.
Yes! Thank you. After reading several articles, this is the one with information that actually works.
If you want everybody on the subnet at work to be able to SSH into your home machine, there’s no -g option for remote forward, so you need to change the SSH configuration, add to sshd_config :
GatewayPorts yes
Did not work for me here =( (Remote forwarding)
Thanks
Never heard of:
GatewayPorts yes
but it saved my day 🙂
how do i do this ?:
i need to forward remote incoming connections to a remote machine !
very useful information ,thank you very much.
A better general form for local port forwarding is:
ssh user@remote -T -L [local_IP:]lport:remote_IP:rport
-T: Suppresses login terminal on remote system
local_IP: Specify interface to listen for connections. Allows finer grained control on which interfaces connections are accepted, if system is multi-homed host.
-g appears to be equivalent to listening on local_IP 0.0.0.0
-L can be specified more than once, so you can specify multiple local_IP/lport values to forward on a single command line
Yes, this article is pretty informative, I used this (SSH port forwarding) in my university to access
high speed proxy server, which was then available only from Labs and not hostel
Echoing XTC’s comment here. I never heard of GatewayPorts, but spent hours trying to figure why all my remote port TCP connections were being dropped….
Thanls very much for this article… it was very useful for me…..
GatewayPorts yes <—— This is the HINT
lol…..
Before i knew about GatewayPorts i was spending much time trying to know why there wasnt my remote ports initialized!!!
EDITED sshd_config *NOTE: it is sshd_config and not ssh_config (wich stands for the client part of ssh)
ADDED GatewayPorts yes
reload ssh daemon and voila!!!!
Remote ports can be accesed globaly in my WAN interfaces….
Regards,
PABLO ALEJANDRO ALANDIA
La Paz, BOLIVIA
hello
can i ssh portforward two times?
soo i am in another country. i connect withh ssh to a server at home and after i am connected i can acces the internet like i where in my house.
but in my house i have another router in the netwrok that is connected to my neighbour’s internet. and threw the first router i can ssh to the second. but my internet ip is still my own, not my neighbours internet.
how can i double ssh tunnel port forwarding :D?
There is a little error in your description:
Section: “Remote port forwarding”
Your Text:
(…) Giving access to a service (SSH port tcp/22) on your home machine (192.168.10.10) to people at work
$ ssh [email protected] -R 10000:192.168.1.10:22…”
I think, the 2nd IP is wrong.
the 2nd IP should be 192.168.10.10, (i think…)
But it is a very well working tutorial. Many thanks.
I just changed my /etc/ssh/sshd.conf and tested he -R option for everyone with a videostream.
It works well.
🙂
Alright here is my current problem I need solved. I am trying to host a services locally on my network but I am unable to accept incomming connections from the internet. I have a VPS that I can allow incomming connections. What I am looking to do is have it so when lets say someone goes to http://www.theurlofthevps.com it would forward the request to the server I have locally bypassing NAT.
Would I do the folllowing?
ssh user@VPS -R 10000:192.168.10.145:80 (192.168.10.145 being the IP of the local webserver)
Would this be sufficient to do what I am looking to do? Also are there any unmentioned risks of doing this that I should be aware of?
Port forwarding for everyone! yay!
Guess why debian admins are professionals’ nightmare.
Just in case your SSH server is on Debian but your tunnel client is on MS Windows. There are three solutions Cygwin ssh client, PuTTY (or PLink) and GSW Business Tunnel. Unfortunately the Business Tunnel is not a free product. Unfortunately … because it has serious advantages over the forst two, in particular, it runs as a Windows service which means that it starts automatically, no need for any batch file(s) or command lines. Additionally it comes with a GUI management tool for configuration and monitoring of activity so you know which tunnels are used and by what IPs, supports Elliptic Curve Cryptography (missing from PuTTY), encrypts and stores private key passwords.