May 28, 2017
11:34 -0400
Hubert Chathi: After about 2.5 years, I'm finally back in the keyring
April 1, 2017

An alternate transport for the Matrix Client-Server API

00:00 -0400

Matrix is an open communications protocol that has many great features. However, one flaw that it has is that the baseline specification is based on long-polling HTTP requests, which is not very efficient. In order to address this deficiency, I've created a spec that presents an alternative transport for the Matrix Client-Server API that uses a protocol that was designed for real-time communications instead of using HTTP.

March 13, 2017

The latest additions to my init.el

11:00 -0400

Inspired by xkcd (but using Alt-mousewheel):

(global-set-key (kbd "<M-mouse-5>") 'undo)
(global-set-key (kbd "<M-mouse-4>") 'redo)

And, since I sometimes need to paste from an HTTP request into a buffer:

(defun insert-from-url (url)
  (interactive "MURL: ")
  (let ((url-request-method "GET")
        (dest (current-buffer))
        (src (url-retrieve-synchronously url)))
    (set-buffer src)
    (goto-char (point-min))
    (search-forward "\n\n")
    (set-buffer dest)
    (insert-buffer-substring src (match-end 0))))
March 9, 2017
23:00 -0500
Hubert Chathi: First, combines Google Talk with Hangouts, and now they are separating the conferencing and chat functionality again
March 3, 2017
15:19 -0500
Hubert Chathi: so true
February 27, 2017
20:11 -0500
Hubert Chathi: Congratulations to all the organizations accepted to GSoC
February 24, 2017
09:56 -0500
Hubert Chathi: Well, thats just embarassing.
February 23, 2017
22:12 -0500
Hubert Chathi: Anyone proxied by or using sites proxied by them: your private data may have been leaked #
11:18 -0500
Hubert Chathi: SHA-1 is officially broken #
February 15, 2017
19:02 -0500
Hubert Chathi: RIP Stuart McLean
February 11, 2017
10:00 -0500
Hubert Chathi: Sign the petition to ask the government to honour their promise to fix our electoral system #
January 31, 2017
08:54 -0500
Hubert Chathi: Got our free Parks Canada Discovery Pass yesterday. Get yours at
January 25, 2017

On transparency

21:01 -0500

I've written briefly before about the value of companies being open and transparent. Back then, I wrote that the way that companies react when things go wrong is a good way to differentiate between them. No matter what company you deal with, things will go wrong at one point or another. Some companies try to avoid responsibility, or only tell you that something has happened if you ask them. Others companies are much more open about what happened. (and the associated is an example of a team that falls into the latter category. And last night's incident is a good example. Their post-mortem blog post is a great example for others to follow. It gives a detailed timeline of what happened and why the outage occurred. And it finishes off with steps that they will take to prevent future incidents.

Kudos to the team for their transparency.

December 25, 2016
09:30 -0500
Hubert Chathi: Merry Christmas
December 1, 2016

Let's Encrypt for Kubernetes

21:08 -0500

A while ago, I blogged about automatic Let's Encrypt certificate renewal with nginx. Since then, I've also set up renewal in our Kubernetes cluster.

Like with nginx, I'm using acme-tiny to do the renewals. For Kubernetes, I created a Docker image. It reads the Let's Encrypt secret key from /etc/acme-tiny/secrets/account.key, and CSR files from /etc/acme-tiny/csrs/{name}.csr. In Kubernetes, these can be set up by mounting a Secrets store and a ConfigMap, respectively. It also reads the current certificates from /etc/acme-tiny/certs/{name}, which should also be set up by mounting a ConfigMap (called certificates), since that is where the container will put the new certificates.

Starting an acme-tiny pod will start an nginx server to store the .well-known directory for the Acme challenge. Running /opt/acme-tiny-utils/renew in the pod will renew the certificate if it will expire within 20 days (running it with the -f option will disable the check). Of course, we want the renewal to be automated, so we want to set up a sort of cron task. Kubernetes has cron jobs since 1.4, but at the time I was setting this up, we were still on 1.3. Kubernetes also does cron jobs by creating a new pod, whereas the way I want this to work is to run a program in an existing pod (though it could be set up to work the other way too). So I have another cron Docker image, which I have set up to run

kubectl exec `kubectl get pods --namespace=lb -l role=acme -o name | cut -d / -f 2` --namespace=lb ./renew

every day. That command finds the acme-tiny pod and runs the renew command, telling it to renew the certificate.

Now in order for the Acme challenge to work, HTTP requests to /.well-known/acme-challenge/ get redirected to acme-tiny rather than to the regular pods serving those services. Our services are behind our HAProxy image. So I have a 0acmetiny entry (the 0 causes it to be sorted before all other entries) in the services ConfigMap for HAProxy that reads:

      "namespace": "lb",
      "selector": {
        "role": "acme"
      "hostnames": ["^.*"],
      "path": "^/\\.well-known/acme-challenge/.*$",
      "ports": [80]

This causes HAProxy to all the Acme challeges to the acme-tiny pod, while leaving all the other requests alone.

And that's how we have our certificates automatically renewed from Let's Encrypt.

November 21, 2016
21:31 -0500
Hubert Chathi: Congratulations to and for the beta release of cross-platform end-to-end encryption
November 8, 2016
08:09 -0500
Hubert Chathi: Americans: hold your nose and vote today. And may the lesser of two evils win.
November 3, 2016
16:34 -0400
Hubert Chathi: My solution to people not changing passwords on their devices: set the default password to "IAmAnIdiotForNotChangingThePassword"
October 25, 2016
09:27 -0400
Hubert Chathi: Amanda's picture was in our local newspaper
September 7, 2016
16:50 -0400
Hubert Chathi: Domain owners, beware of the Chinese Domain Scam. I've gotten some of these emails too.