Blog Engineering Tutorial: Securing your GitLab Pages with TLS and Let's Encrypt
April 11, 2016
6 min read

Tutorial: Securing your GitLab Pages with TLS and Let's Encrypt

In this post we will talk about HTTPS and how to add it to your GitLab Pages site with Let's Encrypt

altssh.jpg

In this post we will talk about HTTPS and how to add it to your GitLab Pages site
with [Let's Encrypt][letsencrypt].

Why TLS/SSL?

When discussing HTTPS, it's common to hear people saying that a static
website doesn't need HTTPS, since it doesn't receive any POST requests, or isn't
handling credit card transactions or any other secure request.
But that's not the whole story.

TLS ([formerly SSL][TLSwiki]) is a security protocol that can be added to HTTP
to increase the security of your website by:

  1. properly authenticating yourself: the client can trust that you are really
    you. The TLS handshake that is made at the beginning of the connection
    ensures the client that no one is trying to impersonate you;
  2. data integrity: this ensures that no one has tampered with the data in a
    request/response cycle;
  3. encryption: this is the main selling point of TLS, but the
    other two are just as important. This protects the privacy of the communication
    between client and server.

The TLS layer can be added to other protocols too, such as FTP (making it
FTPS) or WebSockets
(making ws:// wss://).

HTTPS Everywhere

Nowadays, there is a strong push for using TLS on every website.
The ultimate goal is to make the web safer, by adding those three components
cited above to every website.

The first big player was the HTTPS Everywhere
browser extension. Google has also been using HTTPS compliance to better
rank websites since 2014.

How to get TLS certificates

In order to add TLS to HTTP, one would need to get a certificate, and until 2015,
one would need to either pay for it or figure out how to do it with one of the
available [Certificate Authorities][certificateauthority].

Enter [Let's Encrypt][letsencrypt], a free, automated, and open Certificate Authority.
Since [December 2015][publicbeta] anyone can get a free certificate from this
new Certificate Authority from the comfort of their terminal.

Implementation

So, let's suppose we're going to create a static blog with [Jekyll 3][Jekyll].
If you are not creating a blog or are not using Jekyll just follow along, it
should be straightforward enough to translate the steps for different purposes.
You can also find many example projects using different static site generators
(like Middleman or Hugo) in [GitLab's example projects][examplepages].

A simple example blog can be created with:

$ jekyll new cool-blog
New jekyll site installed in ~/cool-blog.
$ cd cool-blog/

Now you have to create a GitLab project. Here we are going to create a "user
page", which means that it is a project created within a user account (not a
group account), and that the name of the project looks like YOURUSERNAME.gitlab.io.
Refer to the ["Getting started" section of the GitLab Pages manual][pagesdocs]
for more information on that.

From now on, remember to replace YOURDOMAIN.org with your custom domain and
YOURUSERNAME with, well, your username. ;)

[Create a project] named YOURUSERNAME.gitlab.io so that GitLab will
identify the project correctly. After that, upload your code to GitLab:

$ git remote add origin [email protected]:YOURUSERNAME/YOURUSERNAME.gitlab.io.git
$ git push -u origin master

OK, so far we have a project uploaded to GitLab, but we haven't configured GitLab Pages yet.
To configure it, just create a .gitlab-ci.yml file in the root directory of your repository
with the following contents:

pages:
  stage: deploy
  image: ruby:2.3
  script:
    - gem install jekyll
    - jekyll build -d public/
  artifacts:
    paths:
      - public
  only:
    - master

This file instructs GitLab Runner to deploy by installing Jekyll and
building your website under the public/ folder
(jekyll build -d public/).

While you Wait for the build process to complete, you can track the progress in the
Builds page of your project. Once it starts, it probably won't take longer
than a few minutes. Once the build is finished, your website will be available at
https://YOURUSERNAME.gitlab.io. Note that GitLab already provides TLS
certificates to all subdomains of gitlab.io (but it has some limitations, so
please [refer to the documentation for more][limitation]). So if you don't want to add a
custom domain, you're done.

How to configure the TLS certificate of your custom domain.

Once you buy a domain name and point that domain to your GitLab Pages website,
you need to configure 2 things:

  1. add the domain to GitLab Pages configuration ([see documentation][customdomain]);
  2. add your custom certificate to your website.

Once you add your domain, your website will be available under both
http://YOURDOMAIN.org and https://YOURUSERNAME.gitlab.io.

But if you try to access your custom domain with HTTPS
(https://YOURDOMAIN.org in this case), your browser will show that
horrible page, saying that things are going wrong and someone is trying to
steal your information. Why is that?

Since GitLab offers TLS certificates to all gitlab.io pages
and your custom domain is just a CNAME over that same domain, GitLab serves
the gitlab.io certificate, and your browser receives mixed messages: on one
side, the browser is trying to access YOURDOMAIN.org, but on the other side
it is getting a TLS certificate for *.gitlab.io,
signaling that something is wrong.

In order to fix it, you need to obtain a certificate for YOURDOMAIN.org and
add it to GitLab Pages. For that we are going to use
Let's Encrypt.

Let's Encrypt is a new certificate authority that offers both free and
automated certificates. That's perfect for us: we don't have to pay for
having HTTPS and you can do everything within the comfort of your terminal.

We begin with downloading the letsencrypt-auto utility.
Open a new terminal window and type:

$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt

letsencrypt-auto offers a lot of functionality. For example, if you have
a web server running Apache, you could add letsencrypt-auto --apache inside your
webserver and have everything done for you. letsencrypt targets primarily Unix-like
webservers, so the letsencrypt-auto tool won't work for Windows users. Check [this
tutorial][letsencryptwindows] to see how to get Let's Encrypt certificates while running
Windows.

Since we are running on GitLab's servers instead, we have to do a bit of manual
work:

$ ./letsencrypt-auto certonly -a manual -d YOURDOMAIN.org
#
# If you want to support another domain, www.YOURDOMAIN.org, for example, you
# can add it to the domain list after -d like:
# ./letsencrypt-auto certonly -a manual -d YOURDOMAIN.org www.YOURDOMAIN.org
#

After you accept that your IP will be publicly logged, a message like the
following will appear:

Make sure your web server displays the following content at
http://YOURDOMAIN.org/.well-known/acme-challenge/5TBu788fW0tQ5EOwZMdu1Gv3e9C33gxjV58hVtWTbDM
before continuing:

5TBu788fW0tQ5EOwZMdu1Gv3e9C33gxjV58hVtWTbDM.ewlbSYgvIxVOqiP1lD2zeDKWBGEZMRfO_4kJyLRP_4U

#
# output omitted
#

Press ENTER to continue

Now it is waiting for the server to be correctly configured so it can go on.
Leave this terminal window open for now.

So, the goal is to the make our already-published static website return
said token when said URL is requested. That's easy: create a custom
page! Just create a file in your blog folder that looks like this:

We want to hear from you

Enjoyed reading this blog post or have questions or feedback? Share your thoughts by creating a new topic in the GitLab community forum. Share your feedback

Ready to get started?

See what your team could do with a unified DevSecOps Platform.

Get free trial

New to GitLab and not sure where to start?

Get started guide

Learn about what GitLab can do for your team

Talk to an expert