12

There are tons of identical solutions over the internet for defining proxy tunnel for git's downloads like this one, which all is by setting git's https.proxy & http.proxy config. but those answers are not working when you try to clone/push/pull etc. over the ssh protocol!

For example, by setting git config --global https.proxy socks5://127.0.0.1:9999 when you try to clone git clone git@github.org:user/repo.git it does not go through the defined sock5 tunnel!

I've tried various thing but none was working!

Question:

How to set git to use a local socks5 proxy (e.g. 127.0.0.1:9999) when it uses ssh connections?

dariush
  • 3,191
  • 3
  • 24
  • 43

5 Answers5

22

There are 2 types to clone git: HTTP, and ssh. There are 2 common types of proxy: HTTP, and socks.

Here's the method dealing with 2 * 2 conditions:

# Method 1. git http + proxy http
git config --global http.proxy "http://127.0.0.1:1080"
git config --global https.proxy "http://127.0.0.1:1080"

# Method 2. git http + proxy shocks
git config --global http.proxy "socks5://127.0.0.1:1080"
git config --global https.proxy "socks5://127.0.0.1:1080"

# to unset
git config --global --unset http.proxy
git config --global --unset https.proxy

# Method 3. git ssh + proxy http
vim ~/.ssh/config
Host github.com
HostName github.com
User git
ProxyCommand socat - PROXY:127.0.0.1:%h:%p,proxyport=1087

# Method 4. git ssh + proxy socks
vim ~/.ssh/config
Host github.com
HostName github.com
User git
ProxyCommand nc -v -x 127.0.0.1:1080 %h %p

Sheldon
  • 481
  • 4
  • 6
  • 1
    I know this because it's necessary for Chinese guys, hh. https://www.notion.so/Accelerate-Git-in-China-d1b66e3a51bd4051b79f8ff435aafb59 – Sheldon May 13 '21 at 02:15
  • Use `Method 4` succeeded! – spike014 Sep 08 '22 at 08:31
  • For method 3 & method 4, do NOT change the 'Host github.com' part or you will lose 10 mins to debug as I did. – Orca Sep 08 '22 at 08:54
  • 1
    You can't do metod 4 if your proxy requires authentication, but you can use `ncat` as follow: `ProxyCommand ncat --proxy : --proxy-type socks5 --proxy-auth : %h %p` – Héctor Valverde Oct 28 '22 at 14:22
  • for all windows platform guys. Use ProxyCommand connect -S localhost:1081 %h %p instead. – zz-m Nov 17 '22 at 08:42
11

After some visiting so many pages, I finally find the solution to my question:

# [step 1] create a ssh-proxy
  ssh -D 9999 -qCN user@server.net

# [step 2] make git connect through the ssh-proxy
  # [current script only]
  export GIT_SSH_COMMAND='ssh -o ProxyCommand="connect -S 127.0.0.1:9999 %h %p"'
  # OR [git global setting] 
  git config --global core.sshCommand 'ssh -o ProxyCommand="connect -S 127.0.0.1:9999 %h %p"'
  # OR [one-time only use]
  git clone -c=core.sshCommand 'ssh -o ProxyCommand="connect -S 127.0.0.1:9999 %h %p"' git@github.com:user/repo.git
  # OR [current repository use only]
  git config core.sshCommand 'ssh -o ProxyCommand="connect -S 127.0.0.1:9999 %h %p"'

To install connect on Ubuntu:

sudo apt install connect-proxy
dariush
  • 3,191
  • 3
  • 24
  • 43
  • It says ```kex_exchange_identification: Connection closed by remote host. Connection closed by UNKNOWN port 65535``` – Ziyuan Jan 06 '23 at 11:40
  • Verify that you can actually connect yo the server through a normal ssh – dariush Jan 11 '23 at 16:42
8

The previous answers may work but I find them overly complex.

The most common case should be to access a corporate git server over a SOCKS5 proxy. In this example:

  • Git server: git.evilcorp.com
  • SOCKS5 proxy: localhost:11080

The easiest way to configure git in this case is to have a nice SSH config for the git server (~/.ssh/config):

Host git.evilcorp.com
  # Identity file specifies wich SSH key used to access the git server.
  Identityfile ~/.ssh/id_rsa
  # ProxyCommand does the magic to access the proxy server.
  ProxyCommand /bin/nc -X 5 -x 127.0.0.1:11080 %h %p

Cool detail: The DNS resolution is done by the proxy, so your machine doesn't need to know about the corp DNS servers.

Telegrapher
  • 330
  • 4
  • 11
4

git's own git --config 'http.proxy=socks5://127.0.0.1:4444' or ssh_config's proxycommand using socat and nc techniques successfully reroute git commands over the SOCKS proxy.

The problem could be, however, that the DNS lookup fails due to the lookup being done locally rather than remotely over over the SOCKS proxy. For example, in the case of an intranet, the servers may not have domain names on the internet (only known to intranet DNS).

There are two ways to solve this. The first one I've seen recommended several times, but it makes the ambitious assumption that you control the remote server.

  1. Reroute local 53 traffic (DNS) to port X, forward that to the server at port Y, forward port Y to 53 on the server. Usually X=Y for simplicity.

  2. Intercept local system calls that retrieve ip addresses for names.

I would argue that 2. is better, because it catches the problem at the source and only assumes that you control your local machine, which is a more likely case than controlling the remote server.

proxychains-ng intecepts the getaddrinfo system call before it accesses your local nss.

Steps

Open a SOCKS5 port

ssh -v -NT -D 127.0.0.1:4444 intranethost

Setup proxychains to use that port.

~/.proxychains/proxychains.conf

strict_chain
proxy_dns
tcp_read_time_out 150000
tcp_connect_time_out 80000

[ProxyList]
socks5 127.0.0.1 4444

Use proxychains to encapsulate git.

alias gitproxy='proxychains git'
gitproxy clone intranethost:path/to/repo.git

The beauty of taking this route is that this is all transparent to git and its remotes.

Jonathan Komar
  • 2,678
  • 4
  • 32
  • 43
  • On the proxy the DNS Server 4.2.2.2 is used by default to work around this, use the following alias: alias gitproxy='PROXYRESOLV_DNS=$IP_OF_YOUR_DNS_SERVER proxychains git' – arved May 04 '21 at 14:04
  • 2
    If DNS is the problem, just use `socks5h` to use remote dns resolution: `git --config 'http.proxy=socks5h://127.0.0.1:4444'` – PhillyTheThrilly May 27 '21 at 16:50
  • @PhillyTheThrilly Nice one. I did not know about socks5h. Your comment seems like it should be an answer. – Jonathan Komar Jul 28 '21 at 05:03
2

You need to define the GIT_SSH_COMMAND environment variable first

In it, you can redefine the ssh command, in order to use your socks proxy setting

ssh -D $port_number $hostname
# or
ssh -D $port_number $username@$hostname

Or using a proxycommand nc (or ncat on Windows)

The point is: once ssh is working with your socks5 proxy, you can define the same syntax in GIT_SSH_COMMAND, and Git will use the right ssh command.

You can also test it with a local configuration:

git -c core.sshCommand='ssh -D 9998 user@host.com' git pull
git -c core.sshCommand='ssh -D 9999 127.0.0.1' git pull
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks for the answer, I couldn't come up with you solution, Let's say I have `host` and `user` to set up my socks5 proxy with `sh -D 9999 -C -N user@host.com`; with your instructions I have tried the followings: `GIT_SSH_COMMAND='ssh -D 9998 user@host.com' git pull` (with no proxy tunnel running in the system) and `GIT_SSH_COMMAND='ssh -D 9999 127.0.0.1' git pull` (when a proxy is running at port: 9999 at localhost) none was success. Maybe I'm doing it wrong, can you be kind enough to write a copy & past solution? [The connection with none of the above approaches was got through the proxy!] – dariush Oct 05 '19 at 08:05
  • What is you OS, OS version, shell, shell version, Git version? – VonC Oct 05 '19 at 08:08
  • Os: `Ubuntu 18.04` shell: `GNU bash, version 4.4.20` git: `2.23.0` – dariush Oct 05 '19 at 08:09
  • @dariush Does your ssh work through the proxy, without using Git? – VonC Oct 05 '19 at 08:11
  • just updated my comment, mistakenly press Enter for new-line and it submitted the comment – dariush Oct 05 '19 at 08:12
  • No, I but in the browser when I set the proxy details, the browser goes through the ssh-proxy, The command which I created the proxy to one of my VPS is: `ssh -D 9999 -C -N user@host.com` – dariush Oct 05 '19 at 08:16
  • worth to mention that by using command `ssh -D 9999 -C -N user@host.com` a socks5 proxy will run in my localhost at port `9999` – dariush Oct 05 '19 at 08:18
  • @dariush I have an errand to make, but the goal is: make sure your SSH commands work, from command line (without using Git): once that works, then Git can easily use the same SSH command for all its SSH calls. – VonC Oct 05 '19 at 08:31