I’m working on learning the Go language. In order to do so, I’m going through the exercises in The Go Programming Language. But before I got too far, it seemed worthwhile to set up a git repo to hold the code. The git docs provide useful info for making this go on linux, but I wanted to make it work on my mac. And after a bit of work, I came up with the following process for setting up a git server:
Set up a git user
We’re going to want a git user that doesn’t have login permissions, so that there’s a service account to own the files in the repo. There’s no
adduser command, and on the mac these days, everything is done via opendirectory. On macOS 10.12, the following sequence of commands will create a git user:
sudo dscl localhost create /Local/Default/Users/git # username is git sudo dscl localhost create /Local/Default/Users/git RealName "git repo management" sudo dscl localhost create /Local/Default/Users/git Password '*' # should not be able to login via password sudo dscl localhost create /Local/Default/Users/git UniqueID 250 # Pick something unique sudo dscl localhost create /Local/Default/Users/git PrimaryGroupID 20 # Staff group sudo dscl localhost create /Local/Default/Users/git UserShell /usr/bin/git-shell # No shell access allowed! sudo dscl localhost create /Local/Default/Users/git NFSHomeDirectory /usr/local/gitrepo
Set up git-shell as a valid shell
Now there’s a
git user, but it needs a bit more work before we’re ready to roll.
sudo emacs -nw /etc/shells
/usr/bin/git-shell to the list of valid shells so that ssh access will work.
Allow the git user to use ssh
The macOS Sharing setting in Preferences can be used to lock down ssh (or “Remote Login”, as it’s called on macOS). The new
git user will need to be allowed to use ssh. This turns out to be easy:
sudo dseditgroup -o edit -t user -a git com.apple.access_ssh
Create the git user’s home directory
I decided to put the git user’s directory in
We’ll need to make that directory, and then add a
.ssh directory in there to hold the
authorized_keys. Here’s how:
sudo mkdir /usr/local/gitrepo sudo mkdir /usr/local/gitrepo/.ssh sudo chmod 700 .ssh sudo touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys sudo chown -R git /usr/local/gitrepo
Make an bare repo for your project
In this case, I want to set up an empty repo for testing. I’m going to make a bare repo with the name
sudo --user git bash # get a shell as the git user cd /usr/local/gitrepo mkdir empty.git cd empty.git git init -bare
Set up ssh pubkeys for your users
We’ve blocked the git user from having password-driven authentication, so we now need to add our SSH keypair pubkeys to the git user’s account.
You’ll find your pubkey in the file
~/.ssh/id_rsa.pub. If you don’t have one of those, make a keypair by running:
ssh-keygen -t rsa -b 4096 -C "email@example.com" (of course, replace firstname.lastname@example.org with your own email address).
Now you’ll need to add the contents of the
~/.ssh/id_rsa.pub to the git account. This is easy to do, but a little tricky because the git user can’t read your pubkey, and you can’t write it to the
authorized_keys file as anyone other than the git user (or root). This is where the /tmp directory comes into play!
cp ~/.ssh/id_rsa.pub /tmp/user.pubkey sudo --user git bash cd /usr/local/gitrepo/.ssh cat /tmp/user.pubkey >> authorized_keys
Test it out!
At this point you should be about ready to test. Try to ssh to your server, from the user account where the pubkey came from:
You should see something like
fatal: Interactive git shell is not enabled.
Now you can try to clone the repo, which is the true test.
cd ~/Projects git clone git@localhost:/usr/local/gitrepo/empty.git
If all is well, you should now have a new folder named empty, and a warning that says
warning: You appear to have cloned an empty repository. Which is true!
Now you can make a new repo for your project, clone it, and collaborate.