Eastern European Road Trip Completion

It’s been such an incredible adventure and such a strange feeling to be back that I think we’ll be waiting a week or so to re-adjust to life in a more stationary setting before sharing stories or posting anything significant.

Suffice it to say at this stage that the trip has been deeply enlightening, a true journey of discovery and has changed us both as people for the better.

If you missed anything on our travels or indeed the entire thing, the tracker will be permanently archived here

Comments off    

Eastern European Road Trip Begins

It’s been a long time in the planning but it’s finally upon us! Shweta and I are off for a month around Eastern Europe, taking our own car over 6,000 miles, visiting in excess of 12 countries and reaching as far East as the Black Sea coast of Romania and Bulgaria.

As you would expect there is a little technology backing us up along the way and so if you click on the tyre tracks on the right or follow this tracker link, you’ll be taken to a dedicated trip page where you can follow our progress and share in some of the travel excitement.

We hope you enjoy our updates and we look forward to meeting up with friends upon our return to tell our travel stories!

Comments off    

Hashing phpBB Passwords

At some point in the future I’ll be writing a more comprehensive article on linking external applications authentication to the phpBB user system, but in the meantime, if you just want to hash passwords or compare hashes then the following code is really useful

define('IN_PHPBB', true);
$phpbb_root_path = './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);

$password = 'password';
$hash = phpbb_hash($password);

if (phpbb_check_hash($password, $hash)) {
echo '"Hash "'.$hash.'" matches password "'.$password.'"';
}

It allows you to run a separate php file which utilises phpBB functions to hash passwords; call it from a shell script, use it to login to servers etc.

Comments off    

Renaming WordPress index.php

Now as any developer who’s dabbled with WordPress knows, it’s easy to change the root directory location of WordPress so that directory structure wise different CMS systems can play nicely alongside one another.

What about, however, the situation where two CMS systems both require a root file of index.php? Well there you have a problem because if you change the name of the WordPress index file, which on the face of it seems easiest, you break the search feature (and possibly other things I’ve not found yet).

Fortunately I found a simple 3 step method which requires modifying only 1 line in 1 core file, which compared to other CMS systems, is not that many.

  1. Firstly you’ll want to follow the instructions on the link at the start of the article to move your WordPress root away from the root of your site so that it can co-exist with your other app. Then, instead of creating a file named index.php in your website root, you create wordpress.php or another name of your choosing
  2. Secondly, in the .htaccess file you created as part of the aforementioned guide, replace instances of index.php with wordpress.php or whatever name you chose
  3. Now, for the final bit of magic, locate the following file wp-includes/class-wp-rewrite.php and replace

    public $index = 'index.php';

    with

    public $index = 'wordpress.php';

    taking care to use your alternative file name if it differs

That’s a wrap as they say! You should find that WordPress works fine, including the search feature, all the while leaving index.php free for use by another CMS. Do let me know in comments how you get along with this if you try it.

Oh and remember, if you upgrade WordPress, which will happen every now and again, do check to make sure your core file change gets put back – I hate to change core, but as index.php is hard-coded, it’s the only way.

Comments off    

Last FM 1.0.1 Released

I’ve just pushed out a quick update to Last FM for WordPress. As well as validating compatibility with recent changes to WordPress core, the release comes with a number of useful bug fixes and features, including a rather nice one that permits the display of album covers alongside the track listing. Hope you enjoy the release!

Comments off    

Calendar 1.3.10 Released

It’s been a little while since I’ve posted a blog update on the WordPress Calendar plugin, but as I’ve just pushed out another bug fix version I thought it a good idea to outline what has changed since I last posted and what is to come.

Firstly in skipping the last 2 versions worth of blog posts I’ve missed trumpeting a really useful new feature. I was contacted by an individual at the BBC last year who wanted to use my calendar (amongst others) to syndicate music event listings across a number of websites for a local radio station. What emerged was an iCalendar feed which both provided long desired functionality to the masses as well as allowing BBC local radio to syndicate events to their own music pages from dozens of local music related websites. Beers all round I think. The 1.3.10 release contains some well deserved fixes to this new functionality along with the usual checks to ensure the latest version of WordPress causes no issues.

In the pipeline then are performance boosts and a semi-rewrite which will seek to harmonise the visuals of a much loved and actively used front-end with developments and improvements in the big wide world of online calendaring. I’d like to provide a date, but as ever, these things take time and thought, neither of which are easy to estimate when holding down a day job and a hectic social schedule.

As ever it’s well worth hitting the update button to get hold of 1.3.10. Any problems or questions in the forums as usual please.

Comments off    

Expanded ULEZ Consultation Response

Living in Central London I recently submitted the following response to the consultation on expanding the Ultra Low Emission Zone from the congestion charging area outwards to the boundaries of the North and South circular roads. While I strongly believe that greener vehicles alongside reduced car use is essential for the improvement of our health and environment, I feel it’s not right to impose such things at a local level in such a way as to cause those who are already doing their bit to end up paying a pseudo tax.

While the rationale behind these proposals is extremely laudable, the financial implications for residents living within the proposed expanded ULEZ zone who own non-compliant light vehicles is simply unacceptable. For car users in this category, many will be faced with the prospect of borrowing large sums of money to replace perfectly serviceable vehicles or paying a pseudo tax every time they drive their existing car (the word pseudo is used here because if there is little choice in the matter it equates to a tax). The daily charge is most likely then to be paid by infrequent car users as such a cost would be significantly less than replacing their vehicle and yet these infrequent car users are the ones who should be supported; though infrequent car use they necessarily use public transport where possible and in turn will be at the bottom end of the scale in terms of contributors to pollution and congestion amongst the car owning public. These issues are compounded by the fact that there is no proposed sunset period for expanded ULEZ area residents which might have allowed for either a period of saving for replacement or natural wastage in terms of eventual expensive repairs necessitating replacement anyway. Despite the undoubted health and environmental benefits for such residents, the uncompromising nature of the proposals make it impossible for these individuals to support these plans which is very great shame.

Having shared my response, I now feel that I should explain my position in an attempt to solicit a response from readers. I own a car, but use it infrequently – primarily for visiting friends or family out of town at weekends or to facilitate hiking trips. It is an old car, but as current electric vehicles are not capable of the kind of range I would require, I’m retaining my existing car until such time as technology improves to allow me to make the switch.

I feel this is the greener option; if I was to switch immediately, it would likely be to another fossil fuel vehicle which I would then keep for much longer on account of the investment cost and thus would, most probably, end up contributing more negatively to emissions. Insight and opinions from those with a better knowledge of these matters would be most welcome!

Comments off    

Family Christmas 2017

Continuing the tradition of a family photo at the Christmas dinner table before tucking into the festive feast. Shweta’s Father was able to join us from India this year which made the occasion all the more special.

Comments (2)    

Let’s Encrypt – Doing it Properly

A while ago I made a passing comment about replacing StartSSL using Let’s Encrypt and while it’s true you can use it in the way I described, it’s not as simple as the command would imply and there are a number of pitfalls – not least that if you side-step most of them by going a truly manual route, your efforts only last for 3 months – let’s encrypt certificates expire after only 3 months.

What this all boils down to is that in order to make proper use of this excellent free service you have to automate the process of obtaining and renewing certificates. Not just that though, because their python tooling (certbot) will do this in a general fashion for you, but to truly implement a hands off one size fits all solution. I articulated this as the following requirements.

  • Tool must check for impending expiry and renew in time to avoid nag e-mails
  • Support should be available for adding new certificate requests to the “pool”, not just to renew existing ones
  • A fixed, permanent web server must not be required
  • Servers running on non-standard ports must be supproted
  • Servers not ordinarily accessible to the public must be supported
  • Firewall must not be required to always be open to Let’s Encrypt servers
  • Tool must support servers who’s control IP (SSH etc.) differs from that to which an SSL certificate is to be assigned (A record of SSL domain)

A evening of hacking around on a Raspberry Pi to get certbot running and some hasty coding in bash revealed a solution which essentially, does the following, in order, for each domain requiring a certificate.

  1. Checks to see if the domain has a cert and if it’s expiring
  2. Creates a remote directory from which files will be served as part of the renewal process
  3. Inserts a temporary firewall rule to allow Lets’ Encrypt servers to validate the served files
  4. Starts a temporary lightweight webserver to serve said files and runs it on a port that Let’s Encrypt supports (80)
  5. Mounts this served directory locally on the certbot machine so that certbot can load files into it
  6. Runs certbot to create/renew the certificate
  7. Unmounts the temporary server directory
  8. Stops the temporary webserver
  9. Removes the temporary firewall rule
  10. Cleans up temporary files
  11. Load the certificate files onto the remote server over SSH
  12. Bounces any services that use them so that they are picked up (e.g. Apache)

Before I share the script, a few words of warning and a few pointers

  • Everything needs to run as root
  • I mounted a NAS share of my certificate files so that they were stored and backed up centrally. Certbot expects to find everything in /etc/letsencrypt so that will need to be your mount point if you use the NAS option
  • The script assumes that the server on which it is running has SSH keys setup on all hosts it needs to connect to such that passwordless root is possible.

If you don’t know how to do any of these things then you probably shouldn’t try using the script. It’s not that you won’t be capable or anything, rather that there are a lot of moving parts and basic Linux knowledge that would allow you to achieve these 3 points will go a long way in helping you to debug any issues with the script.

Finally then, the script; configured for two dummy domains, running on the same box, one serving from apache, the other a custom process.

#!/bin/bash
# Configuration section
email=your.email@address.com
certPath=/etc/letsencrypt/live/
remotePort=80 # Lets encrypt only supports 80 - ouch - we'll need to stop servers while doing this
domains=('one.domain.com' 'two.domain.com')
hosts=('1.2.3.5' '1.2.3.6')
sshHosts=('1.2.3.4' '1.2.3.4')
sslPathOnServer=('/etc/apache2/ssl/' '/etc/specialprocess/ssl/')
keyFileNameOnServer=('www.key' 'pub.key')
certFileNameOnServer=('www.crt' 'cert.crt')
chainFileNameOnServer=('www-chain.pem' 'chain.pem')
serverStopCommand=('/etc/init.d/apache2 stop' '/etc/init.d/specialprocess stop')
serverStartCommand=('/etc/init.d/apache2 start' '/etc/init.d/specialprocess start')

# Work is done here, no further edits!
i=0
for domain in ${domains[@]}; do
        # Ascertain if the certificate will expire in 3 weeks or less - stops lets encrypt nagging e-mails
        new=0
        if [ -d "$certPath$domain" ]
        then
                openssl x509 -in $certPath$domain/cert.pem -checkend $(( 86400 * 21 )) -noout
                result=$?
        else
                new=1
                result=1
        fi
        if [[ $result == 1 ]]
        then
                # Report the status
                if [[ $new == 1 ]]
                then
                        echo "Certificate for $domain [New]"
                        echo "Running certificate creation process..."
                else
                        echo "Ceritificate for $domain [Expiring]"
                        echo "Running renewal process..."
                fi
                # Start renewal process; create remote directory, iptables rule, start remote server
                echo -n "       Setting up iptables rules on remote server, stopping server process using certs & starting temporary micro server..."
                rule="INPUT 1 -p tcp -m tcp --dport $remotePort -d ${hosts[i]} -j ACCEPT"
                ssh root@${sshHosts[i]} << ENDSSH > /dev/null 2>&1
                eval ${serverStopCommand[i]}
                mkdir /tmp/$domain
                iptables -I $rule
                cd /tmp/$domain
                python -m SimpleHTTPServer $remotePort > /dev/null 2>&1 &
ENDSSH
                echo " Done"

                # Mount remote directory locally over SSHFS
                echo -n "       Creating mount to directory served by temporary micro server..."
                if [ -d /tmp/certbot ]
                then
                        rm -rf /tmp/certbot
                fi
                mkdir /tmp/certbot
                sshfs ${sshHosts[i]}:/tmp/$domain /tmp/certbot
                echo " Done"

                # Call letsencrypt to renew/create
                echo -n "       Call letsencrypt to renew the certificate in our store..."
                letsencrypt certonly --webroot -n -w /tmp/certbot -m $email -d $domain > /dev/null 2>&1
                echo " Done"

                # Unmount remote SSHFS directory
                echo -n "       Unmounting micro server directory and cleaning mount point..."
                umount /tmp/certbot
                rm -rf /tmp/certbot
                echo " Done"

                # SCP certificate/chain/key files to remote host
                echo -n "       Copying new certificate files to the server..."
                scp $certPath$domain/cert.pem ${sshHosts[i]}:${sslPathOnServer[i]}${certFileNameOnServer[i]} > /dev/null 2>&1
                scp $certPath$domain/privkey.pem ${sshHosts[i]}:${sslPathOnServer[i]}${keyFileNameOnServer[i]} > /dev/null 2>&1
                scp $certPath$domain/chain.pem ${sshHosts[i]}:${sslPathOnServer[i]}${chainFileNameOnServer[i]} > /dev/null 2>&1
                echo " Done"

                # Cleanup remote host; stop temp server, reload default iptables, cleanup temp directory, restart server process
                echo -n "       Stop micro server, clean up iptables rule & start server process using certs... "
                ssh ${sshHosts[i]} << ENDSSH > /dev/null 2>&1
                kill \`ps -ef | grep SimpleHTTPServer | grep -v grep | awk '{ print \$2; }'\`
                iptables -D INPUT 1
                rm -rf /tmp/$domain
                eval ${serverStartCommand[i]}
ENDSSH
                echo " Done"

                # Confirm completion
                if [[ $new == 1 ]]
                then
                        echo "Certificate for $domain [Created]"
                        echo "Creation process complete"
                else
                        echo "Renewal process complete"
                        echo "Certificate for $domain [Renewed]"
                fi
        else
                # Certificate needs no renewal, indicate as such
                echo "Certificate for $domain [OK]"
        fi
        i=$i+1
done

You’ll need to modify the variables/arrays at the start to get it working, some are obvious, but I’ll explain them anyway.

  • email : This is used to create, recover and access your account. Once created, the private key for accessing your account will be stored in the let’s encrypt home directory (usully /etc/letsencrypt)
  • certPath : The path to the /live directory in your let’s encrypt home directory, usually /etc/letsencrypt/live
  • remotePort : Leave this at 80; it’s just here to help setup iptables rules – it cannot be changed in let’s encrypt config
  • domains : An array of domains for which you want certificates
  • hosts : An array of IP addresses corresponding to the aforementioned certificates – keep the ordering the same!
  • sshHosts : An array of IP addresses used for administering each of the aforementioned domains; for example you may have several web servers/domains all being served from the same physical host – this would then be an array of identical IPs, corresponding in array size with the number of domains
  • sslPathOnServer : What is the file system path to each domain’s certificates on the host server
  • keyFileNameOnServer : Within that directory, what is the key file name
  • certFileNameOnServer : Within that directory, what is the certificate file name
  • chainFileNameOnServer : Within that directory, what is the chain file name
  • serverStopCommand : For each domain, what command stops the server process the domain is used for
  • serverStartCommand : Likewise, what is the command to start the server process again

That’s it! Best of luck if you choose to go this way and do let me know if the script is useful to you.

Comments (1)    

Raspberry Pi MAC Address Changing on Reboot

I recently did a apt-get dist-upgrade on my Raspberry Pi running Raspbian 8 and when I rebooted the device appeared to drop clean off my network. I was away from home at the time so I decided to fix it when I was next on the premises – it wasn’t a hugely important device to have running 24/7.

When I looked at the device in person I realised that it was in fact connected to the network, but with a different IP address to that it had held before. Having MAC address based IP allocation, this seemed rather strange. Looking at the MAC address in ifconfig revealed the problem – it had changed! Thinking this to just be a fluke, I rebooted. Now, not only was the MAC still different to that which it should have been, it had changed a third time!

Investigating what had happened during the upgrade revealed that both the bootloader and the kernel had both been upgraded, but for whatever reason, the new kernel wasn’t being loaded. Modifying the /boot/config.txt as follows along with a reboot fixed this discrepancy and lo and behold the MAC returned to it’s former value and the device picked up the IP address it was supposed to have over DHCP

From

[pi1]
kernel=vmlinuz-4.4.0-1-rpi
initramfs initrd.img-4.4.0-1-rpi followkernel
# to enable DeviceTree, comment out the next line
device_tree=

To

[pi1]
kernel=vmlinuz-4.9.0-2-rpi
initramfs initrd.img-4.9.0-2-rpi followkernel
# to enable DeviceTree, comment out the next line
device_tree=

It’s worth pointing out that you may have a similar problem with a similar cause but slightly different kernel versions to me. If this is the case, or to check if it is, verify the old/new versions in /boot as follows

ls -lha /boot | grep initrd.*rpi

Which will reveal your old/new versions

-rwxr-xr-x 1 root root 5.7M Jul 3 18:26 initrd.img-4.4.0-1-rpi
-rwxr-xr-x 1 root root 13M Jul 3 18:46 initrd.img-4.9.0-2-rpi

You should then modify /boot/config.txt from the old version to the new version as per my above example.

Comments off    

« Previous entries