bookmark_borderSSH as a proxy on Windows, Mac or Linux

You can do a lot of things with SSH besides working securely remote on machines. I’ve already covered at another article how to tunnel (port forwarding) through SSH. This time we’re looking at a way to use SSH as a proxy.

SSH: A tool not only to do remote work

SSH (Secure Shell) is mostly used to do maintenance on your Linux machines. However, over the years the capabilities of SSH has been extended from a simple secure „remote maintenance protocol“ to a utility which is capable of doing things like X-Forwarding (for forwarding graphical application), port forwarding or providing a SOCKS proxy.

Why do you even want to use an proxy server?

Proxy servers are helpful in a lot of ways. For e.g. if you’re staying some nights in a hotel or you’re in any other public Wireless LAN which blocks a specific website you want to visit a proxy will help you to surpass the filter. Or if you are forced to use techniques like DSLight, were you have to share a single IPv4 address with other users. Or to unblock videos on Netflix which are blocked in your country. You see, the situations where a proxy server is helping you are almost countless.
But why would you want to „setup“ an proxy server on your own? The simple answer is, that a lot of the public proxy servers are simply overloaded. They have to handle so much traffic that you sometime barely be able to get 50% of your normal internet speed while using one of these public proxy servers. Besides this, using SSH as a proxy is really easy.

How start a SOCKS proxy server by using SSH

In order to establish a SSH connection to your server which will then be an SOCKS proxy, you have to have the SSH server installed on the server side and the client software on the client side of course.

Using SSH as a proxy on Linux or Mac

For Linux or Mac you can use the SSH client command which is integrated in both systems. The following command would start an SSH connection, where your SOCKS proxy would then be locally reachable on port 19999 (19999 is just an suggestion and can be changed to almost everything starting from 1024 to 49151 (so called „user ports“)) :

user@client:~$ ssh -D 19999 user@server

After the connection has been successfully established, configure your browser to use the proxy server (follow the instructions below).

Using SSH as a proxy on Windows

Windows doesn’t comes with an SSH command integrated. This means we need an additional software in order to get connected and use the SSH server as a proxy. My recommendation here is PuTTY. PuTTY is a lightweight SSH client for Windows, which is the counterpart of the SSH command on Linux / Mac. You can download it here. After the download is finished, start PuTTY and enter the server you want to connect to like this:

Hostname you want to connect to

Navigate to Connection –> SSH –> Tunnels and enter the port 19999 in the Source port field (19999 is just an suggestion and can be almost everything starting from 1024 to 49151 (so called „user ports“)). After you’ve entered the desired port number, ensure that you’ve selected Dynamic instead of Local:
Settings to tell SSH to create a SOCKS proxy

Click on the button Add in order to tell PuTTY to actually use the given information for the next connection. If you clicked on Add, you should see the port number you have chosen with the letter D in the upper box. If you’ve done this as well, you’re ready to connect to your server. After the connection is successfully established, go on and configure your browser (follow the instructions below).

Configure Firefox / Google Chrome to use the SOCKS proxy

Now that we’ve connected successfully to our server via SSH, we can actually use the SOCKS proxy which has been provided with the actual SSH connection.

Configuring Firefox to use the SOCKS proxy

Click on the upper right options Symbol (represented as three horizontal lines) and click on Preferences. On the upcoming window, select General and scroll down until you see the context Network proxy. Click on Settings and enter your SOCKS proxy details like this:

Firefox proxy settings

Ensure that you’ve checked the box Use this proxy server for all protocols. After you’ve clicked on OK you’re ready to go. Use portals like BearsMyIp to check if you’re actually surfing through your SSH SOCKS proxy tunnel.
Configuring Google Chrome (or Chromium) to use the SOCKS proxy
For Googles Chrome browser you have to use the command line in order to set your SOCKS proxy. This includes Windows users as well. To start Googles Chrome using your SSH SOCKS proxy start the browser like this:

google-chrome --socks-proxy="socks5://localhost:19999"

The windows command line may look like this:

google-chrome.exe --socks-proxy="socks5://localhost:19999"

Of course you can change google-chrome to chromium if you’re an Chromium user instead.

Final words

An proxy server does have it’s advantages. However, public proxies are sometimes overloaded and you will recognize that as a significantly slow down of your internet connection when you start using them. As an alternative you can use SSH as a simple and fast way to make yourself an SOCKS proxy. Using SSH as a SOCKS proxy is a lot easier than configuring an Apache with Squid for e.g.. If you have a server and you need a proxy, I highly recommend you to use SSH in order to get a safe, fast and stable proxy server with a single command or a few clicks.

Further links

 

bookmark_borderMy new helper Ansible

For some weeks ago, I decided to use Ansible as my central configuration tool of choice. The following text should give you a short intro in how to deploy files with Ansible.

What exactly is Ansible?

Now, what exactly is Ansible? Ansible is an auto configuration tool, which helps you to keep your configuration files central managed. You will benefit from easier configuration and you will save a lot of time. For example, if you have 3 DNS servers and you want to ensure that all this systems have the same db and configuration files used, you could use either a network storage (which is obviously something over the top here) or keep them central and push them to all DNS servers.
And Ansible is exactly doing that. It pushes your configuration files on given hosts. Another really pro for Ansible is, that it uses SSH to do so. This means that you don’t have to install a service to get your machines configured. Ansible is agent-less.

How to install

For almost every distribution out there in the wild, Ansible is available in the system repositories. For Ubuntu / Debian you can easily do:

sudo apt-get install ansible

as well as for openSUSE you can just do:

sudo zypper install ansible

After this, you can find the standard configuration under /etc/ansible.

Make SSH ready for Ansible

Every host which will be managed via Ansible needs to have a Public Key and a user which is allowed to use this Public Key to connect to the Host.
For my personal purposes I created a user which is allowed to change the files which are coming from Ansible. This is of course optional. You could also do this with the user root even if that means a little bit more of a security risk. Anyway, you have to generate a Public Key which is done with the following command for the user ant:

ant@ansible:~$ ssh-keygen -t rsa -b 4096

For our scenario, you shouldn’t set a password for the key. The other questions can be confirmed with pressing ENTER without any changes. After this your SSH Key is ready and you can push them to your Host which will be configured with Ansible later. After the following command is issued, the user ant on your Ansible system will be able to login as user ant on the system target without entering a password. As described above, you could also do this with the user root here:

ant@ansible:~$ ssh-copy-id -i ~/.ssh/id_rsa.pub ant@target

Now you should be able to login via ssh as the user ant on the system target without entering a password.

Groups and Hosts

Now that you have the target System fed with an Public Key, you are able to make the target System known in Ansible. The Ansible configuration files are located at /etc/ansible. First of all you should add the target system in the /etc/ansible/hosts file:

[testsystems]
target.local.dom

Let me explain this file a little bit. You can enter a hostname per line in this file. Ansible then knows them and will deploy the given files. To make the configuration easier, you can use groups. A definition of a group start with [ and ends with ]. So in this case the host target.local.dom would be in the group testsystems. You can put one host into multiple groups.

Playbooks

The host is now known for Ansible. As next we need to define the files which will be pushed and where their going to be deployed at the root filesystem of the target host.
For this, Ansible is using so called Playbooks. As its name implies, the Playbook is a collection of things which has to be done on the target system. You can do almost everything here which you also would be able to do by hand in the console. There a plenty of modules which can be used for e.g. Update your system, set file permission, and so on. And even if there is no module available which fits your needs, you can always use the bash module and write down what the system should do by yourself. A complete list of the modules and how to use them can be found at the official documentation. In this example we will push files to the target system. So we have to define this in the Playbook. You can either use the copy or the synchronize function within the file module to push the wanted files to the target. The following example will use the synchronize function:

---
- hosts: testsystems
vars:
files: /etc/ansible/files/testsystems/
gather_facts: false
become: false
tasks:
- name: copy files
synchronize: src={{ files }} dest=/opt
notify: restart ssh
handlers:
- include: handlers.yml

So what does this Playbook do now? Let me explain this file step by step:

  • hosts: Here we insert the group(s) which has been declared in the /etc/ansible/hosts file. You can name here single hosts as well as groups. It’s always recommended to use groups here.
  • vars: In vars we can declare variables which are used within this Playbook configuration. There is actually one variable defined which is called files. This variable is used later in the tasks section.
  • gather_facts: This is true or false. The standard is true. gather_facts is collecting informations about your system which can be used within the modules. Here it is disabled because we know that this Playbook will running well with the settings we give Ansible.
  • become: In earlier versions of Ansible this was called sudo. Become decides wether this Playbook needs root /sudo privileges to run, or not. The way how the system will become the root is defined in the central ansible.cfg. If set to true, you have to ensure that the „become user“, is available on the target system and has sudo permissions.
  • tasks: In tasks we define what to do on the target system. In this case we have one task, which is named „copy files“. It uses synchronize which is provided by the file module. The source path is the path which is defined in the variable files at the beginning of the Playbook-file. The Destination is the absolute path on the target system. In this case „/opt“. At the end, we use a notifier. This notifier is calling „restart ssh“ if a file has really changed on the target system. „restart ssh“ is written down in the „handlers.yml“ file. This file has to be in the same directory as this Playbook.

This is a really short and easy example of the capabilitys of Ansible. As I said earlier, you can do a lot of more stuff. For this you should consider to read the official documentation.
You can now save the file where ever you want. I recommend a place like /etc/ansible/conf.d. The filename ending should be .yml. So for e.g. we could save the file „testservers.yml“ under /etc/ansible/conf.d.

The handlers.yml file

As mentioned before, the handlers.yml file is just an addition to your existing Playbook. In the handlers file you can write down commands which can be reused a lot of more times. For example the „restart ssh“ command, which has been called in our Playbook, can be also needed by other upcoming hosts. To prevent for writing down the same commands again and again, we use an external extra file, which holds all the reusable commands. This file is here called handlers.yml and has to be stored in the same directory as your Playbooks. An example handlers file looks like this:

---
- name: restart bind
service: name=named state=restarted
- name: restart ssh
service: name=ssh state=restarted

So as you can see, we use the module service to restart the services ssh and bind. The services are restarted on the target system, when they get called in a Playbook. In our Playbook-example above, the „restart ssh“ command is triggered after copying files.

Testing our new configuration

We have a valid hosts and Playbook file and our target system has the needed Public Key. So we should be ready to go. To start or „call“ a Playbook you have to issue the following command on your command line:

ant@ansible:~$ ansible-playbook /etc/ansible/conf.d/testservers.yml

NOTE: Don’t forget, that you have to issue the command on your Ansible system, with the user which has the Public Key stored on the target system.
Now your Ansible server system should start pushing the data to the target system. A output like this should be shown to you:

PLAY [testservers] ************************************************************
TASK: [copy files] **************************************************
changed: [target.dom.local -> 127.0.0.1]
NOTIFIED: [restart ssh] ******************************************************
changed: [target.dom.local]
PLAY RECAP ********************************************************************
target.dom.local : ok=2 changed=0 unreachable=0 failed=0

This means the files are successfully copied and the ssh service was restarted. This means your first Ansible Playbook is running fine without issues. Now you can go on in adding more tasks.
Don’t for get the official documentation to do so 🙂

Further links

bookmark_borderHow to create an SSH tunnel under Linux

Creating an SSH Tunnel allows you to encrypt every network communication you want. You are also be able to access other network services which are only available at the destination which you trying to ssh to. Almost every Linux distribution is already able to create such a tunnel. However in term of „tunneling“, using SSH to create a tunnel is more like doing port forwarding.

SSH command to create a tunnel

Tunneling with SSH is really simple. You define the port on your local machine, where your forwarded port should be listening to. Then you define the destination it should point to. The following picture tries to show you how easy it really is:
ssh_blog
As you can see in the picture, the first number after the -L parameter (marked red) states the local port on your local machine where you execute the ssh command. This means that the remote service will be available locally on your machine with this port. You should only use ports above the „System Ports“ which are regulated in RFC 6335. This means ports greater than 1023 (in the picture we use port 5000 which is fine).
The second value (yellow marked) states the remote address. The remote address can be localhost but in this case localhost does not mean your local machine. It means the remote machine you are ssh-ing to. It is possible that you insert a machine name or IP behind the destination machine. The destination tries to establish the connection to the remote address then.
The third value after the -L parameter (marked blue) is the port of the destination address which is given in the step before (yellow marked). This means, if you want to connect to a running Webserver, then you have to enter 80 here (80 is the standard port for a HTTP connection).
The last value (marked green) is your username and the server you’re going to ssh to.

A more pratical example

Another good example would be something like this:

ssh -L5000:www.google.de:443 myserver.my.domain

This example will open a SSH connection to the server myserver.my.domain and will tunnel (or forward) the Port 443 on the destination address (in this example „www.google.de“) to the local port 5000 on your local machine. After this you will be able to enter https://localhost:5000 in your webbrowser on your local machine and you should see the google start page. This means all traffic which is going to www.google.de via HTTPS is routed over your myserver.my.domain.

Encrypting VNC traffic

VNC doesn’t encrypt network traffic by default. If you do remote administration with VNC you could either use a VPN or SSH as a much more simpler solution. There are other remote administration solution available which do support encryption out of the box (like X2Go or NXNomachine). However, using VNC in combination with SSH for encryption is as easy as possible. Encrypting a VNC connection over an SSH tunnel gives you some great benefits:

  1. The VNC traffic between your local machine and the destination (VNC Server) is encrypted.
  2. As a home server user, you can just open the SSH port in your routers firewall for external access. All other ports can remain closed because you can port forward them with the help of SSH.
  3. Due to the SSH user authentication you have something like a „low-level“ user authentication.

The following example opens a SSH connection to the server myserver.my.domain and forwards the VNC Server port on this server so that the VNC Server is reachable locally under the port 5000:

ssh -L5000:localhost:5900 myserver.my.domain

After the connection is established the VNC Server on the server myserver.my.domain can now be reached under the address localhost port 5000. If your server does listen on another port than the standard port of SSH (22) you can add the -p parameter to ssh to your server with the port you want:

ssh -p1234 -L5000:localhost:5900 myserver.my.domain

Further links