Automatically reconnecting SSH Sessions

I use SSH on a daily basis to connect to a number of networks, see my previous posting on Opening up network using SSH tunnels. Unfortunately not all network connections, most notably the wireless ones, are very reliable.

Some of the tunnels I use are 'reverse tunnels', which means that I need to physically access the remote machine in order to setup those tunnels, which is not always possible or practical.

The standard OpenSSH client application does not seem to have a function to automatically retry when there is a network hiccup. However, with a little bit of creativity we can add this functionality ourselves.

The solution: Setup a bash script that executes the ssh command in an infinite loop. In order to make this work we need to ensure that the user does not need to manually authenticate on every retry as that would defeat the purpose of a fully automatic mechanism. This solution has been tested with Cygwin and should work on Linux without change.

SSH supports authentication using either passwords or public keys. We have already established that password authentication is not going to work so we need to setup DSA (Digital Signature Algorithm) authentication.

In this example we will be using the following names:

  • UserClient: The user on the client PC (running the SSH client) that wants to connect to a server. Please replace this with the actual user name.
  • UserServer: The user on the server we want to login as. Change this to the actual user name.
  • Client: The machine we are connecting from.
  • Server: The machine we are connecting to.

First we need to create the keys for UserClient on the Client machine. Enter the following command to do so:

ssh-keygen -t dsa

When asked for a pass phrase press enter. This generates a set of keys in the ~UserClient/.ssh directory on the Client machine. As I use Cygwin this directory is located in the following location.

C:\Program Files\cygwin\home\UserClient\.ssh

This file needs to be appended to the list of authorized keys on the Server. Copy ~UserClient/.ssh/id_dsa.pub to the server and concatenate it to the list of authorized keys for UserServer using the following commands:

cat id_dsa.pub >> ~UserServer/.ssh/authorized_keys2

chmod 644 ~UserServer/.ssh/authorized_keys2

That is all what is needed to login using DSA. Try it by issuing the following command on the Client:

ssh UserServer@Server

With this mechanism in place, we can create a small bash script that rebuilds the SSH connection in an infinite loop. Note that in the following example I use the most basic SSH command only. Replace this with your combination of Local and Remote tunnel command line switches.

#!/bin/bash
while [ true ]; do
    echo Opening SSH session
    ssh UserServer@Server
    echo SSH session disconnected
done

Name this file something like 'ssh_connect.sh'. Once saved it can be executed using ./ssh_connect.sh.

That is it, works like a charm.

Another article on setting up SSH using DSA can be found here. An introduction to BASH scripting is available here.

Opening networks using SSH Tunnels

Disclaimer - This post outlines how you can 'open up' firewalls to give you access where network administrators may not want you to go. Please realise that when applying these workarounds in a company you may be breaching corporate policy and  end up in serious trouble.

The problem: Sometimes you end up in an environment where you don't quite have the liberal network access that you enjoy, let's say, at home. Network ports for services you have come to rely on such as Remote Desktop, Skype or MSN Messenger, have been closed for whatever reason. Sometimes for good reasons such as security, sometimes for sad reasons such as public WiFi access points that only want to offer you limited access.

The solution: Enter SSH (Wikipedia definition), which allows you to set up secure encrypted connections between machines. Most people may think SSH is just a glorified secure replacement for good old Telnet, but it has much more tricks up its sleeve, most notably a way of tunneling multiple connections for different destination ports over a single port. Sorry if this sounds confusing, it is the best way I can describe it.


Light at the end of the tunnel?

Before going into more detail and installation instructions, a quick discussion of the kind of problems you can solve using SSH tunneling. First and foremost, if you have no access at all to a network then SSH is not going to help you. All you need for SSH to work is a single open port.

Example 1: Accessing your home PC via remote desktop. One of my friends recently started a new job for an insurance underwriter. Unfortunately he cannot access his home PC via Remote Desktop as the company blocks port 3389. He can solve this by installing SSHD (server application) on his home PC to listen on a port he can access, e.g. port 443 or any other outgoing port that is not blocked by the company firewall. He can then use SSH (client application) to setup a connection from his work PC to listen on a port, e.g. 13389 and connect it to the Remote Desktop port (3389) on his home PC.

Example 2: Accessing a company server from the public Internet. Another friend's retarded boss has not paid the ADSL bill, which results in him having to use a fallback network connection that does not allow any connections to the internal network from the public Internet. The solution to his problem is to setup SSHD (server application) on his home PC and configure his home firewall to allow public access on port 22 (SSH) and one other port that will be used to set up a tunnel. He can then use SSH (client application) to setup a tunnel from his home PC to his office PC.

Installation: SSH and all related utilities originate, like so many network utilities, in the Unix domain. Fortunately most of these extremely useful Unix / Linux utilities have been ported to Windows as part of the excellent Cygwin project. Installation instructions for Cygwin including full instructions for setting up the OpenSSH SSHD Server are available here.

Once everything has been installed you can either use a user friendly Windows Utility such as Putty to setup tunnels or use the SSH command line utility. My personal experience with Putty is that it is an excellent terminal client, but that it is a bit sensitive to network hiccups when tunneling connections. Since I switched to the SSH command line utility things have been more stable.

To set up the tunnels for the above mentioned Example 1 use these settings:

  • replace HOME_PC with the public IP-number of your home PC
  • replace USER with the name of a user with login privileges on your home PC, e.g. Administrator.
  • Install OpenSSH on your home pc as described previously.
  • On your office pc start BASH from the Cygwin group and type the following command to setup the tunnel:

       ssh -p 22 -C -L 13389:localhost:3389 USER@HOME_PC

This sets up an ssh connection on the standard port 22 to the SSHD running on the home pc. Once the connection has been established it creates port 13389 on the OFFICE_PC, which maps to the remote desktop port (3389) on the localhost SSHD is running on. The -C flag enables compression, which will give you a nice speed boost.

You can now connect to your home pc by opening the Remote Desktop Client on your office PC and typing localhost:13389. If you get a message that you cannot open a session to localhost then apply this workaround.

If port 22 is blocked then you can setup SSHD to listen on a different port. This setting is stored in C:\Program Files\Cygwin\etc\sshd_config (I have installed Cygwin in 'c:\progra~1').

That is all for now, I am not sure if this clarifies anything, but I hope it will be useful. This posting just scratches the surface of what you can do with SSH. Some of the other highlights are: using SSH as a SOCKS proxy, setting up multiple tunnels with one command, setting up reverse tunnels (-R switch) etc etc.

A similar article, focused on connecting to hosts outside of the corporate network using Linux can be found here. When using Cygwin 99% is the same as Linux anyway.

 

Safeguarding against Cross Site Scripting (XSS) vulnerabilities

Any company worth anything will perform a 'penetration test' on any kind of service or application that is internet facing, including websites.

An obvious way to approach this is to run any of the many publicly available hacking scripts against port 80 in anticipation of the webserver, being it Apache or an old dodgy IIS installation, not being fully patched.

However, there is another way to hack websites, which is by looking for flaws in the code that is being served up by the website. These kind of attacks usually involve looking for cross site scripting vulnerabilities. 

In short, cross site scripting attacks exploit badly written code that does not validate user input before writing it back to the browser. I could go into much more detail but this XSS Article explains it much better and also describes an actual exploit in a site that was so badly written I find it difficult to believe it is for real.

How to Break Web Software: Functional and Security Testing of Web Applications and Web Services

Fortunately the main environment I develop for, Microsoft's ASP.net, has built-in support for XSS attacks. Just place the following bit of code in a file named test.aspx, point your browser to it and enter <script>alert(document.cookie)</script> in the input box and click the button.

<HTML><BODY>
    <FORM METHOD="POST" ACTION="test.aspx">
      <INPUT TYPE="TEXT" NAME="TestVar">
      <INPUT TYPE="Submit">
    </FORM>
</BODY></HTML>

ASP.net pre-validates all code that a user may have manipulated and throws an HTTPRequestValidationException when it finds anything that is potentially harmful.

Pretty cool, even the worst developer, there are many, is now protected.

Some files can harm your computer. If the file information looks suspicious or you do not fully trust the source, do not open the file.

I am now officially a Sharepoint user and developer...wooohooo! One of the first things I ran into is that every time I open a document from SharePoint I get the following message.
Some files can harm your computer. If the file information looks suspicious or you do not fully trust the source, do not open the file.
There are a number of ways to get rid of this message. You can either download a registry script from SharePoint University that disables this message for the most common files types or manually change the settings for each file using the following steps:
  1. Go to Windows explorer under "Tools" --> "Folder options...",
  2. Select the "File types" option.
  3. Highlight the word file type (.doc) and click on the "advanced" button.
  4. The value corresponds to the first check box "Confirm open after download". If you remove this option, the files are opened without any prompt.

Using host headers and Visual Studio Web projects

If you are a .net developer using Visual Studio then you probably know of the pain inflicted when taking over someone else's project and trying to get it running on your own system with full web and SourceSafe integration.
 
The only way to make it worse is to add multiple web sites to your machine and differentiate between them using 'host headers'. The problem is that VS.NET (or FrontPage server extensions or whatever process messes up this whole web integration) iterates through the list of available sites using WMI with complete disregard of the host headers. The last site it finds for the specified port, usually 80, is used, which is rarely the correct site.
 
To make a long story short, the solution of getting web integration working on the correct site is as follows:
  1. Temporarily put the site on a different port, e.g. 81.
  2. Open the solution and when VS asks you what web site to use, enter the site name AND the port number (e.g. http://localhost:81/
  3. With some luck - It is impossible to offer guarantees with this fragile system - VS will ope