SSH Port Forwarding Configuration
Most of the test systems are not exposed to the public interent directly and reside in a private network space. So one can't directly connect to network services (e.g. web server, ssh) running on these systems using a public hostname or IP address. One of the way to connect with such systems is using SSH Port Forwarding (a.k.a. SSH tunneling). In this technique a port on the local system is 'SSH tunneled' to a service port on the remote system using a public facing SSH server.
For example, consider a remote system on private network called 'oak' which runs a web server and an SSH server. And consider 'cheaha' as a public facing SSH server which is connected to both public and private networks. Now to connect to any of the network services on 'oak' a user will have to 'SSH tunnel' connections through 'cheaha'. Below is a command-line example to perform this setup.
- First we setup an SSH-tunnel which forwards a port (10080) on a local system (where following ssh command will be run) to a port (80) on the remote system 'oak' using public facing SSH server 'cheaha'.
# General syntax $ ssh -L <local-port>:<remote-system-IP-or-Hostname>:<remote-system-port>
$ ssh -L 10080:oak.subdomain.uab.edu:80 firstname.lastname@example.org
Above command SSH-tunnels (forwards) connections to a local-port 10080 to remote system 'oak's' port 80. This allows user to access web pages on 'oak' using following connection string - 'http://localhost:10080'. When you run above SSH command you will have an SSH terminal window open on your system and it has a session open with public SSH server 'cheaha'. You can use the same terminal window to SSH to remote system 'oak'.
Quite often you have to connect with remote systems on private network on regular basis. And specifying long SSH command-line options may soon become annoying. This can be avoided by putting above SSH option in the '~/.ssh/config' SSH client configuration file. Following is an example '~/.ssh/config' file equivalent to above SSH command.
# 'rnet' gateway - happens to be cheaha head node Host rnet User blazerid hostname cheaha.uabgrid.uab.edu # Port forwarding <remote-system-IP-or-Hostname> # LocalForward localhost:<local-port> <remote-system-IP-or-Hostname>:<remote-port> LocalForward localhost:10080 oak.subdomain.uab.edu:80
Consider another remote system on a private network called 'pine'. Now if I need to access web server and SSH-server with X11 forwarding on 'pine' then I would setup '~/.ssh/config' in following manner (includes SSH config for 'oak'):
# 'rnet' gateway - happens to be cheaha head node Host rnet User blazerid hostname cheaha.uabgrid.uab.edu # LocalForward localhost:<local-port> <remote-system-IP-or-Hostname>:<remote-port> # Port forwarding for oak LocalForward localhost:10080 oak.subdomain.uab.edu:80 # Port forwarding for pine LocalForward localhost:20080 pine.subdomain.uab.edu:80 LocalForward localhost:20022 pine.subdomain.uab.edu:22 # SSH config for pine Host pine host localhost Port 20022 User blazerid ForwardX11 yes
Note the port forwarding configuration for 'pine'. Here I have chosen a different local port number (20080) than for the 'oak' (10080). This is necessary because we can't forward same local port to multiple remote-systems. Also, in addition to the web server port (80) I have setup SSH tunnel for the SSH server (port 22) on pine. As mentioned in previous example, I could have used the same SSH terminal window to connect with 'pine', however typically I want to have multiple SSH terminal windows/tabs open at the same and hence I have added configuration line to save some keystrokes. The port forwarding 'SSH tunnels' local port (20022) to a remote system 'pine's' port 22. So to SSH to 'pine' I can simply SSH to local-port 20022. Now take a look at the SSH config for pine host. This configuration allows me to SSH to pine 'ssh pine' - the hostname, port number, username and X11 forwarding is setup in the '~/.ssh/config' to avoid typing it repeatedly.