Tutorial

How To Set Up SSH Tunneling on a VPS

Published on September 20, 2013
Default avatar

By

How To Set Up SSH Tunneling on a VPS

Introduction

In this article, you'll learn how to create a safe, encrypted tunnel between your computer and your VPS along with how to bypass limits in a corporate network, how to bypass NAT, etc.

This article will cover some basic theory, which you can skip if you like just by going straight to the examples further down.

Communication in the Internet, Network Protocols and Communication Ports

Every piece of software installed in your computer, that wants to send or receive data through the Internet, has to use a protocol of the application layer from TCP/IP stack. Those protocols define a way to communicate and the format of the messages sent between the hosts over the Internet etc. For instance:

  • HTTP - used to download websites and files from your web browser
  • FTP - used to send files between a client and server
  • DNS - used to change host name into an IP address and vice versa
  • POP3 and (or) IMAP - used to download/browse your e-mail
  • SMTP - used to send e-mail
  • telnet - used to connect remotely to a server
  • SSH - similar to telnet, but in a secure, encrypted version, so nobody can see what we send to a server and what the server sends to us.

Next, messages of the given protocol has to be packed into a TCP segment or UDP datagram (in transport layer). Those protocols are used to transport data through the Internet - they are working in transport layer. TCP protocol is connection-oriented, which means that before sending data, it is required to create a connection between the remote machines. TCP always provides data in the correct order. If any segment will be lost in the network, it will be sent again if it does not receive the confirmation in time. TCP is considered fairly reliable.

UDP protocol is not connection-oriented. It doesn't provide retransmissioning for lost datagrams. If packets are not received in the correct order, UDP will, nonetheless give them to an application in the order that they were received. Because of that, UDP is mainly used to transmit real-time multimedia data - VoIP talks, videoconferences, audio and video. UDP is used sometimes by other protocols in the application layer - for instance, in the case of DNS.

In this case a protocol of the higher layer has to resend a query after not receiving an answer in the given amount of time. UDP is used here mainly, because it has low overhead: sending 1 small query in 1 datagram and receiving an answer takes less time and needs to transmit less data than making a TCP connection (exchanging 3 segment between hosts): sending a query from a client, sending a confirmation from the server, sending an answer from the server, and then sending a confirmation from a client and disconnecting the connection (4 segments).

To identify different connections to and from the same IP address, we use port numbers. Each server of a given application layer protocol binds to a given port number and waits for an incoming connection. The client connects to this port (in the case of a TCP connection) or sends a datagram to that port (in the case of UDP). For the most used, well-known protocols, there are reserved port numbers. For example, the HTTP server usually listens on port 80 TCP (alternatively, clients would have to connect to it by specifying the port number itself in an address - http://example.org:1234/), DNS server usually listens on port 53 UDP (sometimes port 53 TCP, too). The client needs to use a port on its side, too. They are "high ports" like 52044 and are randomly generated.

Here, you can see more reserved ports that we use everyday.

The segments and datagrams are then packed into IP packets, in the network layer. In the packets, the source and target computer are identified by IP addresses. They are global - only 1 host can use the same address at a time (excluding a magic like NAT used in home routers with private IP addresses: 192.168.x.x, 10.x.x.x, 172.16-31.x.x; x is a number between 1 and 255). Based on those addresses, routers can decide how to send the packet to get to the target computer.

The packets are then packed into frames/cells in the data link layer and then transmitted in a cable or in the form of radio waves on the local network. In the data link layer, in the frames, the computers are identified by their MAC addresses. Frames with MAC addresses are completely deleted from the routers which extract packets from them. They decide which network to send the packets to, pack them into new frames and send them on their way. If a network between both routers uses MAC addresses, addresses of those routers are included in the frame - the source one and the target one. It's not possible to communicate between two computers in different networks using only MAC addresses, even if they are not duplicated - the producer associates only one address with one card, so any manufactured carts can have the same MAC address as a card made by another producer.

TCP/IP (DoD) model Encapsulation

About SSH. Theory, Part 1

SSH is a protocol in the application layer. It's the successor of telnet and is used for connecting to your VPS remotely in text mode. Unlike telnet, SSH is encrypted. It uses port 22 TCP, but you can easily change the port in your server's configuration. SSH allows the user to authenticate themselves several different ways.

For example:

  • using a username and password
  • using a pair of keys - first, a private one (top secret), and second - a public one (on server): a program that you use to connect with SSH has to solve math problem using a private key and send the solution to the server. The problem is different each time, so it's difficult to break the key using that authentication method.

Nowadays we use version 2 of SSH.

The most popular SSH server implementation is OpenSSH. The most popular clients are PuTTY (for Windows) and OpenSSH (for Linux). Both PuTTY and OpenSHH allow users to create tunnels.

SSH allows users to create a TCP tunnel between the server and client and to send data through that tunnel. SSH supports TCP tunnels only, but you can work around that i.e. via a SOCKS proxy. A tunnel like that is established between a chosen TCP port on server and a chosen local port. It's unencrypted, of course, so anybody can check what we use it for.

Concepts that will be used

Loopback interface - a virtual network card installed in the system with the IP address 127.0.0.1. Only applications installed on the system have access to that address. Remote access is not possible. You can start a VPS on that interface and have remote access only from the same system or via tunnel.

SMTP - an application layer protocol that let you send e-mails. It's used for both communicating between mail servers and the communication between a server and a mail client. SMTP uses port 25 TCP for unencrypted communication and port 587 TCP or 465 TCP (deprecated - not recommended) for an encrypted connection (SSL).

POP3 - protocol in the application layer used to download new e-mails from a server to local mail client. It's rarely used nowadays as it has been superseded by IMAP. For unencrypted connections it uses port 110 TCP, for encrypted connections - port 995 TCP.

IMAP - a protocol similar to POP3, but with support for folders, labels, reading and managing messages and folders on the server without downloading everything to local PC and deleting it from the server. IMAP uses port 143 TCP for unencrypted connections and port 993 TCP for encrypted connections.

Example 1: Tunnel to an IMAP server

A tunnel between local port 143 on the loopback interface - 127.0.0.1 - and the IMAP server for receiving mail (unencrypted connection) on the same remote machine.

Unix and OpenSSH:

ssh abc@def -L 110:127.0.0.1:110
 
abc - username on server
def - server address
110: - local port that will be opened on loopback interface (127.0.0.1) on local machine
127.0.0.1 - IP address of computer that we creating a tunnel to via our SSH tunnel
:110 - port number of target machine we'll get to via tunnel

Windows and PuTTY:

Here you can read how to create connection to your VPS using PuTTY. That connection is required to create a tunnel.

  • Choose your connection, load data and go to Connection->SSH->Tunnels and set it as follows:

    Yay!
  • Click on Add. After that every protocols it should look like this:

    Yay!
  • Now you can save the session and connect using it.

Now you can just configure your mail client to connect to the VPS not directly, but using port 110 of the loopback interface - 127.0.0.1. You can do the same thing with different protocols - SMTP (25), IMAP (143), etc.

Example 2. Tunnel to a Web Server

A tunnel between local port 8080 on the local interface (127.0.0.1) and the WWW server, bound to a remote machine's port 80. This time we'll connect to it using the loopback interface.

As I said earlier, the HTTP protocol is used to download WWW websites to the browser.

Unix and OpenSSH:

ssh abc@def -L 8080:11.22.33.44:80
 
    abc - username on server
    def - server address
    8080: - port on the local machine that will be opened on loopback interface (127.0.0.1)
    11.22.33.44 - IP address of the server that we'll create a tunnel to using SSH

Windows and PuTTY:

  • Choose the connection and load the settings.
  • Go to Connection->SSH->Tunnels
  • Set it like this:

    it looks like this
  • Click on Add:

    it looks like that
  • Now you can save the session and connect.

Theoretically speaking, after going to 127.0.0.1:8080 in your browser, you should see a website located on the remote server we've connected to.

Practically speaking, HTTP 1.1 introduced the Host parameter to queries. This parameter is used to send the DNS domain name of the VPS we're connecting to. If it uses the Virtual Host mechanism, the page you'll get will either be an error page or the server's main page, but not through the tunnel.

In this case, we have to do one more thing: in the hosts file on local PC, add the VPS address and your loopback interface:

127.0.0.1 website

website is the address to site you want to connect to (without the http:// at beginning and the / at the end).

The Hosts file is located at /etc/hosts (Linux) or C:\Windows\system32\drivers\etc\hosts (Windows). To edit this file, you must be an administrator or have administrative privileges.

Important! If you want to create a tunnel on a local port numbered less than 1024 on Unix systems, you must have root privileges.

Example 3. SOCKS proxy

A SOCKS proxy allows you to send traffic from any protocol through a tunnel. It looks, from the outside, like a single TCP connection.

In this example, we'll create a tunnel between an SSH server and a client on port 5555 on the loopback interface. Next, we'll set our browser to use our SOCKS server as proxy server for every outgoing connections.

This solution might be useful to bypass the restrictions on corporate networks. If the port that our SSH uses is locked, we can tell the server to listen on port 443 using the Listen option in the OpenSSH configuration file (/etc/ssh/sshd_config or /etc/openssh/sshd_config).

Unix and OpenSSH:

ssh abc@def -D 5555
 
    abc - username
    def - server address
    5555 - local port number, where the tunnel will be created

Windows and PuTTY:

  • Choose the connection and load the settings.
  • Go to Connection->SSH->Tunnels
  • Set it like this:

    noname1
  • Click on Add:

    noname2
  • Save the session and connect to it.

In your browser settings, set up a SOCKS proxy that runs on 127.0.0.1:5555, from now until you close the connection in PuTTY or OpenSSH.

Example 4. Bypassing NAT

NAT (specifically PAT, which is the NAT form used in home routers) is a mechanism that allows many people to use one internet connection. A router that uses NAT has one public address and modifies all private addresses in packets received from internal network to its own public address and sends them to the Internet. Upon receiving packets back, it does the opposite - it remembers the IP addresses and port numbers in a special NAT table.

A connection from the outside is possible only when we set appropriate port forwarding on the router. However, we can bypass that problem and create a tunnel between our computer and the server to connect our computer and server directly.

Part 1.

In the second part, we'll create a tunnel between local port 80 (on our computer - the local HTTP server) and port 8080 on the remote server. However, because of security reasons, the remote port 8080 will be opened only on the loopback interface of the VPS - 127.0.0.1. Because of that, we have to reconfigure our server to open connections on every port. We'll do that now.

  1. In your favorite editor, open the /etc/ssh/sshd_config (or /etc/openssh/sshd_config) file as root.
    nano /etc/ssh/sshd_config
  2. Find:
    #GatewayPorts no
  3. Change that line to:
    GatewayPorts yes
  4. Save the file and close the editor.
  5. Restart SSHD server:
    Debian/Ubuntu:
    service ssh restart
    

    CentOS: /etc/init.d/sshd restart

Part 2.

In this section, we will create the tunnel.

Unix and OpenSSH:

ssh abc@def -R 8080:127.0.0.1:80
 
    abc - username
    def - server address
    8080 - port number that will be opened on remote server - our proxy server
    127.0.0.1 - IP address we open tunnel to
    80 - port number we open tunnel to

This time, our tunnel is local, but we can make a tunnel connection to other computers in the same network by using NAT.

Windows and PuTTY:

  • Choose the connection and load the settings.
  • Go to Connection->SSH->Tunnels
  • Set it like that:

    It looks like that
  • Click on Add:

    noname3
  • Save the session and connect.

After logging in, we can get to our local HTTP server from outside our network through an OpenSSH proxy server that has a public IP address. Open the following in a browser:

http://IP-address-or-domain-of-our-server-change-that-for-your-name:8080/

Theory continued

As you can see, there are three types of SSH tunnels:

  • Local - -L option - a tunnel is opened on our local port and listens for connections that are redirected first to our saved connection to the SSH server, and next to the target host.
  • Remote - -R option - a tunnel is opened on SSH server. After receiving a connection by the server, all transmissions are redirected out our local tunnel.
  • Dynamic - -D option - a tunnel is opened on a local loopback interface. Transmission takes place through the SOCKS protocol. You can tunnel any packets through this - TCP, UDP. It's possible to connect to any server on the Internet through a proxy SSH server. To redirect all system traffic through the SOCKS proxy, you can use a program like proxifier.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
9 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sorry but this was a little hard to follow. I already understand tunnels and proxys and was hoping to strengthen or gain new knowledge on the subject. Certain parts where hard to understand. I do t mean to sound rude but it’s not hard to tell that English is probably not your native language. I found this to be more confusing than helpful.

For “Example 2. Tunnel to a Web Server” to work I had to edit /etc/hosts and add the line: 127.0.0.1 localhost Followed by rebooting the droplet

is there any way to play a game like League of Legends/ WoW behind a company firewall using this way? i can use the browser and i cannot install or run any program with admin rights…

Hi,

My uni is blocking all UDP connections, I mean there is no port oppened for UDP. And I need to establish UDP connection to connect to game clients and game. Proxifier and Proxycap is not redirecting the network properly and it just shuts down the connection. I managed to bypass the browser restrictions using port 443 in my server and port 5359 in my machine, anyway it doesn’t matters I can use any port there,

The problem is that when I try to open a game client it dosen’t establish connection and I don’t know what’s the matter…

For benefit of us neophytes: Consider this from Part 2. above:

***ssh abc@def -R 8080:127.0.0.1:80

abc - username
def - server address
8080 - port number that will be opened on remote server - our proxy server
127.0.0.1 - IP address we open tunnel to
80 - port number we open tunnel to***
  1. Is the ssh command entered in the local or remote machine. You could show this by noting: $remote ssh abc@def -R 8080:127.0.0.1:80

  2. So this opens port 8080 on our remote vps machine. Do I need to open 8080 in the firewall using something like this? Or does ssh take care of that. $remote sudo ufw allow 8080

  3. In my browser on the local machine, I enter this: http://127.0.0.1:80 then my browser responds to packets received on port 8080 at my remote vps server?

4,“127.0.0.1 - IP address we open tunnel to” implies the ip address on the local machine that packets received on the remote vps on port 8080 will be forwarded to? I sit at 127.0.0.1 with my local machine tuned to port 80 and receive all packets coming in from the vps as received there on 8080?

  1. Another name for this is inbound (aka reverse) ssh tunneling. I assume the tunnel is two way? That is to say, packets generated by my local machine at 127.0.0.1 streaming out of port 80 flow up to the vps server via the ssh tunnel. And packets impinging on port 8080 at ip “server address” flow “down” to the local machine where they are consumed on port 80?

Yeah I know RTF but it really wasn’t obvious to me. Great tutorials here at Digital Ocean. Thanks to all contributors.

Thanks for taking the time to share some tunneling tricks~

– Sam Smith Technology Evangelist and Aspiring Chef. Large file transfers made easy. www.innorix.com/en/DS

For anyone wondering, if you want a SOCKS proxy and want to listen to all interfaces, the format is the following: ssh abc@def -D 0.0.0.0:port

There is image placement mistakes from Example 2. Tunnel to a Web Server for WINDOWS PUTTY… …/tunneling/img3.png is not placed and hence all the succeeding putty window images are placed in decrement of 1 place then they should be placed

I can’t use the SOCKS server as Dante in Digital Ocean’s Droplets?

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel