Search code examples
gitsshgithookssshdgit-daemon

How to determine SSH fingerprint of client for usage in Git hook


I've got a Git update hook which checks if the branch being updated is master and if so, sends an error message to the client. I now would like to make it so only pushes to master which I myself make will pass.

Currently I have two SSH keys added to the authorized_keys of a user git. One of them is mine, and I intend to add others. I read here:

If you’ve allowed everyone to connect with a single user (like “git”) via public-key authentication, you may have to give that user a shell wrapper that determines which user is connecting based on the public key, and set an environment variable accordingly.

But they don't explain how to do that, and I can't find any examples of how to do such a thing. How do you determine the fingerprint of the machine which is SSH'ing in? I also considered creating a separate "git-admin" user account, but the bare repos are in the /home/git directory, and I couldn't think about how to have both users pushing to the same repo with the same url. I can't make the users share the same home directory because then the authorized_keys would apply for both, and I wouldn't have any way of setting an environment variable only for the one and not the other.

My server is running on FreeBSD.

Any thoughts on how to achieve what I'm trying to do?


Solution

  • This is called ssh forced command, and is used for instance by gitolite

    You could either:

    • install gitolite on the server side, which takes advantage of that native ssh feature, and can limit write (push) access to certain branches.
      It is an authorization layer, and you can test for access for specific branches.

      if gitolite access -q reponame username W master
      then
          ...
      
    • or modify your ~/.ssh/authorized_keys to add a forced command, that is a script called on any ssh call, which can then test which key is involved in that call, identifying you and letting the command pass.
      That is what a "ssh forced command" stands for (and it has nothing to do with Git)