Git

Installing

The git package available in most distribution’s package repositories contains everything needed for a basic client and/or server configuration.

On Debian-derived GNU/Linux distributions, install git with:

sudo apt install git

Configuring

There are numerous ways to set up Git infrastructure for various collaborative purposes. This page describes the configurations useful for and familiar to the Tech Autonomy Infrastructure committee needs. Most of this information is also briefly discussed in the official Git-SCM book, Chapter 4: Git on the Server.

Daemonless single Git-user via git-shell over SSH

This configuration uses a single server Operating System user account (by convention, named git) to provide SSH access to the server hosting the Git repositories themselves. See SSH for SSH server installation and configuration instructions. Access is granted to individual humans using SSH public keys. Capabilities are restricted using git-shell(1) instead of a standard login shell. This configuration can (and should?) be “Torified” with an SSH Onion service. See Tor for details on how to accomplish generic service torification.

Git itself has no notion of access control, so granting access to an individual collaborator grants them this access to all repositories accessible to the git user. This makes such a configuration most useful for a small group of collaborators who all share a set of repositories, as there is no access control at the level of each separate repository. To accomplish more granular access control configurations, see other setups or external guides.

Server configuration

  1. Create the system’s Git user, and its primary group:
    sudo adduser --system --home /srv/git git # Create the "git" user.
    sudo addgroup --system git                # Create the "git" group.
    sudo usermod -g git git                   # Set the "git" user's primary group to the "git" group.
    
  2. Restrict the git user to using git-shell as their login shell:
    1. Append the path to git-shell(1) to /etc/shells (see the manual page for shells(5) for details), if that shell is not already included in the whitelist:
      sudo sh -c 'grep git-shell /etc/shells || echo "$(which git-shell)" >> /etc/shells'
      
    2. Change the shell of the git user to git-shell:
      sudo chsh --shell $(which git-shell) git
      
  3. If you have hardened SSH, you may also need to allow the new git user access to the SSH service:
    # Add the `git` user to the `ssh` group, or whatever group `sshd` restricts (see `AllowGroups` in `sshd_config(5)` for details)
    sudo usermod -a -G ssh git
    
  4. Each collaborator who wants access to the Git server needs to generate their own SSH key. Be certain to generate strong SSH keys with ssh-keygen(1), with commands such as these suggestions:
    # Generate 4096-bit RSA keypair in hardened (new format) key file. Omit `-o` if you have an old SSH.
    ssh-keygen -t rsa -b 4096 -o -a 100
    # Generate a strong Edwards curve 25519 (elliptic curve Diffie-Hellman, ECDH) 128-bit keypair.
    ssh-keygen -t ed25519 -a 100
    

    Collaborators only need to generate one key, but the RSA keypair is compatible with both older and newer SSH servers, while only newer servers recognize ECDH keypairs.
  5. Add the SSH public keys for each collaborator you want to grant Git server access to:
    cd ~git                              # Go to the `git` user's home directory.
    sudo mkdir .ssh                      # Create the user's `.ssh` directory.
    sudo chmod 700 .ssh                  # Restrict access to this directory to only the `git` user itself.
    sudo touch .ssh/authorized_keys      # Create the user's `authorized_keys(8)` file.
    sudo chmod 600 .ssh/authorized_keys  # Restrict access to this file, too.
    sudo chown -R git:git ~git/.ssh      # Assure ownership is set correctly.
    
  6. When a collaborator sends you their SSH public key file, append it to the git user’s authorized_keys file:
    sudo sh -c 'cat /tmp/COLLABORATOR_PUBLIC_KEY_FILE.pub >> ~/.ssh/authorized_keys'
    
  7. Create shared (bare) repositories, if not already created, with restricted access permissions to the git user only (via --shared):
    cd ~git                          # Go to the `git` user's home directory.
    sudo -u git mkdir PROJECT_FOLDER # Make a sensible place to hold repositories for this project.
    sudo -u git git init --bare --shared=0600 PROJECT_FOLDER/REPOSITORY_NAME.git # Initialize the repository itself.
    

Assuming this server is called GIT_SERVER_ADDRESS, clients can now do

git clone git@GIT_SERVER_ADDRESS:PROJECT_FOLDER/REPOSITORY_NAME.git

to get a copy of the repository contents.

Client configuration

If a simple git clone does not succeed, the client’s repository may need to be initialized manually:

  1. Configure the client appropriately:
    mkdir -p ~/src/REPOSITORY_ROOT           # Create a folder to hold the repository.
    cd !$                                    # Go there.
    git init                                 # Initialize the repository.
    git config user.name COLLABORATOR_NAME   # Choose a Git identity name for this repository.
    git config user.email COLLABORATOR_EMAIL # Choose a Git identity email address for this repository.
    
    # If necessary, tell Git to use SSH in a specific way, with a specific identity file (`-i`).
    # (This is only available in Git versions 2.10 and later, which is now widely available. Update your git.)
    git config core.sshCommand "ssh -i ~/.ssh/COLLABORATOR_PRIVATE_KEY_FILE"
    
    # Add the remote repository address.
    git remote add origin git@GIT_SERVER_ADDRESS:PROJECT_FOLDER/REPOSITORY_NAME.git
    git pull                                 # Pull in the changes.
    

Amenities

Numerous additional conveniences can be added atop a simple Git infrastructure. This list provides a couple of suggested configurations for next steps:

See also