Part 7 - Configuring SSL/HTTPs for GitLab

This is the seventh post in the series of how to host your own git server on a Raspberry Pi

You have successfully set a Reverse Proxy in the previous post. We will now take a look into configuring SSL to secure our connections to GitLab through HTTPs.

In order to establish secure connections, the first thing we need is a security certificate. Since we are using our Raspberry Pi on our local network, we are going to create and use our own security certificates.

Create a directory on Raspberry Pi for your certificates:

sudo mkdir /var/cert

Get read/write access to this certificate folder:

sudo chmod 777 /var/cert

We will start by creating a CA (Certification Authority) certificate, which will be our root certificate. Create a configuration file <CA-CONFIG>.cnf and include the following:

[req]
default_bits = 2048
encrypt_key = no
default_md = sha256
utf8 = yes
prompt = no
distinguished_name = names
x509_extensions = extensions
[names]
countryName = <COUNTRY>
stateOrProvinceName = <STATE>
localityName = <CITY>
organizationName = <COMPANY>
organizationalUnitName = <DEPARTMENT>
commonName = <CA_CERTIFICATE_NAME>
emailAddress = <EMAIL>
[extensions]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
keyUsage = digitalSignature, keyEncipherment, cRLSign, keyCertSign
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = @domains
[domains]
DNS.1 = <HOSTNAME>.<DOMAIN>
DNS.2 = *.<HOSTNAME>.<DOMAIN>

Create an RSA key for your CA certificate:

openssl genrsa -out <CA-CERTIFICATE>.key 2048

And finally, create your CA certificate:

openssl req -new -x509 -key <CA-CERTIFICATE>.key -out <CA-CERTIFICATE>.crt -days <EXPIRATION-TIME> -config <CA-CONFIG>.cnf

You should specify an expiration time (-days) less than or equal to 825 days to be compatible with most devices!

Next step is to create a certificate for your server signed by you CA certificate. Create a configuration file <SERVER-CONFIG>.cnf and add the following:

[req]
default_bits = 2048
encrypt_key = no
default_md = sha256
utf8 = yes
prompt = no
distinguished_name = names[names]
countryName = <COUNTRY>
stateOrProvinceName = <STATE>
localityName = <CITY>
organizationName = <COMPANY>
organizationalUnitName = <DEPARTMENT>
commonName = <SERVER_CERTIFICATE_NAME>
emailAddress = <EMAIL>
[extensions]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = @domains
[domains]
DNS.1 = <HOSTNAME>.<DOMAIN>
DNS.2 = *.<HOSTNAME>.<DOMAIN>

Create an RSA key for your server certificate:

openssl genrsa -out <SERVER-CERTIFICATE>.key 2048

Create a certificate signing request:

openssl req -new -key <SERVER-CERTIFICATE>.key -out <SERVER-CERTIFICATE>.csr -config <SERVER_CONFIG>.cnf

Using your signing request, create the server certificate:

openssl x509 -req -days <EXPIRATION-TIME> -in <SERVER-CERTIFICATE>.csr -CA <CA-CERTIFICATE>.crt -CAkey <CA-CERTIFICATE>.key -CAcreateserial -extfile <SERVER_CONFIG>.cnf -extensions extensions -out <SERVER-CERTIFICATE>.crt

You should now have a <CA-CERTIFICATE>.crt and <SERVER-CERTIFICATE>.crt ready to install on your systems.

Next step is to add the CA certificate to trusted certificate authorities in the Raspberry Pi. Start by creating a directory under /usr/share folder for self-signed certificates:

sudo mkdir /usr/share/ca-certificates/self

Copy the certificate into this folder:

sudo cp /var/cert/<CA-CERTIFICATE>.crt /usr/share/ca-certificates/self/

You can then run the following to reconfigure your certificates:

sudo dpkg-reconfigure ca-certificates

This will scan for new certificates on , and prompt the following:

Once you say yes, you will see a list that covers all security certificates on this device. Scroll all the way down to see the certificate you have added. Make sure that it is selected, then proceed.

You will see that the terminal will prompt that a security certificate is added:

Now that our CA certificate is added, we will then update all connections specified in Nginx configurations to use our server certificate through HTTPs (and the associated port 443).

Update your configurations as follows:

sudo nano /etc/nginx/sites-enabled/home

server {
listen 80;
listen [::]:80;
server_name <HOSTNAME>.<DOMAIN>;

return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
listen [::]:443 ssl;
server_name <HOSTNAME>.<DOMAIN>;

ssl_certificate /var/cert/<SERVER-CERTIFICATE>.crt;
ssl_certificate_key /var/cert/<SERVER-CERTIFICATE>.key;

root /var/www/home;
index index.html;
}

sudo nano /etc/nginx/sites-enabled/hello

server {
listen 80;
listen [::]:80;
server_name hello.<HOSTNAME>.<DOMAIN>;

return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
listen [::]:443 ssl;
server_name hello.<HOSTNAME>.<DOMAIN>;

ssl_certificate /var/cert/<SERVER-CERTIFICATE>.crt;
ssl_certificate_key /var/cert/<SERVER-CERTIFICATE>.key;

root /var/www/hello;
index index.html;
}

sudo nano /etc/nginx/sites-enabled/404

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;

return 301 https://$host$request_uri;
}

server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;

ssl_certificate /var/cert/<SERVER-CERTIFICATE>.crt;
ssl_certificate_key /var/cert/<SERVER-CERTIFICATE>.key;

root /var/www/404;
location / {
try_files $uri $uri/ =404;
}
}

sudo nano /etc/nginx/sites-enabled/gitlab

upstream gitlab-workhorse {
server unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket;
}
server {
listen 80;
listen [::]:80;
server_name git.<HOSTNAME>.<DOMAIN>;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name git.<HOSTNAME>.<DOMAIN>;
server_tokens off;
ssl_certificate /var/cert/<SERVER-CERTIFICATE>.crt;
ssl_certificate_key /var/cert/<SERVER-CERTIFICATE>.key;
access_log /var/log/nginx/gitlab_access.log;
error_log /var/log/nginx/gitlab_error.log;
root /opt/gitlab/embedded/service/gitlab-rails/public;
location / {
client_max_body_size 0;
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://gitlab-workhorse;
}
}

Restart Nginx to finish configuration updates:

sudo systemctl restart nginx

We will also need to update the links in GitLab configuration file to use secure connection. Open the configuration file with the following:

sudo nano /etc/gitlab/gitlab.rb

Make sure the following fields are enabled, and using HTTPs:

external_url 'https://git.<HOSTNAME>.<DOMAIN>'
gitlab_rails['internal_api_url'] = 'https://git.<HOSTNAME>.<DOMAIN>'

Reconfigure GitLab to finish the changes:

sudo gitlab-ctl reconfigure

At this point, if you try to access GitLab through the secure HTTP link, https://git.<HOSTNAME>.<DOMAIN> you will see that your browser will display this warning:

This is because while we have installed the newly created certificates on the Raspberry Pi, we haven’t installed them on the device we are using to access GitLab through the browser.

Depending on the type of your device, you may follow the ways below:

Transfer the newly created certificate file to your windows device. Double clicking on the certificate file and selecting Install Certificate will open up the Certificate Import Wizard.

Store Location — Local Machine

Certificate Store — Browse

Select Trusted Root Certification Authorities.

Following the remaining steps will install the certificate to your Windows device.

Transfer the newly created CA certificate file to your Mac OSX device.

Navigate to Finder > Applications > Utilities > Keychain Access and import the certificate files into the System keychain.

Double click the security certificate and change the setting to “Always Trust”.

Transfer the newly created CA certificate file to your Linux device.

sudo mkdir /usr/share/ca-certificates/self

sudo cp <CA-CERTIFICATE>.crt /usr/share/ca-certificates/self/

sudo dpkg-reconfigure ca-certificates

Transfer the newly created CA certificate onto your Android device. Double clicking on this file will open up the certificate install pop-up.

Name your certificate, then select Used for - VPN and apps option.

Android will confirm the CA certificate is successfully installed.

I should also point out that Firefox browser does not use the CA certificates from the host machine, but rather uses its own copy for “additional security”.

If you plan to access your pages hosted on Raspberry Pi through Firefox browser, you need to go to developer settings (about:config) and set security.enterprise_roots.enabled to true.

After restarting the browser, Firefox should start displaying your page without any warnings.

In post 5 we have configured a runner for Continuous Integration on our projects. Since we have enabled HTTPs in our links, the Coordinator URL has to be changed in this runner. Register the runner again by following the following command:

sudo gitlab-runner register

You can verify if the runner is running with following:

sudo gitlab-runner status

Congratulations — You have added SSL support to your services and now support HTTPs access to your pages! Our final chapter is going to talk about bringing everything you set up together, creating a git project automatically building, and deploying web pages.

You can follow my future articles on building Internet of Things devices and general chat regarding to life at Google at Baking Pi — An IoT Blog. :)

Systems Engineer, specialized in building Internet of Things (IoT) devices and applications. Harvesting crops at Google. 💻

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store