Setting up GitLab with Active Directory Authentication over Kerberos
Tags: gitlab, kerberos, activedirectory, docker
Published: 2019-08-21 14:47:02

This guide explains how to set up GitLab with Docker and enable authentication with Windows Active Directory accounts over a secure Kerberos connection. 


# Index

- [First Things First](#first-things-first)
- [Join the Debian Machine to the Windows Domain](#join-the-debian-machine-to-the-windows-domain)
- [Set the Service Principal Name for GitLab](#set-the-service-principal-name-for-gitlab)
- [Set Up Docker Environment](#set-up-docker-environment)
- [Configure GitLab](#configure-gitlab)
- [NGINX configuration](#nginx-configuration)
- [Git Client Access](#git-client-access)
- [Further Information](#further-information)


# First Things First

Of course, you need a set up and configured domain controller hosting an Active Directory service. In my test case, this was hosted by a Windows Server 2012 R2 instance. Also, you need a Linux based machine for hosting GitLab on. For that, I have used a Debian 10 Buster image.

> All package installation processes will be performed using `apt` in this guide. If you are using a different package manager, adapt these steps for your use case.


# Join the Debian Machine to the Windows Domain

To access the Domain Controller which is hosting the Active Directory service, we need to join the Debian machine to the domain. For that, we are using the Linux tool [`realmd`](https://www.systutorials.com/docs/linux/man/8-realm/).

**1.** Install `realmd` using your package manager:  
```
# apt install realmd -y
```

**2.** Now, check and test if you have network access to the domain using the follwing command:  
```
# realmd discover your.domain.com
```
*Of course, the dummy name `your.domain.com` must be replaced by your domain name.*  

The Result of this should look like follwoing:
```
your.domain.com
  type: kerberos
  real.name: YOUR.DOMAIN.COM
  domain-name: your.domain.com
  configured: no
  server-software: active-directory
  client-software: sssd
  required-packages: sssd-tools
  required-packages: sssd
  required-packages: libnss-sss
  required-packages: libpam-sss
  required-packages: adcli
  required-packages: samba-common-bin
```
   
**3.** Install the packages which are defined as `required-packages` by the output of the last command.  
```
# apt install -y sssd-tools sssd libnss-sss ...
```

**4.** Join the machine to the domain:  
```
# realm join your.domain.com -U 'admin' --install=/' -v
```
*The defined user must be an administrator or a user permitted to join machines to the domain.*

> **ATTENTION**  
> The Linux machine may not automatically create a DNS entry on your domain controller on joining the domain. In this case, you need to manually add the `A` record to your DNS server.


# Set the Service Principal Name for GitLab

You need to set a Service Principal Name (SPN) to your Active Directory machine object in order to allow secure authentication via Kerberos to your web application (GitLab).

For that, open an administrator console on the Domain Controller and use the following command:  

```
> setspn -A HTTP/MachineName.your.domain.com MachineName
```
*Again, you need to replace `MachineName` by the DNS name of your GitLab server and `your.domain.com` with the actual name of your domain.*


# Set Up Docker Environment

> These steps are adopted from the official Docker documentation about installing on Debian.
  - https://docs.docker.com/install/linux/docker-ce/debian
  - https://docs.docker.com/compose/install

**1.** Install the required packages to install and run the Docker packages:  
```
# apt install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg2 \
    software-properties-common
```

**2.** Add Dockers GPG key:  
```
# curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
```

**3.** Add Dockers repository to apt:  
```
# add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/debian \
    $(lsb_release -cs) \
    stable" && apt update
```

**4.** Install Docker packages:  
```
# apt install -y docker-ce docker-ce-cli containerd.io
```

**5.** Install docker-compose:  
```
# curl -L \
    "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" \
    -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
```

**6.** Create a `docker-compose.yml`. 

This file defines how Docker will set up the containers and which parameters to use for them. Furthermore, it creates a virtual network between the containers which is only accessable by them and over exposed ports.

> [Here](https://docs.docker.com/compose) you can read more about docker-compose.

{% gist https://gist.github.com/zekroTJA/a0a1c518dce5c77ce87d6c4d025696e0 file=docker-compose.yml %}


**7.** Pull the images and create the containers:  
```
# docker-compose up -d
```

After that, stop the containers again:

```
# docker-compose stop
```

# Configure GitLab

**1.** Linking the `keytab` file. 

In order to access the Windows Domain securely via Kerberos, the Docker container needs access to the hosts `krb5.keytab` file, which was created on joining the Domain using `realm` located at `/etc/krb5.keytab`.  
This file can either be directly copied into the mounted host directory of `/etc/gitlab/` (in this case `./volumes/gitlab/config/`), or directly mounted as file to the container. 

After that, the container needs read access to the `krb5.keytab` file:

```
# docker exec gitlab chown root /etc/gitlab/krb5.keytab
# docker exec gitlab chmod 0600 /etc/gitlab/krb5.keytab
```

> If you chose to directly mount the file into the container, keep in mind that the file **must** be existent on the host system in order to mount the file and not to create a directory on container startup.

**2.** Open the GitLab configuration file (`./volumes/gitlab/config/gitlab.rb`) and add the folowing lines at the end of the file:  

{% gist https://gist.github.com/zekroTJA/a0a1c518dce5c77ce87d6c4d025696e0 file=gitlab.rb %}

> When you set `omniauth_allow_single_sign_on` to `true`, AD users are able to log in which creates an account and blocks it automatically after. If you disable this, every account must be created in GitLab before and then linked to an AD identifier. Read [this](https://docs.gitlab.com/ee/integration/kerberos.html#linking-kerberos-and-ldap-accounts-together) for further information.

**3.** Run the GitLab reconfiguration command to make your changes effective. Also, this must be done inside the docker container:

```
# docker exec gitlab gitlab-ctl reconfigure
```

**4.** Restart the GitLab container.

Then, there should appear a new authentication method below the internal authentication named `Kerberos Spnego`. This method uses your Windows login ticket as authentication so that you don't need to enter your account credentials. After that, there will be a notice that your account has been blocked. Don't worry, GitLab defaultly creates the account for the AD user and blocks it automatically after. The account must be manually un-blocked by a GitLab administrator.


# NGINX configuration

As defined in the `docker-compose.yml` file, we put the ENGINX web server as an additional layer over the actual GitLab server. That is very useful for managing SSL certificates and configuring further HTTP routing to the GitLab server.

In our case, we are creating a self-singed SSL certificate with the following commands:  
```
# mkdir -p /etc/cert
# openssl req \
     -x509 \
     -newkey rsa:4096 \
     -keyout /etc/cert/key.pem \
     -out /etc/cert/cert.pem \
     -days 365 \
     -nodes
```

> Of course, if you already have a valid certificate, you can use that one instead.

Then, create the NGINX config file in the volume of the container (`./volumes/nginx/config/nginx.cfg`):  

> [Here](https://nginx.org/en/docs/http/ngx_http_core_module.html) you can read the fully detailed documentation about the NGINX configuration:   

{% gist https://gist.github.com/zekroTJA/a0a1c518dce5c77ce87d6c4d025696e0 file=nginx.cfg %}

In order to support Active Directory authentication, we need to increase the size of client header buffers of NGINX by using the `large_client_header_buffers` config key. Read more about this [here](https://docs.gitlab.com/ee/integration/kerberos.html#support-for-active-directory-kerberos-environments).


# Git Client Access

As commonly proceed, you can create a GPG key-pair on your development client and push your public key to your GitLab account to access repositories over SSH. This step bypasses the Kerberos authentication because it is only based on the authentication over the corresponding public key linked to your private key.

Of course, you are also able to clone and access repositories over HTTPS using the Kerberos authentication.

For that, you need to set two configuration values on your Git client:

First, download the GitLab certificate and safe it as base64 encoded X.509 cert file using your browser.

Then, set the file as trusted certificate in your git client config:

```
$ git config --global http.sslCAInfo <PathToTheDownloadedCertFile>
```

Also, if you are using Git v.2.11 or newer and the following error occurs:

```
remote: HTTP Basic: Access denied
fatal: Authentication failed for '<KRB5 path>'
```

Set following configuration to fix this issue:

```
$ git config --global http.emptyAuth true
```

Then, you can use the `Kerberos` link to your repository, e.g. `https://:@MachineName:8443/jd/coolrepo.git`, to access the upstream repository on your client. Also as similar to the web interface login, you don't need to enter your account credentials because the authentication uses the Kerberos ticket system.

If you are using the `HTTPS` link, you may need to enter your AD account credentials because this is a password-based authentication method.


# Further Information

Here you can find further readings and informations I have also used to achive this setup:

- https://docs.gitlab.com/ee/integration/kerberos.html
- https://docs.gitlab.com/omnibus/docker/
- https://4sysops.com/archives/join-a-debian-linux-server-to-an-active-directory-domain/
- https://www.systutorials.com/docs/linux/man/8-realm/
- https://blogs.technet.microsoft.com/pie/2018/01/03/all-you-need-to-know-about-keytab-files/
- https://support.microsoft.com/en-us/help/929650/how-to-use-spns-when-you-configure-web-applications-that-are-hosted-on
- https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc731241(v=ws.11)

### Further information about NGINX 

- https://www.nginx.com/resources/wiki/start
- https://nginx.org/en/docs/http/ngx_http_core_module.html 

### Further information bout Docker and docker-compose

- https://docs.docker.com/
- https://docs.docker.com/compose/
- https://docs.docker.com/compose/compose-file/

---

*GitLab logo used in header image © by GitLab Inc.*
*Microsoft Windows logo used in header © by Microsoft Corporation.*