Adding Social Media Sharing Buttons to a Nikola Site

In November 2011 I migrated my site from Joomla to Nikola.

Unlike Joomla (and, for that matter, Wordpress/Drupal), Nikola is a static site generator (SSG): when adding content to the site I invoke Nikola and it generates a static files for each of the pages in the site (one of which you're reading now).

This provides significant security and performance benefit. There's no PHP in the background calculating what to serve to you, the file is simply loaded from disk and served on request, reducing both response time and attack surface.

However, because responses are not dynamically calculated, there are things that become harder as a page cannot dynamically include something based upon the user's request.

Social Media sharing icons are an example of this.

In a dynamic site, we might update a template to include

<div class="social-icon">
   // Broken up for readability on smaller screens
   $t = urlencode($page->title);
   $p = urlencode($_SERVER['REQUEST_URI']);
   $d = "";
   <a href="<?php echo $t; ?>&url=<?php echo $d . $p; ?>&via=bentasker">
     Tweet This

This injects the title of the current page, as well as the path of the page being requested (in practice you'd use one of the CMS's methods rather than the $_SERVER superglobal, but it allows the example to fit into a small screen more easily).

In a SSG we need to use a slightly different approach. Although the underlying principle is similar, rather than acquiring details from the request, we instead need to ask Nikola's templating engine to include specific details from the post so that we can display preconfigured buttons like these:

This post details the process of adding social media sharing icons to Nikola post pages - it's more or less exactly the process I used to add icons to my own site.

Read more…

Stop Requiring Phone Numbers

I recently wrote about the need to observe the overall aims of GDPR when designing compliance into a system.

In that post, I wrote a little about my objections to the unnecessary collection of phone numbers, something that I've alluded to in past posts (also here (NSFW)) but never really laid out in much depth.

This post will lay out the issues inherent in collection and processing of phone numbers, as well as why those issues mean that that processing is (IMO) unnecessary, unjustified and needs to be replaced with better solutions.

Read more…

Enabling and monitoring the zswap compressed page cache on Linux

I use a Lenovo X1 Carbon for work, and generally speaking it's a lovely bit of kit.

Unfortunately, the laptop was only specced with 16GB of RAM at purchase time, and it turns out that Lenovo decided it was a good idea to solder RAM in, so it's not actually possible to add more.

As a result, I frequently find that I'm using swap.

This isn't as bad as it sounds, the laptop's NVME storage is blazing fast, so it's often not immediately obvious that it's swapping (so much so, in fact, that I set up an ordered set of swap partitions so that it's more obvious when the system is approaching swap exhaustion).

Inevitably though, I reach the point where the system just doesn't have the resources that it needs, especially if I'm busy and multitasking.

The full fix for that, really, is a new laptop but there are things which can be done to mitigate the issue and improve performance a bit.

One of those is enabling a compressed in-memory page cache using the Linux kernel's zswap support (introduced in kernel version 3.11). zswap is more computationally expensive than RAM, but less expensive than swapping to disk.

This post details the process of enabling zswap in order to improve the performance of a Linux system. We'll also explore how to monitor it's usage with Telegraf.

Read more…

The Effectiveness Of SSH Tarpits

About 18 months ago, I wrote and deployed a SSH Tarpit which works on exactly the same basis as endlessh.

Just like a normal SSH daemon, the tarpit listens on tcp/22. Once a client connects, it sends an endless stream of characters as the SSH banner, inserting a random sleep between each chunk in order to reduce resource/bandwidth demand on the server.

// Calculate a length for the string we should output
strlength = rand.Intn(MAX_LENGTH - MIN_LENGTH) + MIN_LENGTH

// Generate the string
randstr = genString(strlength)

// Write it to the socket
_, err := conn.Write([]byte(randstr + "\r\n"))

/* Sleep for a period before sending the next
    * We vary the period a bit to tie the client up for varying amounts of time
delay = time.Duration(rand.Intn(MAX_SLEEP - MIN_SLEEP) + MIN_SLEEP)
time.Sleep(delay * time.Second)

The idea being that the client will bog down waiting on a SSH connection that will never actually be usable, rather than simply moving on to bug someone else.

About a week after deploying the tarpit, I pulled some stats and did some basic (but messy) analysis on the tarpit's activities.

I recently needed to re-deploy a tarpit, because of a failure in the underlying hardware. Whilst doing so, I also made changes so that statistics would be written into InfluxDB for later analysis.

The aim of this post is to explore how behaviour observed in the tarpit has changed since January 2021 as well as to try and assess whether tarpits are still effective enough to be worth running.

Read more…

Designing Software to Minimise Harm Whilst Complying With Legal Obligations

Under GDPR, data controllers are expected to assess the legal basis for their collection and processing of data and declare it in their privacy policies (for example, mine is here).

The regulations enumerate the various legal basis that data controllers can rely upon

(a) the data subject has given consent to the processing of his or her 
    personal data for one or more specific purposes;

(b) processing is necessary for the performance of a contract to which
    the data subject is party or in order to take steps at the request 
    of the data subject prior to entering into a contract;

(c) processing is necessary for compliance with a legal obligation to 
    which the controller is subject;

(d) processing is necessary in order to protect the vital interests 
    of the data subject or of another natural person;

(e) processing is necessary for the performance of a task carried 
    out in the public interest or in the exercise of official 
    authority vested in the controller;

(f) processing is necessary for the purposes of the legitimate 
    interests pursued by the controller or by a third party, 
    except where such interests are overridden by the interests 
    or fundamental rights and freedoms of the data subject 
    which require protection of personal data, in particular 
    where the data subject is a child.

In the years since GDPR came into force, there's been a lot of focus on how to properly obtain consent ((a)), as well as when and why Legitimate Interest ((f)) can reasonably be used.

However, (to my knowledge) there's been much less focus on clause (c)

(c) processing is necessary for compliance with a legal obligation to 
    which the controller is subject;

This clause is often taken at face value: the law says I must collect x, so I collect x.

But, it's not always that clear-cut, because the law isn't always specific about what needs to be collected (or how).

In this post I'm going to explore an example that I believe highlights the implications of GDPR on how we design software and processes that need to comply with some form of legal obligation.

As is obligatory for these sorts of posts: I am not a lawyer, I'm just a grumbly git who enjoys thought exercises.

Read more…

Examining Toxicity in Software Related Discussions

Earlier this week, The Register carried an interesting analysis of a study by CMU into online toxicity and, in particular, how it manifests in open-source projects.

The paper doesn't actually suggest that this is an Open Source Specific problem, just that the traits they identified are more common in OSS communities than other forms of toxicity are.

This seems to fit well with the idea that this is an issue around software communities, Open Source or otherwise.

As a timely example, the lead on the (forthcoming) game Return to Monkey Island has announced that he won't post on his blog about Return To Monkey Island anymore, specifially because of the abuse he's receiving.

I'm shutting down comments. People are just being mean and I'm having to delete personal attack comments. It's an amazing game and everyone on the team is very proud of it. Play it or don't play it but don't ruin it for everyone else. I won't be posting anymore about the game on my blog. The joy of sharing has been driven from me.

The abuse is being sent because RTMI uses a different style of art-work to the original Monkey Island games.

That's right, because the artwork is different to the original 30 year old series, the lead on a game has been abused until he lost the will to share news/previews. It's an utterly shitty thing to do.

It seem's unlikely that Ron will read this, but if you are: mate, the game looks amazing and I'm so stoked that it's going to be a thing.

It's been a while since I've written a proper opinion piece, but in this post I want to analyse a few examples of toxicity (or potential toxicity) in the context of CMU's definition.

Read more…

Manually applying a snap package update

Snap is a convenient way to install containerised applications. Like all package management systems it has it's flaws, but sees widespread use (in particular on Ubuntu derived distros).

There's a little known feature of Snap that's started catching people out though. Snap has the ability to force updates, and will push notifications about a forthcoming attempt to do so.

Pending update of "signal-desktop snap"

Although this feature was actually introduced back in 2019, it's still not particularly well received at times.

Misleading Notification

One concern is that the notification is quite misleading and doesn't really give a clear indication of what the user is supposed to do

Pending update of "signal-desktop" snap

Close the app to avoid disruption (7 days left)

The call to action seems to suggest (particularly to those familiar with things like AWS degraded instance notifications) that you can avoid the disruption of a forced update by closing the app and re-opening it.

But, this isn't the case. On relaunch, the app will be running the same version and notifications will continue unabated.

It is, however, possible (desirable, even) to update (or, in snap parlance: refresh) the package/application manually rather than waiting for the scheduled update.

This documentation details the (simple) process to refresh a snap package on linux.

Read more…

Tracking and Alerting on LetsEncrypt Certificate Renewals With InfluxDB and Kapacitor

LetsEncrypt has been providing free SSL certificates since 2014, and has seen widespread usage.

With a 90 day lifetime, the certificates only have relatively short lifespans and need renewing regularly, with the recommended way being to automate renewal using certbot.

The relatively short lifetime of these certificates means there's also a fairly short window to notice and intervene if renewal fails (whether because you've hit LetsEncrypt's rate limits, because certbot has started failing to fire, or some other reason).

Service monitoring often includes a check that connects in and checks certificate expiration dates, but there's usually a window between where a certificate should have renewed and when it gets close enough to expiry to breach your alert threshold.

If we apply a defense-in-depth mindset, there should also be monitoring of the renewal process itself: not only does this provide an earlier opportunity to trigger an intervention, it also addresses the risk of reliance on a single health check (which might itself malfunction).

This post covers the process of configuring a post-deploy hook in certbot to write renewal information into InfluxDB so that alerts can be generated when an expected renewal is missed.

Read more…

Building a Topper to Extend My Desk (and Increase Leg Room)

I've never placed much importance on having a nice looking desk: it's just a bit of furniture that you pay no real attention to whilst it holds the stuff that you are paying attention to.

When we last moved, I switched from my original desk to using one that I'd previously been using as a workbench. The switch was purely on the basis that the workbench didn't have drawers built in, giving more room for me to move my legs around.

As a result, for the last couple of years, my desk has been an unimposing white thing. At 46cm deep, it has just enough space to hold my various bits and pieces

Tightly packed desk

Until recently, this worked absolutely fine.

For reasons involving a motorcycle and diesel, I've got longstanding knee pain. Lately, it's been giving more jip than normal so I decided to order a foam foot-rest to see whether that helps.

Unfortunately, doing so has revealed something I hadn't previously realised: the recess under my desk is perfectly sized for me. Adding the foot-rest raised my knees too high, so I needed to wheel my chair back a bit, leaving me unable to rest my wrists on the edge of the desk.

I didn't want to replace the desk entirely, so decided to try and make a topper that would extend the desk outward, allowing me to sit a little further back whilst still providing that all important wrist support.

This post details the process I followed to make my desk extender.

Read more…

tor-daemon telegraf plugin v0.2

Version: 0.2

Project Info

The tor-daemon plugin is an exec plugin for Telegraf allowing statistics to be captured from the Tor daemon on Onion services and relays.

Details on usage can be found at Monitoring the Tor daemon with Telegraf.

Release Notes

Version 0.1 implements the basic functionality of the plugin

Release Revision

This version was released in commit c30a1bd

Release issue tracking

Issues assigned to this release can be viewed in GILS


The plugin can be downloaded from Github or from here.