Using git with self signed certificates

Using git internally to access an external git repository? Behind a corporate proxy that has an self signed CA cert? Is git complaining about ‘SSL certificate problem: unable to get local issuer certificate’? Here ya go.

High level:

  1. Get the self-signed cert in a base 64 encoded file.
  2. git config http.sslCAInfo “path/to/that/file.cer”

You will hear a lot about setting http.sslVerify to false. Please don’t do this. If you leave the environment having the self-signed cert then git will not be verifying any TLS/SSL traffic, opening you up to man in the middle attacks.

Detailed with scripts for Windows (I’ll work on Linux later).

You need to get the self-signed certificate in a base 64 encoded file. There are a couple ways to do this depending on your situation.

On Windows when the certificate is only available from the remote git server itself.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# powershell
CLEAR

Write-Host "Getting certificate for internal site"

$request = [Net.WebRequest]::Create("https://internalsite.supercorp")
$request.GetResponse() | Out-Null
$cert = $request.ServicePoint.Certificate
$bytes = $cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)
Set-Content -value $bytes -encoding byte -path "internalsite.supercorp.cer"

Write-Host "Getting chain for CA cert"
$chain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain
$chain.Build($cert)

$root = $chain.ChainElements | Select -Last 1

$bytes = $root.Certificate.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)
Set-Content -value $bytes -encoding byte -path "supercorp.ca.cer"
On Windows when the certificate is in the Windows cert store.

This may be typical for corporate environments. Easy to tell, if git complains about self-signed cert but your Chrome or Edge browser doesn’t complain then it’s likely the cert is already on your computer.

1
2
3
4
5

# powershell
$rootCA = dir Cert:\LocalMachine\Root | Where DnsNameList -Contains "NAME OF YOUR ROOT CA CERT" | Select -First 1
$rootCA = @("-----BEGIN CERTIFICATE-----",[System.Convert]::ToBase64String($rootCA.RawData),"-----END CERTIFICATE-----")
$rootCAPath = "$Home\where-you-want-the-file-ca.cer"
$rootCA | Out-File $rootCAPath -Encoding ascii

The Where above may need to be modified to find the appropriate cert in your cert store.

Tell git to trust that certificate.

1
git config http.sslCAInfo "path-to-file-above.cer"

Special thanks

I must thank Philip Kelly for posting an article on this exact situation back in 2014. I also want to say thank you to Alejandro Campos Magencio for the post on getting the certificate chain. I put those two together with the exporting of the certifcate to a file to produce this post.

Philip Kelley’s post

Alejandro Campos Magencio’ post

How to fix git ssh asking for password on Windows 10

TL;DR

1
Get-Command ssh

If the output of that lists an executable not in your git usr/bin directory then do this:

1
git config core.sshCommand (get-command ssh).Source.Replace('\','/')

Or, if you want to test this in your current PowerShell session w/o messing with Git config

1
$ENV:GIT_SSH_COMMAND = (get-command ssh).Source.Replace('\','/')

Why does this work?

When you install git, it comes with ssh. But if you have a newer version of Windows 10, Windows has an install of SSH that comes with it. Installed in C:\Windows\System32\OpenSSH. That gets put into the environment PATH and so testing:

1
ssh -T git@github.com

Uses your key you added via ssh-add using the Windows provided binaries. But git is using the ssh stuff within the git usr/bin folder. Different set of keys. So you’d end up getting prompted for your passphrase every single time you git pull.

Nearly drove me crazy, this did.

VSTS: Disable features/services API

VSTS is rolling out a new navigation. One of the features in it is the ability to turn off certain services/features, such as Test, Build and Release, etc. But you have to go into each project individually. That’s manual work, I want to automate it.

So if you want to disable some services/features in VSTS across multiple projects there is a REST API that you can use. It’s in preview, and you’ll have to script the calls but here you go:

1
2
3
4
PATCH https://{account}.visualstudio.com/_apis/FeatureManagement/FeatureStates/host/project/{project-id}/{feature-id}?api-version='4.1-preview.1'
content-type: application/json

{"featureId":"{feature-id}","scope":{"settingScope":"project","userScoped":false},"state":0}

Replace account,project-id and feature-id as appropriate. Here are the feature id’s I know of.

  • ms.vss-build.pipelines
  • ms.vss-test-web.test
  • ms.vss-work.agile
  • ms.vss-code.version-control

Using the VSTeam PowerShell module

1
2
3
4
5
6
7
8
# Get the build feature setting
$buildFeature = Invoke-VSTeamRequest -Area FeatureManagement -Resource FeatureStates -Id "host/project/$($project.Id)/ms.vss-build.pipelines"

# Adjust the setting: 0 | 1 | 'undefined'
$buildFeature.state = 0

# Update VSTS
Invoke-VSTeamRequest -method patch -ContentType 'application/json' -body ($buildFeature | ConvertTo-Json -Depth 5 -Compress) -Area FeatureManagement -Resource FeatureStates -Id "host/project/$($project.Id)/ms.vss-build.pipelines" -version '4.1-preview.1' | Out-Null

Host level settings

You can also do the above at the ‘host’ level. From my experimentation that’s the project collection as a whole.

1
https://{account}.visualstudio.com/_apis/FeatureManagement/FeatureStates/host/{feature-id}

Same payload, in that case you are simply ignoring the project. However, this doesn’t actually remove the service/feature from all the projects. What it does is removes them from the services page. You won’t even see a ‘Build and Release’ toggle for example. So be careful, if you disable a service at the host level but it’s enabled at the project level (or undefined) then the project can still use that service as usual, but you won’t be able to turn it on/off via the new navigation ui.

Developing behind a proxy

Working behind a proxy can be annoying at times but it’s not difficult to work with, most of the time that is. This is mostly here for my own reference in the future and you get the added benefit.