Reputation: 136972
I have a project with a dependency that gets pulled in from a self-hosted GitLab server over HTTP, e.g.:
{
"name": "Project",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"some-dependency": "git+http://user:[email protected]/group/project.git"
}
}
The GitLab server's SSL certificate is signed by an internal certificate authority connected to the company's Active Directory infrastructure. On domain machines, Chrome and Microsoft Edge automatically trust it via policy.
Git does not:
fatal: unable to access 'https://server.tld/group/project.git': server certificate verification failed.
On Windows, I can use the Schannel SSL back-end to make Git trust certificates signed by the internal CA:
git config --global http.sslBackend schannel
Since the schannel
SSL back-end is only available on Windows, that isn't an option for my tests running in a Docker runner on GitLab CI.
How can I install the project's dependencies on GitLab CI without completely disabling certificate checking?
Edit: I do not have admin access to the shared runners I'm using so I cannot install trusted SSL certs on them directly.
Upvotes: -2
Views: 1063
Reputation: 136972
It is important to verify that the certificate is genuine. Since Chrome already trusts the certificate via policy, we can safely retrieve the certificate from Chrome:
server-name.crt
server-cert.crt
should contain something like
-----BEGIN CERTIFICATE-----
MIIJKoHjzstDxgmHL2j/LQ46PHAbnVYz/JlflAQl3AAjoy9VdtY1hkiG9otrEQmF
...
tMn95/0eWw3lqeduiv5ux982PpepGY3aozPyTzt/1P==
-----END CERTIFICATE-----
If you prefer to retrieve the cert another way, e.g. via the openssl
CLI tool, make sure to check its fingerprint against a reliable source. You can view the downloaded certificate's fingerprint like so:
openssl x509 -in server-cert.crt -noout -fingerprint
If you need another type of fingerprint you can request one, e.g. by adding an argument like -sha256
.
Now that we have a copy of the certificate we need to make Git aware of it during CI jobs. There are at least two options.
Git has a setting for this:
http.sslCAInfo
File containing the certificates to verify the peer with when fetching or pushing over HTTPS. Can be overridden by the
GIT_SSL_CAINFO
environment variable.
Add a CI variable to the project:
GIT_SSL_CAINFO
(the environment variable Git will look for)server-name.crt
into the Value fieldDuring jobs, GitLab CI will now create a temporary file, put the text of the certificate into that file, and set the GIT_SSL_CAINFO
environment variable to the file's path. Git will pick it up automatically.
This has the benefit of (probably) not requiring any code changes. Your existing GitLab CI job should "just work". This means you should be able to set the variable at the group level in case you have multiple projects that are affected.
I'll show one way to do this with a Debian- or Ubuntu-based image. Alpine, Fedora, etc. images may require a few tweaks.
Create a file variable as shown in the first part of Option 1 above, but give it a different Key. I'll use TRUSTED_CERTS
here.
Update your gitlab-ci.yml
to pull the cert into the OS-level certificate store. One way to do that is shown here:
default:
before_script:
# Add certificates contained in $TRUSTED_CERTS to OS-level certificate store
- >
[ -f "$TRUSTED_CERTS" ] &&
ln -s "$TRUSTED_CERTS" /usr/local/share/ca-certificates/trusted.crt &&
update-ca-certificates
- yarn install # Installing dependencies should work now
If $TRUSTED_CERTS
is set, this creates a symlink to that file in /usr/local/share/ca-certificates/
and then runs update-ca-certificates
to update the OS-level certificate store.
This option should make most tools trust the certificate at the expense of some additional complexity in the CI job.
Since the gitlab-ci.yml
file must be modified, it also can't be implemented at the group level as easily. A custom Docker base image that includes updated certificates could mitigate that.
Upvotes: 1