Like many people, I rely heavily on ssh to maintain and configure computers remotely. However, doing so usually requires making an outbound ssh connection from the computer you're working on, which isn't always convenient. For example, if you're using someone else's computer, the chances are they're using Windows and don't have an ssh client program installed. PuTTY goes a long way to mitigating this problem, but it can't help you if the place you're connecting from has a firewall that blocks outgoing ssh traffic, or if your ssh server is configured to require RSA key authentication.
This is where Ajaxterm and Anyterm come in useful. Essentially, they are apache modules that provide a webpage containing an ssh terminal. So long as you have access to the internet, you can then go to this webpage in a browser and use it to log in to your system using ssh.
Since Ajaxterm is rather simpler than Anyterm to set up, I decided to focus on using that. However, there were a few complications along the way, which is what this article is about. In theory, setting up Ajaxterm on Ubuntu is as simple as typing
sudo apt-get install ajaxterm, and then connecting to the terminal at http://example.com:8022/ (substitute example.com for your own domain name; 8022 is the default port that Ajaxterm runs on). The problem with this is that the connection is unencrypted, i.e. your ssh login details could be intercepted as they cross the internet, which defeats the purpose of using ssh in the first place. It also uses port 8022, so you'd need to enable access to this port in your firewall.
Configuring Apache as a proxy
The solution to these problems is to use apache's proxying capabilities to make Ajaxterm run over an encrypted https connection. If you don't already have an https site running on the server, there is a basic example configuration in the Ubuntu Community documentation. The Ajaxterm page will then be accessible on https://example.com/. You'll need to make sure proxying is enabled by running
sudo a2enmod proxy proxy_http. Don't forget to restart Apache once you have made your configuration changes and enabled the extra modules.
However, since it's only possible to run one secure site per IP address, if you already have a secure site running on your server, you'll need to do something slightly more complicated. The Ajaxterm documentation provides an example in this case: in the VirtualHost block for your secure site, just add the following section:
Allow from all
ProxyPass /ajaxterm/ http://localhost:8022/
ProxyPassReverse /ajaxterm/ http://localhost:8022/
The Ajaxterm page will then be accessible on https://example.com/ajaxterm/, while the usual site at https://example.com/ will be unaffected.
So far, so good. Unfortunately, there is a bug in the default version (0.10-2) of Ajaxterm that ships with Ubuntu 8.10. The Ajaxterm page loads fine, but gives a 502 connection error, meaning that it's not possible to log in. This is apparently fixed in version 0.10-3 and later, which ship with Ubuntu 9.04+, but that doesn't help much if you're on Ubuntu 8.10 and don't want to upgrade your server at the moment. Whether it affects Ajaxterm version 0.10-1, which is the default in Ubuntu 8.04, I'm not sure.
Fortunately, it's pretty straightforward to apply a quick fix to the package and get Ajaxterm working. Note that this is something of a rough-and-ready hack, not the correct procedure for producing a standard Ubuntu/Debian package! It's adapted from an article by Menzonius. Depending on how paranoid you are, you may want to build the modified package on a client computer, rather than on the server itself, because the build process requires installing a compiler, which arguably creates an extra security risk on the server. However, things may get complicated if the client computer is not running the same release and architecture of Ubuntu as the target server.
First of all, you'll need to install some build tools, using the command
sudo apt-get install build-essential fakeroot. There may be others packages required, such as dpatch; I'm afraid you'll need to figure out which packages you're missing from the output of the build process. Next it's time to get the source for the Ubuntu Ajaxterm package. I advise doing this in a subdirectory you've created for the purpose, i.e.
mkdir ajaxterm && cd ajaxterm. To get the source, use the command
apt-get source ajaxterm. This will download the necessary files to build the package. You need to enter the directory called ajaxterm-0.10 and modify the file called
ajaxterm.py. You need to find the line
fcntl.ioctl(fd, struct.unpack('i',struct.pack('I',termios.TIOCSWINSZ)), struct.pack("HHHH",h,w,0,0))
and change it to (change taken from the Debian bug report)
fcntl.ioctl(fd, termios.TIOCSWINSZ, struct.pack("HHHH",h,w,0,0))
You may also want to modify
ajaxterm.html while you're at it: I find the default Ajaxterm terminal size a little small, so I changed the line
to (change taken from a comment about Ajaxterm)
You'll need to modify the package change log in debian/changelog. I changed the version number from (0.10-2) to (0.10-2+ioerrorfix) and made a note of the code modifications. It's a good idea to change the version number by adding "+text" rather than increasing the number, because this guarantees that when you do upgrade your server, the package manager will know to upgrade the package to the standard version, rather than staying with your custom build.
Once this is done, you're ready to rebuild the package. To do this, you'll need a couple of extra dependencies:
sudo apt-get install cdbs python-dev. To build the package, make sure you're in the
ajaxterm-0.10 directory and type
dpkg-buildpackage -rfakeroot. Once again, you may need to install more dependencies if the build process tells you they are missing. Once the build process has completed, go up one directory and you will find the .deb archive, for example the package I built is called
ajaxterm_0.10-2+ioerrorfix_all.deb. Install this package using the command
sudo dpkg -i ajaxterm_0.10-2+ioerrorfix_all.deb. If all has gone to plan, Ajaxterm should restart, and should now be working correctly!
That's the end of the process, you should now have a working Ajaxterm installation on your server. Note that you may want to add password protection to the Ajaxterm page, to reduce the risk of bruteforce ssh login attempts. Rather than covering that here, I suggest you look at the example given in the Ajaxterm Ubuntu Community documentation.
Just a couple of notes to expand on what's been said above. I've been doing some work using Debian Lenny lately and came across some relevant information.
First, Debian Lenny uses the same version of Ajaxterm as Ubuntu 8.10. The bug is present on PowerPC but not on x86, even though the code line I mentioned has not been patched in Lenny, which leads me to suspect that this is an architecture specific bug. There is a comment in the code on the line above the bug, which mentions an x86_64 workaround - my guess is that they did not test the code on PowerPC or other less common architectures, so the problem occurs on some platforms and not on others. That being the case there should be no need to rebuild the package if you're using a common architecture such as x86, unless of course you want to resize the terminal display etc.
Second, to build Ajaxterm on Debian you will need the packages patchutils and dpkg-dev. Both of these packages are present on my Ubuntu system too, so I think they are also required there. Adding these two to the list of packages above should give a complete list of requirements.
Third, there is another bug in Ajaxterm that prevents the ssh console from displaying when viewed in Firefox 3.6. Thankfully this one is easy to fix: just replace
sarissa.js with an updated version when rebuilding the package. I took a fixed version of
sarissa.js from the Debian Sid version of Ajaxterm, which you can find at http://packages.debian.org/source/sid/ajaxterm.