The lead developer at Mosaic, Brighton with a passion for web application development and motorcycles.
External Link: Why won't ssh-agent save my unencrypted key for later use?
I recently was annoyed by always having to enter my private keys passphrase every time I wanted to do a git push to or pull from a public git repository. Turns out that if you are logged into a Gnome session on an Ubuntu machine it will automatically add you key to ssh-agent, but if you are logged into a bash session (as I was) then it won’t.
So you can either manually do the ssh-add yourself or following the instructions in the answer to my question you can setup an automatic way of facilitating this.
One problem I discovered is that if you have git displaying the current branch information in your bash prompt like me then when you start a session it will ask you for your passphrase before rendering your bash prompt.
I am thinking that to work around this I could change the git function in the .bash_profile file to look at the arguments passed to it and if it is a remote operation such as a pull, push or clone then trigger the ssh-add otherwise it can safely skip it.
Any other ideas or patches?
Installing Gearman is pretty easy as there are packages for it in Ubuntu:
sudo apt-get install gearman libgearman-dev
The development headers (libgearman-dev) are only required if you need to compile a library for your programming language such as a PHP extension. To install the PHP module you would run:
sudo pecl install channel://pecl.php.net/gearman-0.7.0
If you have trouble with the above step then it is probably because you are running an older version of Ubuntu. In this case take a look at my previous post Getting gearman to install on Ubuntu.
Moving onto mod_gearman_status, which is an Apache module to show the status of Jobs and their associated workers. It looks like the following:

Firstly lets ensure that the system has the build-essentials package installed:
sudo apt-get install build-essentials
We now need to install the Apache2 development headers, which assuming you installed the standard Ubuntu Apache2 package will be the prefork edition. If you don’t understand this then don’t worry you can just continue below.
sudo apt-get install apache2-prefork-dev
Now download modules C file and run the following command to build it and install it as an Apache module:
sudo apxs2 -c -i mod_gearman_status.c
Apache now needs to be told how to load the module and what configuration settings to use. In /etc/apache2/mods-available you need to create two files.
/etc/apache2/mods-available/gearman_status.load:
LoadModule gearman_status_module /usr/lib/apache2/modules/mod_gearman_status.so
/etc/apache2/mods-available/gearman_status.conf:
<IfModule mod_gearman_status.c> <Location /gearman-status> SetHandler gearman_status </Location> </IfModule>
Enable the module with the following command:
sudo a2enmod gearman_status
Restart Apache to load the module:
sudo service apache2 restart
Now in your browser you can visit http://example.org/gearman-status where example.org is your servers address.
When working in a team it is very useful to have a central web server with multiple environments and a configuration as close to the live server as possible. This can be a bit of a nightmare though if you need to setup a new VirtualHost container in Apache every time a new project is brought on or when a developer wants to work on a version of the site in their own environment.
The good news is that this can all be handled automatically and new sites can be setup by simply adding a new directory to the file system. There are at least two ways of getting this going; the first of which is the mod_vhost_alias module for Apache and the second is enabled via mod_rewrite. I prefer to use the second method as it is more flexible and it allows you tap into the ability of mod_rewrite to introduce environment variables and redirect requests (this is particularly useful for robots.txt - you’ll see).
The Apache2 Manual does have a very good page dedicated to overcoming this problem, but I will be sharing with you all the settings I am using which you will need to stop Google et. al. from crawling your sites served from the staging environment for example.
External Link: php_ssdeep Fuzzy Hashing PHP Extension
Updated 16/9: php_ssdeep is now in PECL so I have updated this post to reflect that.
On a recent project I needed a fast way to compare documents for likeness and return a percentage match. With much research and one unanswered Stackoverflow post later I came across Jesse Kornblum’s ssdeep utility intended for computer forensics such as looking for signatures in files when hunting rootkits etc. All the technical details of fuzzy hashing are described in his 2006 journal article Identifying almost identical files using context triggered piecewise hashing.
I was using a wrapper around the ssdeep binary written in pure PHP, but I recently decided to write my first PHP extension by tying into the fuzzy hashing API ssdeep provides. The result is now a PECL extension or module and the BSD licensed source code is hosted on PHP.net’s SVN.
There are full instructions provided in the PHP manual and the php_ssdeep site to install the exension and use the provided functions. If you end up using this extension or its code I would be very interested to find out more about your project.
A project I am working on at the moment requires time delayed job queues and having found nothing yet that can manage it properly so I decided to wrap up `at` into a PHP class. This gives you simple methods to add, list and remove jobs from the `at` queue using object oriented code.
The code is very simple and I have documented it reasonably well so along with the examples you should get on your way quickly. The class can, of course, be used from the command line as well so if you want to write batch scripts in PHP to handle adding a collection of predefined `at` jobs for example - it can make it easier.
I feel the important features of `at` have been added into the code, but if you want to wrap any of the other functions then please do fork my code and make a patch or post a pull request. For more information on what `at` can do please either run `man at` in your console or visit the Edinburgh University’s man at page.
You can get the code from my repository on GitHub: PHP-at-Job-Queue-Wrapper.
If you do have any trouble getting the `at` daemon (atd) going then my previous post may help you debug it - please see If you are having problems getting Ubuntu atd running for more on that.
External Link: Batch remove extensions in Ubuntu
Sometimes you will want to batch remove extensions from a load of files:
for i in $(ls *.png); do mv $i ${i%.png}; done
If you want to remove extensions from files with a .txt extension then you would replace the two instances of .png in the script above with .txt.
You can take the extension off of all files using the following:
for i in $(ls *.*); do mv $i ${i%.*}; done
I also extended it by using it for a batch change of extensions rather than just removing the extension:
for i in $(ls *.html); do mv $i ${i%.html}.htm; done
Note the extra .htm after the curly braces in the above command.
If you just cannot get atd to start running check the permissions on your /var/spool/cron/atjobs and /var/spool/cron/atspool directories. The should be `chmod 770` and then `chmod +t`. Also they should be owned by `daemon:daemon`.
I was getting this error when attempting to set new at jobs:
Can’t open /var/run/atd.pid to signal atd. No atd running?
If I tried to start the daemon through the service management I was getting:
sudo service atd start
start: Job is already running: atd
But running `ps -elf | grep ‘atd’` yielded no appropriate results.
When trying to start the atd daemon manually on the command line I was getting:
simon@forge:~$ sudo atd -d
Cannot change to /var/spool/cron/atjobs: Permission denied
Which finally gave me the clue!

Sun VirtualBox Logo
Often Linux just does it better! Often I find myself developing a Windows machine without access to a Linux development server, but I still need to access to some of the Linux binaries and features such as cron jobs, the at command and binaries such as imagemagick, pdftotext, etc. Some things can be emulated with ported binaries or through Cygwin, but I feel a lot more comfortable developing on a platform that is representative of the live server the web site will run on.
I have not removed XAMPP as it is very useful for developing small scripts or sites without the overhead of running a virtual machine. Therein lies the problem with this solution – it is virtual machine based and that will mean your local development machine will suffer when the virtual machine steals computing time from the CPU or more memory. So whilst I can use XAMPP on my netbook I am not so sure a VM will run smoothly.
The idea behind this step is to minimise the time it takes to setup a new host on the server. Basically all you have to do is create a new directory an away you go. (Don’t forget it will still need to appear in your hosts file).
VirtualDocumentRoot sets the directory that the VHosts public directory is contained in. This will basically convert http://subdomain.localhost/ to /mnt/htdocs/subdomain and pull the relevant files through.
A side note when using this method that you should be aware of. This will affect your rewrite rules if they are placed into a .htaccess file. To avoid any problems always declare the RewriteBase rule in your .htaccess.
For example:
Nathan brought a glaring omission from my post to the fore – thanks! Currently you maybe having permissions issues with your shared folders because they might be being mounted as root:root. To get them to load with a specified user and group you will need to edit your /etc/fstab file again and change ‘defaults‘ to be ‘uid=username,gid=groupname‘ – an example would be ‘uid=simon,gid=www-data‘.
A full line example would be from:htdocs /mnt/htdocs vboxsf defaults 0 0
tohtdocs /mnt/htdocs vboxsf uid=simon,gid=www-data 0 0

Apache HTTP Server
I really like the way the Apache modules and virtualhosts are seperated out on Debian into folders containing those, which are available and those which are enabled. There is one small problem with this – it is more work than before! Luckily there are some helper scripts.
The Apache configuration files are layed out in the following way:
mods-available – the actual text files containing the modules configuration
sites-available – the vhosts text file for the site
mods-enabled – a symlink to the actual text file in mods-available
sites-enabled – a symlink to the actual text file in sites-available
Anything listed in the enabled directories will be loaded when Apache is therefore enabling the respective site or module. Manually symlinking these up can be a right pain so I use the following scripts to assist me:
“a2ensite sitename” – will create the symlink for you
“a2dissite sitename” – will remove the symlink for you
“a2enmod modulename” – will create the symlink for you
“a2dismod modulename” – will remove the symlink for you
When the symlink is place the module or site will be loaded and vice versa.
Do not forget that you still need to reload the configurations into Apache by running “/etc/init.d/apache2 reload”.
Certificates are a useful way of restricting access to your SSH server because a user must have three things to log onto the server:
Normally they would only need to have a password and username, which can be guess at or (potentially) brute forced. Forcing the user to supply a certificate on log on means that they must also have a tangible source of identification (without the key file they cannot log in!).
Log onto the server and run ssh-keygen and you will get asked a few questions as follows (enter a passphrase):
user@host$ sudo ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
95:60:c2:31:2e:94:cf:66:b6:fa:8b:b8:45:6c:dd:22 user@server
The key’s randomart image is:
+–[ RSA 2048]—-+
| .o+.o |
| ….+ . . |
| .o. o |
| . o*. . |
| E+o.S |
| o … |
| .. |
| o.. |
| o…o. |
+—————–+
This will generate two files:
in your home directory (if you chose the defaults). They are your private and public keys respectively. The public key is the one that goes on your server and the private key is the one you use when logging into the server.
Now on the server run
user@server:~$ cat id_rsa.pub » ~/.ssh/authorized_keys
user@server:~$ rm id_rsa
which adds the public key to the list of authorized keys for this user.
To edit the config run
user@server:~$ sudo vim /etc/ssh/sshd_config
Ensure that you have the following lines uncommented and set correctly in your configuration file:
RSAAuthentication yes
PubkeyAuthentication yes
If you wish to lock non-certified logins from the server then also ensure you activate the following settings:
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
Now reload the SSH configuration to get the new settings going:
user@server:~$ sudo /etc/init.d/ssh reload
PuTTY has its own private key format and the private key you created earlier now needs to be converted, which is a very simple process. Firstly you need to download the key from the server and save it to your computer.
Now the new key we just saved is compatible with PuTTY we can start a new PuTTY session as usual, but don’t forget to tell PuTTY where the key file is located by looking in the Category tree menu and clicking on Connection -> SSH -> Auth. You can now click the “Browse” button and point PuTTY to the key file you just created.
Click open and a new session will load: