Using Let's Encrypt to add SSL to GitLab
I just used Let’s Encrypt to set up SSL on my personal GitLab site, and wanted to record a few notes about the process, in case it helps anybody else.
Background
I installed GitLab from source (before the Omnibus installer), and have been running it in http-only mode for a while now. I host it myself, on Linode. (Full-disclosure: That’s a referral link.)
I really like self-hosting Gitlab, because I can have as many private repositories as I want, and have full control over the site and backups etc. And, I’m just starting to set up GitLab CI Runners, which I think will be very useful too. Importantly, I’ve found that maintainence has been pretty painless. GitLab has frequent releases, but a well-document upgrade process, which have always gone smoothly.
I pieced together these instructions from a few places, including the Let’s Encrypt - Getting Started documentation, the GitLab Instalation instructions, and this older blog post, which was outdated mostly with the GitLab details.
Overview
The main trick was that GitLab runs behind nginx, and letsencrypt
doesn’t automatically
support nginx
yet, so I did the certificate request using the standalone
mode. I didn’t set
it up for auto-refresh (but did create a calendar reminder to myself to refresh it before it
expires).
The other gotcha was with making the certs readable to the gitlab-shell
process. See notes
below.
Steps
All of the follow commands are run from the admin user at my Linode instance, so login there first:
$ ssh admin@mylinode
Start by getting the letsencrypt
repo.
$ cd ~
$ git clone https://github.com/letsencrypt/letsencrypt
Set up a config file for running letsencrypt-auto
.
$ mkdir letsencrypt-config
$ vim letsencrypt-config/gitlab.ini
gitlab.ini
:
# This is the Let's Encrypt config for our gitlab instance
authenticator = standalone
# Generate certificates for the specified domains.
domains = gitlab.example.com
# Register certs with the following email address
email = me@example.com
# Use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096
I found it simplest to just temporarily stop nginx and use the standalone
mode of
letsencrypt-auto
(which we specified in the config file).
$ sudo service nginx stop
$ sudo mkdir /var/www/letsencrypt
$ sudo letsencrypt/letsencrypt-auto certonly -c letsencrypt-config/gitlab.ini
If it goes well, it should show output like:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/gitlab.example.com/fullchain.pem. Your cert will
expire on 2016-06-18. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.
Put nginx back to normal:
$ sudo service nginx start
Update GitLab to use SSL
Make a copy of the certs into a new dir, specific for GitLab (see the Pitfall below for more info about why).
$ sudo mkdir -p /etc/gitlab/ssl
$ sudo cp /etc/letsencrypt/live/gitlab.example.com/{cert,chain,fullchain,privkey}.pem /etc/gitlab/ssl/.
$ sudo chown -R git:git /etc/gitlab
$ sudo chmod -R 700 /etc/gitlab
$ sudo chmod 600 /etc/gitlab/ssl/{cert,chain,fullchain,privkey}.pem
Now, update the GitLab config files.
$ cd /home/git/gitlab
$ sudo -u git -H vim config/gitlab.yml
# Set `port: 443` and `https: true`
$ sudo -u git -H vim ../gitlab-shell/config.yml
# set `gitlab_url` to have `https`, and add:
http_settings:
ca_file: "/etc/gitlab/ssl/fullchain.pem"
ca_path: "/etc/gitlab/ssl"
Finally, update the nginx
config to the SSL version.
# Use the SSL version of the nginx config
$ sudo cp lib/support/nginx/gitlab-ssl /etc/nginx/sites-available/.
$ sudo vim /etc/nginx/sites-available/gitlab-ssl
# Change the FQDN to gitlab.example.com (in 2 places)
# Uptate these:
ssl_certificate /etc/letsencrypt/live/gitlab.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gitlab.example.com/privkey.pem;
$ sudo ln -s /etc/nginx/sites-available/gitlab-ssl /etc/nginx/sites-enabled/gitlab-ssl
# Turn off the old non-SSL nginx config
$ sudo rm /etc/nginx/sites-enabled/gitlab
# Test and restart nginx
$ sudo nginx -t
$ sudo service nginx restart
Optional: Stronger Diffie-Hellman Parameters
From the “more is better” department, we might as well generate stronger Diffie-Hellman parameters while we’re in here.
To do that, just run:
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
It says “This is going to take a long time”, and for the 4096
size, it took about 10 minutes on my
Linode server. Just be patient.
Then un-comment the line in the nginx.conf
that has:
ssl_dhparam /etc/ssl/certs/dhparam.pem;
and restart nginx again.
Done
Now you should be able to visit https://gitlab.example.com and see your GitLab site over SSL.
Update 2016-04-23
A helpful reader, Michel Nemnom, pointed out that I should test my
server with SSL Labs’ awesome SSL Server Test. My
original instructions here had the nginx.conf
pointing the ssl_certificate
at cert.pem
, which
caused the SSL Labs test to give me a grade of only B (because “This server’s certificate chain is
incomplete”). But, simply changing that value to be the fullchain.pem
, it now gives me a grade of
A+. Much better! I’ve already
updated this in the instructions above.
Michel also recommended generating stronger Diffie-Hellman parameters, which prompted the section about that above.