Howto: Git Server over SSH
Git and SSH are both powerful tools, and git/ssh work well together. We introduce how to set up git server via ssh in this post. Git server through SSH is easy and fast to set up, although every user will have access to all repositories in the git server over SSH and every user is the git administrator. This is okay for a small group of git members who trust each other. But for better privilege control, you should try gitolite or gitosis.
If you need to set up a git server for multiple users which may contain contributors and administrator, you may try gitolite as recommended by the gitolite author. A good tutorial for gitolite is here: gitolite tutorial.
If you prefer gitosis, please refer to: Setting Up Git Server Using Gitosis and Managing Repositories on Git Server Using Gitosis. The gitosis proves quit stable from my experience, although it does not have as many features as gitolite.
In this post how to set up a basic git server and a more complex one (the git server is a server inside of a local area network) will be introduced.
A basic git server through SSH tutorial
In this part we will build up a git server through ssh connection. We use ssh to pull or push data from or to git server. The git server can be directly connected. Suppose that we set up git server on machines example.org.Server side git user and home
logon to the git server by ssh username@example.org. username is the account name that have administrator privilege (or can sudo) on the git server. Install git package# yum install gitAdd the user for git
# useradd -m -d /lhome/git -u 1005 gitConfigure the git user’s shell
# vim /etc/passwdHere we assume git’s home directory is /lhome/git. Then we can change git’s shell from /bin/bash to /usr/bin/git-shell to forbid logging in for a shell for the git account. It can be made by editing /etc/passwd, but this is not suggested. One good method (thanks to victor) is to use the usermod command:
# usermod -s /usr/bin/git-shell gitHowever, there may be problem. To make this work, the /usr/bin/git-shell should be put into /etc/shells to avoid “user ‘git’ has invalid shell, rejected” error. (Thanks to Tiago for this)
In addition, COMMAND_DIR (the path “$HOME/git-shell-commands”) must exist and any of the executables in it can be invoked. The user must have read and execute permissions to the directory in order to execute the programs in it. Hence, we should create the COMMAND_DIR in git’s home and give read and execute permission to git:
# cd /lhome/git/
# mkdir git-shell-commands
# chmod 755 git-shell-commands
Add id_rsa.pub to git’s .ssh/authorized_keys
log on to git server, using the account that have root or sudo privilege
ssh username@example.orgCopy pub key to a temp directory
# cp .ssh/id_rsa.pub /dev/shm/
operate in git’s home as root
# cd /lhome/git/.sshbackup before changing is a good habit
# cp authorizedkeys authorizedkeys.bakappend pub key to git’s autorized keys list
# cat /dev/shm/id_rsa.pub >> authorized_keys
Create repository
log on example.org using the account that can edit git’s files.
If you have set the git user account’s shell to git-shell on the git server, you need to add the -s /bin/bash in the su command to use bash as the shell instead of git-shell.
Create the repository directory (as the git user on server)
# su -s /bin/bash - git
$ cd ~
$ mkdir example.git
Initial the repository, –bare means only objects is stored on server (as the git user on server)
# su -s /bin/bash - git
$ cd ~/example.git
$ git --bare init
First commit:
The first commit and push on local machine will create the initial repository. Initialize the local repository
$ mkdir example $ cd example $ git initAdd a initial empty README file
$ touch READMEAdd README to the repository
$ git add READMECommit the changes (adding a file)
$ git commit -m 'first commit'Add the remote git repository address
$ git remote add origin ssh://git@example.org/~/example.gitPush the commit to remote repository
$ git push origin master
When programming:
We need to clone the repository for one time:$ git clone ssh://git@example.org/~/example.gitThen every time we want to edit some files:
$ cd example $ git pull # pull the newest version from the repositoryAfter changing some files:
$ git commit -a -m 'msg' # commit the changes with a message msg $ git push # push the changes to the repository
A more complex git server through SSH tutorial
In this part we will build up a git server through ssh connection. We use ssh to pull or push data from or to git server. The git server is inside of a local area network. We use port forwarding to connect to it. Suppose that we set up git server on virtual machines vm111, the gateway server of the net work which vm111 is inside of is gate.example.org, and port 22111 on gate.example.org is port forwarded to vm111:22.
Server side git user and home
logon to the git server by ssh username@gate.example.org -p 22111. username is the account name that can sudo on the git server.# yum install git
# useradd -m -d /lhome/git -u 1005 git
# vim /etc/passwd
Then change git’s shell from /bin/bash to /usr/bin/git-shell to forbid logging on for a shell for the git account. And remember to set the /etc/shells file (refer to the “basic git” section above).
Add id_rsa.pub to git’s .ssh/authorized_keys
ssh gate.example.org -p 22111 # log on to vm111, using the account that can sudo
# cp .ssh/id_rsa.pub /dev/shm/ # copy pub key to a temp directory
# su -s /bin/bash - git # operate in git's hom
$ cd /lhome/git/.ssh
$ cp authorized_keys authorized_keys.bak # backup before changing is a good habit
$ cat /dev/shm/id_rsa.pub >> authorized_keys # append pub key to git's authorized keys list
Create repository
log on gate.example.org -p 22111 # using the account that can sudo
# su -s /bin/bash git
$ cd /lhome/git
$ mkdir example.git # the repository directory
$ cd example.git
$ git --bare init # initial the repository, --bare means only objects is stored on server
First commit:
on local laptop:
$ mkdir example $ cd example $ git init $ touch README $ git add README $ git commit -m 'first commit' $ git remote add origin ssh://git@gate.example.org:22111/~/example.git $ git push origin master
When programming:
We need to clone the repository for one time:$ git clone ssh://git@gate.example.org:22111/~/example.gitThen every time we want to edit some files:
$ cd example $ git pull # pull the newest version from the repositoryAfter changing some files:
$ git commit -a -m 'msg' # commit the changes with a message msg $ git push # push the changes to the repository
Tags: administrator privilege, Client config, etc passwd, Git, SSH, Tutorial
Why the hell do you specifie uid while creating it ?
A good question but not asked in a very good way.
There are lots possible reasons. For us, the reason is to make the id of `git` special so that you can identify which users in one of our system are special ones (like the git account for providing service only and not login should be allowed) rather than normal users.
thanks
this tutorial really helped me
im using cent os
your guide is good
Ok.. in your Tutorial..
First you changed the default shell to git-shell and then you created a new directory with mkdir?! Are you sure that it works like that?
This is a bug. Fixed now.
# usermod -s /usr/bin/git-shell git
usermod: no changes
and then
fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.
Got this error and solution is perhaps with permissions [1] but cannot yet understand which permissions, ideas?
[1] http://serverfault.com/questions/285324/git-shell-not-enabled
What about:
$ chmod 755 ~/git-shell-commands
You can change user shell either at creation time with adduser -s /path/to/git-shell
or by using usermod -s /path/to/git-shell gituser. Hand editing of /etc/passwd should be avoided.
Good tip! Thanks for the suggestion. I have updated the post suggesting using usermod.
guide fails for me
“fatal: couldn’t not switch to..”
Thanks for a very helpful tutorial. There are also some instructions on setting up a git server on Ubuntu using the apt-get installer at http://coderatlarge.net/howto/setting-git-server-linux
Leave out the part about git-shell. If you do it as written, it will mess you up in subsequent steps. The git-shell is not likely intended to be used as a login shell. If you change the login shell from its default (typically /bin/bash) to /usr/bin/git-shell, you will no longer be able to log into the server as the git user and will be unable to complete the subsequent steps which require logging in or su’ing to the git user.
Thanks for the tutorial!
Thanks for the post. Wish I could have found it few hours back.
I missed “git init” on local machine and I was getting error (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
Now I could setup my repositories.
-lb
Pleasure to know this post helps. Enjoy.
Hi,
Sadly, gitosis is unmaintained and unsupported. The regular folks on the IRC channel (#git on freenode) constantly have to tell people this, and point them to gitolite, which *is* maintained, supported, and has lots of documentation. And then they have to migrate.
Even though gitolite also comes with amigration guide, in the interests of letting people avoid this needless step if they haven’t yet started at all, may I request you change the links above to refer to gitolite. If you’re looking for a tutorial, http://sites.google.com/site/senawario/home/gitolite-tutorial is good. There are many others too, I’m sure.
PS: I’m the gitolite author, so this may be biased, but if you hang around on #git you’ll see there are many others who use it and happily recommend it, so I feel reasonably “not biased” :-)
Hi Sitaram,
Thanks for your suggestion. It is not biased at all—I know gitosis is not maintained now and gitolite seems do the work (and better through continuous development) that gitosis did.
I will edit this post and suggest gitolite to the readers.
BTW: thanks for your work on gitolite which give us a good choice beside gitosis.
@Slavi,
Thanks for the information. I have marked it in the post.
@Slavi and @Zhiqiang Ma,
The problem isn’t really with Fedora.
I was setting up a private Git repository on a Debian server yesterday and experienced the same problem. After changing the shell from bash to git-shell I wasn’t able to push anymore too. But looking at /var/log/auth.log I noticed something like: “user ‘git’ has invalid shell, rejected”.
Googling around I found that you have to append the line “/usr/bin/git-shell” to the /etc/shells file. Doing that I was able to push again, this time using the restricted Git shell.
Great and thanks for your solution to this!
I update the original post to contain this tips.
hi,
when I changed the shell to: /usr/bin/git-shell
I wasn’t able to push anymore so I restored it to /bin/bash
OS: Fedora 14
Thanks a lot!
git isn’t in RHEL or CentOS’s repository. But the community supported EPEL has git. Users of CentOS or RHEL can use it to install git:
https://fedoraproject.org/wiki/EPEL
Articles like these put the consumer in the driver seat-very improatnt.
hello,
thank you for your useful article.
can i use this in linux cent os 5.4?
Hello. I haven’t try it on cent os 5.4. I make it run on Fedora 11. But it should work. You can have a try ;)
As far as I know, you should install git by yourself since git is not in it’s repository.