gitbashsshgit-bashauthorized-keys

Check authorized_keys to see which key was used for pushing the commit


Say there's a large list of ssh public keys in ~/.ssh/authorized_keys on a server with Git repositories, with a general format of " user@mail.com"

I want to write bash script for the pre-receive hook, that checks which SSH key was used to push the commit and then performs certain operations on the commit before it's received. So the outline of the script would be..

#!/bin/sh
#
<Check key which was used from authorized_keys for the commit>
<Print email corresponding to the SSH key to a file as a log>
<Do some other stuff here>

But since the server stores public keys, and private keys are used to push the commits, is it possible to check which key was used? If so how?

Sorry if I'm missing something obvious, just need some direction to get started.

Any help is appreciated, thanks.


Solution

  • You can edit your ~/.ssh/authorized_keys file to include an environment variable or custom command to run associated with each key.

    Let's say you have the following public keys in your authorized_keys file:

    ssh-rsa AAAA.... usera@hosta
    ssh-rsa AAAA.... usera@hostb
    ssh-rsa AAAA.... userb@hostc
    

    And you want to be able to get the user's email associated with each of those. You could edit authorized_keys to instead read:

    environment="EMAIL=usera@example.com" ssh-rsa AAAA.... usera@hosta
    environment="EMAIL=usera@example.com" ssh-rsa AAAA.... usera@hostb
    environment="EMAIL=userb@example.com" ssh-rsa AAAA.... userb@hostc
    

    Now in your script, you could just access the EMAIL variable:

    #!/bin/sh
    
    sendmail "$EMAIL" <<EOF
    To: $EMAIL
    From: admin@example.com
    
    This is a test message
    EOF
    

    Note that this mechanism should be used for convenience if you trust your users, not security if you want this not to be able to be subverted. If you want this to be secure so that the users couldn't tamper with it, you need to use the forced command feature, in which all access goes through a wrapper command that only allows running the specific Git commands. You could write your own wrapper for this, but if you're going to go down this route just using gitolite is probably the best solution. If you did want to implement this yourself, gitolite has a page explaining how it works.