The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.
At some point, you may find yourself on a network that is insecure or has an overly restrictive firewall and you’ll want to make sure no one is watching your traffic. One solution is to set up a VPN on Ubuntu 22.04 / 20.04 / 18.04, but many VPNs require special client software on your machine, which you may not have rights to install. However, if all you need to secure is your web browsing, there is a fast, free, and useful alternative: a SOCKS 5 proxy tunnel.
A SOCKS proxy is an SSH encrypted tunnel in which configured applications forward their traffic down, and then, on the server-end, the proxy forwards the traffic to the general Internet. Unlike a VPN, a SOCKS proxy has to be configured on an app-by-app basis on the client machine, but you can set up apps without any specialty client software as long as the app is capable of using a SOCKS proxy. On the server-side, all you need to configure is SSH.
In this tutorial you’ll use a server running Ubuntu 22.04 (although any Linux distribution that you can access via SSH will work), and the Firefox web browser as the client application. By the end of this tutorial you will be able to browse websites securely through the encrypted SSH tunnel.
If you are using Ubuntu version 16.04 or below, we recommend you upgrade to a more latest version since Ubuntu no longer provides support for these versions. This collection of guides will help you in upgrading your Ubuntu version.
sudo
user and SSH access. For guidance on how to set these up, please choose your distribution from this list and follow our Initial Server Setup Guide.. Go here to build your tunnel on a DigitalOcean Droplet.
An application to configure with the SOCKS proxy, such as the Firefox web browser.
For Windows users, you’ll also need either the PuTTY tool or Windows Subsystem for Linux (WSL)
PuTTY is used to set up the proxy tunnel for Windows users. Users of macOS or Linux have the tools to set up the tunnel pre-installed.
On your local computer, create an SSH key if you didn’t create your Droplet with one already in place. Once the key is created, make sure the public side is added to the ‘authorized_keys’ file on your SSH Droplet. Then open a terminal application to create an SSH tunnel with SOCKS proxy enabled.
Set up the tunnel with this command:
- ssh -i ~/.ssh/id_rsa -D 1337 -f -C -q -N sammy@your_domain
Explanation of arguments
-i
: The path to the SSH key to be used to connect to the host
-D
: Tells SSH that we want a SOCKS tunnel on the specified port number (you can choose a number between 1025
and 65536
)
-f
: Forks the process to the background
-C
: Compresses the data before sending it
-q
: Uses quiet mode
-N
: Tells SSH that no command will be sent once the tunnel is up
Be sure to replace sammy@your_domain
with your sudo
user and server IP address/domain name.
Once you enter the command, you’ll immediately be brought to the command prompt again with no sign of success or failure; that’s normal.
Verify that the tunnel is running with this command:
- ps aux | grep ssh
You will see a line in the output like this:
Outputsammy 14345 0.0 0.0 2462228 452 ?? Ss 6:43AM 0:00.00 ssh -i ~/.ssh/id_rsa -D 1337 -f -C -q -N sammy@your_domain
You can quit your terminal application and the tunnel will stay up. That is because we used the -f
argument, which put the SSH session into the background:
Note: to terminate the tunnel you’ll have to grab the PID via ps
. In our example, the PID is 14345
. We would then use the command kill 14345
. We’ll walk through termination in Step 3.
Open PuTTY.
If you haven’t installed it yet, download PuTTY and save it where you like. PuTTY doesn’t require admin rights to install; just download the .exe
and run it.
Complete the following steps to set up the tunnel:
From the Session section, add the Host Name (or IP address) of your server, and the SSH Port (typically 22)
On the left, navigate to: Connection > SSH > Tunnels
Enter any Source port number between 1025
and 65536
, such as 1337
Select the Dynamic radio button
Click the Add button
Go back to Session on the left
Add a name under Saved Sessions and click the Save button
Now click the Open button to make the connection
Enter your sudo
username and server password to log in
You can minimize the PuTTY window now, but don’t close it. Your SSH connection should be open:
Note: You can save your sudo
username (sammy) and SSH key for this same session by following the PuTTY SSH Key instructions. Then you won’t have to enter your username and password every time you open the connection.
Now that you have an SSH tunnel, it’s time to configure Firefox to use that tunnel. Remember that for a SOCKS 5 tunnel to work, you have to use a local application that can implement the tunnel; Firefox has this capability:
This step is the same for Windows, macOS, and Linux.
Make sure you have the port number that you used in your SSH command; in our examples we’ve used 1337
.
(The following steps were performed with Firefox version 80 but should work on other versions, though the locations of the options may be different.)
Open Firefox.
In the upper right hand corner, click on the hamburger icon to access Firefox’s menu.
Click on the Preferences or Options menu item.
Scroll to the bottom and under Network Settings select the Settings… button.
Under the ‘Configure Proxy Access to the Internet’ heading select Manual proxy configuration.
For the SOCKS Host enter localhost
or 127.0.0.1
and for the port, use the custom port specified in your tunnel, 1337
.
Near the bottom, check the box ‘Proxy DNS when using SOCKS v5’
Click the OK button to save and close your configuration
Now, open another tab in Firefox and start browsing the web. You should be all set for secure browsing through your SSH tunnel. The data that you get back from the website encrypted. Additionally, because you checked the Proxy DNS option, your DNS lookups are also encrypted so your ISP can’t see what you see or where you went to get it.
To verify that you are using the proxy, go back to the Network Settings in Firefox and enter a different port number and save the settings. Now if you try to browse the web, you should get an error message: ‘The proxy server is refusing connections’. This proves that Firefox is using the proxy and not just the default connection. Alternatively, you can go to a public IP site, such as ipecho.net, and the IP it returns should be the IP of your SSH Droplet since it is acting as your proxy now.
When you are done needing the privacy of the SSH tunnel, go back to the network proxy settings in Firefox. Click on the radio button for ‘Use system proxy settings’ and click OK. Now that Firefox is no longer using the SOCKS tunnel we can shut that down as well. You can leave the tunnel up so you can enable and disable the proxy in Firefox at will but if you leave the tunnel idle for too long, it may close itself.
The tunnel we created earlier on our local machine was sent to the background, so closing the terminal window you used to open the tunnel won’t terminate it. To terminate the tunnel we need to identify the Process ID (PID) using the ps
command, and then terminate the process using the kill
command.
Let’s search for all active ssh
processes on our machine:
- ps aux |grep ssh
Find the line that looks like the command you entered earlier to create the tunnel. Here’s the sample output:
Outputsammy 14345 0.0 0.0 2462228 452 ?? Ss 6:43AM 0:00.00 ssh -i ~/.ssh/id_rsa -D 1337 -f -C -q -N sammy@your_domain
From the beginning of the line, in one of the first two columns, is a 3-5 digit number. This is the PID. The sample PID of 14345
is highlighted in here.
Now that you know what the PID is, you can use the kill
command to bring the tunnel down. Use your PID when you kill the process:
- kill 14345
Close the PuTTY window you used to create the tunnel. That’s it.
For macOS or Linux systems, we can make an alias or create a script to quickly create the tunnel for us. The following are two ways to automate the tunnel process:
These shortcut methods both require passwordless/passphraseless SSH key authentication to the server.
If you want an icon that, when clicked, will start the tunnel, we can create a small BASH script to do the job. The script will set up the tunnel and then launch Firefox, although you’ll still need to add the proxy settings manually in Firefox the first time.
On macOS, the Firefox binary that we can launch from the command line is inside Firefox.app. Assuming the app is in the Applications folder, the binary will be found at /Applications/Firefox.app/Contents/MacOS/firefox
.
On Linux systems, if you installed Firefox via a repo or if it’s pre-installed, then its location should be /usr/bin/firefox
. You can always use the command which firefox
to find out where Firefox resides on your system if it’s not in the standard location.
In this script, replace the path to Firefox with the one that is appropriate for your system. You may also need to adjust the SSH line to reflect the successful command you used previously to stand up a tunnel.
Using a text editor like nano
create a new file:
- nano ~/socks.sh
Add the following lines:
#!/bin/bash -e
ssh -i ~/.ssh/id_rsa -D 1337 -f -C -q -N sammy@`your_domain`
/Applications/Firefox.app/Contents/MacOS/firefox &
Replace 1337
with your desired port number (it should match what you put in Firefox)
Replace sammy@your_domain
with your SSH user @ your hostname or IP
Replace /Applications/Firefox.app/Contents/MacOS/firefox
with the path to Firefox’s binary for your system
Save your script. For nano
, type CONTROL + o
, and then to quit, type CONTROL + x
.
Make the script executable, so that when you double click on it, it will execute. From the command line, use the chmod
command to add execute permissions:
- chmod +x /path/to/socks.sh
On macOS, you may have to perform an additional step to tell macOS that a .sh file should be executed like a program and not be opened in an editor. To do this, right click on your socks.sh
file and select ‘Get Info’.
Locate the section ‘Open with:’ and if the disclosure triangle isn’t pointing down, click on it so you can see the dropdown menu. Xcode might be set as the default app.
Change it to Terminal.app. If Terminal.app isn’t listed, choose ‘Other’, and then navigate to Applications > Utilities > Terminal.app (you may need to set the pull down menu ‘Enable’ from ‘Recommended Applications’ to ‘All Applications’).
To open your SOCKS proxy now, double click on the socks.sh
file. The script will open a terminal window, start the SSH connection, and launch Firefox. Feel free to close the terminal window at this point. As long as you kept the proxy settings in Firefox, you can start browsing over your secure connection:
This script will help you quickly stand up the proxy, but you’ll still have to perform the manual steps listed above to find the ssh process and kill it when you’re done.
If you find yourself on the command line frequently and want to bring up the tunnel, you can create a command line alias to do the job for you.
The hardest part of creating an alias is figuring out where to save the alias command.
Different Linux distributions and macOS releases save aliases in different places. The best bet is to look for one of the following files and search for alias
to see where other aliases are currently being saved. Possibilities include:
~/.bashrc
~/.zshrc
~/.bash_aliases
~/.bash_profile
~/.profile
Once you’ve located the correct file, add the alias below to any you already have, or just at the end of the file. In the example below we’re using the alias ‘firesox’ to bring up the SOCKS tunnel, but you can use any word you wish as your alias:
alias firesox='ssh -i ~/.ssh/id_rsa -D 1337 -f -C -q -N sammy@your_domain && /Applications/Firefox.app/Contents/MacOS/firefox &'
Replace 1337
with your desired port number (it should match what you put in Firefox)
Replace sammy@your_domain
with your SSH user @ hostname or IP
Replace /Applications/Firefox.app/Contents/MacOS/firefox
with the path to Firefox’s binary
Your aliases are only loaded when you start a new shell, so close your terminal session and start a new one. Now when you type:
- firesox
This alias sets up your tunnel, then launches Firefox for you and returns you to the command prompt. Make sure Firefox is still set to use the proxy. You can now browse securely.
If your connection is working, you are good to go and can stop reading. However, if you’ve discovered that you can’t make an SSH connection out due to a restrictive firewall, then it’s likely that port 22
, which is required to create the tunnel, is being blocked. If you can control the proxy server’s SSH settings (with root access to a DigitalOcean Droplet, you will be able to do this), you can set SSH to listen on a port other than 22
.
Which port can you use that isn’t being blocked?
Ports that are often open include 80 (general web traffic) and 443 (TLS, secure web traffic).
If your SSH server isn’t serving web content, we can tell SSH to use one of these web ports to communicate over instead of the default port 22
. 443
is the best choice since it’s expected to have encrypted traffic on this port, and our SSH traffic will be encrypted.
From a non-firewalled location, SSH in to the DigitalOcean Droplet you are using for the proxy or use the built in console from the Digital Ocean control panel.
Edit the server’s SSH settings:
- sudo nano /etc/ssh/sshd_config
Look for the line Port 22
.
We can either replace ‘22’ entirely or add a second port for SSH to listen on. We’ll choose to have SSH listen on multiple ports, so we’ll add a new line under Port 22
that reads Port 443
. Here is an example:
. . .
Port 22
Port 443
. . .
Restart SSH so it will reload the SSH configuration you just edited. Depending on your distribution, the name of the SSH server daemon may be different, but it’s likely to be ssh
or sshd
. If one doesn’t work try the other:
- sudo service ssh restart
To verify that your new SSH port works, open a new shell (don’t close the current one yet, just in case you accidentally locked yourself out) and SSH in using the new port:
- ssh sammy@your_domain -p 443
If you are successful, you can now log out of both shells and open your SSH tunnel using the new port:
- ssh -i ~/.ssh/id_rsa -D 1337 -f -C -q -N sammy@your_domain -p 443
The Firefox settings will be the same since it doesn’t depend on the SSH port, just the tunnel port (1337
above).
In this modern day and age there are a multitude of ways to browse securely when you’re on a potentially hostile network, like a coffee shop’s public wifi. In most situations, if you’re able the use a VPN to secure and protect all of your traffic then its usage is preferred. But having a SOCKS Tunnel will give you the security you need while web browsing when you can’t use or trust a VPN. A SOCKS tunnel is quick to set up and use in a pinch, and you have total control over it. They are an excellent option for secure browsing.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
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!
Rather than to use
ssh -D 8123 -f -C -q -N sammy@example.com -p 443
I would recommend that you create
ssh -D 8123 -f -C -c blowfish -q sammy@example.com -p 443 sleep 10
This will execute sleep 10, and simply as a side effect run your tunnel. It creates and keeps tunnel alive for 10 seconds. Launch a firefox within these 10 seconds, and the tunnel will be kept alive until firefox closes connections, then ssh tunnel will auto close, and exit.
The -c blowfish is simply a personal choice.
I’m not sure this is as private as you think. Where do DNS queries go?
great! I would like to add that if using firefox you can use an add on like foxy proxy to manage proxy server profiles - so that you can use that for geo targetted websites - like appearing to be in the US for certain websites - or based on URL!!
great, thanks
Here’s another take on the same problem, using an Electron desktop app: https://github.com/ab77/proxy-socks#instructions
The example is kept as vanilla as possible to make it more adaptable to various use-cases.
very details tutorial. ssh tunneling was fine. but after making the sock5 setting in firefox, I couldn’t connect to the desire location. any clue
You really dropped the ball on that alias name… should’ve been firesox.
Which website can I buy ssh for bitvise tunneling to enable me send mass messages for my email marketing online?
All images on this (otherwise excellent) article appear to be broken.
Chrome reports a Cert Revoked error on the https connection to assets.digitalocean.com, so they’re not loaded.
Hey,thanks for the info, can you teach me how to put headers on ssh such as x-online host,connect method? And if you are somehow k nowledgeable in linux ovpn,can you help me in custom http headers x-online host? Thanks in advance