BOINC, power cuts and an APC UPS

I’ve experienced a number of power cuts here today due to repairs being carried out on the local grid after the recent freezing weather. Not a problem, I thought, as I’ve got uninterruptible power supplies on all my computers. As long as the electricity isn’t off for too long, it’ll be fine.

And indeed, “Server Corner” in the room upstairs was fine. My LAN switch, the HP Microserver, Raspberry Pis and their external HDs carried on running on their UPS throughout the whole power cut.

The trouble was that my internet router and the house phone share their UPS with my main PC – which happened to be keeping the room warm while I was out walking the doy by running BOINC full-chat on its four CPU cores and on the GPU too. It’s power consumption is pretty close to the UPS’s rated capacity when doing that, so when the power failed, my APC Back-UPS 650 CS was hit with a load close to its recommended load capacity (>90%).

This shouldn’t have been a problem but for three things that have happened since we last had a long power cut. First, I’ve started running BOINC on my main PC again. Second, I recently removed the control cable from the back its APC UPS in order to test a “for spares or repair, no cables and sorry about the sticky mess” APC UPS I scored on eBay (it was fine – it just needed a new battery… and disinfecting). Third, I forgot I’d moved the UPS control cable over to the 99p eBay UPS and had then baulked at buying another control cable when I discovered that they cost nearly as much as a new battery. The cable in question being one of APC’s proprietary USB-to-not-quite-an-ethernet-jack ones.

The result of all this was that my main PC never received a signal from its UPS that the power was out, carried on running BOINC at full-chat and fully depleted the UPS battery in around two minutes. Having reached a critical battery level, UPS then shut itself down, depriving the internet router and house phone of power.

So much for sustaining essential services during a power cut!

Anyway, I’ve now returned the UPS data cable to my main computer and configured apcupsd (the Linux APC UPS daemon) to automatically shut down boinc-client when mains power is lost and restart it when power is restored.

To do this, three files must be edited:
/etc/apcupsd/apcupsd.conf
/etc/apcupsd/onbattery
/etc/apcupsd/offbattery

but before that, start boinc-client and then from the command line, run the command sudo apcaccess status to display your UPS status data. We’re interested in the TIMELEFT value. Note it down.

NB: I’m assuming that you already have apcupsd installed and configured for your UPS and have the data cable connected.

Now open /etc/apcupsd/apcupsd.conf in your favourite text editor. Look for the variables ONBATTERYDELAY, MINUTES, BATTERYLEVEL and TIMEOUT.

ONBATTERYDELAY should be set to only a few seconds – we want boinc-client running on batteries for as short a time as possible.

MINUTES must be set to less than the TIMELEFT value obtained from the output of the apcaccess status command while boinc-client is running· Otherwise a complete system shutdown will be initiated before boinc-client can be stopped.

BATTERYLEVEL should be set to the battery percentage you do want to initiate system shutdown at. I’ve set mine to 70 in order to leave a decent capacity for running the internet router and house phone.

TIMEOUT is set to zero.

Now save the file and restart the apcupsd daemon.

The final step is to add the appropriate commands for stopping and starting boinc-client to /etc/apcupsd/onbattery and /etc/apcupsd/offbattery. In each file the command should be added after the #!/bin/bash line but before the default emailing script that’s already in the files.

To /etc/apcupsd/onbattery add the line /sbin/service boinc-client stop (or it’s equivalent for your system – first experiment with starting and stopping boinc-client from the command line if you’re not sure) and to /etc/apcupsd/offbattery add the line /sbin/service boinc-client restart. Save and close the files. You should now be set up for automatically turning the CPU and GPU intensive boinc-client off whenever the power goes out.

If you want to test this, load up your sysstem monitor so you can see the graph of CPU utilisation. It should be pretty high with boinc-client running. Now cut the power at the wall socket. Within seconds, the CPU utilistation should drop as apcupsd reads the onbattery script and kills boinc-client.

To illustrate the benefits this has, here are the numbers for my system. With boinc-client running, apcaccess status shows

LOADPCT  :  88.0 Percent Load Capacity
...
TIMELEFT :   4.5 Minutes

and the power meter at the wall socket that the UPS is plugged into shows a UPS load of 3000W/325VA. Whereas without boinc-client I get

LOADPCT  :  47.0 Percent Load Capacity
...
TIMELEFT :   14 Minutes

and the power meter at the wall socket that the UPS is plugged into shows a UPS load of 140W/170VA.

This is quite a useful improvement in UPS runtime and just goes to show both how much boinc-client can stress a powerful machine when it’s running and how efficiently Intel processors and nVidia GPUs can throttle back when there’s no load on them.

Grid Computing

After a long hiatus where I’m ashamed to admit that I completely forgot about it – given that I’ve had a server running 24/7 with a very low workload for the last year – I’m back crunching numbers for the World Community Grid with both the server and also my desktop computer.

I installed BOINC on both my computers without any trouble. My server (HP Microserver) runs Debian and my desktop (Intel i2500K based system) runs OpenSuSE. Both had BOINC in their repositories and after very minimal configuration, both were up and running the World Community Grid projects.

I’ve also harnessed the power of my GPU in the desktop (an nVidia GTX 560 Ti) to run a different project – the GPU Grid – as the World Community Grid doesn’t have any projects that harness the GPU active at the moment. At least, not for Linux. Note: SuSE seems to require that the user boinc join the group video before it can detect any GPUs. This prevents the message “no usable GPUs found” from appearing in the BOINC logfile.

Click the links and donate your spare processing power today!

Providing Secure Access to the Transmission Web Interface

Recently I needed to set up a dedicated BitTorrent client to manage the download of a multitude of enormous torrents. Way beyond the “I’ll just leave the desktop on overnight to finish these downloads” stage but not wanting to infest my proper server with endless gigabytes of torrent junk, I looked to my Raspberry Pi for a solution.

The hardware side of the solution comprised the Raspberry Pi and an external USB hard drive, while the software solution came in the form of the Lighttpd web server and the Transmission BitTorrent client/daemon. Both Lighttpd and Transmission are available in the default Raspbian repositories.

Now, you don’t actually need Lighttpd at all in order to download torrents with the Transmission daemon. But you do need it if you require secure remote access to Transmission’s web interface for torrent management. Transmission’s web interface only supports plain http, so I’ve used Lighttpd to provide both user authentication and secure access to Transmission.

After installing Lighttpd and Transmission, adding rules to iptables for the BitTorrent ports and mounting an external hard drive to store all those precious videos of kittens, our attention turns to configuring Lighttpd.

But just before we get there, there’s a small change to make to Transmission’s own settings file. Stop the Transmission daemon (essential, as otherwise it will overwrite any changes we make to the configuration file) and open the Transmission settings file with the following commands:

$ sudo /etc/init.d/transmission-daemon stop
$ sudo nano /etc/transmission-daemon/settings.json

Now set the value of “rpc-authentication-required” to false as we will be using Lighttpd to authenticate users instead. Make any other changes to the configuration file that you want (the options are all explained here) before saving and closing the file. Now start transmission again (see the command above, but replace ‘stop’ with ‘start).

The first step of configuring Lightppd is to install the apache2-utils package. Installing a package associated with a different web server that we’re not using might seem bizarre, but it contains the useful htpasswd and htdigest tools which can be used to generate authentication files for Lighttpd. In this instance, we’re going to use htdigest to create a file containing usernames and passwords that can be used in conjunction with Lightppd to enforce password protected access to Transmission’s web interface using the following commands.

# sudo aptitude install apache2-utils
$ cd /etc/lighttpd/
$ sudo htdigest digest.txt -c 'TransmissionWebInterface' username_one
$ cat digest.txt

Replace ‘username_one’ with the name of the first user you want to grant access to Transmission’s web interface. If you want to grant more than one user access, run the htdigest command again  but without ‘-c’. Running htdigest with ‘-c’ destroys any existing digest.txt file before creating a new one, whereas running htdigest without ‘-c’ appends to the existing file instead. The cat command simply confirms what has been added to the digest.txt file – a list of users (and their password hashes) who will be allowed to access Transmission’s web interface. The text ‘TransmissionWebInterface’ in the htdigest command is known as the realm that the credentials are valid for. I’ve used ‘TransmissionWebInterface’ rather than simply ‘Transmission’ to avoid possible confusion as ‘Transmission’ is the text in the (otherwise identical) credentials prompt that Transmission’s own RPC authentication procedure presents if you’ve forgotten to turn it off.

Now, before leaving the /etc/lighttpd directory, we must create a security certificate for Lighttpd in order to provide secure https access to Transmission’s web interface. The openssl command is used for this. It requires responses to a number of questions. Look here if you need help answering them.

# sudo openssl req -new -x509 -keyout certificate.pem -out certificate.pem -days 365 -nodes
$ sudo chown www-data:www-data certificate.pem
$ sudo chmod 0600 certificate.pem

Now it is time to delve into the lighttpd.conf file itself. Edit it with the nano text editor by issuing the following command.

$ sudo nano /etc/lighttpd/lighttpd.conf

Before I show you the modifications to the configuration file, I will summarise what I want to accomplish.

  1. We want to be able to easily access the Transmission daemon running on our Raspberry Pi from anywhere in the world by typing a simple address like www.ourdomain.com/transmission
  2. We want the connection to be secure, so we automatically redirect any request for www.ourdomain.com/transmission to https://www.ourdomain.com/transmission
  3. We want to restrict access to a limited set of users, so we request a username and password from any visitor to https://www.ourdomain.com/transmission

This can all be accomplished with the following lighttpd.conf file

server.modules = (
"mod_access",
"mod_alias",
"mod_auth",
"mod_compress",
"mod_proxy",
"mod_redirect",
#"mod_rewrite",
)

server.document-root = "/var/www"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid"
server.username = "www-data"
server.groupname = "www-data"
server.port = 80

index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )

# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"

# Auth directives
auth.backend = "htdigest"
auth.backend.htdigest.userfile = "/etc/lighttpd/digest.txt"
auth.debug = 1

# Force https for certain URLs
$SERVER["socket"] == ":80" {
$HTTP["url"] =~ "^/transmission" {
url.redirect = ( "^/(.*)" => "https://www.ourdomain.com:443/transmission/web/" )
}
server.document-root = "/var/www"
}

# Supply SSL certrificate for the https connection
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/lighttpd/certificate.pem"
# Restrict access to only those users in the digest.txt file
$HTTP["url"] =~ "^/transmission*" {
auth.require = ( "" =>
(
"method" => "digest",
"realm" => "TransmissionWebInterface",
"require" => "valid-user"
) )
# Use proxy to redirect authenticated users to Transmission's own web interface
proxy.debug = 1
proxy.server = ( "" =>
( (
"host" => "127.0.0.1",
"port" => 9091
) )
)
}
}

The lighttpd.conf file can be downloaded here (with the bonus of better formatting than above!). Don’t just overwrite your existing lighttpd.conf file with this one, as you’ll lose any changes you’ve already made to it. Also you’ll need to alter www.ourdomain.com to whatever your domain is and also pay attention to whether or not the names or locations of certificate.pem and digest.txt are correct if you deviated from the instructions for creating them earlier.

The modified lighttpd.conf configuration can be tested with the command below. It should return ‘Syntax OK’, in which case you can restart Lighttpd to apply the changes to the webserver. If not, then it should at least provide a line number for where it found a problem. If it does give an error, double check that all the required server modules have been added at the top of the file before doing anything else.

$ lighttpd -t -f /etc/lighttpd/lighttpd.conf
Syntax OK
$ sudo /etc/init.d/lighttpd restart

Now that Lighttpd has accepted the new configuration file, you can test it by pointing your browser at www.ourdomain.com/transmission . The first sign that everything’s working properly should be a warning message saying that the site’s security certificate is not to be trusted. This is fine – the browser is alerting the user as it doesn’t recognise the certificate as being from a trusted certificate provider. Indeed, it shouldn’t for it’s the home-made certificate we generated earlier using the openssl command. Depending on your browser, ‘Proceed Anyway’ or ‘Add security exception’ to convince your browser that the certificate is to be trusted.

Now a login prompt should appear. Along with the boxes for entering a username and password, the text ‘TransmissionWebInterface’ should appear. If it reads only ‘Transmission’, go back and read about disabling Transmission’s RPC authorisation. Enter the username and password you created for the digest.txt file and you should be rewarded with the Transmission web interface displayed in your browser.

Recursively calculate checksums for all files in a directory tree

Recently, I had reason to doubt the integrity of the weekly backup that I make of my home directory. To check the integrity of the backup I thought it would be a simple matter of running

md5sum * > homeChecksums.md5

on my home directory, followed by

md5sum -c homeChecksums.md5

on the backup directory, but no such luck. md5sum doesn’t automatically operate recursively on a directory and nor is there a -R option to force it do so, like some other Linux programs have.

Now, there’s probably some bash scripting wizardry that could accomplish what I want in five lines or less, but I absolutely loathe bash scripting and so decided to write a simple program in C# to accomplish what I wanted instead.

What started out as a simple program has grown somewhat and should now be fairly robust and user-friendly. It sanity-checks all command line arguments, should catch all exceptions possible during normal operation and presents the user with a clear summary of what it has done/found when it finishes executing. The only thing it can’t handle at present is being run on special directories like /dev, /proc, or /sys.

Program Information

The program can operate in three different modes:

  1. Given a source directory, it generates checksums for all files within that directory tree and writes them to a file.
  2. Given both a source and a destination directory, it compares checksums for all files within the source tree with those in the destination tree. Optionally it will also write the checksums for all files within the source directory to a file.
  3. Given a destination directory, it checks the checksums for all files within that directory against a list provided from a file.

Depending on the mode, the program present the user with a summary of what it has found. This summary may include

  • the number of files and directories processed
  • Files that have changed between the source and destination folders
  • Files present in either the source or destination directory but absent in the other

When the program is set to output checksums to a file, I have ensured that the file created can be read by md5sum when that utility is used with the -c option.

I have attempted to add a degree of cross-platform compatibility with the inclusion of an option/fallback to use .Net’s built-in checksum generating functions instead of the Linux md5sum utility. However, I haven’t yet had the opportunity to thoroughly test its operation in Windows but from what I’ve seen so far, there are some problems.

The program also has the advantage of being able to run multiple checksum generating processes simultaneously, giving a potentially reduced execution time on multi-core computers. On a quad core Intel 2500K, the benefits of running multiple checksum generating processes simultaneously on a 32 GB folder containing nearly 53.000 files are illustrated by the following chart. Also of note is the relative performance of md5sum and .Net’s own checksum generation functions.

Chart to illustrate the advantage of running multiple simultaneous checksum generating processes

Usage Examples

Mode 1

mono /path/to/RecursiveChecksummer.exe -s /path/to/HomeDir -f /path/to/fileToWriteChecksumsOfHomeDirTo.txt -c 2

Mode 2

mono /path/to/RecursiveChecksummer.exe -s /path/to/HomeDir -d /path/to/backupOfHomeDir -n

Mode 3

mono /path/to/RecursiveChecksummer.exe -d /path/to/backupOfHome -f /path/to/fileContainingChecksumsOfHomeDir -c 4

Linux users who d not want to prefix every instance of the command with “mono” should read the “Registering .exe as non-native binaries” section of the mono documentation.

Download the Code

The code for the program is available on GitHub. You’ll need either Monodevelop or Visual C# Express to compile it and version 4.0 or higher of the Mono/.Net framework.