WordPress on Raspberry Pi 2 running Slackware ARM

Two weeks ago, I decided to move this blog from its old hosting and deploy it on a Raspberry Pi 2. The geek in me could no longer resist the urge to discover if a $35 worth computer could replace the need for commercial hosting. Besides, what a great opportunity to finally get my hands on Slackware’s official ARM port.

RPi2 setup:

Raspberry Pi 2 Model B
Raspberry Pi 2 Micro USB Power Cable 1.2A
MicroSDHC Ultra UHS-I 32GB

LAMP setup:

Slackware ARM current
Package series: a, ap, d, l, k, n (and a few from “x”).
Apache 2.4.12 (rebuilt)
MariaDB 5.5.40 (rebuilt)
PHP 5.4.40 with mod_proxy_fcgi and php-fpm (rebuilt)

Non stock packages:
Modsecurity 2.9.0
Fail2ban 0.9.1

Why use Slackware and not a hard float port?

A hardware floating-point unit you say, well I’d never heard of it.

ARMv7 includes a hardware floating-point unit (FPU), with improved speed compared to software-based floating-point. http://en.wikipedia.org/wiki/ARM_architecture

In short, Slackware is not optimized for modern ARM implementations and it would be reasonable to assume that performance could be improved on a hard float port.

WordPress performance out of the box

It was not great truth to be told, page load times using the twenyfifteen theme clocked in at around 2.5 seconds on average (using 17 queries). I’ve always believed WordPress to be a “lightweight” application, but I guess that’s up for debate. Anyhow, I decided to try my hand at overclocking the RPi2 to see if I could improve performance to something more sustainable for production.

RPi2 final config:

force_turbo=1
arm_freq=1000
core_freq=500
sdram_freq=500
over_voltage=6
temp_limit=75
gpu_mem=16

I tried to push the arm_freq higher, but that caused the RPi2 to cough and crash under high load. Pushing the RPi2 to its limit sliced off another second of page load time, which was good, but obviously not comparable to commercial hosting. It was pretty much as expected, but it still felt like somewhat of a disappointment. However, since I rely heavily on caching with any WordPress installation, this RPi2 was not out of the game yet.

Optimizing the environment

By installing the “WP Super Cache” plugin from Automattic, and optimizing Apache for serving cached and compressed content, the RPi2 turned into a regular powerhouse.

Latest Performance Report for: www.blog.paranoidpenguin.net
Latest Performance Report for: www.blog.paranoidpenguin.net

Analyzing the performance over at GTmetrix.com gave me a page speed score of 96% and a YSlow grade of 92%. That’s a decent result on any platform and I’m rather impressed with the performance of the Raspberry Pi 2 in that regard.

The fact that the RPi2 is sitting on my desk while being assigned a dynamic IP, instead of cooling off at a high tech data center  with next to unlimited bandwidth makes it even more enjoyable.

I have one sour note though, compiling software is painfully slow, but that should not come as a huge surprise.

Onwards

This site will keep rolling on Raspberry Pi 2 and Slackware ARM until something breaks beyond repair. As Slackware current is ripe for an avalanche of updates that might be sooner than later. If that should be the case, then I’ll update the changelog with the latest turn of events.

Slackware ARM current hosting blog.paranoidpenguin.net
Slackware ARM current – Now hosting www.blog.paranoidpenguin.net

How to upgrade PHP on Slackware Linux

I usually leave patching of stock Slackware packages to our BDFL, but I’ll make a few exceptions. As of Fri Apr 03 2015, the stock PHP version on Slackware Linux 14.1 is at version 5.4.36. Looking at the PHP changelog, it would seem that this is not “optimal” for a production server.

To upgrade PHP to version 5.4.39, I’ll use the stock Slackware build scripts. Slackware will build PHP with the IMAP extension, which requires the c-client library to be available. This is taken care of by having the php.SlackBuild script build Alpine (alpine.SlackBuild) and subsequently copying the needed files to /usr/local/lib64/c-client/, before resuming with the PHP build.

For the record, I always recommend building packages for Slackware by using a dedicated build box where possible.

# Build directory
mkdir /tmp/source/
cd /tmp/source/

# Download the Alpine and PHP source
wget -r -l0 -nH --cut-dirs=5 ftp://ftp.df.lth.se/pub/slackware/slackware64-14.1/source/n/alpine/
wget -r -l0 -R tar.xz -nH --cut-dirs=5 ftp://ftp.df.lth.se/pub/slackware/slackware64-14.1/source/n/php/

# Make the build scripts executable
chmod +x /tmp/source/alpine/alpine.SlackBuild
chmod +x /tmp/source/php/php.SlackBuild

# Download PHP 5.4.39 source and signature from php.net
cd /tmp/source/php/
wget http://us.php.net/distributions/php-5.4.39.tar.bz2
wget http://us.php.net/distributions/php-5.4.39.tar.bz2.asc 

# Verify the signature (http://php.net/downloads.php#gpg-5.4)
gpg --keyserver pgpkeys.mit.edu --recv-key 5DA04B5D
gpg --verify php-5.4.39.tar.bz2.asc

# Delete the signature
rm php-5.4.39.tar.bz2.asc

# Change file extension to set correct version for the package
sed -i 's/tar.xz/tar.bz2/g' php.SlackBuild

# Build Alpine and PHP
./php.SlackBuild

# Install the new version
upgradepkg /tmp/php-5.4.39-x86_64-1.txz

# restart php-fpm (if used) and apache
/etc/rc.d/rc.php-fpm restart
apachectl restart
Slackware PHP Build
Slackware Linux 14.1 running PHP 5.4.39

If all went according to plan, then lets make sure everything works as expected before we deploy to production servers.

How to configure KMail with GPG on Slackware Linux 14.1

No additional software is required on a full Slackware 14.1 install.
Slackware 14.1 ships with KDE 4.10.5.

Prerequisites

If you don’t already have a key pair (secret and public key), then your first order of business is to create one. The preferrable option is to use the CLI with the command:

gpg --gen-key

KDE provides two graphical tools for working with GPG, namely KGpg and Kleopatra.  KGpg will walk you through the initial setup using an interactive wizard and subsequently create the needed key pair and config files (do not use Kleopatra for your initial setup).
If you’re importing an existing private key then make sure to change the default trust level afterwards.

Regarding the key properties, most folks recommend the RSA/RSA algorithm and a key size of 4096 bits (if you’re really paranoid security conscious).

Enabling the GPG Agent on Slackware Linux

The gpg-agent is a daemon to manage secret (private) keys independently from any protocol. It is used as a backend for gpg and gpgsm as well as for a couple of other utilities.

Basically the gpg-agent will take care of caching the passphrase securely between applications and thus removing the need for typing the passphrase everytime we use our key.

Enabling the gpg-agent is simple enough, edit ~/.gnupg/gpg.conf and remove the comment sign in front of the use-agent directive.

# Edit your gpg.conf
vi ~/.gnupg/gpg.conf
# Remove the comment sign in front of use-agent
use-agent

Configuring pinentry on Slackware Linux

Pinentry is a small collection of dialog programs that allow GnuPG to read passphrases and PIN numbers in a secure manner.

In short, Pinentry will pop up and ask for the passphrase when using our GPG key.

# Create gpg-agent.conf in your home path
vi ~/.gnupg/gpg-agent.conf
# Add the following directives to gpg-agent.conf
pinentry-program /usr/bin/pinentry-qt4
no-grab
default-cache-ttl 3600

As KDE is based on the Qt framework, pinentry-qt4 is a viable choice (pinentry is also available in curses, qt and gtk-2).
The default-cache-ttl directive specifies the amount of time (in seconds) in which the passphrase should be cached. The no-grab directive avoids having the pinentry dialog glued to your keyboard, which is no fun at all.

Adding startup and shutdown scripts for KDE on Slackware Linux

We need to have the gpg-agent running before KDE starts up. To achieve this, we’ll use two bash scripts that will start and subsequently kill the gpg-agent daemon.

Gpg-agent-start.sh

KDE has a feature called “Pre-KDE Startup” that let us run user defined scripts at the earliest stage. Those scripts resides in the ~/.kde/env directory. This folder is not available by default, so we’ll create it and add the gpg-agent-start.sh script.

# Create the env folder and the startup script
mkdir ~/.kde/env
vi ~/.kde/env/gpg-agent-start.sh
# Add the code below to gpg-agent-start.sh
#!/bin/sh
eval "$(gpg-agent --daemon)"
# Make the script executable
chmod +x ~/.kde/env/gpg-agent-start.sh

Gpg-agent-stop.sh

We don’t want to have multiple instances of gpg-agent running when logging in and out of sessions. KDE has a Shutdown feature for user defined scripts as well, so we’ll make another script to kill  gpg-agent when our KDE session ends. The shutdown script is to be placed in ~/.kde/shutdown/, another folder that doesn’t exist on a default installation.

# Create the shutdown folder and the shutdown script 
mkdir ~/.kde/shutdown/
vi ~/.kde/shutdown/gpg-agent-stop.sh
# Add the code below to gpg-agent-stop.sh
#!/bin/sh
if [ -n "${GPG_AGENT_INFO}" ]; then
 kill $(echo ${GPG_AGENT_INFO} | cut -d':' -f 2) >/dev/null 2>&1
fi
# Make the script executable
chmod +x ~/.kde/shutdown/gpg-agent-stop.sh

Verify that gpg-agent is running as a daemon

Log out and start a new KDE session.
Run the following code to verify that the gpg-agent is running and available:

gpg-agent status

Configuring KMail

Start KMail and select:
“Settings” => “Configure KMail” => “Manage Identities” => Modify {your identity} => “Cryptography”.

KMail - Cryptography
KMail – Cryptography

Select your key for signing and encryption, and optionally your preferred format. Save and your’e good to go.
You might also want to set signing and encrypting messages as preferred options by editing the default settings under:
“Settings” => “Configure KMail” => “Security” =>  “Composing”.

Gotchas

Don’t fiddle with the GnuPG Log Viewer .
Changing the debug level sounds like a plan during troubleshooting, but it’s not. The result will instead be a corrupted gpg.conf.
If that should be the case then just remove the lines in question, they will look similar to this:

###+++--- GPGConf ---+++###
utf8-strings
debug-level guru
Viewing a signed and decrypted message with KMail.
Viewing a signed and decrypted message with KMail.