Commit 320f3423 authored by Nicholas J Anderson's avatar Nicholas J Anderson

Testing blog posting.

parent a58d1e38
Pipeline #2595 passed with stage
in 1 minute and 1 second
---
layout: post
title: "Self-Hosted GitLab Pages"
date: 2018-06-25 20:00:00 -0400
categories: gitlab pages srct
---
No better way to break my way into the world of blogging with GitLab Pages
than with a post about how I set it up.
As a slight introduction, I manage a small-to-medium sized GitLab instance for
[MasonSRCT][srct-home]. I wanted to provide this service to allow students to
easily set up their own homepages under [gmu.io][gmu-io] and to even setup a
custom domain and TLS certificate for their homepage. This site that you're
reading is an implementation of that! In this post, I'll be sharing the
complete administrative setup process as well as a sample user implementation.
[srct-home]: https://srct.gmu.edu/
[gmu-io]: https://www.gmu.io/
## Administrative Guide
To get started, our GitLab instance is an omnibus self-hosted GitLab Community
Edition running on a standard Ubuntu Digital Ocean droplet (c2.r4.d50). Also,
we run our own bind DNS server and have a wildcard domain `gmu.io`.
### The Basics
Getting a basic GitLab Pages implementation is fairly straight-foward following
the [documentation][gitlab-pages-doc].
`/etc/gitlab/gitlab.rb`
{% highlight ruby %}
pages_external_url "http://gmu.io"
gitlab_pages['enable'] = true
{% endhighlight %}
`/var/cache/bind/gmu.io.zone`
```
@ IN A 159.65.244.195
@ IN AAAA 2604:a880:800:a1::cd9:9001
* IN A 159.65.244.195
* IN AAAA 2604:a880:800:a1::cd9:9001
```
This will provide you a standard non-TLS setup. Let's kick this up a notch.
[gitlab-pages-doc]: https://docs.gitlab.com/ee/administration/pages/index.html
### TLS
We can take advantage of Let's Encrypt's new-ish wildcard certificate program.
As of this writing, only the `dns-01` verification worked for these types of
certificates. Additionally, we must utilize the beta Acme v2 protocol servers.
This is easy enough to do with manual verification:
```
certbot certonly --manual -d *.gmu.io -d gmu.io --agree-tos --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
```
Then update your bind zone to contain the challenge that given from the above
command:
```
_acme-challenge.gmu.io. IN TXT "xxxx_xxxxxxxxxxxxxxx_xxxxxxxxx"
```
But I'm lazy and don't want to have to worry about this 4 times a year, so
let's try to see if we can automate this!
Certbot offers a variety of [DNS Plugins][certbot-dns-plugins] to help automate
the `dns-01` veriification method. In my case, I utilized the `rfc2136` plugin
since I was using a self-hosted Bind server.
#### Bind Configuration
[RFC2136][ietf-rfc2136] is, to quote the RFC, "Dynamic Updates in the Domain
Name System". Your standard bind server implements the protocol, so now we just
need to configure it.
To start, from your bind server, you will need to create the symmetric shared
key that will be used to authenticate our RFC2136 client to the bind server.
Run the following command:
```
dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST -r /dev/urandom gmu.io.
```
This will drop two files in your current working directory named something like
`Kgmu.io.+123+456789.key` and `Kgmu.io.+123+456789.private`. Despite the naming,
we generated a symmetric key, so both files contain the same key, just in
different formats.
Inspect the contents of the `.key` file, and you'll find something like:
```
gmu.io. IN KEY 512 3 165 pEx3VSFcEUdLCu8JQKtr7crpuvA3lFvhnEupdxAcg0Y5i24mtXKAkZNJ xTZeKf6W1E3PYZ4vX+hi5pBNCe4V+A==
```
We're interested in the last two sections:
```
pEx3VSFcEUdLCu8JQKtr7crpuvA3lFvhnEupdxAcg0Y5i24mtXKAkZNJ xTZeKf6W1E3PYZ4vX+hi5pBNCe4V+A==
```
Next, we'll need to modify our Bind config to add our key and grant permissions
to updates from our key.
`/etc/bind/named.conf.local`
```
key "gmu.io." {
algorithm hmac-sha512;
secret "pEx3VSFcEUdLCu8JQKtr7crpuvA3lFvhnEupdxAcg0Y5i24mtXKAkZNJ xTZeKf6W1E3PYZ4vX+hi5pBNCe4V+A==";
};
zone "gmu.io" IN {
type master;
file "/var/cache/bind/gmu.io.zone.signed";
// Push updates to our slave nameserver
notify yes;
also-notify { 159.65.244.195; };
// Allow transfer to our slave nameserver
allow-transfer { 159.65.244.195; };
allow-update { key gmu.io.; };
};
```
The `allow-update` config I used in this example is fairly permissive. Ideally,
you would further lock it down to just the operations certbot needs, such as:
```
allow-update { key gmu.io. name _acme-challenge.example.com. txt; };
```
#### Certbot Configuration
The official documentation suggests using the provided Docker containers for
running the verification. Unfortuantely, I ran into a few quirks throughout
the process.
First note, `--dry-run` is not compatible with `--server https://acme-v02.api.letsencrypt.org/directory`,
and the standard server will reject wildcart certificate requests.
... To be continued...
[ietf-rfc2136]: https://tools.ietf.org/html/rfc2136
[certbot-dns-plugins]: https://certbot.eff.org/docs/using.html#dns-plugins
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment