Capistrano Series - Setting up Git

So now the Slice is setup and ready for our Ruby on Rails with Capistrano stack.

Let's get straight on and install git and set up a repository.


The What

What we're going to do is securely setup a git repository under it's own user account. Then we will secure the shell on this account, allowing us to give others access to the repository using standard SSH keys without them having full shell access to the Slice.

Assumptions

The only assumptions made for these articles are:

1: You are running Ubuntu Hardy (The instructions may work on other distros but it has not been tested and is not guaranteed)

2: You have followed the setup articles: page 1 and page 2

Installing Git

First things first, let's install git on our Slice.

sudo aptitude install git-core

Setting up the git user

Now we will set up a special user account to hold the git repository.

sudo adduser git

Let's setup SSH keys for the new git user. If you followed along with page 1 and page 2 of our Ubuntu Hardy articles, this step will be very familiar to you. Since our public key is already on the Slice though, we can just copy it over.

Switch to our git user, create the necessary SSH directories and set the proper permissions.

sudo su git
cd /home/git
mkdir .ssh
chmod 700 .ssh
exit

Copy our authorized_keys file from our user account to our git user account and ensure that it's owned by the git user.

sudo cp /home/demo/.ssh/authorized_keys /home/git/.ssh/
sudo chown git.git /home/git/.ssh/authorized_keys

If you followed along with page 1 and page 2 of the Hardy articles, you'll recall that we disallowed SSH access to all but our main user in our sshd_config. We'll need to add the git to the list of allowed users, as our repository will be using SSH to communicate with our client.

Open up your sshd config.

sudo nano -w /etc/ssh/sshd_config

Find the "AllowUsers" line and add our git user to the list.

AllowUsers demo git

Reload the SSH config.

sudo /etc/init.d/ssh reload

Let's make sure that we can properly establish an SSH connection using the git user now. From your local machine:

ssh git@YOUR-SLICE-IP

It should connect fine at this point.

Great! Now that the git user is set up, we want to create our first repository.

Creating a Repository

We are going to do this work as the git user so that we don't have to fiddle with permissions when we are done.

su git

Now we want to create a directory in the git users home, this will be the name of the repository. For the sake of example, I will just call this repo "project1"

cd /home/git
mkdir project1
cd project1

Let's initialize that directory to be a bare git repo and exit out of the git user.

git --bare init
exit

We just created our first git repository! Easy, huh?

Restricting shell access for the git user

In the future, we may want to add more keys to our authorized_keys file to grant access to the repo for others. However, we don't want these users to have SSH access to our server - so we are going to use a special tool called "git-shell" to restrict the access that the git user has.

First, open up /etc/passwd in your favorite text editor.

sudo nano /etc/passwd

Find the line the git user we added is on, it should read something like this (note that the user ID and group ID numbers may differ on your Slice, you should not touch those values):

git:x:1001:1001:Git,,,:/home/git:/bin/bash

Note that the "/bin/bash" means that this user gets a bash shell when SSH'ing into the Slice. This is generally the default shell for most distributions and is the heart of your interactions with the command line.

Let's change the "/bin/bash" to "/usr/bin/git-shell"

Now it should read something like this:

git:x:1001:1001:Git,,,:/home/git:/usr/bin/git-shell

Now, if someone successfully SSH's into your Slice as the git user, they will be forced to use the git-shell. The git shell is specially designed to restrict access. Let's see what happens when we attempt to SSH in as the git user now.

From your local machine:

ssh git@YOUR-SLICE-IP

You should see the following output.

fatal: What do you think I am? A shell?
connection to [YOUR-SLICE-IP] closed.

Excellent! Now the git user we created is secured and will not be able to SSH into your Slice.

Let's move on.

Making your first commit

Now that we've got our repository setup and our git user secured, we want to make our first commit to the repository. The first commit requires a bit of work, but you only need to do this once. After that, committing and pushing to the repository is a breeze.

At this point you will want to make sure that you have git installed on your client machine, as that is where we will be running the following commands from.

Make a new folder on your system wherever you'd like to keep your project files. Again, I will call this "project1"

mkdir project1

Initialize the new folder as a git repository.

cd project1
git init

Create a new file or files to add to the repo.

touch hello.txt

Add all files in this folder to the repo.

git add .

Commit the files we just added.

git commit -m "added hello.txt"

Note that the -m and the text that follows is simply the message that gets logged about that commit. Generally you will want that to relate to what you just committed in some way in case you ever need to go searching for when a particular change was made.

Add the remote origin.

git remote add origin git@YOUR-SLICE-IP:project1

Now, let's push our changes to the repo.

git push origin master

Wow! We have accomplished quite a bit so far.

Almost Done

Now our repo is set up and ready to be cloned. Let's delete the "project1" folder we made on our local machine (as that was just temporary) but required to complete some of the work. Then we will 'clone' our remote repo back down to our workstation.

On your local machine:

rm -rf project1
git clone git@YOUR-SLICE-IP:project1

That's it! We now have a fully functioning git repository on our Slice and we've pulled a clone of it down to our local machine.

For a list of the common git commands you'll want to familiarize yourself with, run this command on your local machine.

git --help

Enjoy!

Ben B.

Article Comments:

Frantisek Malina commented Tue May 19 02:54:22 UTC 2009:

If you've specified a custom port for SSH login (other than 22), use the following pattern to add the remote login

git remote add origin ssh://git@12.34.56.789:30000/absolute/path/to/git/project

seanl commented Fri May 22 15:43:16 UTC 2009:

Is setting up Gitosis a better option than using the method prescribed above as it doesn't not require the use of shell accounts and should be inherently more secure. I only ask as I'm having difficulties setting it up and wonder if this simpler method might serve me best

Łukasz Adamczak commented Tue Jul 14 08:11:57 UTC 2009:

@seanl: Gitosis does require a git account, just as in this article. It greatly simplifies administering your git repositories - adding users, creating new repos etc.

See http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way

Ionut G. Stan commented Sat Jul 18 20:01:55 UTC 2009:

For those that are trying to manage Git with Gitosis. I've installed it (Gitosis) using the instructions on scie.nti.st. The damn thing won't work though until you edit /etc/ssh/sshd_config and add the git user to allowed users:

AllowUsers demo git

Shawn commented Wed Aug 05 13:44:16 UTC 2009:

Great article! A question, after disable the shell, how can I create another repo?

Thanks Shawn

Goro commented Tue Sep 08 23:43:53 UTC 2009:

I got an error when push my local repository to remote.

$ git push origin master FATAL ERROR: Network error: Connection timed out fatal: The remote end hung up unexpectedly

Why remote timed out? Any ideas?

Goro commented Wed Sep 09 03:05:29 UTC 2009:

I fixed it.

It was SSH autorization problem.

Naveen Garg commented Tue Sep 15 15:26:06 UTC 2009:

There is a typo in this line: sudo chown git.git /home/git/.ssh/authorized_keys

should be sudo chown git /home/git/.ssh/authorized_keys

also, you may want to add instructions to add repositories after restricting the git user to git-shell

Ben commented Wed Sep 23 04:37:11 UTC 2009:

@Naveen - that wasn't a typo, using "git.git" changes both the 'user' and the 'group' so that it is also owned by the git group. It may not have been needed, but I find that it is a good habit to be as explicit as possible when assigning file permissions.

Thank you for the article suggestion. I will make a note of it!

Cheers.

fabilo commented Sat Oct 10 09:07:49 UTC 2009:

When I try to change the default shell for git user to git-shell eg:

git:x:1001:1001:Git,,,:/home/git:/usr/bin/git-shell

there is no /usr/bin/git-shell file, should there be?

Trent commented Tue Dec 01 11:36:13 UTC 2009:

@shawn to create another repository, log into your slice with an account that has sudo access, then execute:

sudo su --shell /bin/bash git

Now you can complete the 'Creating a Repository' steps

Jason Ervin commented Sat Feb 20 06:18:07 UTC 2010:

I am trying to do the "git push origin master" and I am getting "connetion to host 173..... port 22: Connection refused"

I changed the port to 3333 but it keeps trying to connect to 22

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)