Delving the depths of computing,
hoping not to get eaten by a wumpus

By Timm Murray

Running Apache files on a Raspberry Pi ramdisk with mod_perl

2014-11-06


When used as a web app server, the Raspberry Pi often hosts a small number of static files that rarely change. Although the Raspberry Pi Model B(+) only has 512 MB of RAM, using 10MB for a ramdisk is usually more than enough.

Files will be copied by Apache at startup. If you make changes to these files, you’ll either need to copy them manually, or restart Apache.

Start by making the directory mount point. I used /var/www-ramdisk:

# mkdir /var/www-ramdisk

Modern linux systems mount ramdisks through ‘tmpfs’, so add an entry to /etc/fstab:

tmpfs /var/www-ramdisk tmpfs nodev,nosuid,uid=[UID],gid=[GID],size=10M 0 0

Replace [UID] and [GID] with the respective uid and gid that Apache runs under for your system. On the default Raspbian install, this will be the www-data user and group.

Run mount -a and the ramdisk should appear (use df to confirm).

Next comes the Apache config. Somewhere in the config, you’ll need a PerlConfigRequire:

PerlPostConfigRequire /etc/apache2/mod_perl_post_config.pl

Create /etc/apache2/mod_perl_post_config.pl, an write in:

# Copy files to the RAM disk
(system( 'cp -R /var/www/* /var/www-ramdisk' ) == 0)
        or die "Could not copy files to ramdisk: $!\n";
1;

This shells out during startup to recursively copy everything from the default Apache docroot to the ramdisk.

Now grep through your Apache config, and change all paths to /var/www and replace it with /var/www-ramdisk. Lastly, restart Apache with:

# /etc/init.d/apache2 restart

Check the files with ls -l /var/www-ramdisk and you should see everything that’s in /var/www.

Edit: Forgot to credit domoticz.com, where I got much of the fstab setup.


"use strict" makes us forget that Perl used to be worse

2014-11-04


What does “int a, b, c” do in Perl? Lots of people want to say that this won’t even compile. There’s even a comment on the StackOverflow post accusing OP of posting uncompilable code.

It is compilable. Without use strict, perl will accept damn near anything. What’s interesting here is that the immediate response by many people is that it’s invalid code. That was my initial reaction, and it took me a second to remind myself.

It’s interesting that we’re all so conditioned to use strict that we forgot how Perl looks without it. This is probably a good thing.


Considering the Security of SSL Client Certs Versus HTTP Basic Auth

2014-10-10


People often overlook this option, but SSL allows clients to have their own certificates for authentication. It’s similar to SSH key authentication, except because it’s SSL, it’s mind-numbingly complicated to setup. For optimal results, you’ll want to have one client cert for each desktop, laptop, tablet, etc. that you want to connect to the site.

Tablets and smartphones are particularly tricky, because they can be stolen so easily. If you have a client cert loaded, my Galaxy S5 forces you to use at least a pin code for unlocking the phone. Sensible, but also more awkward to use.

Given that I was working on an HTTPS site, I wondered how the security of a long, random password (using basic HTTP auth) would be compared to SSL.

Basic auth is transfered in plaintext. The HTTP protocol does support digest encryption for plaintext connections, but that’s unnecessary for SSL.

On the server side, basic auth passwords can be stored in encrypted form. Apache’s default htpasswd uses either MD5 or crypt(), neither of which is adequate.

What about the security of the authentication handshake? Consider that SSL initiates connections with public key crypto, but for performance reasons, it uses that connection to transmit a newly-created, random block cipher key. The server and client negotiate for the specific block cipher, but it’s probably going to be AES128, or maybe something else of around 128 bits.

Therefore, transmitting a password with 128 bits of entropy will be just as secure as AES128. That is, if the password were stronger than this, then an attacker would have an easier time attacking the block cipher rather than the password.

So what do you need to get to 128 bits of password entropy? It’s a function of how many characters are allowed in the password, and its total length. Since we’re talking about characters that can be typed on a keyboard (whichever kind is standard in your country–US for me), we aren’t using the complete space of an 8-bit byte. So we need to get out some math:

H = L * (log(N) / log(2))

Where H is the bits of entropy, L is the password length, and N is the number of characters that you are allowing in your password.

Here’s 90 characters that can be typed out on a US-standard keyboard:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789~!@#$%^&*-_+=[]:;"|<>,.?/{}()

Run that through the formula, and you find that a 20 character password will get you about 130 bits of entropy–more than AES128. If you’re considering against AES256, then 40 characters will go to 260 bits.

Given that, I wonder if it’s even worth it to use SSL client auth over HTTPS. Apache’s password storage needs modernizing, but that can be handled with server modules.


Device::WebIO Family Version 0.002

2014-09-20


A little while ago, I made a tentative release of Device::WebIO. That was a basic version so I didn’t talk much about it. I’ve now finished up what I wanted for v0.002, which gets things to where I want.

Device::WebIO provides a unified API for controlling all the wonderful System on a Chip hardware that’s been coming out of late. If you wanted to control one of these devices on Perl previously, you would have used HiPi for Raspberry Pi, Firmata for Arduino, or Device::PCDuino for PCDuino. Each of these has their own API. With Device::WebIO, you use a single interface with a driver for your specific device.

The project borrows from WebIOPi, a Python project which is specific to the Raspberry Pi. What I really liked about it was the REST interface, which lets you control the pins over a web browser. But I also wanted to branch out from just the Raspberry Pi, and hey, I also prefer Perl.

So I grabbed the REST interface and implemented in Device::WebIO::Dancer. It’s mostly compatible with WebIOPi’s interface, but I made a few changes where it tended to be too specific to the Raspberry Pi. For instance, Analog-to-Digital Converters need a voltref and a bit resolution. On the Rpi (or rather, expander boards for the Rpi, since it doesn’t have an ADC pin on its own), the voltref and resolution values are the same across all pins, but that’s not true on the PCDuino. The original interface didn’t specify such a pin, so I added a pin value to the call.

All such changes are documented in the pod for the REST API.


Device::PCDuino -- Perl Module for Accessing I/O on the pcDuino

2014-07-21


The Bodgery (my makerspace) was donated a few pcDuinos. These are great little devices, more powerful than the Raspberry Pi, and with a built-in WiFi adapter and Arduino-like pin headers.

One thing it lacked was a Perl interface to the I/O pins. I quickly fixed this oversight with Device::PCDuino.

Currently, GPIO and ADC pins are implemented. PWM should be easy to work out. SPI and I2C look like they’ll be a little more involved (see the Sparkfun examples in C).

Usage is about as simple as can be. Use set_output() and set_input() to set the type you want for a given pin, then call output() and input() to set or receive values, respectively. See the POD docs and the “examples/“ directory in the distribution for more details.


MongoDB -- Madmongers 2014/07/08

2014-07-09


https://www.youtube.com/watch?v=Iy9u8CSbqlc


YAPC::NA 2014

2014-06-26


The UAV::Pilot talk went well. It’s all up on YouTube already.

Hotel wifi is predictably shitty. Half the bandwidth is being used to stream everything to YouTube, and the rest of us are stuck with the leftovers. Hotels just don’t have networking staff who know what they’re doing on site.

I also helped out Steven Lembark with his “Getting Testy with Perl“ talk. We spent the evening before hacking up a test script for the AR.Drone to integrate with his talk. Having a UAV takeoff and flip around sure is more interesting than your usual “check that the row went in the database” demo test.

One thing I found while working on that is that UAV::Pilot has a terrible interface for simple scripting. The ‘uav’ shell is fine for typing stuff out yourself, and the object interface is fine for big complicated things, but there’s a space in between that isn’t being served.

At the Hardware Hackathon, Robert Blackwell brought an iRobot Create. I quickly hacked together a UAV::Pilot interface for it using Robotics::IRobot.

Lastly, some maniac did this:

https://www.youtube.com/watch?v=EQx9TopTH8U


Hooking into @INC

2014-06-05


In UAV::Pilot, there’s a shell called uav that’s meant to be an easy way to mess around. It takes arbitrary Perl commands and runs them through eval(). By loading up libraries into its context namespace, we can provide commands for all your basic UAV needs.

The old way of loading these libraries was to write them as a normal module, except without a package statement at the top. When you loaded a library, UAV::Pilot::Command would go digging around in the distro’s share dir. Once found, it slurps in the file, adds a package for the namespace we want, and hands it to eval().

This worked OK, but it had the downside that for development, you couldn’t make in-place fixes to the library. File::ShareDir gives you back the path to the distro’s system share directory, so you had to install the development distribution first and then find out if your fixes worked.

Then, I saw this tidbit in the perldelta for 5.20:

“Since Perl v5.10, it has been possible for subroutines in @INC to return a reference to a scalar holding initial source code to prepend to the file. This is now documented.”

Specifically, it’s documented in perlfunc under the require entry. But what I really wanted was the method of sticking a subroutine in @INC.

When you do this, the subroutine is passed a reference to itself, and a path to the file. It should return a list of up to four things:

  1. Reference to a scalar, which is text that will be prepended to the module
  2. Filehandle to read from
  3. Subref, which if there is no filehandle above, will be called in a loop to get the module text until it returns 0
  4. Subroutine state var

For my purposes, I only needed to return the first two.

This means the Commands modules can be in the regular module paths (though still without a package statement). This is was implemented in UAV::Pilot v1.0_0 trial release, and UAV::Pilot::ARDrone has been ported to the new way, too. WumpusRover should be forthcoming.

I’m letting the CPAN smoke testers go over the trial release before I put the big official v1.0 on the module, but we’re looking good so far.


Jenkins: Video Presentation for Madison Perl Mongers, 2014/05/13

2014-05-14


https://www.youtube.com/watch?v=iN3SJN6kTYU


DIY Arduino-based Quadcopter: Noted

2014-05-13


http://hackaday.com/2014/05/12/a-quadcopter-from-scratch/



Copyright © 2024 Timm Murray
CC BY-NC

Opinions expressed are solely my own and do not express the views or opinions of my employer.