git-shell
Restrict SSH access to Git operations only
SYNOPSIS
git-shell [-h | --help] [-upload-pack <directory>] [-receive-pack <directory>] [-upload-archive <directory>]
PARAMETERS
-h, --help
Display help and exit.
-upload-pack <directory>
Run git-upload-pack (pack upload for fetch/clone) on directory.
-receive-pack <directory>
Run git-receive-pack (pack receive for push) on directory.
-upload-archive <directory>
Run git-upload-archive (archive export) on directory.
DESCRIPTION
git-shell is a specialized restricted login shell from Git, enabling secure repository access over SSH without full shell privileges. Ideal for Git servers or hosting setups, it limits users to essential Git operations: fetching, pushing, and archiving repositories.
To deploy, append /usr/bin/git-shell to /etc/shells, then assign it to a user via chsh -s /usr/bin/git-shell username or usermod -s /usr/bin/git-shell username. Upon SSH login, git-shell displays banners like repository lists from ~/.ssh/authorized_keys comments and restricts input to:
- git-upload-pack <directory> (for git fetch/git clone)
- git-receive-pack <directory> (for git push)
- git-upload-archive <directory> (for archive downloads).
Invalid commands trigger errors and session termination. It honors per-key restrictions in authorized_keys, e.g., command="git-shell -upload-pack repo.git". Direct invocation tests these commands on bare repositories.
This enhances security by preventing arbitrary execution while supporting standard Git workflows.
CAVEATS
If no options are given and the first argument is a directory path (no leading dash), acts as -upload-pack <directory>. Requires listing in /etc/shells for login shell use. Repositories must be bare or configured appropriately (e.g., --stateless-rpc support). No interactive shell or other Git commands allowed.
LOGIN MODE RESTRICTIONS
Permits only git-upload-pack, git-receive-pack, git-upload-archive on repos. Scans ~/.ssh/authorized_keys for repo lists and key-specific command= overrides.
QUICK SETUP
echo '/usr/bin/git-shell' | sudo tee -a /etc/shells
sudo chsh -s /usr/bin/git-shell username
Test: ssh -t git@example.com (replace 'git' with username).
HISTORY
Introduced in Git 1.6.4 (April 2009) to enable shell-less Git hosting. Evolved with Git core for better SSH integration, security fixes, and support for forced commands in authorized_keys. Widely used in GitLab, GitHub Enterprise, and self-hosted setups.


