Installing x509 certificates (SSL/TLS)¶
For some customers, additional requirements on x509 certificates may present itself. In most cases, customers will want to provide their own x509 certificate when using an internal domain.
Below the steps are presented to:
- Generate a x509 signing request for the customer to fulfill
- Importing the signed x509 certificate in the correct location
- Configuring the solution to use these new certificates.
Depending on the configuration, multiple certificates may need to be created and installed to various places.
- Primary endpoints: certificate need to be imported into AWS ACM and the ID in ACM needs to be set.
- Pages without custom domains: wildcard certificate is required, needs to be imported into ACM.
- Pages with custom domains: wildcard certificate is required and needs to be available in the solution folder, ACM is not used at all for pages in this case.
For all cases where ACM is used, the customer may also provide their certificate in ACM directly, and/or you may request a Amazon Issued certificate in ACM as well. You can set these in the same way as described below, just skip the Generate and Import steps.
Generating a x509 signing request¶
In order to securely transmit x509 certificates over email, you need to generate a private key, and use that to generate a CSR, a 'certificate signing request'. The CSR cannot be used to encrypt traffic, so it is safe to transmit over email. The customer can use this CSR to request a x509 certificate. The resulting certificate file is useless without the private key, so the certificate can also safely be transmitted over email.
You should use a actual instance of the solution in question to perform the openssl commands below, do NOT generate
private keys and/or CSR on your local machine! Usage of the gitlab-rails-primary node is preferred. Switch to root
to make sure the material is protected on disk from regular system users.
First: create a folder to perform the operations in, this will keep your materials seperated, and makes it easy to copy/paste the commands below, as they can reuse the same filenames.
mkdir -p /root/tls/2025-primary/
cd /root/tls/2025-primary/
Next, open a text editor and write the following data to openssl.cnf. Modify data where required below:
[req]
# Length of private key
default_bits = 4096
# Signing algorithm of private key
default_md = sha256
# Prevent passwords on key, otherwise it cannot be used in automated ways
encrypt_key = no
# Various recommended options
distinguished_name = dn
prompt = no
req_extensions = req_ext
# This section contains the details that will be set in the CSR.
# Modify as per customer request.
[dn]
C="NL" # Country
ST="Groningen" # State/Province
L="Groningen" # Location: city/town
O="GitLabHost" # Organization name
OU="HA Team" # Organizational Unit, eg: team or departement name
CN="*.pages.glhn.nl" # Common name: the primary DNS name on the certificate
emailAddress="ha@gitlabhost.com" # Email address
# Leave this as-is.
[req_ext]
subjectAltName = @alt_names
[alt_names]
# Note: DNS.0 must always be the same as CN above!
DNS.0 = *.pages.glhn.nl
# Additional names to request can be listed one per line.
# For wildcard certificates, always list the CN without *.`
DNS.1 = pages.glhn.nl
Then: generate a new key and the CSR in one go using this command:
openssl req -config openssl.cnf -keyout private.key -new -out request.csr
You can check if everything is set correctly by using these commands.
Now you can send request.csr to the customer, simply by attaching it to an email. It's recommended you copy (+paste)
the file to your local machine, and (re)name it in the format domain.name.csr, so the customer does not end up with
10 files called request.csr in their downloads folder.
In case the customer gets back to you with issues in the CSR, like a typo made in one of the names, always remove both the private key and the CSR file before generating new ones.
When the customer responds with the certificate and matching chain, continue to the next section.
Importing the x509 certificate into ACM¶
Note: if your certificate is for Pages with custom domains (only), skip to Pages with custom domains.
You should now have three sets of data:
- The private key you generated earlier
- The issued certificate
- One or more public certificates from the signing authority to present in the trust chain.
Go to the correct AWS organization, and go to the AWS Certificate Manager (ACM) service.
Ensure you are in the correct region for your cluster, the Load Balancers must be in the same region as the certificate.
Go to the Import certificate page, and paste your material in the desginated textareas and submit the form.
Your imported details should now show up in the List certificates overview. You can view the DNS names and expiry
date on the certificate by opening a item in the certificate list.
The certificate should have been assigned as UUID + ARN that looks like this:
arn:aws:acm:eu-west-1:946348436774:certificate/35088461-629f-43d6-be09-29bfeb4ee2a2.
Make note of the ARNs of the certificates you want to use.
Configuring the solution for a certificate¶
Certificate in ACM¶
Certificates in ACM can be used for the following components:
- GitLab web interface
- Docker Registry endpoints
- GitLab pages, with custom domains disabled.
Most of these settings can be found in environment.tf if you follow our templates. If you define certificate_arn,
all other *_certificate_arn values will default to that unless overriden, so if you have one cerfificate for
everything, specifying just certificate_arn will be enough.
module "gitlab_cluster" {
certificate_arn = "arn:aws:acm:eu-west-1:946348436774:certificate/35088461-629f-43d6-be09-29bfeb4ee2a2"
domain_name = "git.glhd.nl"
registry_certificate_arn = "arn:aws:acm:eu-west-1:946348436774:certificate/35088461-629f-43d6-be09-29bfeb4ee2a2"
registry_domain_name = "registry.glhn.nl"
pages_certificate_arn = "arn:aws:acm:eu-west-1:946348436774:certificate/35088461-629f-43d6-be09-29bfeb4ee2a2"
pages_domain_name = "pages.glhn.nl"
}
Run terraform apply after setting the changes. Note: the changes will take effect right away, so make sure your chain
is actually valid.
Pages with custom domains¶
If you have Pages with custom domains enabled, the Pages deamons need to parse the TLS traffic internally in order to
provide valid certificates for dynamically provided domain names by users. In this mode, the TLS traffic is not
decrypted by the AWS loadbalancers, so pages_certificate_arn will not have any effect.
In this case, perform the following steps:
- Go to
your_solution/ansibleon your local machine mkdir -p files/tls- Copy the private key to
files/tls/gitlab_pages.key - Copy the certificate file to
files/tls/gitlab_pages.crt. Append the entire PEM chain in the same file as well. - Encrypt the data using
ansible-vault:ansible-vault encrypt files/tls/gitlab_pages.keyansible-vault encrypt files/tls/gitlab_pages.crt
- Configure
inventory/vars.ymlas per the example below. - Run any Ansible Playbook that performs regular tasks on the GitLab Rails node.
Ansible variable config:
all:
vars:
pwd: "{{ lookup('env', 'PWD') }}"
pages_ssl_cert_file: "{{ pwd + '/files/tls/gitlab_pages.crt' }}"
pages_ssl_key_file: "{{ pwd + '/files/tls/gitlab_pages.key' }}"
Viewing contents of x509 and related files¶
You can have OpenSSL present the contents of various x509 and related files in friendly text for, so you can validate if they are correct for what you are trying to do.
View a certificate file:
openssl x509 -noout -text -in certificate.pem
View contents of a CSR:
openssl req -noout -text -in request.csr
View details on a private key:
openssl pkey -noout -text -in private.key