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.
1. Create Certificate Directory
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
2. Generate CA Certificate
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 = nodistinguished_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!
3. Generate Server Certificate
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 = nodistinguished_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.
4. Install CA Certificate on Raspberry Pi
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:
5. Update Nginx Configurations
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
6. Update GitLab Configuration
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:
7.(a) Install Certificate for Client (Windows)
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.
7.(b) Install Certificate for Client (Mac)
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”.
7.(c) Install Certificate for Client (Linux)
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
7.(d) Install Certificate for Client (Android)
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.
7.(x) Install Certificate for Client (Any—Firefox!)
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.
8. Update GitLab Runner (Optional)
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. :)