Gitlab in Production – Part 4: Gitlab Installation

Welcome to part 4 of my Gitlab series – in this part you’ll see how Gitlab can be installed and how you do the initial configuration.

Note: this part is still work in progress so let me know if I need to be more elaborate with my explanations

Gitlab Installation

The gitlab installation manual recommends using their Omnibus packages for the setup:

We recommend installing the Omnibus package instead of installing GitLab from source. Omnibus GitLab takes just 2 minutes to install and is packaged in the popular deb and rpm formats. Compared to an installation from source, the Omnibus package is faster to install and upgrade, more reliable to upgrade and maintain, and it shortens the response time for our subscribers’ issues. A package contains GitLab and all its depencies (Ruby, PostgreSQL, Redis, Nginx, Unicorn, etc.), it can be installed without an internet connection. For troubleshooting and configuration options please see the Omnibus GitLab readme.

In addition to the Omnibus packages they provide bash scripts that take care of everything for you (chef, puppet and bundler configurations are available as well) and that’s what we’re going to use. In our case, since we’re using Debian, we run the deb installation script like this:

curl | sudo bash

What’s happening behind the scenes is this:

  • Detect OS (and its version)
  • Install required packages for the actual Gitlab installation
  • Add Gitlab Package Repositories to /etc/apt/sources.list.d/
  • Add PGP Keys for Gitlab Package Repositories

It adds the following packages…

apt-get install -q -y curl
apt-get install -y debian-archive-keyring &> /dev/null
apt-get install -y apt-transport-https

… then adds the Gitlab Repositories…

ladmin@srvapp037:~/scripts$ cat /etc/apt/sources.list.d/gitlab_gitlab-ce.list
# this file was generated by for
# the repository at

deb jessie main
deb-src jessie main

… and finally installs the GPG key:

curl 2> /dev/null | apt-key add - &>/dev/null

So now that we’ve run the script which has taken care of all the prerequisites for us we can finally install Gitlab CE:

sudo apt-get update
sudo apt-get install gitlab-ce

It’ll take a bit and you’ll see the output from their chef recipes before it shows you that all Gitlab services have been started.

Gitlab Configuration

SSL Configuration

I’ve created a SHA2 certificate for the Gitlab web server with the SAN field (Subject Alternative Name) containing the alias name of the server name that we’re going to use from now on.

common name: srvapp037.mydomain.internal
SAN: srvapp037, git, git.mydomain.internal

Next we create the certificate folder on our git server, apply proper permissions and place our certificates in there:

sudo mkdir /etc/gitlab/ssl
sudo chmod 700 /etc/gitlab/ssl
sudo vim /etc/gitlab/ssl/git.mydomain.internal.crt
sudo vim /etc/gitlab/ssl/git.mydomain.internal.key

Note: I’ve pasted the certificate contents from the clipboard, that’s why I’m using vim here

After copying my new cert to the server I have to configure our Gitlab webserver by editing the Gitlab configuration file /etc/gitlab/gitlab.rb:

The most important line here is

nginx['ssl_ciphers'] = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"

It contains two cipher suites that make use of elliptic curve key exchanges. These are TLS 1.2 only which is fine since we don’t have to ensure backwards compatibility (IE10 doesn’t support TLS 1.2 but isn’t supported anymore anyway).

Then restart Gitlab with:

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart

So far so good, right? Nope, nginx doesn’t start – browsing to https://git.mydomain.internal gives me a server error message. So what’s the problem?

Well, it turns out that nginx doesn’t know how to deal with the passphrase on my certificate key. You can see that by looking at the nginx logs under /var/log/gitlab/nginx/:

ladmin@srvapp037:~$ sudo grep –iR "error" /var/log/gitlab/nginx/
2015/11/03 17:38:04 [emerg] 21995#0: SSL_CTX_use_PrivateKey_file("/etc/gitlab/ssl/git.mydomain.internal.key") failed (SSL: error:0906406D:PEM routines:PEM_def_callback:problems getting password error:0906A068:PEM routines:PEM_do_header:bad password read error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib)

You can remove the passphrase from the key with OpenSSL like this:

sudo openssl rsa -in /etc/gitlab/ssl/git.mydomain.internal.key -out /etc/gitlab/ssl/git.mydomain.internal.nocrypt.key

Since we now have a key file without passphrase we need to change one line in the gitlab nginx configuration as follows:

# old:
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/git.mydomain.internal.key"
# new:
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/git.mydomain.internal.nocrypt.key"

LDAP Authentication

Note: we’re in the process of setting up a PKI which is why we still connect via LDAP (TCP\389) instead of LDAPS (TCP\636) – the required steps for LDAPS will be added once the PKI is in place.

Again we edit our global Gitlab configuration file /etc/gitlab/gitlab.rb:

I believe that is fairly self-explanatory but I’ll cover the settings really quick anyway. The easiest way to get the bind_dn path is to use PowerShell with the Active Directory module:

Import-Module ActiveDirectory
Get-AdUser -Identity <ldap-service-account-samaccountname>

Base – will be used as searchbase to find your LDAP users
active_directory: true – just means that the LDAP server is a Microsoft AD
allow_username_or_email_login: false – we want users to login with their samaccountname and not their email address so we disable this
block_auto_created_users: true – if an LDAP user authenticates against Gitlab for the first time it is imported into Gitlab but needs to be unblocked by a Gitlab administrator before the user can actually log in

So now that this is in place we can apply the configuration by running

sudo gitlab-ctl reconfigure

SMTP Configuration

In our case the SMTP configuration is fairly simple:

I enable SMTP, specify our internal relay with its SMTP port and domain and don’t use authentication (Note: I know but the Gitlab server and relay are on the management network that has additional security measures in place). As you can see I set the Reply-To field to my public email address so that I can respond to accidental replies to Gitlab emails.

Verify Webserver Security

In order to verify that the webserver is secure I use the testssl shell script from Just download the archive and extract it:



What we have now is a fully usable Gitlab Server. In the next part I’m going to cover sensible user defaults and the steps to configure your git client for use with our server.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s