Skip to content

micrictor/git-gateway

Repository files navigation

git-gateway

A GIT_SSH_COMMAND-compatible client and gateway that allows the gateway to apply protocol-aware policies to SSH sessions without breaking key authentication.

Without this software (or something very much like it), you cannot prevent a host that needs to upload/download software from a shared git server (e.g. GitHub/GitLab) from uploading/downloading software from organizations, users, and repositories you do not control. This is a data exfiltration and malware risk.

Overview

Because SSH, and by extension Git, often uses key-based authentication, the traffic inside of the SSH session cannot be inspected by traditional proxies using "break-and-inspect". This setup gets around that limitation by having the client securely forward its client-to-server key to the Gateway. Using that key, the Gateway can apply policy on encrypted SSH packets, applying limits on:

  • Remote forwarding, including limitations on addresses/ports
  • Local forwarding, including limitations on addresses/ports
  • PTY allocation
  • X11 forwarding
  • Shell execution
  • Arbitrary subsystems (e.g. sftp)
  • Commands ran

The ability to limit commands ran also gives the Gateway the ability to apply policy on Git traffic, permitting or denying downloading/uploading data based on hostname and Git path.

Configuring the Client

Git can be configured globally with the gateway client using core.sshCommand:

git config --global core.sshCommand \
  '/usr/local/bin/git-gateway-ssh --gateway jump@gateway.example.com:22'

git clone git@github.com:example/repository.git

Testing

  1. Make the software and a test host key for the gateway
make all && make host-key
  1. In one window, run the server:
# Replace authorized key with whatever ssh key you actually have available
bin/ssh-gateway -authorized-key ~/.ssh/id_rsa.pub -host-key ./gateway_host_ed25519
  1. Run git with the custom command:
# Should work - policy permits this repo
GIT_GATEWAY_INSECURE_HOST_KEY='true' GIT_SSH_COMMAND='bin/git-gateway-s
sh --gateway jump@127.0.0.1:2222' git pull

# Should fail - policy default denies
GIT_GATEWAY_INSECURE_HOST_KEY='true' GIT_SSH_COMMAND='bin/git-gateway-ssh --gateway jump@127.0.0.1:2222' git clone git@github.com:git/git.git

Example rejection:

micrictor@laptop:~/git-gateway$ GIT_GATEWAY_INSECURE_HOST_KEY='true' GIT_SSH_COMMAND='bin/git-gateway-ssh --gateway jump@127.0.0.1:2222' git clone git@github.com:git/git.git
Cloning into 'git'...
git-gateway-ssh: gateway policy denied request: Git policy denied fetch for git/git on github.com
git-gateway-ssh: gateway policy denied request: Git policy denied fetch for git/git on github.com
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Proposed Deployment

  1. Deploy system Git config to use the custom client.
  • Install the gateway trusted key/certificate
  • In /etc/gitconfig (or similar file) on all endpoints, add:
[core]
  sshCommand = '/path/to/git-gateway-ssh --gateway jump@yourgateway:22'
  1. Via host or network firewalls, block SSH traffic directly to all "known" public Git servers (GitHub/GitLab/Bitbucket/Gitee/Codeberg), forcing the use of the proxy to connect to those hosts.

A more agressive approach would be to block ALL ssh traffic that does not route via the Gateway. For this to work without breaking SSH, that would require you to:

  • Alter the gateway logic to only conditionally allow "failopen" when the destination IPs are not known git servers (i.e. not GitHub/GitLab/Bitbucket/Codeberg/etc)
    • Potential advantage of this is that you could use your "onboarded" git clients to continously build a set of known "git server" IPs.
  • Build a patched version of an SSH client that supports the gateway's required key-forwarding, giving you the ability to apply SSH-aware policy to all of your SSH traffic.

About

Git-Aware SSH Gateway

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages