241

The sysadmin for a project I'm on has decided that SSH is "too much trouble"; instead, he has set up Git to be accessible via an https:// URL (and username/password authentication). The server for this URL presents a self-signed certificate, so he advised everyone to turn off certificate validation. This does not strike me as a good setup, security-wise.

Is it possible to tell Git that for remote X (or better, any remote in any repository that happens to begin with https://$SERVERNAME/) it is to accept a particular certificate, and only that certificate? Basically reduplicate SSH's server-key behavior.

5
  • You are asking about C Git on Unix, i presume? Commented Jan 31, 2012 at 0:30
  • Yah. Well, conceivably also Windows, but nobody's doing that right now. Commented Jan 31, 2012 at 1:06
  • 6
    WTF? @Zack you are absolute right about the certificate checks. When your admin says you should turn off certificate checks, he can also turn off TLS on the server, since then every one is disabling the protection against a man-in-the-middle attack. Commented Feb 6, 2012 at 12:17
  • @Rudi, is this still the case if they use an IP address to access the server? (It seems the DNS lookup is how MITM gets inbetween so I think IP address should be immune to this.) Commented Oct 17, 2014 at 10:54
  • 6
    @Chris Yes, it is still the case. A MITM router can pretend to be any IP address they want. (You know those interstitial pages you get on the free wifi in the airport? Those are MITMs. Try accessing a page by IP address sometime.) Commented Oct 17, 2014 at 13:38

2 Answers 2

436

Briefly:

  1. Get the self signed certificate
  2. Put it into some (e.g. ~/git-certs/cert.pem) file
  3. Set git to trust this certificate using http.sslCAInfo parameter

In more details:

Get self signed certificate of remote server

Assuming, the server URL is repos.sample.com and you want to access it over port 443.

There are multiple options, how to get it.

Get certificate using openssl

$ openssl s_client -connect repos.sample.com:443 

Catch the output into a file cert.pem and delete all but part between (and including) -BEGIN CERTIFICATE- and -END CERTIFICATE-

Content of resulting file ~/git-certs/cert.pem may look like this:

-----BEGIN CERTIFICATE----- MIIDnzCCAocCBE/xnXAwDQYJKoZIhvcNAQEFBQAwgZMxCzAJBgNVBAYTAkRFMRUw EwYDVQQIEwxMb3dlciBTYXhvbnkxEjAQBgNVBAcTCVdvbGZzYnVyZzEYMBYGA1UE ChMPU2FhUy1TZWN1cmUuY29tMRowGAYDVQQDFBEqLnNhYXMtc2VjdXJlLmNvbTEj MCEGCSqGSIb3DQEJARYUaW5mb0BzYWFzLXNlY3VyZS5jb20wHhcNMTIwNzAyMTMw OTA0WhcNMTMwNzAyMTMwOTA0WjCBkzELMAkGA1UEBhMCREUxFTATBgNVBAgTDExv d2VyIFNheG9ueTESMBAGA1UEBxMJV29sZnNidXJnMRgwFgYDVQQKEw9TYWFTLVNl Y3VyZS5jb20xGjAYBgNVBAMUESouc2Fhcy1zZWN1cmUuY29tMSMwIQYJKoZIhvcN AQkBFhRpbmZvQHNhYXMtc2VjdXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAMUZ472W3EVFYGSHTgFV0LR2YVE1U//sZimhCKGFBhH3ZfGwqtu7 mzOhlCQef9nqGxgH+U5DG43B6MxDzhoP7R8e1GLbNH3xVqMHqEdcek8jtiJvfj2a pRSkFTCVJ9i0GYFOQfQYV6RJ4vAunQioiw07OmsxL6C5l3K/r+qJTlStpPK5dv4z Sy+jmAcQMaIcWv8wgBAxdzo8UVwIL63gLlBz7WfSB2Ti5XBbse/83wyNa5bPJPf1 U+7uLSofz+dehHtgtKfHD8XpPoQBt0Y9ExbLN1ysdR9XfsNfBI5K6Uokq/tVDxNi SHM4/7uKNo/4b7OP24hvCeXW8oRyRzpyDxMCAwEAATANBgkqhkiG9w0BAQUFAAOC AQEAp7S/E1ZGCey5Oyn3qwP4q+geQqOhRtaPqdH6ABnqUYHcGYB77GcStQxnqnOZ MJwIaIZqlz+59taB6U2lG30u3cZ1FITuz+fWXdfELKPWPjDoHkwumkz3zcCVrrtI ktRzk7AeazHcLEwkUjB5Rm75N9+dOo6Ay89JCcPKb+tNqOszY10y6U3kX3uiSzrJ ejSq/tRyvMFT1FlJ8tKoZBWbkThevMhx7jk5qsoCpLPmPoYCEoLEtpMYiQnDZgUc TNoL1GjoDrjgmSen4QN5QZEGTOe/dsv1sGxWC+Tv/VwUl2GqVtKPZdKtGFqI8TLn /27/jIdVQIKvHok2P/u9tvTUQA== -----END CERTIFICATE----- 

Get certificate using your web browser

I use Redmine with Git repositories and I access the same URL for web UI and for git command line access. This way, I had to add exception for that domain into my web browser.

Using Firefox, I went to Options -> Advanced -> Certificates -> View Certificates -> Servers, found there the self-signed host, selected it and using Export button I got exactly the same file, as created using openssl.

Note: I was a bit surprised, there is no name of the authority visibly mentioned. This is fine.

Having the trusted certificate in dedicated file

Previous steps shall result in having the certificate in some file. It does not matter, what file it is as long as it is visible to your git when accessing that domain. I used ~/git-certs/cert.pem

Note: If you need more trusted self-signed certificates, put them into the same file:

-----BEGIN CERTIFICATE----- MIIDnzCCAocCBE/xnXAwDQYJKoZIhvcNAQEFBQAwgZMxCzAJBgNVBAYTAkRFMRUw ........... /27/jIdVQIKvHok2P/u9tvTUQA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- AnOtHeRtRuStEdCeRtIfIcAtEgOeShErExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxw ........... /27/jIdVQIKvHok2P/u9tvTUQA== -----END CERTIFICATE----- 

This should work (but I tested it only with single certificate).

Configure git to trust this certificate

$ git config --global http.sslCAInfo /home/javl/git-certs/cert.pem 

You may also try to do that system wide, using --system instead of --global.

Test it. You should now be able to communicate with your server without resorting to:

$ git config --global http.sslVerify false # NO NEED TO USE THIS 

If you already set your git to ignore ssl certificates, unset that:

$ git config --global --unset http.sslVerify 

You may also check that you did it all correctly, without spelling errors:

$ git config --global --list 

That should list all variables, you have set globally.

If you wish the certificate file to only be used for a specific server URL, you can edit the ~/.gitconfig file and move the sslCAInfo parameter from the generic [http] section to a URL-matching section [http "https://your.server.here/"]. You can accomplish this all with one command:

$ git config --global http."https://your.server.here/".sslCAInfo /home/javl/git-certs/cert.pem 
Sign up to request clarification or add additional context in comments.

15 Comments

i think that this answer is more correct and complete than the accepted one. thank you @Jan Vlcinsky
@MichaelIvko solution that takes into account 'usual authority-signed certificates' descried here (you need to add your certificate to 'curl-ca-bundle.crt' file): blogs.msdn.com/b/phkelley/archive/2014/01/20/…
The problem with this approach is that it effectively removes all the default CAs that come with git (eg after doing this, you won't be able to pull from github). Most likely that's not what most are looking for. A better example is to add the new root CA to a copy of Git\bin\curl-ca-bundle.crt, and then reference the new copy of curl-ca-bundle.crt from your gitconfig.
it does work on windows! export every cert in the certificate-chain as Base64 coded X.509 file (.CER) Put all the files together and reference this file. Be sure that you don't have spaces in the path to the cert file (use oldschool paths)
To not disable all default/system CAs for all domains but only for this one domain use instead: git config --global http."https://repos.sample.com".sslCAInfo /home/javl/git-certs/cert.pem and if there are any http urls that get redirected additionally also git config --global http."http://redirect-source.example.com".sslCAInfo /home/javl/git-certs/cert.pem
|
10

OSX User adjustments.

Following the steps of the Accepted answer worked for me with a small addition when configuring on OSX.

I put the cert.pem file in a directory under my OSX logged in user and thus caused me to adjust the location for the trusted certificate.

Configure git to trust this certificate:

$ git config --global http.sslCAInfo $HOME/git-certs/cert.pem 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.