Murukesh Mohanan

Enabling HTTPS

  1. Configuration
  2. Technology

So, it’s been around a year and a half since I set up this site. At the time I shifted to Github pages and got a custom domain, I had thought about setting up HTTPS. For several reasons, I’m a proponent of an HTTPS-only web. Where I can, I try to make it so.

For example, the main IITB CSE website (http://www.cse.iitb.ac.in) is HTTPS-only, however this is only enforced for the department website. User pages and parts of the site proxied to other servers aren’t HTTPS-only, much as I’d like them to be. I had initially tried enforcing HTTPS for the entire site, but it broke some old pages that the users were unwilling or unable to fix.

Of course, it’d be hypocritical of me to not offer or enforce HTTPS on my own site. That, however, is difficult to do. Github Pages didn’t support HTTPS at all earlier. (Now it does, albeit unofficially.) It still has no option to support HTTPS for custom domains.

Recently, two things happened:

  1. I had occasion to visit a friend’s website, and he had HTTPS setup and enforced.
  2. Gitlab started offering their own Gitlab Pages service, which did support HTTPS for their Pages domains from the start.

Ever since I installed Gitlab for the CSE Git server, I’ve been a fan of their work. Their monthly release schedule meant that bugs were fixed and features added regularly. Integration of a CI implementation and Mattermost was a plus. So, when Gitlab Pages was announced, I was interested. It supported more Static Site Generators (SSGs) than did Github (which only supported a crippled Jekyll). You could use practically any Jekyll plugin you wanted, since the command to generate the site was specified by you as CI configuration. I didn’t see much reason to migrate at the time, since I’d have to add CI configuration, and there seemed to be not much benefit with having my page available from four (!) places (#visitors ≤ #sites :stuck_out_tongue:).

Seeing the friend’s site gave me impetus to investigate my options for HTTPS once again. This time, there seemed to be some updates:

  1. Using CloudFlare to provide HTTPS is a commonly-suggested method.
  2. Other options offering a similar workaround have come up, like Kloudsec.
  3. Let’s Encrypt has taken wing.
  4. And finally, Gitlab Pages started supporting custom domains with HTTPS.

First, I tried the CloudFlare way. That was fairly easy, following this blog post. Register with CloudFlare, add your domains, switch nameservers with the ones provided by them, and then start toggling the options. Of interest:

  1. You have to enable both DNS+proxy with CF for HTTPS, HTTPS redirection and HSTS to take effect.
  2. The Full (Strict) option is what you need to make CF use HTTPS with the actual server and check certificate validity. This won’t work with Github Pages.
  3. As usual, changing nameservers takes a while. So, for immediate testing, I added the CF nameservers to /etc/resolv.conf. (And looked up the IPs for use in /etc/hosts, just in case.)

The annoying bit is that the Github Pages site, which redirects to my custom domain, still prefers HTTP. So: https://murukeshm.github.iohttp://murukesh.mehttps://murukesh.me. :unamused: And if you do enable Full (Strict) SSL, down goes your site.

And so the hunt continued. Like I said, Gitlab Pages had started some time ago, but I didn’t know that it support custom domains with HTTPS support. I learnt about that while browsing the Github issue about HTTPS support on Pages, from @konkone’s comment.

So, off I went to Gitlab.com, where I already had an account I made for participating in Gitlab CE issues. I imported the repository from Github, renamed it, and added a .gitlab-ci.yml to kickstart the Gitlab CI’s page building process. I lifted the contents from the default Jekyll setup for Gitlab. The build started, and took a couple of minutes to finish. That’s not a big deal, since updates to Github Pages may take upto 5 minutes, and with Gitlab, you can see the status of the build, and the live log output as well. In particular, the latter is very useful to spot bugs.

Now came the most tiresome part: actually getting a certificate for murukesh.me. There are a few options for getting a free certificate. I decided to try Let’s Encrypt (instead of StartSSL, just for the sake of it). So, I installed the letsencrypt package on my Arch Linux system, and ran the tool. And, well, apparently by default it’s designed to run on the server hosting the site you want to encrypt. :neutral_face: You have to pick the manual option, and this, I discovered too late, is already well-described in Gitlab’s tutorial on using Let’s Encrypt.

It’s still cumbersome though:

  1. You have to add the domains on Gitlab without the certificates.
  2. When you run the letsencrypt tool, it generates some text you have to add to your site. Annoyingly, it does so once each for each domain listed, and it waits for each addition to finish. So, two domains, two commits.
  3. Then, after LE has generated the certificates, you have to remove and add back the domains on Gitlab, since it doesn’t support editing an added domain to add a certificate. :tired_face:

After all that, I do have HTTPS on both murukesh.me and murukesh.gitlab.io. (Side note: Yay for getting in early enough to get murukesh as my ID!) However, Gitlab still doesn’t support redirection of HTTP to HTTPS. So, I’m back to using CloudFlare to add HTTP-to-HTTPS redirection and HSTS for my site.

There’s also the problem of renewing the Let’s Encrypt certificate, which lasts around three months. Apparently there are plans to integrate LE with Gitlab Pages to automate the whole shebang. There’s also a recent feature request to enable redirection of HTTP to HTTPS.

Here’s to hoping both of them getting implemented!

Update (June 13, 2016)

On June 8, Github announced official support for HTTPS on their user pages. Not only are *.github.io pages available on HTTPS like *.gitlab.io ones, you can also force them to be HTTPS-only, as long as you don’t use a custom domain. That means I’ll probably have to remove the CNAME file from the repo. Your move, Gitlab!