Tunneling git through ssh (to get past a firewall): port specification interperted as relative path?
Why does it not work
http://localhost:3333/path/to/repo.git
This fails because the URL's hostname is different (localhost
vs server2
), and as a result the server uses a different configuration.
All HTTP clients send the requested hostname to the server, and the server may choose from several configurations (virtual hosts) based on that name. This is how many websites (often hundreds) can share the same IP address at a hosting provider.
localhost:3333/path/to/repo.git
This fails because it's not an HTTP URL, or in fact any URL at all. (Git is not a web browser and doesn't assume http://
by default.)
Instead it's an rcp-style SSH address in the form [user@]host:path
. You might have seen it earlier as [email protected]:foo/bar.git
, where the ssh@
prefix is really just a SSH username.
Git treats it as equivalent to ssh://[user@]host[:port]/path
URLs, except the rcp-style addresses do not have a port field at all.
What to do
curl, the HTTP client used by Git, supports SOCKS proxies as provided by ssh -D
dynamic tunnel.
Set up a dynamic (SOCKS) tunnel with:
ssh username@serverA -D 1080 -N
Configure Git to use it as a proxy:
Globally (or per-repository):
git config [--global] http.proxy socks5://localhost:1080
For a single command:
git -c http.proxy=socks5://localhost:1080 clone http://serverB/repo.git
The socks5
and socks4
protocols perform DNS resolution on the client side, while socks5h
and socks4a
pass all hostnames through SOCKS to the SSH server.
Related videos on Youtube
Kristin
Updated on September 18, 2022Comments
-
Kristin over 1 year
I have access to server A via ssh, and from server A can access server B, which runs gitlabs and contains the repository I need access to. When I am ssh'd into server A, I can run
git clone http://serverB/path/to/repo.git
successfully. Usingssh://
orgit://
instead ofhttp://
does not work. (Errors are "does not appear to be a git repository" and "unable to connect to serverB," respectively.)If I set up a tunnel like this:
ssh username@serverA -L 3333:serverB:80 -N
The following two attempts at git clones fail:
git clone http://localhost:3333/path/to/repo.git
Fails with: "fatal: repository not found"
git clone localhost:3333/path/to/repo.git
Prompts me for my password for serverB, and then fails with "fatal: 3333/path/to/repo.git does not appear to be a git repository." Of course, it isn't! My attempt at specifying localhost, port 3333, is clearly being interpreted as a relative path on serverB.
Is there a way to fix this? Is something fundamentally wrong with this approach?
-
Kristin over 7 yearsWhen I try this, I get "Could not resolve host: serverB". But, I can access this same serverB URL via a web browser, using foxyproxy and the SOCKS tunnel created in (1.) Any ideas?
-
user1686 over 7 yearsTry the
socks5h://
type in that case, or maybesocks4a://
. That'll let the server do the hostname resolution, instead of the client. -
Kristin over 7 years
socks5h://
did it! Thanks for the help and detailed explanation. -
eri0o about 5 yearswhere should command from item 1 be ran? At serverA, B or on my pc?
-
user1686 about 5 years@eri0o: You run this on the same computer that you'll be running the Git commands on. So usually you run it on the local computer and it connects to serverA (like regular ssh).