Print This Page
Tuesday, 07 September 2004
My Handy Restaurant security is fairly high, but everything could be compromised if the environment on which the system is running is not secured, too.
This guide faces the wireless and general clients security question with the ssh tunnels solution.

Preface

It should be clear that security is a wide field with many problems and many possible solutions.
This howto only faces on of the possible security problems, and tries to solve it with SSH tunnelling.
It should be possible to apply the concepts described in this tutorial to almost any Operating System, but here only the GNU/Linux case is described. If you manage to adapt these instructions for another OS, please let us know, so that we can write a new howto.
The howto has been written for a Debian GNU/Linux system, but other GNU/Linux distributions should be more or less the same.

It is given that you already installed SSH server on your server, SSH client on your client and have a working My Handy Restaurant installation on the server,
You will need 2 computers (a server and a client) to test everything.


The SSH tunnels

I'm not good at explaining and many other websites already went through the topic, so I will not get deep on how a tunnel works. Basically the data gets incapsulated in packets and then is passed from one computer to another inside the "containers".
Doing this with SSH ensures that the data also gets crypted while being transported, so that someone listening for the network traffic (as it is easy to do on a wireless network or on a hub concetrated network) cannot understand the encapsulated data.


The bad side...

As ever, nothing is for free!
The downside of the SSH tunnels is that they may add a big overhead on the network and on the processor. Of course these are negligible on oversized networks and quite powerful computers, but this may be an issue on a handheld client, for example.


The concept

We'll use the SSH tunnel to automatically authenticate a client on the server and forward a local port to the server's HTTP port (80). In this way we'll have two main effects:
1. The data will be encrypted, so that sniffers cannot understand data or inject anything.
2. The server will believe we're connecting from itself and not from our client, in this way we can deny any client apart from the server itself to connect to the HTTP server and avoid unwanted clients to work on the system!


The SSH connection

First of all, let's try an easy SSH connection from the client to the server, just to check that everything works smoothly.
clientuser@client:~$ ssh serveruser@serverip_or_hostname
(if you never connected with this user to the host you may get a warning telling that the authenticity of the host can't be established, just answer yes)
password: [your server's user password here]

and now you should be logged in, looking at somehting like: serveruser@server:~$

Easy, isn't it?
OK, if everything went ok, we can begin the hard work!


Creating a new dedicated user

To be sure that we don't make any damage to the system while preparing the tunnel, we'll create a new user on the server. He will be called mhr.
First login as root on the server and create the user:
root@server:~# adduser mhr
Provide a strong password (you will use it a few times and it is very important to choose a difficult password) and leave blank all the contact info. Then confirm the data when asked to.

Good the user mhr now exists!


SSH server configuration

Before going on, it is good to check if the SSH server configuration file (on debian located in /etc/ssh/sshd_config) includes the following two lines (not commented, of course):
RSAAuthentication yes
PubkeyAuthentication yes

If they're not present or are commented out (preceded by a #), add or uncomment them.


Creating and copying SSH keys

Now let's work on the client.
We want the client to automatically connect when the systems boot up. The only user available at that time is the root user, so we'll create a script that connects to the server as mhr, but is run by root locally; this is not the most secure solution because we will run the script as root, but it's good enough and it is the simplest.
To make everyhting happen automatically, without asking for password, we should create the SSH keys on the client and upload the public key on the server.

log in as root on the client:
root@client:~# ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/root/.ssh/id_dsa):
Press enter to accept the suggestion.
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Press enter: we don't want any passphrase.
Enter same passphrase again:
Enter again
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
63:56:d5:9c:06:53:4d:cd:82:63:77:56:d5:52:76:3b root@client

Good, keys created.
Now we should upload them to the server:
root@client:~# scp .ssh/id_dsa.pub mhr@server:~/client_key.pub
Password:
Give password chosen when creating user mhr
Now the file has been copied via ssh copy (scp).

Log in on the server as mhr and add the client key to the list of the authorized clients:
mhr@server:~$ cat client_key.pub >> .ssh/authorized_keys
The client key has been added, we can remove the temp file we copied.
mhr@server:~$ rm client_key.pub

Ok, now the client key has been copied and the user root from client can authenticate automatically (with no user input) on the server as user mhr. Let's check it:
root@client:~# ssh mhr@server
Now no password request is prompted and you get directly the server shell:
mhr@server:~$

Wow! Cool, isn't it?


The tunnel script

Now the big part is gone. We only need to make the SSH tunnel and create it automatically at system boot.
To do this we'll prepare a script to be executed on the client at boot time.

The script is really simple.
Log in as root on the client and in your favorite text editor on the client create a new file called tunnel, add the following to lines and save it:
#!/bin/bash
/usr/bin/ssh -L 5000:server_ip:80 -N mhr@server_ip &

We're opening an ssh connection (/usr/bin/ssh), as user mhr on host server_ip (mhr@server_ip) and forwarding port 5000 on localhost to port 80 on server_ip (-L 5000:server_ip:80). We don't need a shell (-N).

Now make the script executable
root@client:~# chmod a+x tunnel

The script is ready to be run by root.
Now you should add it to the scripts run at boot time. Anyway here it will not be discussed how to make it automatically executed at boot time, because this aspect is too much related on the chosen distribution, so please consult your distribution documentation on how to run a script at boot automatically.


Testing the tunnel

Now we can test the tunnel.
First, run the script as root:
root@client:~# ./tunnel
Then open a browser and point it to http://localhost:5000/, you will see the server main page, as if you were pointing the browser to http://server_ip/.
This is very good, because it means that the tunnel is working and that you are connecting through a crypted connection.


Closing the HTTP server

When you have set up the tunnel on all your clients, you can finally deny access to anyybody apart from the server itself, because your clients will appear as server-based connections.
Create or edit the file .htaccess in the directory on your web server where My Handy Restaurant is installed and add the following lines:
order deny,allow
deny from all
allow from 127.0.0.1/255.0.0.0
allow from server_ip

Then reload apache (log in as root):
root@server:~# killall -HUP apache

Now if you try to connect from a browser on a client to http://localhost:5000/ it will work (tunnelled connection), while if you try to connect from a client to http://server_ip/ you will get an access denied error.

And that's all!

Please, review this howto so that we can improve it with your suggestions and experience!
Bye,
Fabio 'Kilyerd' De Pascale