Blogging with Hugo and GitLab (4): HTTPS with Let's Encrypt

The default HTTPS support by GitLab will be unavailable with custom domains. Fortunately, there is the solution to add HTTPS back for free.

Why HTTPS?

HTTPS (HTTP over TLS or HTTP over SSL) is more secure than HTTP. Today many browsers will mark a website as insecure if it's visited via HTTP instead of HTTPS. I think that's important for personal bloggers as you don't want people to think they are exposed to security risk by visiting your blog website.

Why Let's Encrypt?

In order to equip your website with HTTPS, you need to acquire a SSL/TLS certificate from a certificate authority (CA) that is trusted by browsers. The good thing is that free certificates are available. For example:

  • CAcert is more in the Linux world while certificates issued by it are still not trusted by most browsers.
  • Cloudflare (btw, they own an interesting domain https://one.one.one.one) offers free certificates, but it might not be really free if you go with full features.
  • Let's Encrypt provides full-feature free certificates which are valid for 90 days and renewable.

Overall, Let's Encrypt is the best.

Environment

  • macOS Sierra 10.12.6.

Obtain a Let's Encrypt certificate

  1. Install Homebrew in macOS.
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  1. Install Certbot.
brew install certbot
  1. Request a certificate. Though optional, it's recommended to provide an email to receive notifications (e.g., certificate expiration). Here we request the certificate for both root domain and sub-domain.
sudo certbot certonly -a manual -d loadbalancing.xyz -d www.loadbalancing.xyz --email example@email.com

It's then followed by several steps:

  • Type A to agree with their terms of service.
  • Type either Y or N depending on if you want to receive news from Let's Encrypt.
  • Type Y to agree with logging your IP.
  1. Then pause here (don't press Enter). Follow the instruction to create a file containing the data specified and commit it to your repository.
cd your_repository/static
mkdir -p .well-known/acme-challenge/
vi the_specified_file_name

The file need to be available at: http://loadbalancing.xyz/.well-known/acme-challenge/the_specified_file_name

  1. Now press Enter. It will generate and save the certificate and key to local. Record their content which will be used in the next step.
sudo cat /etc/letsencrypt/live/loadbalancing.xyz/fullchain.pem
sudo cat /etc/letsencrypt/live/loadbalancing.xyz/privkey.pem 

Add the certificate to GitLab

  1. Add the certificate and key to your website.
  • “Setting” > “Pages”.
    For each domain (root and sub-domain), click “Details” > “Edit”.
  1. Copy and paste the certificate into the first field Certificate (PEM).

  2. Copy and paste the private key into the second field Key (PEM).

  3. Let traffics be automatically directed to HTTPS.

  • Select “Force HTTPS (requires valid certificates)".
    Click “Save”.

After a few minutes, you will be able to visit your website via HTTPS. You may also want to update the base URL in config.toml.

Renewal

As mentioned earlier, Let's Encrypt certificates expire every 90 days and you will have to renew them periodically. To renew certificates:

sudo certbot renew

Alright, after two months I realized the above renewal just doesn't work. The following error was given:

“Attempting to renew cert (loadbalancing.xyz) from /etc/letsencrypt/renewal/loadbalancing.xyz.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.

The error was: PluginError(‘An authentication script must be provided with –manual-auth-hook when using the manual plugin non-interactively.'). Skipping."

Looks like the only way of renewal is to manually redo the whole procedure, which I don't think is gonna be sustainable. Fortunately, someone else figured out a nice way of auto renewal with GitLab and I will update my experience of trying that in the next post.

Contents