gitsslgitlabgit-lfsssl-client-authentication

Git LFS and HTTP client authentication


I have a private gitlab instance that requires client authentication when trying to access it via https. So going to myserver.com will only work if you install a client certificate in the web browser. This isn't a problem for regular usage because I only ever use git via SSH.

However, git LFS only appears to support HTTPS. So when I try to git push to my server in a project that uses LFS, it will attempt the upload using HTTPS only, and it will obviously fail.

git push gitlab mybranch
fatal: unable to access 'https://git.myserver.com/coolguy/my-software.git/': gnutls_handshake() failed: Handshake failed

This is what my remote looks like:

git remote -v
gitlab  git@git.myserver.com:coolguy/my-software (fetch)
gitlab  git@git.myserver.com:coolguy/my-software (push)

Besides nuking the git history and creating a new repo without LFS (or reconfiguring my server, using a VPN, etc), is there anything else I can do in this situation? Does git/lfs support client certificates for HTTPS auth? I'm currently stuck with a private fork on my local machine that I can't git push anywhere!

EDIT: Disregard the following, it turned out to be a bad apache config file, unrelated to git and gitlab

I am getting a strange error that seems unrelated to client authentication, and might be a LFS bug:
git push gitlab mybranch
Remote "gitlab" does not support the LFS locking API. Consider disabling it with:
  $ git config lfs.https://git.myserver.com/coolguy/my-software.git/info/lfs.locksverify false
batch response: Post https://git.myserver.comcoolguy/my-software.git/info/lfs/objects/batch: dial tcp: lookup git.myserver.comcoolguy: no such host             
batch response: Post https://git.myserver.comcoolguy/my-software.git/info/lfs/objects/batch: dial tcp: lookup git.myserver.comcoolguy: no such host
batch response: Post https://git.myserver.comcoolguy/my-software.git/info/lfs/objects/batch: dial tcp: lookup git.myserver.comcoolguy: no such host
batch response: Post https://git.myserver.comcoolguy/my-software.git/info/lfs/objects/batch: dial tcp: lookup git.myserver.comcoolguy: no such host
batch response: Post https://git.myserver.comcoolguy/my-software.git/info/lfs/objects/batch: dial tcp: lookup git.myserver.comcoolguy: no such host
batch response: Post https://git.myserver.comcoolguy/my-software.git/info/lfs/objects/batch: dial tcp: lookup git.myserver.comcoolguy: no such host

Notice how it's butchering the URL as git.myserver.comcoolguy instead of git.myserver.com/coolguy or git.myserver.com:coolguy

Thanks


Solution

  • Git LFS has just recently, in 3.0, added support for a pure SSH-based protocol. However, none of the major forges support it at the moment, so you're practically limited to authentication over SSH which then operates over HTTPS.

    When you use this approach, the remote URL comes from the server over SSH. You can see this from this slightly modified example:

    $ ssh git@github.com git-lfs-authenticate octocat/knife-sppon.git download
    {
      "href": "https://lfs.github.com/octocat/knife-spoon",
      "header": {
        "Authorization": "RemoteAuth SECRET"
      },
      "expires_at": "2021-10-15T01:34:57Z",
      "expires_in": 599
    }
    

    If the URL is not correct there, then it's probably the cause of your URL problems. Note that you can see the exact invocation over SSH by setting GIT_TRACE=1 before running your push, which will show you what Git LFS is invoking.

    Git LFS does indeed support certificates for HTTPS, just as Git does. The options http.sslCert and http.sslKey control the certificate and key, and you can specify the CA with http.sslCAInfo. These can also be set on a per-URL or per-URL pattern basis; see git config --help for more details.

    Note that with Git LFS, the key and cert need to be in PKCS#1 format; you cannot use PKCS#8 or PKCS#12 format, since the Go TLS library which Git LFS uses can't handle those formats in all the ways that Git LFS needs it to.