Friday, June 29, 2018

TFS Build Agent - SSL certificate problem: unable to get local issuer certificate

After upgrading to a new TFS server and going full HTTPS, our git based builds started to fail with the following error message:

2018-06-12T21:28:45.8463514Z ##[command]git init "D:\Builds\dev-agent-1\_work\5\s"

2018-06-12T21:28:45.9154418Z Initialized empty Git repository in D:/Builds/dev-agent-1/_work/5/s/.git/

2018-06-12T21:28:45.9219662Z ##[command]git remote add origin https://tfs/DefaultCollection/_git/Sample

2018-06-12T21:28:45.9821910Z ##[command]git config gc.auto 0

2018-06-12T21:28:46.0407163Z ##[command]git config --get-all http.https://tfs/DefaultCollection/_git/Sample.extraheader

2018-06-12T21:28:46.0994413Z ##[command]git config --get-all http.proxy

2018-06-12T21:28:46.1508406Z ##[command]git -c http.extraheader="AUTHORIZATION: bearer ********" fetch --tags --prune --progress --no-recurse-submodules origin

2018-06-12T21:28:46.3636860Z fatal: unable to access 'https://tfs/DefaultCollection/_git/Sample/': SSL certificate problem: unable to get local issuer certificate

2018-06-12T21:28:46.3988694Z ##[error]Git fetch failed with exit code: 128

2018-06-12T21:28:46.4040002Z ##[section]Finishing: Get Sources

The SSL certificate we are using is based on a corporate root certificate. This root certificate is stored in the certificate store on all the servers .Any application written to use the Windows crypto APIs will have access to that root certificate, and will consider your TFS deployment to be trusted.

Unfortunately, Git for Windows (git.exe) uses OpenSSL for its crypto stack, and the Git for Windows distribution includes a set of trusted root certificates in a simple text file. As our root certificate is not in this set, we’ll get the error above.

An easy workaround we used at first was to add the following configuration setting on the global git config available at c:\programdata\git

[http] sslVerify=false

As this globally disables TLS(/SSL) certificate verification, it is not a solution I would recommend. This defeats the purpose of introducing SSL in the first place.

We’ll have to find a better solution, but we’ll leave that for another blog post…

2 comments:

Unknown said...
This comment has been removed by the author.
Kat said...

The better way is:

1) Get your root CA certificate as a .cer file
2) Find the standard cabundle.crt file from a normal git install
3) Edit cabundle.crt and append the .cer of your Root CA on the bottom, and save this as a new file somewhere.
4) Create a .gitconfig file containing the following

[http]
sslCAInfo = [path/to/file/created/in/step/3]

5) Copy that .gitconfig file into the home folder of the service account that the TFS Agent runs as (e.g. c:\windows\ServiceProfiles\NetworkService\ )

If your build agent is connecting to other services that also use self-signed certs, you may want to add an environment variable AGENT_CAINFO=[path\to\file\in\step3] as well.