There are numerous occasions that I was limited in my work because of connectivity which could not be trusted. For example;
- I could not download large installers due to a proxy anti virus tool which manipulated downloads causing files to become corrupted.
- I needed to visit a website to find a solution to a problem, but the local proxy server found the content offensive and disallowed me to visit the site.
- I have stayed in hotels in which I was not sure that my internet traffic was not being monitored. I was hesitant to access remote services which required credentials.
- Public Wifi can sometimes not be trusted. Someone could run a local hotspot with the same name and intercept credentials of people trying to connect to it.
The method described in this blog allows you to access external resources with few limitations in a relatively secure way. It makes it easy to circumvent most content scanning/manipulation. Do mind that using this method might be in violation of certain rules/regulations/policies. When in doubt, first confirm you’re allowed to use it.
In short what you do is
- Run an SSH server on a different location on port 443
- On the same server which runs an SSH server, run your own HTTP/HTTPS proxy server (or use the SSH server itself as SOCKS proxy)
- Connect to the SSH server
- Map the proxy port to your local machine
- Use the configured port as proxy server in your browser configuration.
This might seem complex but it is easier than you might think and once setup, it is easy to re-use. Also it is easier, more flexible and in some cases also more secure than using a VPN.
Create a proxy server
I’ve used a Raspberry Pi for this. I was not interested in running a full blown server. A Raspberry does not require much electricity and is very small. On a Raspberry Pi, you can install Raspbian. This is a Debian flavor.
It is easy to enable SSH and install Squid; ‘apt-get install squid’. The default install will do. Mind that Squid is an HTTP(S) proxy and no SOCKS proxy. Squid only proxies HTTP(S) and no other TCP protocols. It does however also function as a cache which can be useful.
As an alternative you can use the SSH server itself as SOCKS proxy. This is also described below.
Make the server accessible
Next, you need to create a port-forward in your router in order to be able to access 443 remotely. Why port 443? That is the usual port HTTPS sites run on. Most proxy servers and routers allow access to remote hosts on port 443. This configuration differs per router. Usually you configure static routes based on IP addresses. In order for this to work, your server needs to always have the same IP address. In order to fix this you can configure your routers DHCP server to always give the MAC address of the SSH server the same IP address. As an alternative, you can configure a static IP address on your SSH server. This way you only need to create a port forwarding rule in your router and do not require DHCP server configuration.
Just running an SSH server is not enough. You want to proxy requests! Bitvise SSH Client (also called Tunnelier) is my favorite tool to create/manage tunnels with. The easiest is to use the remote SSH server as a SOCKS proxy and configure a local listen port for it.
You can configure Firefox like below to use it:
An alternative it to create a port forwarding rule to the previously installed squid instance. The default port for squid is 3128.
In Firefox the configuration is the same as for the Squid HTTP proxy except the port is 3128. You can expect more protocols to work when using the SOCKS proxy.
- If you are behind a proxy server, you can configure it at the ‘Proxy settings’ link. The proxy server is used to establish the connection to your SSH server so you can in turn access your own proxy server (which does not have the limitations as the server you use to establish the SSH connection).
- This of course only works if the proxy server you are using is a SOCKS proxy which allows TCP connection to your SSH server. Just an HTTP proxy won’t do.
- If you select Initial method ‘Password’ you can authenticate with a password on your SSH server. You can of course also use a key to make it more secure but a password is easy. This password can be stored in your profile if you want to.
After you have authenticated, you will most likely get 2 pop-up windows. a terminal and an SFTP window which allows you to exchange files. The creation of these windows upon connection can be disabled of course if you don’t like them. I recommend installing fortune (‘sudo apt-get install fortune’ and add ‘/usr/games/fortune -a’ as the last line of /etc/profile for some entertainment)
If your connection fails, you could get something like:
In this case the hostname to connect to is incorrect
In this picture the proxy server name (set under Proxy settings) is incorrect.
To summarize, there can be various connection issues depending on the situation/environment. When setting up the your SSH server, it is a good idea to first confirm it works from a local environment since otherwise it will be difficult to determine what the issue is when in a remote location.
A workaround could have been using my mobile phone as a Wifi hotspot, but downloading large files this way can be expensive (especially when abroad). A VPN could also have been an option but since this requires you to use PPTP and L2TP/IPsec to access a remote server on specific (TCP and UDP) ports, this might not be an option when for example behind a company proxy server which limits access to those ports. OpenVPN uses SSL which can be configured to run on a single TCP port which could have been a viable option. Also a proxy provides more flexibility. In case you need to sometimes access remote and sometimes local resources, using a proxy, which can be configured per application, instead of a VPN would be easier.
Why is this secure
If you are connecting to a remote SSH server, the protocol implements various measures to make the exchange secure.
When using for example a local proxy to connect to your remote SSH server, the connection cannot easily be monitored by the proxy itself since it proxies a byte stream and does not have a way to decrypt the traffic due to the symmetric key cryptography which is used. Read more here. If the proxy server does screw up the transfer, this is detected by the data integrity checks which are part of the protocol. The connection will (most likely, have not tested) be terminated in that case and you have to reconnect. Thus in my humble opinion, you are pretty secure and someone without solid security knowledge (and/or expensive tools) cannot easily translate the traffic.