GCP then Github Pages

Earlier this year I spent a fair amount of time trying to setup a Kubernetes cluster on GCP, for fun.

I wanted to learn and undersand better Docker / Kubernetes. I also thought it could be a good idea to serve a private subdomain behind IAP, restricting access to only people meant to access that content.

It definitely kept me busy for a while, and I learned a lot. I feel a little less rusty in terms of modern Webdev. As a result, for a few months nicdumz.fr had been serving from GCP, instead of Digital Ocean. GKE for a static website is absolutely overkill, but then again I had another actual private website around on that cluster, so I thought why not.

What I had not anticipated was the high price of the setup, which ended up costing a little over $100 USD a month, way more than what I want to spent for an educational only, mostly abandoned few websites.

So I took a step back. Shut down all of those fancy things. Instead, as http://github.io/ pages is perfectly able to serve static / generated pages for free, I’ve moved there. Had to migrate from Blogofile to Jekyll, but that only took a rainy morning. Bye bye hosting costs :-)

Webfaction was great, Digital Ocean seems better


A few years ago, Webfaction had been offering something somewhat unique on the market. Hosting by developers, for developers, for less than 10 USD a month. For that price I could get SSH access to a shared machine, deploy almost whatever I wanted and get it served by nginx, fast. This was unique: at that time you either had to pay for pricier dedicated machines to get SSH access, or downgrade to simple already-configured bricks that had very little flexibility.

I particularly enjoyed the idea that I could push-over-SSH my content via my version control system, and get it deployed via a hook.

Adopting Webfaction was a pretty great experience. Ticket support a few years ago was responsive and helpful. A much better experience than what I had hoped for.

First they came for Let’s Encrypt

And then Let’s Encrypt happened. Free SSL certificates, I thought, great!

You see, I’m not great at it yet, but I do care about security, and in that great idea. I jumped in, and moved this modest website to https. respect an opportunity to participate and help spread SSL further seemed like a

This is where trouble started. Webfaction has no first-party support for SSL certificates. You’re not root, they do not offer direct access to nginx configuration files. Which means that the only way to deploy a certificate is to bother a human via a ticket. And since Let’s Encrypt certificates expire every responsive enough, and I had a script automating renewal and ticket email. But 90 days, it means bothering a human every ~2 months. It’s fine, support is for a coder, it does give you a bad conscience.

After a while (I suppose because support started receiving way too many tickets), they implemented a way via their webadmin dashboard, to upload your own certificates. So instead of my script bothering a human every 2 months, I had to upload, by hand, via a web form, new certificates every 2 months. Not really an improvement.

Webfaction always claimed that they had support coming for full Let’s Encrypt automation, but a year after the CA launch, nothing had landed.

Then they came for gzip

BREACH happened.

tl;dr: this is a compression side-channel attack. For HTTPS websites that (a) do use compression, (b) include query data in the response, and (c) serve some kind of secret, bad guys might be able to guess what the secret is, by repeatedly issuing requests, with various payloads, and observing how the compressed (encrypted) response changes.

It’s a serious class of attack. Any website serving secrets should care and implement counter-measures. But if you’re serious about security (and you should be, if you’re serving secrets over the web, right?), I do hope that way before the publication of this class of attacks, you were already implementing some, if not, all, of the following countermeasures:

  • Try really hard to avoid responses that do include query data, or responses that depend deterministically on user input. Because any website allowing such thing probably has way too many XSS vulnerabilities lurking. Hello ?username=alert(1);.
  • Defend against XSRF issues, using CSRF tokens. For instance, on login pages, it’s common for servers to return a single-use random CSRF token/nonce that the client must submit along their request, to prevent repeatability.
  • Randomize response length and content.
  • Rate-limiting requests.

All of those basic security measures prevent repeatability, and randomize responses, which, de facto, prevent exploiting BREACH class of attacks.

Unfortunately, Webfaction had a very different response to BREACH, possibly because they are not security experts. Or more likely because customers that were at-least-as-ignorant-of-security asked for that specific change: they disabled gzip compression for all their SSL websites.

That’s quite a pity. Sure, it’s a safe, large hammer to use which appears to immediately hide away all problems. But websites written with poor security practices are still vulnerable websites, very likely prone to XSS or CSRF attacks. Disabling gzip as a way to save them from BREACH is a poor decision, not improving web security as a whole.

Webfaction is working on nginx config fragment support, to allow users to e.g. enable compression per-website. But as of writing, there’s no ETA for that feature, and their support denied manual overrides to configs. No way to re-enable gzip compression on your website.

Time to speak out?

Do I really care that much about running a command and submitting a form every 2 months to renew a certificate? Do I even need compression that bad on this static website? No, and no. Definitely not that critical.

But I reached a clear, fundamental disagreement with the way this host is running their services. I care enough about SSL to require first-party, automated support for certificate changes. And the way to secure websites, is to, duh actually fix the root cause, not disable the perceived cause of a vulnerability. Sending more bytes over the wire by disabling compression does not protect websites from basic XSS/CSRF issues.

And why won’t you just let me customize my nginx configuration, urgh.

Digital Ocean

I moved out. Looking around, Digital Ocean seemed like a great option. 5 USD a month, and in a few seconds I could create an instance running a clean OS. SH access, root. I get to run whatever I want. Switch gzip on, and off, and back on, as much as I want.

In a couple of hours, on a lazy Sunday, I migrated my data from Webfaction to Digital Ocean. Configuring nginx and auto-renewal for Let’s Encrypt was easier than Hello World in Haskell, thanks to their community-maintained guides that even sysadmin dummies like me can follow.

Looking back, it’s even somewhat strange. How did I survive not having full access to the machine before?

Hello Digital Ocean, and thanks: I, for one, embrace change.

Visual refresh

I’ve been ignoring for quite some time now warnings from Google webmaster tools. Supposedly, they said, my site wasn’t responsive or mobile-friendly. What do you mean, people actually use smartphones? Fine, I’ll admit, previous setup was a bit clunky, how 2010 of me.

Which framework?

It’s all about frameworks nowadays. So here we are, then. Took the bait. Found a neat, minimalist CSS framework called Bulma. It comes with a couple simple elements and guidelines, and it was quite straightforward to adapt it to have something working for me. Even with a Blogofile-like site doing content generation. Result is mobile and tablet-friendly, almost free of cost.

Colors, next

I’m obviously a poor designer, and decided not to come up with my own color scheme. Colors are from base16, a syntax highlighting scheme which I rely on, everyday, for all Terminal things. This is the flat variant, transposed, as I could, to something web-like.

No Disqus

Comments have also been completely disabled:

  • I don’t imagine or envision this place becoming a very active social forum, requiring that much interaction.
  • So far comments were quite spammy, requiring some moderation, even for this tiny blog (!)
  • More to the point though, Disqus integration added unacceptable extra latency, requiring at times full seconds to load. I find this unreasonable in 2017.

Bye Disqus!

Why Blogofile?

I recently started following Planet Python, and two posts by Mike Pirnat caught my attention: I have to admit that if after the first post I did not really try to learn too much about Blogofile, – “Yet another blog engine”, he thought – the second post, however, got me more interested: pushing a changeset to publish a new blog post, that looked exciting and I decided to learn more. That led to this blog.

I’ve been meaning to start a technical blog for some time now, but I never quite found a setup that would look appealing enough for me to do it. Blogofile got me started: let’s find out why.

Not a $wordpress

I guess that we all fall for free stuff or simplicity, but I’m still fairly amazed by the number of developer blogs that are hosted on Blogger or Wordpress.com: my experiments with those services have not been so great, and most of all, posting any kind of code seemed, at the time, difficult. But, fair enough, setup is simple, and every penny you save is a penny you can spend on troll food.

Using a blog platform was not an option for me: I want control over the content I serve, and, ideally, a blog would only be a starting point.

But then, for those that do spend time setting up a blog themselves, why would you pick $wordpress? ($wordpress being a placeholder for any CMS serving content dynamically). And this applies to me as well: why did I only consider dynamic applications so far? Afterall, we’re geeks, we’re good coders! We write blogs about code generation or compilation, Vim good practices, about details of load balancing or cache invalidations, but we would not be able to come up with a few lines of Python to generate HTML from a set of files formatted with ReST or markdown? Ridiculous! No, the reality is that most of us have hard-coded the blog == dynamic equivalence in our minds, and that it’s hard to work around it.

Static goodness

What’s dynamic in a blog? Article content, and comments. Do we need a database for this? I say that comments can be handled by Disqus: you can argue with that, I’m pretty sure that the FSF will someday pick up a fight against such platforms, but the service is good enough for me, and I can risk losing this data. For articles, you are in control, and from my viewpoint, we can afford to regenerate pages each time we write a post.

A blog is not this dynamic.


We’re getting fairly good at serving dynamic content. But still see a lot of blogs that get fireballed or go down after a couple hundred visits from a news aggregator: setting up a dynamic stack is quite easy; mastering this art is something else. Static content, on the other hand, is easier: Nginx with proper Cache-Control is a good start.


My first hacks as a kid were done on PHP. I used PHP to send and receive Caesar cyphered blobs to my friends; I was creating pages issuing 50 or so unindexed requests to MySQL… I was young.

I then forgot about this sandbox. And when a nostalgic myself visited it years later… My browser blocked my request, warning me that I was accessing a malicious website. Hacked, of course :)

Static content means less things to sanitize, less permission issues. Happy me.

User control

I’m the kind of person that has troubles writing a lot of text without my favorite editor. Here, I wrote this post in Vim. I hit :make, the site is regenerated. I have a “high-end” SimpleHTTPServer running in background, and I can preview everything offline, without a complex setup. I also know that everything I view offline will be rendered as-is online: no backend can play tricks on us.

I version everything in a Mercurial repository (edit from the future: moved to Git and GitHub).

“Backups” are achieved with a simple hg clone.

“Deployments”? hg push and a changegroup hook.

The core blogofile sources are a mere 1200 lines of Python.

The blog controller is an additional 500 lines.

That’s really easy to analyze or patch, if you think that will ever need this.

I have yet to find something I really dislike about blogofile.

Hello world!

All I wanted for Christmas was a blog.

def test():
  print "Hello, world!"
  return 42


So here we are, a simple static blog, with a fairly simple skin derived from the default Blogofile blog. Untested under IE: if you encounter some troubles, feel free to submit patches to the repository on Bitbucket.

What should you expect?

Not much content about romance, but surely some about Sarcasm, Math and Language! I’m mostly into Python: my first posts are likely to cover details of Mercurial, Zope or ERP5, CPython or various other Python interpreters. I’ll categorize posts accordingly so that readers can select a topic or another.

And who knows what might happen next?