Tunneling With SSH to Your Destination
Tunneling With SSH to Your Destination
With SSH, you can create a tunnel (port forwarding) to transfer data that will be encrypted. Using this tunnel, you can then connect to the beginning of the tunnel and come out the other side to either do some work, or forward onto another machine to get to your final destination. A tunnel can also allow you to sidestep some land mines on the way. For example, say you need to connect to remote box, but you can’t connect to it directly due to firewall rules or restrictions sitting on an intermediary box that you must bypass first. A tunnel gives you the flexibility to bypass most of these restrictions. In this article, let’s look at two tunneling examples:
- Basic one-to-one tunnel
- Tunnel that goes via an intermediate box to get to its destination
Sometimes the intermediate system is referred to as a jump host, because you must jump from that box to get to your destination. Typically, these are used when you’re at home or in a hotel and you need to connect to a machine behind a public-facing network. In practice though, you may have to jump a few times to get to your destination depending on the network setup. SSH tunneling has three different types of port forwarding. For this article, we’ll stick with local port forwarding, which is the most common.
Local forwarding allows traffic to be forwarded from a local system to a remote system in a secure manner. Assume each machine discussed has an SSH account.
Prepare Your System SSHD Config File
The machine you’re port forwarding from should have the following in the sshd_config file:
Allow tcpportforwarding=yes
It’s also advantageous to have on any host you have SSH running the following set in the sshd_config file:
TCPKeepAlive=yes
If you make any changes, be sure to restart your SSHD service:
# stopsrc –s sshd # startsrc –s sshd
Just the Basic Tunnel Options
The format for port forwarding in this example is:
ssh -4 –g –L <local_port> : <local_host> : <target_port> <target_host>
-4 | Specifies we are using IPv4 addresses |
-g | Allows remote hosts to connect to the forward listening port |
-L | Indicates local port forwarding |
local_port | Any unused arbitrary port you will connect to. Make sure the port is unused. |
local_host | The literal localhost |
target_port | The target port to connect to. Generally speaking, this should represent the protocol port one is going to use, 22 for SSH, 23 for telnet, etc. |
target_host | Target host you are connecting to |
A Direct Tunnel With Telnet
Figure 1 shows a secure tunnel beginning from host ‘salt’ and ending at host ‘pepper.’ Let’s assume that these are in a demilitarized zone (DMZ) and any connections between hosts in the DMZ must be via an encrypted tunnel. Let’s now create that tunnel. To create the tunnel on host ‘salt,’ use:
salt> ssh -4 -g -L9058:localhost:23 pepper
This commands states data incoming on port 9058 will be forwarded to port 23 (default telnet port) to host ‘pepper’ via a SSH tunnel. Please note that localhost is only evaluated by the host after a connection is made. So localhost in this example means host ‘pepper.’
When creating the tunnel if you specify ‘-v-‘ verbose as part of the SSH connection, you will see activity on the tunnel. To confirm you have the tunnel created, you’ll see a message similar to:
debug1: Local connections to *:9058 forwarded to remote address localhost:23 debug1: Local forwarding listening on 0.0.0.0 port 9058.
Now from another session on host ‘salt,’ telnet using the tunnel. Note we telnet to localhost, which will be forwarded to the remote host ‘pepper’:
salt> telnet localhost 9058 Trying... Connected to localhost. Escape character is '^]'. pepper> hostname pepper pepper> who –u dxtans pts/21 Nov 23 16:11 . 6250664 (localhost)
When you connect via telnet, look at the session where you created the tunnel and you’ll see a message similar to:
debug1: Connection to port 9058 forwarding to localhost port 23 requested. debug1: channel 1: new [direct-tcpip]
This confirms the tunnel is active and you have telnet connection using the tunnel.
Tunneling With a Jump Using SFTP
Figure 2 shows a more common tunneling scenario. Here user on host ‘alpha’ needs to connect to host ‘charlie’ to SFTP some files. However host ’bravo’ is a gateway and thus he needs to go through the gateway to get to ‘charlie.’ Instead of physically logging into ‘bravo’ to get to ‘charlie,’ which is the destination, a tunnel can be created instead that will jump from host ‘bravo’ to get to ‘charlie.’ This creates a direct connection from host ‘alpha’ to ‘charlie.’
Let’s create that tunnel now. Note though there’s no tunnel once the traffic has left host ‘bravo’ to get to ‘charlie.’ To create the tunnel on host ‘alpha,’ use:
alpha> ssh -v -4 -g dxtans@bravo -L 2000:charlie:22 debug1: Local connections to *:2000 forwarded to remote address charlie:22 debug1: Local forwarding listening on 0.0.0.0 port 2000.
This command states that you want to create a tunnel from ‘alpha’ and forward the traffic to ‘bravo’ on port 22, which is then forwarded on to ‘charlie’ at port 2000. In this example, I used my login id (dxtans), but this isn’t strictly necessary. The remote host will pick up my user from my current SSH session.
Now, on another session on ‘alpha,’ connect using SFTP using port 2000 to connect to ‘charlie.’ Remember you’ll be connecting to localhost.
alpha> sftp -P 2000 dxtans@localhost dxtans@localhost's password: Connected to localhost. sftp> get testfile Fetching /home/dxtans/testfile to testfile /home/dxtans/file 100% 532 0.5KB/s 00:00
While connecting via SFTP, look at the session where you created the tunnel. Note the tunnel ends at ‘bravo’ but packets are forwards to ‘charlie.’ We can tell the connection went via the tunnel by following output:
$ debug1: Connection to port 2000 forwarding to charlie port 22 requested. debug1: channel 2: new [direct-tcpip]
Timesaving and Secure
Tunneling is a great way to ensure you have an encrypted connection. It can also save you a lot of time logging into different hosts to get to your destination.