Accept a self-signed certificate with git.

Intro

Some time ago I came into an issue where people served git repositories in a local network using apache but used a self-signed certificate for the server.

Everyone was already trained to add the exception in their browsers to access HTML content but what happened when it came to source code control?

The Problem

It turns out Subversion (SVN) presented no issue since it prompted the user to accept the new server key just once and then didn't pester them again but git was another story. Git tried to verify that the cert was signed by a proper authority and couldn't.

user@user-linux:git$ git clone https://user@dev-server-01/git/repo_name.git 
Cloning into 'repo_name'...
fatal: unable to access 'https://user@dev-server-01/git/repo_name.git/': server certificate verification failed. 
CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none

The Solution

After some googling I came across suggestions to disable SSL verification with git config http.sslVerify "false" but that looked like it could induce some bad habits and it actually wouldn't prevent tampering if, for instance, the user was pointed elsewhere instead of the proper original server.

That's when Stack Overflow came into play and I found about this neat solution where you can associate a hostname with a given certificate that you store locally.

Steps:

1- Download the self signed certificate from the server and store it somewhere like /etc/ssl/certs

/etc/ssl/certs/ssl-cert-dev-01.pem
/etc/ssl/certs/ssl-cert-dev-02.pem

2- Modify your git config (globally or per-repository) to associate hosts with certs:

(From git config --help)

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.

In this case we're going to do it globally by modifying ~/.gitconfig

[http "https://dev-server-01:/"]
    sslCAInfo = /etc/ssl/certs/ssl-cert-dev-01.pem

[http "https://dev-server-02"]
    sslCAInfo = /etc/ssl/certs/ssl-cert-dev-02.pem

Or you can do it with the command line:

$ git config --global http."https://dev-server-01/".sslCAInfo /etc/ssl/certs/ssl-cert-dev-01.pem
$ git config --global http."https://dev-server-02/".sslCAInfo /etc/ssl/certs/ssl-cert-dev-02.pem

Of course, this breaks the flow of those who were using HTTP and the IP address directly since you need the same name that appears in the certificate. That's the one con I can think of and, if your users where not in the habit of doing so, you'll better start getting them used to it.

Cheers


Was this helpful? Do you do it another way? All comments are welcome!

Comments !

links

social