Git Shell
git-shell(1) is a minimal shell meant for hosting git repositories over SSH. The shell exposes very little information or utility, minimizing attack surface.
Contents
Installation
In most cases, git-shell(1) is provided by the git package.
Setup
Interactive user creation scripts will offer the login shell as a configurable setting. Simply select git-shell at this stage.
For a non-interactive approach, try:
adduser --create-home --shell $(command -v git-shell) git
For more details, see here
To set git-shell as the login shell for an existing user, try:
chsh --shell $(command -v git-shell) username
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