# sudo adduser git # su - git $ mkdir .ssh $ cat yourkey.pub >> .ssh/authorized_keys
Next, add a bare repository for each project:
$ mkdir coolproject.git $ cd coolproject.git $ git --bare init
That's the server set up. Now authorised users can commit projects in the same way as with any other Git server:
$ git init $ git add . $ git commit -m 'Initial commit' $ git remote add origin git@gitserver:coolproject.git $ git push origin masterChecking out as simple as:
$ git clone git@gitserver:coolproject.gitThat really is all there is to it! Git has been built to work seamlessly with the SSH protocol, so once you've set up the SSH side of things, Git takes care of the rest.
fatal: Interactive git shell is not enabled. hint: ~/git-shell-commands should exist and have read and execute access.
Notice that last part? There's not much documentation on git-shell-commands, but it turns out that if you create a directory with this name in the Git user's home directory, any executable files you place inside the directory will become accessible through an interactive shell when you su up or SSH into the git user. If you create a script named help, it will get executed when the shell starts. Kind of cool, and really handy for making your Git server more friendly :-)
The tools
Putting it all together, you can now create a user as follows, then use the tools below to create projects and add keys:
# useradd --create-home --skel /dev/null --home-dir /srv/data/git --shell /usr/bin/git-shell git # chmod 750 /srv/data/gitThe first command creates a user named git with a home directory in /srv/data/git (change this as you need), with no skeleton files (.bashrc, .bash_logout, etc), and assigns the user the all-important /usr/bin/git-shell shell. No password was specified, so the user cannot log in by the usual means (we'll use su as root and authorized_keys to allow access). The second command is optional and just sets permissions on git's home directory so that nobody on the server can access the repositories directly.
#!/bin/sh # If the user is not root if [ "$USERNAME" != "root" ] then # Dislpay a notice and stop echo "Sorry, only root can use this command." exit 1 fi # If no project name is given if [ $# -eq 0 ] then # Display usage and stop echo "Usage: create <project.git>" exit 1 fi # Set the project name, adding .git if necessary project=$(echo "$*" | sed 's/\.git$\|$/.git/i') # Create and initialise the project mkdir "$project" && \ cd "$project" && \ git --bare init~/git-shell-commands/addkey
#!/bin/sh # If the user is not root if [ "$USERNAME" != "root" ] then # Dislpay a notice and stop echo "Sorry, only root can use this command." exit 1 fi # Read in the SSH key echo "Input the key to be added:" read key # Place the key in a temporary file (it's hard to get ssh-keygen # to read from stdin; <<< works for bash, but is non-posix) keyfile=$(tempfile) &&\ echo "$key" > $keyfile # Generate a fingerprint fingerprint=$(ssh-keygen -lf $keyfile) # Check for errors if [ $(echo "$fingerprint" | egrep -c '(R|D)SA') -eq 0 ] then # Display the fingerprint error and clean up echo "Error: $fingerprint" rm $keyfile exit 1 fi # Add the key to the authorised keys file and clean up mkdir -p .ssh &&\ echo -n "no-agent-forwarding,no-port-forwarding,no-X11-forwarding " >> .ssh/authorized_keys &&\ cat $keyfile >> .ssh/authorized_keys rm $keyfile # Display the fingerprint for reference echo "Success! Added a key with the following fingerprint:" echo $fingerprintThese two scripts prevent non-root users from using them, but the restriction can of course be relaxed if your users are trusted. I believe checking the shell's USERNAME environment variable is a reasonably secure way to restrict access, because SSH prevents environment variables being passed to the shell, and the user cannot alter the variable's value once logged in (git-shell won't let them!)
$ sudo su git [sudo] password for user: Run 'help' for help, or 'exit' to leave. Available commands: addkey create list git> addkey Input the key to be added: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCwo5wOJQB3gUV4NzZN1q3S9siD8HY9ufj/8+nMj7x5 ggpwbujG9gpFbfi/L6p8OJGi09akGxV2jMXxS4BdinFwvLfcCNIkI6Gq4ME0QRjKuYau/ITR5/MNQTh6 TRTCwFWmUOy3Hd1dsn+bqadbd4gAABW6cA54Ggbknv0JAQsoDW+qdaZDoSJIxXhT6aE9cEJ2PyUl6tul 9RRiQqDZjYRcNJydJ5mYBAksXP7uEVsDM+cO9ZOqqsYQvXN0nzfUZjUNfSxV+JmGBBJzJdXCu+pMb0O8 yTzL8ycSSCkaLHBQ35Qw16fBqrWMH6Oj5wqXl0HtykQCnU14juwWOHfdCPnTsPWBWgJDN9FgiuYwFxIM fuz4tRq2ygcHB+Yt5smiG6eLEE8pCUtTv8EUmVI4LA7fguiA63CYL6aGeK8e08UeaGx0uaxum92D73AB qlFvn0+Wi4efZV1qvdvFcoMtgThKDTaDepYSb/d020BH1tstj7CJcK05nsBoqwOp4GGhGJtkWbN3Dn69 vRfyIX4w4y2Etw9MoW898rtHFN9eB9FbfWbMDPf8cAayoN40Xd0RocRxH46clV1g2bH0Bn5TGkL6Ltj3 Bvqzu5ZLMbw4s0kgOShK2GCNTBDf86aHG/97CL63FBQu/TcZuXxNmwApL2Wo0dfpCBEpvSu3m7+44y5K 6w== user@host Success! Added a key with the following fingerprint: 4096 fc:6f:2d:28:d4:13:a1:65:52:a0:33:f6:76:af:84:6a user@host (RSA) git> create awesomeproject.git Initialized empty Git repository in /srv/data/git/awesomeproject.git/ git> list coolproject.git awesomeproject.git git> exit $Users have also access to the interface and can list available projects:
$ ssh git@gitserver Run 'help' for help, or 'exit' to leave. Available commands: addkey create list git> addkey Sorry, only root can use this command. git> create sneakyproject.git Sorry, only root can use this command. git> list coolproject.git awesomeproject.git git> exit Connection to gitserver closed. $I hope the information presented here will get you off to a good start with your own Git server, and help you spend less time managing Git and more time coding! All git-shell-commands (including the samples provided in the git documentation) can be downloaded below.
git-shell-commands-0.1.tar.bz2