Git Shell

It is trivial to host git repositories for access over SSH. Sometimes you want to make those repositories accessible to others, which opens up a security issue. One shortcut is to create a user locked into Git Shell, a login shell with extremely limited and configurable capabilities.


Installation

In most cases, Git Shell is provided by the git package. A user with a custom login shell and a home directory as /var/git can be created by:

adduser --create-home --home /var/git --shell /usr/bin/git-shell git

For more details, see here


Advanced Configuration

In some cases, it is necessary to have an actual home directory for the git user. For example, in order to restrict access to remote users with a passkey, a truly private (i.e. only the login is a member of its user group) home directory has to exist.

Create the git user in a more normal manner. Then, establish some very simple configuration files.

# create user
adduser --create-home git

# login as user
su - git

# create SSH passkeys directory
mkdir .ssh
chmod 700 .ssh
touch .ssh/authorized_keys

# create profile that will set $HOME and kick user into git-shell
cat <<EOF > .profile
#!/bin/sh
export HOME=/var/git
exec /usr/bin/git-shell
EOF

Lastly, address the SSH URL issue. As-is, repositories must be named by absolute path to clone over SSH. (git clone user@host:/var/git/my-repo.git instead of git clone user@host:my-repo.git) There isn't a perfect solution to this, but there's a very simple good enough solution.

By creating a symbolic link within the git user's home directory, remote users can specify a relative path to the repositories. (git clone user@host:repos/my-repo.git)

ln -s /var/git ~/repos

Alternatively, given enough patience/cleverness, you can create symbolic links to every repository within the git user's home directory.

for repo in /var/git/*; do
  ln -s "$repo" "~/$(basename "$r")"
done


CategoryRicottone