Pages

ssh tunnels set up and port forwarding

SSH tunnels allow you to forward a local TCP port to a remote machine and vice versa. The tunnel option is available in many ssh clients. I will give the example here on how to create SSH tunnels with putty and the openssh-client.
I will consider in the below that we want to access the SERVER on port 80 (http server).

Scenario 1. SSH tunnel setup with local port forwarding.


The SSH tunnel is shown with the red arrow. In order to access the SERVER through the ssh tunnel the connection will have to be made on the CLIENT's local forwarded port (2000 in the example). The traffic between the CLIENT and SSH-HELPER is encrypted by ssh, the traffic between the SSH-HELPER and the SERVER is not encrypted.

SSH tunnel  is set up on the CLIENT:
openssh-client:

ssh -L *:2000:server:80 ssh-helper

The '*' before the local port to be forwarded 2000 denotes that the port 2000 should be listening on all available interfaces on the client. This goes according to the openssh-client configuration.
putty:

The tunnel configuration is done under Connection - SSH - Tunnels. Source port is the local port, destination is where the connection will be forwarded after exiting the SSH tunnel.
After you specify source port and destination, you need to click "Add" for the configuration to take effect.
If you want to access the remote server from other hosts, make sure you check the box  "Local ports accept connections from other hosts", otherwise the port 2000 will be opened only for the loopback address (127.0.0.1)


After the tunnel is added, you can connect to the SSH-HELPER  to initiate the ssh tunnel.


Scenario 2. SSH tunnel setup with remote port forwarding

The SSH tunnel is shown with the red arrow. In order to access the SERVER through the ssh tunnel the connection will have to be made on the SSH-HELPER's forwarded port (2000 in the example). The traffic between the SSH-HELPER and CLIENT is encrypted by ssh, the traffic between the CLIENT and the SERVER is not encrypted.

SSH tunnel  is set up on the CLIENT:
openssh-client:

ssh -R 2000:server:80 ssh-helper
putty:

A note for the SSH-HELPER and sshd daemon configuration. I am using openssh-server on debian. The default sshd_configuration for GatewayPorts does not allow remote hosts to connect to forwarded ports. This in turn would make the forwarded port 2000 accessible and listening only on the loopback (127.0.0.1) address and only the local machine (eg. SSH-HELPER in this case) would be able to access this port.

netstat output on the SSH-HELPER with GatewayPorts set to no:
tcp        0      0 127.0.0.1:2000          0.0.0.0:*               LISTEN      16055/0         
tcp6       0      0 ::1:2000                :::*                    LISTEN      16055/0

     GatewayPorts
             Specifies whether remote hosts are allowed to connect to ports forwarded for the client.  By default, sshd(8) binds remote port forwardings to the loopback address. This prevents other remote hosts from connecting to forwarded ports.  GatewayPorts can be used to specify that sshd should allow remote port forwardings to bind to non-loopback addresses, thus allowing other hosts to connect.  The argument may be “no” to force remote port forwardings to be available to the local host only, “yes” to force remote port forwardings to bind to the wildcard address, or "clientspecified” to allow the client to select the address to which the forwarding is bound.The default is “no”.
So if GatewayPorts is set to yes in the configuration and  remote machines can access also the client forwarded ports (2000) and therefore - through the SSH tunnel - the server on port 80 .

netstat output on the SSH-HELPER with GatewayPorts set to yes:
tcp        0      0 0.0.0.0:2000            0.0.0.0:*               LISTEN      16200/0         
tcp6       0      0 :::2000                 :::*                    LISTEN      16200/0

Advanced SSH tunnel setup

Let's say that the CLIENT, SERVER and SSH-HELPER are all public machines. The SERVER is running an HTTP server on port 80 on an internal private interface inaccessible from the CLIENT or SSH-HELPER.
The only port available on the SERVER's public interface is SSH. More to this let's say that the only machine allowed to connect to the SERVER by ssh is the SSH-HELPER (jump station) and that the CLIENT can connect to the SSH-HELPER via ssh.
Let's say that the SSH helper is not running a desktop environment , so we would like to access the HTTP service (port 80) from the CLIENT machines'  web browser. We can do this with SSH tunnels and I will provide 2 methods in which this can be achieved.

SSH tunnel patching


Here we create one tunnel from the CLIENT to the SSH-HELPER and one SSH tunnel from the SSH-HELPER to the SERVER.
Then the HTTP service will be available on the CLIENT's local forwarded port.
openssh-client:

On the CLIENT machine:
ssh -L 2000:localhost:3000 ssh-helper

The above command forwards the local port 2000 on the CLIENT through the ssh tunnel established with SSH-HELPER to the localhost address (127.0.0.1) of the SSH-HELPER on port 3000. The authentication credentials to be used here are for the SSH-HELPER machine
On the SSH-HELPER machine:

ssh -L 3000:internal_interface_IP:80 server

This command will take and forward everything that comes on port 3000 (hence also what we send from the CLIENT on its local port 2000) to the internal interface address of the SERVER on port 80.  The authentication credentials to be used here are for the SERVER machine.
So the packets from the CLIENT on port 2000 enter the SSH tunnel between CLIENT and SSH-HELPER, exit this tunnel and are sent on the SSH-HELPER's localhost address on port 3000. Here these packets are taken and placed in the 2nd SSH tunnel between the SSH-HELPER and SERVER, they come out at the SERVER side and sent on the internal interface IP. More specific, if you choose this internal interface IP on the server to be the localhost address:

ssh -L 3000:localhost:80 server
putty:

Given our assumption that the SSH-HELPER is not running a graphical environment, I will limit this configuration example to the putty configuration on the CLIENT only. The SSH-HELPER can be setup as shown in the openssh-client section.

SSH tunnel setup over SSH



This setup is is somehow more convenient than the SSH tunnel patching because all configuration is done on the CLIENT.
First we create the red arrow connection stating that a local forwarded port on the CLIENT should establish ssh tunnel with the SSH-HELPER and from the SSH-HELPER the connection should be forwarded to the SERVER's ssh listening port.
Second we create the blue arrow ssh tunnel connection and this will forward another local port from the CLIENT through the established red SSH session (which is ending at the SERVER's external IP address). The blue SSH tunnel will end at the SERVER's internal address. The connection will be forwarded to the SERVER's internal address on the port where HTTP service is listening.
The client will connect then to the port forwarded through the blue connection with its web browser.
openssh-client:

ssh -L 2000:server:22 ssh-helper
ssh -L 3000:internal_interface_IP:80 localhost -p 2000

First ssh command is opening the localport 2000 on the CLIENT and every connection made on that port on the CLIENT will be forwarded via the ssh tunnel with the SSH-HELPER to the SERVER's port 22 (where by default the ssh is listening). The authentication credentials are of the SSH-HELPER machine.
Second ssh command is opening the localport 3000 on the CLIENT and every connection made to this port will be forwarded to the SERVER's internal_interface_IP port 80 through the ssh tunnel made between the CLIENT and the SERVER  port 22 (connection made possible by connecting to the CLIENT's localport 2000 which is sent to the SERVER's port 22 from the first connection). The authentication credentials are of the SEVER machine.
If we consider the internal_interface_IP on the SERVER to be the localhost, the 2nd command looks really nice (and confusing).

ssh -L 2000:server:22 ssh-helper
ssh -L 3000:localhost:80 localhost -p 2000
putty:

First, we create the red connection:
You should open this session to make sure that the first local port is being forwarded. After this connection is opened and you are logged in the SSH-HELPER, create the 2nd SSH tunnel over the blue arrow. Take note of the ports used.
After this, from the CLIENT you can navigate to http://localhost:3000 and this should open display the web pages residing on the SERVER.

No comments: