Integrating GitLab and Google Calendar.

Zeall, like many other software startups, uses GitLab for version control and issue management. We also use the ever-popular Google Calendar to handle meetings, reminders, and deadlines. For several months, we’ve been looking for a way to automatically push GitLab issue deadlines into Google Calendar, and until now it seemed impossible. Only after a recent migration from our own private mailserver to G Suite did we find a solution — or rather, figure out how to feasibly build one.

Continue reading Integrating GitLab and Google Calendar.

Using bcache to back a SSD with a HDD on Ubuntu.

Recently, another student asked me to set up a PostgreSQL instance that they could use for some data mining. I initially put the instance on a HDD, but the dataset was quite large and the import was incredibly slow. I installed the only SSD I had available (120 GB), and it sped up the import for the first few tables. However, this turned out to not be enough space.

I did not want to move the database permanently back to the HDD, as this would mean slow I/O. I also was not about to go buy another SSD. I had heard of bcache, a Linux kernel module that lets a SSD act as a cache for a larger HDD. This seemed like the most appropriate solution — most of the data would fit in the SSD, but the backing HDD would be necessary for the rest of it. This article explains how to set up a bcache instance in this scenario. This tutorial is written for Ubuntu Desktop 16.04.1 (Xenial), but it likely applies to more recent versions as well as Ubuntu Server.

Continue reading Using bcache to back a SSD with a HDD on Ubuntu.

Optimizing MySQL and Apache for a low-memory VPS.

Diagnosing the problem.

My last post had a plug about the migration of our WordPress instance to a new server. However, it didn’t go completely smoothly. The site had gone down a few times in the first day after the migration, with WordPress throwing “Error establishing a database connection.” Sure enough, MySQL had gone down. A simple restart of MySQL would bring the site back up, but what caused the crash in the first place?

Continue reading Optimizing MySQL and Apache for a low-memory VPS.

Quick postfix & dovecot config with virtual hosts (Ubuntu 16.04)

This morning, I received an email from my VPS host notifying me that they will no longer accept PayPal. Instead, my only payment option would be Bitcoin. Not willing to go through this trouble, I decided to migrate from this host (which I had been using for my personal servers for about five years now) to DigitalOcean (which fortunately accepts normal forms of payment).

Part of my server migration was to move email for two of my domains: and Setting up a new mailserver is a notoriously arduous task, so I’m documenting the process in this post — mostly for my future reference, but also to benefit anyone who might stumble upon my blog in their own confusion.

Since I’m serving mail for two domains, I will be using a simple “virtual hosts” configuration. I’ll talk about the process in four parts: local setup, postfix, dovecot, and DNS configuration.

Continue reading Quick postfix & dovecot config with virtual hosts (Ubuntu 16.04)

What’s inside a PEM file?

As you probably know, PEM is a base64-encoded format with human-readable headers, so you can kind of figure out what you’re looking at if you open it in a text editor.

For example, let’s look at an RSA public key:

-----END PUBLIC KEY-----

We can see that we have a public key just from the header. But what’s all the base64 stuff? If it’s a public key, we know that there should be a modulus and an exponent hidden in there. And there’s also probably some kind of hint that this is an RSA key, as opposed to some other type of key.

That base-64 payload actually has the potential to contain a lot of information. It’s an ASN.1 (Abstract Syntax Notation One) data structure, encoded in a format called DER (Distinguished Encoding Rules), and then finally base64-encoded before the header and footer are attached.

ASN.1 is used for a lot of stuff besides keys and certificates; it is a generic file format that can be used to serialize any kind of hierarchical data. DER is just one of many encoding formats for an ASN.1 structure — e.g. there is an older format called BER (Basic Encoding Rules) and an XML-based format called XER (you can probably guess what that stands for).

But anyway, what is inside that public key? How can we find out?

Continue reading What’s inside a PEM file?

My first adventure with Let’s Encrypt on nginx, dovecot, and postfix

Let’s Encrypt is old news by now. It launched back in December, so it has been giving away free DV certificates for nearly four months now. Being a TA for a Computer Security course, it’s about time that I actually tried it out.


Let’s Encrypt is a free certificate authority. They grant TLS certificates that you can use to secure your webserver. They are Domain Validated (DV) certificates, which means they will verify that you control the domain name you are trying to certify.

Continue reading My first adventure with Let’s Encrypt on nginx, dovecot, and postfix

Roll your own dynamic DNS (Ubuntu)

Dynamic DNS, or DDNS, is a type of DNS configuration which allows hosts with dynamic IP addresses to automatically update their DNS records. Often users will rely on services such as DynDNS or No-IP to manage this type of setup, but it is actually relatively easy to run your own DDNS server. Of course, this requires that you have your own domain name and access to at least one host with a static IP (to use as the DNS server).

Continue reading Roll your own dynamic DNS (Ubuntu)

Quick and easy OpenVPN server config (Ubuntu)

VPNs allow you to route your Internet traffic through an encrypted tunnel to a remote server, enhancing your privacy while online. Often a VPS is around the same price per month as a dedicated VPN service, but gives you much more freedom and utility as a poweruser. This post will overview a basic routed OpenVPN configuration on an Ubuntu machine.

Continue reading Quick and easy OpenVPN server config (Ubuntu)